2
* This file is part of the Main Menu.
4
* Copyright (c) 2007 Novell, Inc.
6
* The Main Menu is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License as published by the Free
8
* Software Foundation; either version 2 of the License, or (at your option)
11
* The Main Menu is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16
* You should have received a copy of the GNU General Public License along with
17
* the Main Menu; if not, write to the Free Software Foundation, Inc., 51
18
* Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
#include "bookmark-agent.h"
26
# define PACKAGE "gnome-main-menu"
33
#include <glib/gi18n.h>
34
#include <glib/gstdio.h>
37
#include "libslab-utils.h"
39
#define MODIFIABLE_APPS_GCONF_KEY "/desktop/gnome/applications/main-menu/lock-down/user_modifiable_apps"
40
#define MODIFIABLE_DOCS_GCONF_KEY "/desktop/gnome/applications/main-menu/lock-down/user_modifiable_docs"
41
#define MODIFIABLE_DIRS_GCONF_KEY "/desktop/gnome/applications/main-menu/lock-down/user_modifiable_dirs"
42
#define MODIFIABLE_SYS_GCONF_KEY "/desktop/gnome/applications/main-menu/lock-down/user_modifiable_system_area"
44
#define USER_APPS_STORE_FILE_NAME "applications.xbel"
45
#define USER_DOCS_STORE_FILE_NAME "documents.xbel"
46
#define USER_DIRS_STORE_FILE_NAME "places.xbel"
47
#define SYSTEM_STORE_FILE_NAME "system-items.xbel"
48
#define CALC_TEMPLATE_FILE_NAME "empty.ots"
49
#define WRITER_TEMPLATE_FILE_NAME "empty.ott"
51
#define GTK_BOOKMARKS_FILE ".gtk-bookmarks"
53
#define TYPE_IS_RECENT(type) ((type) == BOOKMARK_STORE_RECENT_APPS || (type) == BOOKMARK_STORE_RECENT_DOCS)
56
BookmarkStoreType type;
60
BookmarkStoreStatus status;
66
gchar *user_store_path;
67
gboolean user_modifiable;
69
const gchar *store_filename;
70
const gchar *lockdown_key;
72
GFileMonitor *store_monitor;
73
GFileMonitor *user_store_monitor;
76
void (* update_path) (BookmarkAgent *);
77
void (* load_store) (BookmarkAgent *);
78
void (* save_store) (BookmarkAgent *);
79
void (* create_item) (BookmarkAgent *, const gchar *);
81
gchar *gtk_store_path;
82
GFileMonitor *gtk_store_monitor;
83
} BookmarkAgentPrivate;
85
#define PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BOOKMARK_AGENT_TYPE, BookmarkAgentPrivate))
93
static BookmarkAgent *instances [BOOKMARK_STORE_N_TYPES];
95
static BookmarkAgentClass *bookmark_agent_parent_class = NULL;
97
static void bookmark_agent_base_init (BookmarkAgentClass *);
98
static void bookmark_agent_class_init (BookmarkAgentClass *);
99
static void bookmark_agent_init (BookmarkAgent *);
100
static BookmarkAgent *bookmark_agent_new (BookmarkStoreType );
102
static void get_property (GObject *, guint, GValue *, GParamSpec *);
103
static void set_property (GObject *, guint, const GValue *, GParamSpec *);
104
static void finalize (GObject *);
106
static void update_agent (BookmarkAgent *);
107
static void update_items (BookmarkAgent *);
108
static void save_store (BookmarkAgent *);
109
static gint get_rank (BookmarkAgent *, const gchar *);
110
static void set_rank (BookmarkAgent *, const gchar *, gint);
112
static void load_xbel_store (BookmarkAgent *);
113
static void load_places_store (BookmarkAgent *);
114
static void update_user_spec_path (BookmarkAgent *);
115
static void save_xbel_store (BookmarkAgent *);
116
static void create_app_item (BookmarkAgent *, const gchar *);
117
static void create_doc_item (BookmarkAgent *, const gchar *);
118
static void create_dir_item (BookmarkAgent *, const gchar *);
120
static void store_monitor_cb (GFileMonitor *, GFile *, GFile *,
121
GFileMonitorEvent, gpointer);
122
static void gconf_notify_cb (GConfClient *, guint, GConfEntry *, gpointer);
123
static void weak_destroy_cb (gpointer, GObject *);
125
static gint recent_item_mru_comp_func (gconstpointer a, gconstpointer b);
127
static gchar *find_package_data_file (const gchar *filename);
131
bookmark_agent_get_type ()
133
static GType g_define_type_id = 0;
135
if (G_UNLIKELY (g_define_type_id == 0)) {
136
static const GTypeInfo info = {
137
sizeof (BookmarkAgentClass),
138
(GBaseInitFunc) bookmark_agent_base_init,
140
(GClassInitFunc) bookmark_agent_class_init,
142
sizeof (BookmarkAgent), 0,
143
(GInstanceInitFunc) bookmark_agent_init,
147
g_define_type_id = g_type_register_static (
148
G_TYPE_OBJECT, "BookmarkAgent", & info, 0);
151
return g_define_type_id;
155
bookmark_agent_get_instance (BookmarkStoreType type)
157
g_return_val_if_fail (0 <= type, NULL);
158
g_return_val_if_fail (type < BOOKMARK_STORE_N_TYPES, NULL);
160
if (! instances [type]) {
161
instances [type] = bookmark_agent_new (type);
162
g_object_weak_ref (G_OBJECT (instances [type]), weak_destroy_cb, GINT_TO_POINTER (type));
165
g_object_ref (G_OBJECT (instances [type]));
167
return instances [type];
171
bookmark_agent_has_item (BookmarkAgent *this, const gchar *uri)
173
return g_bookmark_file_has_item (PRIVATE (this)->store, uri);
177
bookmark_agent_add_item (BookmarkAgent *this, const BookmarkItem *item)
179
BookmarkAgentPrivate *priv = PRIVATE (this);
184
g_return_if_fail (priv->user_modifiable);
185
g_return_if_fail (item->uri);
186
g_return_if_fail (item->mime_type);
188
g_bookmark_file_set_mime_type (priv->store, item->uri, item->mime_type);
191
g_bookmark_file_set_modified (priv->store, item->uri, item->mtime);
194
g_bookmark_file_set_title (priv->store, item->uri, item->title);
196
g_bookmark_file_add_application (priv->store, item->uri, item->app_name, item->app_exec);
198
set_rank (this, item->uri, g_bookmark_file_get_size (priv->store) - 1);
204
bookmark_agent_move_item (BookmarkAgent *this, const gchar *uri, const gchar *uri_new)
206
BookmarkAgentPrivate *priv = PRIVATE (this);
208
GError *error = NULL;
210
if (! TYPE_IS_RECENT (priv->type))
213
gtk_recent_manager_move_item (
214
gtk_recent_manager_get_default (), uri, uri_new, & error);
217
libslab_handle_g_error (
218
& error, "%s: unable to update %s with renamed file, [%s] -> [%s].",
219
G_STRFUNC, priv->store_path, uri, uri_new);
223
bookmark_agent_remove_item (BookmarkAgent *this, const gchar *uri)
225
BookmarkAgentPrivate *priv = PRIVATE (this);
229
GError *error = NULL;
236
g_return_if_fail (priv->user_modifiable);
238
if (! bookmark_agent_has_item (this, uri))
241
if (TYPE_IS_RECENT (priv->type)) {
242
gtk_recent_manager_remove_item (
243
gtk_recent_manager_get_default (), uri, & error);
246
libslab_handle_g_error (
247
& error, "%s: unable to remove [%s] from %s.",
248
G_STRFUNC, priv->store_path, uri);
251
rank = get_rank (this, uri);
253
g_bookmark_file_remove_item (priv->store, uri, NULL);
256
uris = g_bookmark_file_get_uris (priv->store, NULL);
258
for (i = 0; uris && uris [i]; ++i) {
259
rank_i = get_rank (this, uris [i]);
262
set_rank (this, uris [i], rank_i - 1);
273
bookmark_agent_reorder_items (BookmarkAgent *this, const gchar **uris)
275
BookmarkAgentPrivate *priv = PRIVATE (this);
280
g_return_if_fail (priv->reorderable);
282
for (i = 0; uris && uris [i]; ++i)
283
set_rank (this, uris [i], i);
289
make_items_from_bookmark_file (BookmarkAgent *this, GBookmarkFile *store)
291
BookmarkAgentPrivate *priv = PRIVATE (this);
294
GList *items_ordered;
299
uris = g_bookmark_file_get_uris (store, NULL);
300
items_ordered = NULL;
302
for (i = 0; uris && uris [i]; ++i) {
305
if (priv->type == BOOKMARK_STORE_RECENT_APPS)
306
include = g_bookmark_file_has_group (store, uris [i], "recently-used-apps", NULL);
308
include = ! g_bookmark_file_get_is_private (store, uris [i], NULL);
313
item = g_new0 (BookmarkItem, 1);
315
item->uri = g_strdup (uris [i]);
316
item->mime_type = g_bookmark_file_get_mime_type (store, uris [i], NULL);
317
item->mtime = g_bookmark_file_get_modified (store, uris [i], NULL);
319
items_ordered = g_list_prepend (items_ordered, item);
323
items_ordered = g_list_sort (items_ordered, recent_item_mru_comp_func);
327
return items_ordered;
331
bookmark_agent_update_from_bookmark_file (BookmarkAgent *this, GBookmarkFile *store)
333
BookmarkAgentPrivate *priv;
334
GList *items_ordered;
337
g_return_if_fail (IS_BOOKMARK_AGENT (this));
339
priv = PRIVATE (this);
341
libslab_checkpoint ("bookmark_agent_update_from_bookmark_file(): start updating");
343
items_ordered = make_items_from_bookmark_file (this, store);
345
g_bookmark_file_free (priv->store);
346
priv->store = g_bookmark_file_new ();
348
for (node = items_ordered; node; node = node->next) {
351
item = (BookmarkItem *) node->data;
353
g_bookmark_file_set_mime_type (priv->store, item->uri, item->mime_type);
354
g_bookmark_file_set_modified (priv->store, item->uri, item->mtime);
356
bookmark_item_free (item);
359
g_list_free (items_ordered);
361
libslab_checkpoint ("bookmark_agent_update_from_bookmark_file(): updating internal items");
364
libslab_checkpoint ("bookmark_agent_update_from_bookmark_file(): end updating");
368
bookmark_item_free (BookmarkItem *item)
374
g_free (item->title);
375
g_free (item->mime_type);
377
g_free (item->app_name);
378
g_free (item->app_exec);
383
bookmark_agent_base_init (BookmarkAgentClass *this_class)
387
for (i = 0; i < BOOKMARK_STORE_N_TYPES; ++i)
388
instances [i] = NULL;
392
bookmark_agent_class_init (BookmarkAgentClass *this_class)
394
GObjectClass *g_obj_class = G_OBJECT_CLASS (this_class);
396
GParamSpec *items_pspec;
397
GParamSpec *status_pspec;
400
g_obj_class->get_property = get_property;
401
g_obj_class->set_property = set_property;
402
g_obj_class->finalize = finalize;
404
items_pspec = g_param_spec_pointer (
405
BOOKMARK_AGENT_ITEMS_PROP, BOOKMARK_AGENT_ITEMS_PROP,
406
"the null-terminated list which contains the bookmark items in this store",
407
G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
409
status_pspec = g_param_spec_int (
410
BOOKMARK_AGENT_STORE_STATUS_PROP, BOOKMARK_AGENT_STORE_STATUS_PROP, "the status of the store",
411
BOOKMARK_STORE_DEFAULT_ONLY, BOOKMARK_STORE_USER, BOOKMARK_STORE_DEFAULT,
412
G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
414
g_object_class_install_property (g_obj_class, PROP_ITEMS, items_pspec);
415
g_object_class_install_property (g_obj_class, PROP_STATUS, status_pspec);
417
g_type_class_add_private (this_class, sizeof (BookmarkAgentPrivate));
419
bookmark_agent_parent_class = g_type_class_peek_parent (this_class);
423
bookmark_agent_init (BookmarkAgent *this)
425
BookmarkAgentPrivate *priv = PRIVATE (this);
431
priv->status = BOOKMARK_STORE_ABSENT;
434
priv->needs_sync = FALSE;
436
priv->store_path = NULL;
437
priv->user_store_path = NULL;
438
priv->user_modifiable = FALSE;
439
priv->reorderable = FALSE;
440
priv->store_filename = NULL;
441
priv->lockdown_key = NULL;
443
priv->store_monitor = NULL;
444
priv->user_store_monitor = NULL;
445
priv->gconf_monitor = 0;
447
priv->update_path = NULL;
448
priv->load_store = NULL;
449
priv->save_store = NULL;
450
priv->create_item = NULL;
452
priv->gtk_store_path = NULL;
453
priv->gtk_store_monitor = NULL;
456
static BookmarkAgent *
457
bookmark_agent_new (BookmarkStoreType type)
460
BookmarkAgentPrivate *priv;
461
GFile *gtk_store_file;
463
this = g_object_new (BOOKMARK_AGENT_TYPE, NULL);
464
priv = PRIVATE (this);
467
priv->store = g_bookmark_file_new ();
470
case BOOKMARK_STORE_USER_APPS:
471
priv->lockdown_key = MODIFIABLE_APPS_GCONF_KEY;
472
priv->store_filename = USER_APPS_STORE_FILE_NAME;
473
priv->create_item = create_app_item;
477
case BOOKMARK_STORE_USER_DOCS:
478
priv->lockdown_key = MODIFIABLE_DOCS_GCONF_KEY;
479
priv->store_filename = USER_DOCS_STORE_FILE_NAME;
480
priv->create_item = create_doc_item;
484
case BOOKMARK_STORE_USER_DIRS:
485
priv->lockdown_key = MODIFIABLE_DIRS_GCONF_KEY;
486
priv->store_filename = USER_DIRS_STORE_FILE_NAME;
487
priv->create_item = create_dir_item;
489
priv->user_modifiable = GPOINTER_TO_INT (libslab_get_gconf_value (priv->lockdown_key));
490
priv->reorderable = FALSE;
492
priv->load_store = load_places_store;
494
priv->gtk_store_path = g_build_filename (g_get_home_dir (), GTK_BOOKMARKS_FILE, NULL);
495
gtk_store_file = g_file_new_for_path (priv->gtk_store_path);
496
priv->gtk_store_monitor = g_file_monitor_file (gtk_store_file,
498
if (priv->gtk_store_monitor) {
499
g_signal_connect (priv->gtk_store_monitor, "changed",
500
G_CALLBACK (store_monitor_cb), this);
503
g_object_unref (gtk_store_file);
507
case BOOKMARK_STORE_RECENT_APPS:
508
case BOOKMARK_STORE_RECENT_DOCS:
509
priv->user_modifiable = TRUE;
510
priv->reorderable = FALSE;
512
priv->store_path = g_build_filename (g_get_home_dir (), ".recently-used.xbel", NULL);
516
case BOOKMARK_STORE_SYSTEM:
517
priv->lockdown_key = MODIFIABLE_SYS_GCONF_KEY;
518
priv->store_filename = SYSTEM_STORE_FILE_NAME;
519
priv->create_item = create_app_item;
528
type == BOOKMARK_STORE_USER_APPS || type == BOOKMARK_STORE_USER_DOCS ||
529
type == BOOKMARK_STORE_USER_DIRS || type == BOOKMARK_STORE_SYSTEM)
531
priv->user_modifiable = GPOINTER_TO_INT (libslab_get_gconf_value (priv->lockdown_key));
533
priv->user_store_path = g_build_filename (
534
g_get_user_data_dir (), PACKAGE, priv->store_filename, NULL);
536
priv->update_path = update_user_spec_path;
538
priv->gconf_monitor = libslab_gconf_notify_add (
539
priv->lockdown_key, gconf_notify_cb, this);
542
if (type == BOOKMARK_STORE_USER_APPS || type == BOOKMARK_STORE_USER_DOCS || type == BOOKMARK_STORE_SYSTEM) {
543
priv->reorderable = TRUE;
544
priv->load_store = load_xbel_store;
545
priv->save_store = save_xbel_store;
554
get_property (GObject *g_obj, guint prop_id, GValue *value, GParamSpec *pspec)
556
BookmarkAgent *this = BOOKMARK_AGENT (g_obj);
557
BookmarkAgentPrivate *priv = PRIVATE (this);
562
g_value_set_pointer (value, priv->items);
566
g_value_set_int (value, priv->status);
572
set_property (GObject *g_obj, guint prop_id, const GValue *value, GParamSpec *pspec)
574
/* no writeable properties */
578
finalize (GObject *g_obj)
580
BookmarkAgent *this = BOOKMARK_AGENT (g_obj);
581
BookmarkAgentPrivate *priv = PRIVATE (g_obj);
586
for (i = 0; priv->items && priv->items [i]; ++i)
587
bookmark_item_free (priv->items [i]);
589
g_free (priv->items);
590
g_free (priv->store_path);
591
g_free (priv->user_store_path);
592
g_free (priv->gtk_store_path);
594
if (priv->store_monitor) {
595
g_signal_handlers_disconnect_by_func (priv->store_monitor, store_monitor_cb, this);
596
g_file_monitor_cancel (priv->store_monitor);
597
g_object_unref (priv->store_monitor);
600
if (priv->user_store_monitor) {
601
g_signal_handlers_disconnect_by_func (priv->user_store_monitor, store_monitor_cb, this);
602
g_file_monitor_cancel (priv->user_store_monitor);
603
g_object_unref (priv->user_store_monitor);
606
if (priv->gtk_store_monitor) {
607
g_signal_handlers_disconnect_by_func (priv->gtk_store_monitor, store_monitor_cb, this);
608
g_file_monitor_cancel (priv->gtk_store_monitor);
609
g_object_unref (priv->gtk_store_monitor);
612
libslab_gconf_notify_remove (priv->gconf_monitor);
614
g_bookmark_file_free (priv->store);
616
G_OBJECT_CLASS (bookmark_agent_parent_class)->finalize (g_obj);
620
update_agent (BookmarkAgent *this)
622
BookmarkAgentPrivate *priv = PRIVATE (this);
624
if (priv->update_path)
625
priv->update_path (this);
627
if (priv->load_store)
628
priv->load_store (this);
634
update_items (BookmarkAgent *this)
636
BookmarkAgentPrivate *priv = PRIVATE (this);
639
gchar **uris_ordered = NULL;
643
gboolean needs_update = FALSE;
644
gboolean store_corrupted = FALSE;
645
gchar *new_title, *old_title;
650
uris = g_bookmark_file_get_uris (priv->store, & n_uris);
651
uris_ordered = g_new0 (gchar *, n_uris + 1);
652
uris_ordered [n_uris] = NULL;
654
for (i = 0; uris && uris [i]; ++i) {
655
rank = get_rank (this, uris [i]);
657
if (rank < 0 || rank >= n_uris)
660
if (uris_ordered [rank]) {
661
store_corrupted = TRUE;
664
for (rank = 0; rank < n_uris; ++rank)
665
if (! uris_ordered [rank])
669
"store corruption [%s] - multiple uris with same rank (%d): [%s] [%s], moving latter to %d",
670
priv->store_path, rank_corr, uris_ordered [rank_corr], uris [i], rank);
673
set_rank (this, uris [i], rank);
675
uris_ordered [rank] = uris [i];
678
if (priv->n_items != n_uris)
681
for (i = 0; ! needs_update && uris_ordered && uris_ordered [i]; ++i) {
682
if (priv->type == BOOKMARK_STORE_USER_DIRS) {
683
new_title = g_bookmark_file_get_title (priv->store, uris_ordered [i], NULL);
684
old_title = priv->items [i]->title;
685
if (!new_title && !old_title) {
686
if (strcmp (priv->items [i]->uri, uris_ordered [i]))
689
else if ((new_title && !old_title) || (!new_title && old_title))
691
else if (strcmp (old_title, new_title))
695
else if (strcmp (priv->items [i]->uri, uris_ordered [i]))
700
for (i = 0; priv->items && priv->items [i]; ++i)
701
bookmark_item_free (priv->items [i]);
703
g_free (priv->items);
705
priv->n_items = n_uris;
706
priv->items = g_new0 (BookmarkItem *, priv->n_items + 1);
708
for (i = 0; uris_ordered && uris_ordered [i]; ++i) {
709
priv->items [i] = g_new0 (BookmarkItem, 1);
710
priv->items [i]->uri = g_strdup (uris_ordered [i]);
711
priv->items [i]->title = g_bookmark_file_get_title (priv->store, uris_ordered [i], NULL);
712
priv->items [i]->mime_type = g_bookmark_file_get_mime_type (priv->store, uris_ordered [i], NULL);
713
priv->items [i]->mtime = g_bookmark_file_get_modified (priv->store, uris_ordered [i], NULL);
714
priv->items [i]->app_name = NULL;
715
priv->items [i]->app_exec = NULL;
717
g_bookmark_file_get_icon (priv->store, uris_ordered [i], & priv->items [i]->icon, NULL, NULL);
720
/* Since the bookmark store for recently-used items is updated by the caller of BookmarkAgent,
721
* we don't emit notifications in that case. The caller will know when to update itself.
723
if (!TYPE_IS_RECENT (priv->type))
724
g_object_notify (G_OBJECT (this), BOOKMARK_AGENT_ITEMS_PROP);
731
g_free (uris_ordered);
735
save_store (BookmarkAgent *this)
737
BookmarkAgentPrivate *priv = PRIVATE (this);
742
g_return_if_fail (priv->user_modifiable);
744
priv->needs_sync = TRUE;
745
priv->update_path (this);
747
dir = g_path_get_dirname (priv->store_path);
748
g_mkdir_with_parents (dir, 0700);
751
priv->save_store (this);
756
get_rank (BookmarkAgent *this, const gchar *uri)
758
BookmarkAgentPrivate *priv = PRIVATE (this);
766
if (! priv->reorderable)
769
groups = g_bookmark_file_get_groups (priv->store, uri, NULL, NULL);
772
for (i = 0; groups && groups [i]; ++i) {
773
if (g_str_has_prefix (groups [i], "rank-")) {
776
"store corruption - multiple ranks for same uri: [%s] [%s]",
777
priv->store_path, uri);
779
rank = atoi (& groups [i] [5]);
789
set_rank (BookmarkAgent *this, const gchar *uri, gint rank)
791
BookmarkAgentPrivate *priv = PRIVATE (this);
799
if (! (priv->reorderable && bookmark_agent_has_item (this, uri)))
802
groups = g_bookmark_file_get_groups (priv->store, uri, NULL, NULL);
804
for (i = 0; groups && groups [i]; ++i)
805
if (g_str_has_prefix (groups [i], "rank-"))
806
g_bookmark_file_remove_group (priv->store, uri, groups [i], NULL);
810
group = g_strdup_printf ("rank-%d", rank);
811
g_bookmark_file_add_group (priv->store, uri, group);
816
load_xbel_store (BookmarkAgent *this)
818
BookmarkAgentPrivate *priv = PRIVATE (this);
822
GError *error = NULL;
827
if (!priv->store_path)
830
libslab_checkpoint ("load_xbel_store(): start loading %s", priv->store_path);
831
success = g_bookmark_file_load_from_file (priv->store, priv->store_path, & error);
832
libslab_checkpoint ("load_xbel_store(): end loading %s", priv->store_path);
836
g_bookmark_file_free (priv->store);
837
priv->store = g_bookmark_file_new ();
839
libslab_handle_g_error (
840
& error, "%s: couldn't load bookmark file [%s]\n",
841
G_STRFUNC, priv->store_path ? priv->store_path : "NULL");
846
libslab_checkpoint ("load_xbel_store(): start creating items from %s", priv->store_path);
848
uris = g_bookmark_file_get_uris (priv->store, NULL);
850
for (i = 0; uris && uris [i]; ++i)
851
priv->create_item (this, uris [i]);
855
libslab_checkpoint ("load_xbel_store(): end creating items from %s", priv->store_path);
859
load_places_store (BookmarkAgent *this)
861
BookmarkAgentPrivate *priv = PRIVATE (this);
865
gchar **bookmarks = NULL;
867
gchar *buf, *label, *uri;
869
gint i, j, bookmark_len;
871
load_xbel_store (this);
873
uris = g_bookmark_file_get_uris (priv->store, NULL);
875
for (i = 0; uris && uris [i]; ++i) {
876
groups = g_bookmark_file_get_groups (priv->store, uris [i], NULL, NULL);
878
for (j = 0; groups && groups [j]; ++j) {
879
if (! strcmp (groups [j], "gtk-bookmarks")) {
880
g_bookmark_file_remove_item (priv->store, uris [i], NULL);
891
g_file_get_contents (priv->gtk_store_path, & buf, NULL, NULL);
894
bookmarks = g_strsplit (buf, "\n", -1);
898
for (i = 0; bookmarks && bookmarks [i]; ++i) {
899
bookmark_len = strlen (bookmarks [i]);
900
if (bookmark_len > 0) {
901
label = strstr (bookmarks[i], " ");
903
uri = g_strndup (bookmarks [i], bookmark_len - strlen (label));
906
g_bookmark_file_add_group (priv->store, uri, "gtk-bookmarks");
907
priv->create_item (this, uri);
910
if (strlen (label) > 0)
911
g_bookmark_file_set_title (priv->store, uri, label);
917
g_strfreev (bookmarks);
921
find_package_data_file (const gchar *filename)
923
const gchar * const *dirs = NULL;
928
dirs = g_get_system_data_dirs ();
930
for (i = 0; ! path && dirs && dirs [i]; ++i) {
931
path = g_build_filename (dirs [i], PACKAGE, filename, NULL);
933
if (! g_file_test (path, G_FILE_TEST_EXISTS)) {
943
update_user_spec_path (BookmarkAgent *this)
945
BookmarkAgentPrivate *priv = PRIVATE (this);
947
gboolean use_user_path;
950
BookmarkStoreStatus status;
952
use_user_path = priv->user_modifiable &&
953
(priv->needs_sync || g_file_test (priv->user_store_path, G_FILE_TEST_EXISTS));
956
path = g_strdup (priv->user_store_path);
958
path = find_package_data_file (priv->store_filename);
961
status = BOOKMARK_STORE_USER;
962
else if (path && priv->user_modifiable)
963
status = BOOKMARK_STORE_DEFAULT;
965
status = BOOKMARK_STORE_DEFAULT_ONLY;
967
status = BOOKMARK_STORE_ABSENT;
969
if (priv->status != status) {
970
priv->status = status;
971
g_object_notify (G_OBJECT (this), BOOKMARK_AGENT_STORE_STATUS_PROP);
973
if (priv->user_store_monitor) {
974
g_file_monitor_cancel (priv->user_store_monitor);
975
g_object_unref (priv->user_store_monitor);
976
priv->user_store_monitor = NULL;
979
if (priv->status == BOOKMARK_STORE_DEFAULT) {
980
GFile *user_store_file;
982
user_store_file = g_file_new_for_path (priv->user_store_path);
983
priv->user_store_monitor = g_file_monitor_file (user_store_file,
985
if (priv->user_store_monitor) {
986
g_signal_connect (priv->user_store_monitor, "changed",
987
G_CALLBACK (store_monitor_cb), this);
990
g_object_unref (user_store_file);
994
if (libslab_strcmp (priv->store_path, path)) {
995
g_free (priv->store_path);
996
priv->store_path = path;
998
if (priv->store_monitor) {
999
g_file_monitor_cancel (priv->store_monitor);
1000
g_object_unref (priv->store_monitor);
1003
if (priv->store_path) {
1006
store_file = g_file_new_for_path (priv->store_path);
1007
priv->store_monitor = g_file_monitor_file (store_file,
1009
if (priv->store_monitor) {
1010
g_signal_connect (priv->store_monitor, "changed",
1011
G_CALLBACK (store_monitor_cb), this);
1014
g_object_unref (store_file);
1022
save_xbel_store (BookmarkAgent *this)
1024
BookmarkAgentPrivate *priv = PRIVATE (this);
1026
GError *error = NULL;
1029
if (! g_bookmark_file_to_file (priv->store, priv->store_path, & error))
1030
libslab_handle_g_error (
1031
& error, "%s: couldn't save bookmark file [%s]\n", G_STRFUNC, priv->store_path);
1035
create_app_item (BookmarkAgent *this, const gchar *uri)
1037
BookmarkAgentPrivate *priv = PRIVATE (this);
1039
GnomeDesktopItem *ditem;
1040
gchar *uri_new = NULL;
1042
ditem = libslab_gnome_desktop_item_new_from_unknown_id (uri);
1045
uri_new = g_strdup (gnome_desktop_item_get_location (ditem));
1046
gnome_desktop_item_unref (ditem);
1052
if (libslab_strcmp (uri, uri_new))
1053
g_bookmark_file_move_item (priv->store, uri, uri_new, NULL);
1059
create_doc_item (BookmarkAgent *this, const gchar *uri)
1061
BookmarkAgentPrivate *priv = PRIVATE (this);
1063
gchar *uri_new = NULL;
1067
gchar *template = NULL;
1072
if (! (strcmp (uri, "BLANK_SPREADSHEET") && strcmp (uri, "BLANK_DOCUMENT"))) {
1073
dir = g_build_filename (g_get_home_dir (), "Documents", NULL);
1075
if (! strcmp (uri, "BLANK_SPREADSHEET")) {
1076
g_bookmark_file_set_title (priv->store, uri, "BLANK_SPREADSHEET");
1077
file = g_strconcat (_("New Spreadsheet"), ".ots", NULL);
1078
template = find_package_data_file (CALC_TEMPLATE_FILE_NAME);
1081
g_bookmark_file_set_title (priv->store, uri, "BLANK_DOCUMENT");
1082
file = g_strconcat (_("New Document"), ".ott", NULL);
1083
template = find_package_data_file (WRITER_TEMPLATE_FILE_NAME);
1086
path = g_build_filename (dir, file, NULL);
1088
if (! g_file_test (path, G_FILE_TEST_EXISTS)) {
1089
g_mkdir_with_parents (dir, 0700);
1091
if (template != NULL) {
1092
if (g_file_get_contents (template, & contents, & length, NULL))
1093
g_file_set_contents (path, contents, length, NULL);
1098
fclose (g_fopen (path, "w"));
1101
uri_new = g_filename_to_uri (path, NULL, NULL);
1112
if (libslab_strcmp (uri, uri_new))
1113
g_bookmark_file_move_item (priv->store, uri, uri_new, NULL);
1119
create_dir_item (BookmarkAgent *this, const gchar *uri)
1121
BookmarkAgentPrivate *priv = PRIVATE (this);
1123
gchar *uri_new = NULL;
1129
gchar *tag_open_ptr = NULL;
1130
gchar *tag_close_ptr = NULL;
1131
gchar *search_string = NULL;
1133
if (! strcmp (uri, "HOME")) {
1134
uri_new = g_filename_to_uri (g_get_home_dir (), NULL, NULL);
1136
icon = "gnome-fs-home";
1138
else if (! strcmp (uri, "DOCUMENTS")) {
1139
path = g_build_filename (g_get_home_dir (), "Documents", NULL);
1140
name = _("Documents");
1141
uri_new = g_filename_to_uri (path, NULL, NULL);
1144
else if (! strcmp (uri, "DESKTOP")) {
1145
path = g_build_filename (g_get_home_dir (), "Desktop", NULL);
1146
name = _("Desktop");
1147
uri_new = g_filename_to_uri (path, NULL, NULL);
1148
icon = "gnome-fs-desktop";
1151
else if (! strcmp (uri, "file:///")) {
1152
icon = "drive-harddisk";
1153
name = _("File System");
1155
else if (! strcmp (uri, "network:")) {
1156
icon = "network-workgroup";
1157
name = _("Network Servers");
1159
else if (g_str_has_prefix (uri, "x-nautilus-search")) {
1160
icon = "system-search";
1162
path = g_build_filename (g_get_home_dir (), ".nautilus", "searches", & uri [21], NULL);
1164
if (g_file_test (path, G_FILE_TEST_EXISTS)) {
1165
g_file_get_contents (path, & buf, NULL, NULL);
1168
tag_open_ptr = strstr (buf, "<text>");
1169
tag_close_ptr = strstr (buf, "</text>");
1172
if (tag_open_ptr && tag_close_ptr) {
1173
tag_close_ptr [0] = '\0';
1175
search_string = g_strdup_printf ("\"%s\"", & tag_open_ptr [6]);
1177
tag_close_ptr [0] = 'a';
1184
name = search_string;
1192
g_bookmark_file_set_icon (priv->store, uri, icon, "image/png");
1195
g_bookmark_file_set_title (priv->store, uri, name);
1197
if (uri_new && libslab_strcmp (uri, uri_new))
1198
g_bookmark_file_move_item (priv->store, uri, uri_new, NULL);
1204
store_monitor_cb (GFileMonitor *mon, GFile *f1, GFile *f2,
1205
GFileMonitorEvent event_type, gpointer user_data)
1207
update_agent (BOOKMARK_AGENT (user_data));
1211
gconf_notify_cb (GConfClient *client, guint conn_id,
1212
GConfEntry *entry, gpointer user_data)
1214
BookmarkAgent *this = BOOKMARK_AGENT (user_data);
1215
BookmarkAgentPrivate *priv = PRIVATE (this);
1217
gboolean user_modifiable;
1220
user_modifiable = GPOINTER_TO_INT (libslab_get_gconf_value (priv->lockdown_key));
1222
if (priv->user_modifiable != user_modifiable) {
1223
priv->user_modifiable = user_modifiable;
1224
update_agent (this);
1229
weak_destroy_cb (gpointer data, GObject *g_obj)
1231
instances [GPOINTER_TO_INT (data)] = NULL;
1235
recent_item_mru_comp_func (gconstpointer a, gconstpointer b)
1237
return ((BookmarkItem *) b)->mtime - ((BookmarkItem *) a)->mtime;