4
* Copyright 2009 PCMan <pcman@debian>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22
#include "fm-bookmarks.h"
32
static FmBookmarks* fm_bookmarks_new (void);
34
static void fm_bookmarks_finalize (GObject *object);
35
static GList* load_bookmarks(const char* fpath);
36
static void free_item(FmBookmarkItem* item);
37
static char* get_bookmarks_file();
39
G_DEFINE_TYPE(FmBookmarks, fm_bookmarks, G_TYPE_OBJECT);
41
static FmBookmarks* singleton = NULL;
42
static guint signals[N_SIGNALS];
44
static guint idle_handler = 0;
46
static void fm_bookmarks_class_init(FmBookmarksClass *klass)
48
GObjectClass *g_object_class;
49
g_object_class = G_OBJECT_CLASS(klass);
50
g_object_class->finalize = fm_bookmarks_finalize;
53
g_signal_new("changed",
54
G_TYPE_FROM_CLASS(klass),
56
G_STRUCT_OFFSET(FmBookmarksClass, changed),
58
g_cclosure_marshal_VOID__VOID,
62
static void fm_bookmarks_finalize(GObject *object)
66
g_return_if_fail(object != NULL);
67
g_return_if_fail(IS_FM_BOOKMARKS(object));
69
self = FM_BOOKMARKS(object);
73
g_source_remove(idle_handler);
77
g_list_foreach(self->items, (GFunc)free_item, NULL);
78
g_list_free(self->items);
80
g_object_unref(self->mon);
82
G_OBJECT_CLASS(fm_bookmarks_parent_class)->finalize(object);
85
char* get_bookmarks_file()
87
return g_build_filename(g_get_home_dir(), ".gtk-bookmarks", NULL);
90
void free_item(FmBookmarkItem* item)
92
if(item->name != item->path->name)
94
fm_path_unref(item->path);
95
g_slice_free(FmBookmarkItem, item);
98
static void on_changed( GFileMonitor* mon, GFile* gf, GFile* other,
99
GFileMonitorEvent evt, FmBookmarks* bookmarks )
102
/* reload bookmarks */
103
g_list_foreach(bookmarks->items, (GFunc)free_item, NULL);
104
g_list_free(bookmarks->items);
106
fpath = get_bookmarks_file();
107
bookmarks->items = load_bookmarks(fpath);
109
g_signal_emit(bookmarks, signals[CHANGED], 0);
112
static FmBookmarkItem* new_item(char* line)
114
FmBookmarkItem* item = g_slice_new0(FmBookmarkItem);
116
sep = strchr(line, '\n');
119
sep = strchr(line, ' ');
123
/* FIXME: this is no longer needed once fm_path_new can convert file:/// to / */
124
if(g_str_has_prefix(line, "file:/"))
126
char* fpath = g_filename_from_uri(line, NULL, NULL);
127
item->path = fm_path_new(fpath);
132
/* FIXME: is unescape needed? */
133
item->path = fm_path_new(line);
137
item->name = g_strdup(sep+1);
139
item->name = g_filename_display_name(item->path->name);
144
GList* load_bookmarks(const char* fpath)
148
FmBookmarkItem* item;
152
if( f = fopen(fpath, "r") )
154
while(fgets(buf, 1024, f))
156
item = new_item(buf);
157
items = g_list_prepend(items, item);
160
items = g_list_reverse(items);
164
static void fm_bookmarks_init(FmBookmarks *self)
166
char* fpath = get_bookmarks_file();
167
GFile* gf = g_file_new_for_path(fpath);
168
self->mon = g_file_monitor_file(gf, 0, NULL, NULL);
170
g_signal_connect(self->mon, "changed", G_CALLBACK(on_changed), self);
172
self->items = load_bookmarks(fpath);
176
FmBookmarks *fm_bookmarks_new(void)
178
return g_object_new(FM_BOOKMARKS_TYPE, NULL);
181
FmBookmarks* fm_bookmarks_get(void)
183
if( G_LIKELY(singleton) )
184
g_object_ref(singleton);
187
singleton = fm_bookmarks_new();
188
g_object_add_weak_pointer(G_OBJECT(singleton), &singleton);
193
GList* fm_bookmarks_list_all(FmBookmarks* bookmarks)
195
return bookmarks->items;
198
gboolean save_bookmarks(FmBookmarks* bookmarks)
200
FmBookmarkItem* item;
202
GString* buf = g_string_sized_new(1024);
205
for( l=bookmarks->items; l; l=l->next )
208
item = (FmBookmarkItem*)l->data;
209
uri = fm_path_to_uri(item->path);
210
g_string_append(buf, uri);
212
g_string_append_c(buf, ' ');
213
g_string_append(buf, item->name);
214
g_string_append_c(buf, '\n');
217
fpath = get_bookmarks_file();
218
g_file_set_contents(fpath, buf->str, buf->len, NULL);
221
g_string_free(buf, TRUE);
225
void queue_save_bookmarks(FmBookmarks* bookmarks)
228
g_source_remove(idle_handler);
229
idle_handler = g_idle_add((GSourceFunc)save_bookmarks, bookmarks);
232
FmBookmarkItem* fm_bookmarks_insert(FmBookmarks* bookmarks, FmPath* path, const char* name, int pos)
234
FmBookmarkItem* item = g_slice_new0(FmBookmarkItem);
235
item->path = fm_path_ref(path);
236
item->name = g_strdup(name);
237
bookmarks->items = g_list_insert(bookmarks->items, item, pos);
238
/* g_debug("insert %s at %d", name, pos); */
239
queue_save_bookmarks(bookmarks);
243
void fm_bookmarks_remove(FmBookmarks* bookmarks, FmBookmarkItem* item)
245
bookmarks->items = g_list_remove(bookmarks->items, item);
247
queue_save_bookmarks(bookmarks);
250
void fm_bookmarks_rename(FmBookmarks* bookmarks, FmBookmarkItem* item, const char* new_name)
253
item->name = g_strdup(new_name);
254
queue_save_bookmarks(bookmarks);