~noskcaj/ubuntu/utopic/libfm/merge

« back to all changes in this revision

Viewing changes to src/base/fm-bookmarks.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Lee (李健秋)
  • Date: 2010-04-29 03:52:06 UTC
  • Revision ID: james.westby@ubuntu.com-20100429035206-qlj1jwsfcgr5mdx3
Tags: upstream-0.1.11
Import upstream version 0.1.11

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *      fm-gtk-bookmarks.c
 
3
 *
 
4
 *      Copyright 2009 PCMan <pcman@debian>
 
5
 *
 
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.
 
10
 *
 
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.
 
15
 *
 
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,
 
19
 *      MA 02110-1301, USA.
 
20
 */
 
21
 
 
22
#include "fm-bookmarks.h"
 
23
#include <stdio.h>
 
24
#include <string.h>
 
25
 
 
26
enum
 
27
{
 
28
    CHANGED,
 
29
    N_SIGNALS
 
30
};
 
31
 
 
32
static FmBookmarks*     fm_bookmarks_new (void);
 
33
 
 
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();
 
38
 
 
39
G_DEFINE_TYPE(FmBookmarks, fm_bookmarks, G_TYPE_OBJECT);
 
40
 
 
41
static FmBookmarks* singleton = NULL;
 
42
static guint signals[N_SIGNALS];
 
43
 
 
44
static guint idle_handler = 0;
 
45
 
 
46
static void fm_bookmarks_class_init(FmBookmarksClass *klass)
 
47
{
 
48
        GObjectClass *g_object_class;
 
49
        g_object_class = G_OBJECT_CLASS(klass);
 
50
        g_object_class->finalize = fm_bookmarks_finalize;
 
51
 
 
52
    signals[CHANGED] =
 
53
        g_signal_new("changed",
 
54
                     G_TYPE_FROM_CLASS(klass),
 
55
                     G_SIGNAL_RUN_FIRST,
 
56
                     G_STRUCT_OFFSET(FmBookmarksClass, changed),
 
57
                     NULL, NULL,
 
58
                     g_cclosure_marshal_VOID__VOID,
 
59
                     G_TYPE_NONE, 0 );
 
60
}
 
61
 
 
62
static void fm_bookmarks_finalize(GObject *object)
 
63
{
 
64
        FmBookmarks *self;
 
65
 
 
66
        g_return_if_fail(object != NULL);
 
67
        g_return_if_fail(IS_FM_BOOKMARKS(object));
 
68
 
 
69
        self = FM_BOOKMARKS(object);
 
70
 
 
71
    if(idle_handler)
 
72
    {
 
73
        g_source_remove(idle_handler);
 
74
        idle_handler = 0;
 
75
    }
 
76
 
 
77
    g_list_foreach(self->items, (GFunc)free_item, NULL);
 
78
    g_list_free(self->items);
 
79
 
 
80
    g_object_unref(self->mon);
 
81
 
 
82
        G_OBJECT_CLASS(fm_bookmarks_parent_class)->finalize(object);
 
83
}
 
84
 
 
85
char* get_bookmarks_file()
 
86
{
 
87
    return g_build_filename(g_get_home_dir(), ".gtk-bookmarks", NULL);
 
88
}
 
89
 
 
90
void free_item(FmBookmarkItem* item)
 
91
{
 
92
    if(item->name != item->path->name)
 
93
        g_free(item->name);
 
94
    fm_path_unref(item->path);
 
95
    g_slice_free(FmBookmarkItem, item);
 
96
}
 
97
 
 
98
static void on_changed( GFileMonitor* mon, GFile* gf, GFile* other,
 
99
                    GFileMonitorEvent evt, FmBookmarks* bookmarks )
 
100
{
 
101
    char* fpath;
 
102
    /* reload bookmarks */
 
103
    g_list_foreach(bookmarks->items, (GFunc)free_item, NULL);
 
104
    g_list_free(bookmarks->items);
 
105
 
 
106
    fpath = get_bookmarks_file();
 
107
    bookmarks->items = load_bookmarks(fpath);
 
108
    g_free(fpath);
 
109
    g_signal_emit(bookmarks, signals[CHANGED], 0);
 
110
}
 
111
 
 
112
static FmBookmarkItem* new_item(char* line)
 
113
{
 
114
    FmBookmarkItem* item = g_slice_new0(FmBookmarkItem);
 
115
    char* sep;
 
116
    sep = strchr(line, '\n');
 
117
    if(sep)
 
118
        *sep = '\0';
 
119
    sep = strchr(line, ' ');
 
120
    if(sep)
 
121
        *sep = '\0';
 
122
 
 
123
    /* FIXME: this is no longer needed once fm_path_new can convert file:/// to / */
 
124
    if(g_str_has_prefix(line, "file:/"))
 
125
    {
 
126
        char* fpath = g_filename_from_uri(line, NULL, NULL);
 
127
        item->path = fm_path_new(fpath);
 
128
        g_free(fpath);
 
129
    }
 
130
    else
 
131
    {
 
132
        /* FIXME: is unescape needed? */
 
133
        item->path = fm_path_new(line);
 
134
    }
 
135
 
 
136
    if(sep)
 
137
        item->name = g_strdup(sep+1);
 
138
    else
 
139
        item->name = g_filename_display_name(item->path->name);
 
140
 
 
141
    return item;
 
142
}
 
143
 
 
144
GList* load_bookmarks(const char* fpath)
 
145
{
 
146
    FILE* f;
 
147
    char buf[1024];
 
148
    FmBookmarkItem* item;
 
149
    GList* items = NULL;
 
150
 
 
151
    /* load the file */
 
152
    if( f = fopen(fpath, "r") )
 
153
    {
 
154
        while(fgets(buf, 1024, f))
 
155
        {
 
156
            item = new_item(buf);
 
157
            items = g_list_prepend(items, item);
 
158
        }
 
159
    }
 
160
    items = g_list_reverse(items);
 
161
    return items;
 
162
}
 
163
 
 
164
static void fm_bookmarks_init(FmBookmarks *self)
 
165
{
 
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);
 
169
    g_object_unref(gf);
 
170
    g_signal_connect(self->mon, "changed", G_CALLBACK(on_changed), self);
 
171
 
 
172
    self->items = load_bookmarks(fpath);
 
173
    g_free(fpath);
 
174
}
 
175
 
 
176
FmBookmarks *fm_bookmarks_new(void)
 
177
{
 
178
        return g_object_new(FM_BOOKMARKS_TYPE, NULL);
 
179
}
 
180
 
 
181
FmBookmarks* fm_bookmarks_get(void)
 
182
{
 
183
    if( G_LIKELY(singleton) )
 
184
        g_object_ref(singleton);
 
185
    else
 
186
    {
 
187
        singleton = fm_bookmarks_new();
 
188
        g_object_add_weak_pointer(G_OBJECT(singleton), &singleton);
 
189
    }
 
190
    return singleton;
 
191
}
 
192
 
 
193
GList* fm_bookmarks_list_all(FmBookmarks* bookmarks)
 
194
{
 
195
    return bookmarks->items;
 
196
}
 
197
 
 
198
gboolean save_bookmarks(FmBookmarks* bookmarks)
 
199
{
 
200
    FmBookmarkItem* item;
 
201
    GList* l;
 
202
    GString* buf = g_string_sized_new(1024);
 
203
    char* fpath;
 
204
 
 
205
    for( l=bookmarks->items; l; l=l->next )
 
206
    {
 
207
        char* uri;
 
208
        item = (FmBookmarkItem*)l->data;
 
209
        uri = fm_path_to_uri(item->path);
 
210
        g_string_append(buf, uri);
 
211
        g_free(uri);
 
212
        g_string_append_c(buf, ' ');
 
213
        g_string_append(buf, item->name);
 
214
        g_string_append_c(buf, '\n');
 
215
    }
 
216
 
 
217
    fpath = get_bookmarks_file();
 
218
    g_file_set_contents(fpath, buf->str, buf->len, NULL);
 
219
    g_free(fpath);
 
220
 
 
221
    g_string_free(buf, TRUE);
 
222
    return FALSE;
 
223
}
 
224
 
 
225
void queue_save_bookmarks(FmBookmarks* bookmarks)
 
226
{
 
227
    if(idle_handler)
 
228
        g_source_remove(idle_handler);
 
229
    idle_handler = g_idle_add((GSourceFunc)save_bookmarks, bookmarks);
 
230
}
 
231
 
 
232
FmBookmarkItem* fm_bookmarks_insert(FmBookmarks* bookmarks, FmPath* path, const char* name, int pos)
 
233
{
 
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);
 
240
    return item;
 
241
}
 
242
 
 
243
void fm_bookmarks_remove(FmBookmarks* bookmarks, FmBookmarkItem* item)
 
244
{
 
245
    bookmarks->items = g_list_remove(bookmarks->items, item);
 
246
    free_item(item);
 
247
    queue_save_bookmarks(bookmarks);
 
248
}
 
249
 
 
250
void fm_bookmarks_rename(FmBookmarks* bookmarks, FmBookmarkItem* item, const char* new_name)
 
251
{
 
252
    g_free(item->name);
 
253
    item->name = g_strdup(new_name);
 
254
    queue_save_bookmarks(bookmarks);
 
255
}