~noskcaj/ubuntu/trusty/gnome-documents/3.10.2

« back to all changes in this revision

Viewing changes to src/lib/gd-bookmarks.c

  • Committer: Package Import Robot
  • Author(s): Andreas Henriksson, Thomas Bechtold
  • Date: 2013-04-04 13:32:08 UTC
  • mfrom: (3.1.4 experimental)
  • Revision ID: package-import@ubuntu.com-20130404133208-n19gqczi05z31ogb
Tags: 3.8.0-1
[ Thomas Bechtold ]
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8;  -*-
 
2
 *
 
3
 *  Copyright (C) 2010 Carlos Garcia Campos  <carlosgc@gnome.org>
 
4
 *  Copyright (C) 2013 Red Hat, Inc.
 
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, or (at your option)
 
9
 *  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, MA 02110-1301, USA.
 
19
 */
 
20
 
 
21
#include "config.h"
 
22
 
 
23
#include <string.h>
 
24
 
 
25
#include "gd-bookmarks.h"
 
26
 
 
27
enum {
 
28
        PROP_0,
 
29
        PROP_METADATA,
 
30
        PROP_N_ITEMS
 
31
};
 
32
 
 
33
enum {
 
34
        CHANGED,
 
35
        N_SIGNALS
 
36
};
 
37
 
 
38
struct _GdBookmarks {
 
39
        GObject base;
 
40
 
 
41
        GdMetadata *metadata;
 
42
        GList *items;
 
43
};
 
44
 
 
45
struct _GdBookmarksClass {
 
46
        GObjectClass base_class;
 
47
 
 
48
        void (*changed) (GdBookmarks *bookmarks);
 
49
};
 
50
 
 
51
G_DEFINE_TYPE (GdBookmarks, gd_bookmarks, G_TYPE_OBJECT)
 
52
 
 
53
static guint signals[N_SIGNALS];
 
54
 
 
55
static void
 
56
gd_bookmarks_finalize (GObject *object)
 
57
{
 
58
        GdBookmarks *self = GD_BOOKMARKS (object);
 
59
 
 
60
        g_list_free_full (self->items, g_object_unref);
 
61
 
 
62
        g_clear_object (&self->metadata);
 
63
 
 
64
        G_OBJECT_CLASS (gd_bookmarks_parent_class)->finalize (object);
 
65
}
 
66
 
 
67
static void
 
68
gd_bookmarks_init (GdBookmarks *bookmarks)
 
69
{
 
70
}
 
71
 
 
72
guint
 
73
gd_bookmarks_get_n_items (GdBookmarks *bookmarks)
 
74
{
 
75
        g_return_val_if_fail (GD_IS_BOOKMARKS (bookmarks), 0);
 
76
 
 
77
        return g_list_length (bookmarks->items);
 
78
}
 
79
 
 
80
static void
 
81
gd_bookmarks_get_property (GObject      *object,
 
82
                           guint         prop_id,
 
83
                           GValue       *value,
 
84
                           GParamSpec   *pspec)
 
85
{
 
86
        GdBookmarks *self = GD_BOOKMARKS (object);
 
87
 
 
88
        switch (prop_id) {
 
89
        case PROP_N_ITEMS:
 
90
                g_value_set_uint (value, gd_bookmarks_get_n_items (self));
 
91
                break;
 
92
        default:
 
93
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
94
        }
 
95
}
 
96
 
 
97
static void
 
98
gd_bookmarks_set_property (GObject      *object,
 
99
                           guint         prop_id,
 
100
                           const GValue *value,
 
101
                           GParamSpec   *pspec)
 
102
{
 
103
        GdBookmarks *self = GD_BOOKMARKS (object);
 
104
 
 
105
        switch (prop_id) {
 
106
        case PROP_METADATA:
 
107
                self->metadata = (GdMetadata *)g_value_dup_object (value);
 
108
                break;
 
109
        default:
 
110
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
111
        }
 
112
}
 
113
 
 
114
static void
 
115
gd_bookmarks_constructed (GObject *object)
 
116
{
 
117
        GdBookmarks *self = GD_BOOKMARKS (object);
 
118
        const char  *bm_list_str;
 
119
        GVariant    *bm_list;
 
120
        GVariantIter iter;
 
121
        GVariant    *child;
 
122
        GError      *error = NULL;
 
123
 
 
124
        if (!gd_metadata_get_string (self->metadata, "bookmarks", &bm_list_str)) {
 
125
                return;
 
126
        }
 
127
 
 
128
        if (bm_list_str == NULL || bm_list_str[0] == '\0') {
 
129
                return;
 
130
        }
 
131
 
 
132
        bm_list = g_variant_parse ((const GVariantType *)"a(us)",
 
133
                                   bm_list_str, NULL, NULL,
 
134
                                   &error);
 
135
        if (bm_list == NULL) {
 
136
                g_warning ("Error getting bookmarks: %s\n", error->message);
 
137
                g_error_free (error);
 
138
 
 
139
                return;
 
140
        }
 
141
 
 
142
        g_variant_iter_init (&iter, bm_list);
 
143
        while ((child = g_variant_iter_next_value (&iter))) {
 
144
                guint page_num;
 
145
                const char *title = NULL;
 
146
 
 
147
                g_variant_get (child, "(u&s)", &page_num, &title);
 
148
                if (title != NULL) {
 
149
                        GdBookmark *bm = gd_bookmark_new ();
 
150
                        gd_bookmark_set_title (bm, title);
 
151
                        gd_bookmark_set_page_number (bm, page_num);
 
152
                        self->items = g_list_prepend (self->items, bm);
 
153
                        g_object_notify (G_OBJECT (self), "n-items");
 
154
                }
 
155
                g_variant_unref (child);
 
156
        }
 
157
        g_variant_unref (bm_list);
 
158
 
 
159
        self->items = g_list_reverse (self->items);
 
160
}
 
161
 
 
162
static void
 
163
gd_bookmarks_class_init (GdBookmarksClass *klass)
 
164
{
 
165
        GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
166
 
 
167
        gobject_class->get_property = gd_bookmarks_get_property;
 
168
        gobject_class->set_property = gd_bookmarks_set_property;
 
169
        gobject_class->finalize = gd_bookmarks_finalize;
 
170
        gobject_class->constructed = gd_bookmarks_constructed;
 
171
 
 
172
        g_object_class_install_property (gobject_class,
 
173
                                         PROP_METADATA,
 
174
                                         g_param_spec_object ("metadata",
 
175
                                                              "Metadata",
 
176
                                                              "The document metadata",
 
177
                                                              GD_TYPE_METADATA,
 
178
                                                              G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE |
 
179
                                                              G_PARAM_STATIC_STRINGS));
 
180
        g_object_class_install_property (gobject_class,
 
181
                                         PROP_N_ITEMS,
 
182
                                         g_param_spec_uint ("n-items",
 
183
                                                            "N Items",
 
184
                                                            "Number of bookmark items",
 
185
                                                            0,
 
186
                                                            G_MAXUINT,
 
187
                                                            0,
 
188
                                                            G_PARAM_READABLE |
 
189
                                                            G_PARAM_STATIC_STRINGS));
 
190
 
 
191
        /* Signals */
 
192
        signals[CHANGED] = g_signal_new ("changed",
 
193
                                         GD_TYPE_BOOKMARKS,
 
194
                                         G_SIGNAL_RUN_LAST,
 
195
                                         G_STRUCT_OFFSET (GdBookmarksClass, changed),
 
196
                                         NULL, NULL,
 
197
                                         g_cclosure_marshal_VOID__VOID,
 
198
                                         G_TYPE_NONE, 0);
 
199
}
 
200
 
 
201
GdBookmarks *
 
202
gd_bookmarks_new (GdMetadata *metadata)
 
203
{
 
204
        g_return_val_if_fail (GD_IS_METADATA (metadata), NULL);
 
205
 
 
206
        return GD_BOOKMARKS (g_object_new (GD_TYPE_BOOKMARKS,
 
207
                                           "metadata", metadata,
 
208
                                           NULL));
 
209
}
 
210
 
 
211
static void
 
212
gd_bookmarks_save (GdBookmarks *self)
 
213
{
 
214
        GList          *l;
 
215
        GVariantBuilder builder;
 
216
        GVariant       *bm_list;
 
217
        char           *bm_list_str;
 
218
 
 
219
        if (self->items == NULL) {
 
220
                gd_metadata_set_string (self->metadata, "bookmarks", "");
 
221
                return;
 
222
        }
 
223
 
 
224
        g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
 
225
        for (l = self->items; l; l = g_list_next (l)) {
 
226
                GdBookmark *bm = (GdBookmark *)l->data;
 
227
                const char *title = gd_bookmark_get_title (bm);
 
228
                guint page_num = gd_bookmark_get_page_number (bm);
 
229
 
 
230
                g_variant_builder_add (&builder, "(u&s)",
 
231
                                       page_num,
 
232
                                       title != NULL ? title : "");
 
233
        }
 
234
        bm_list = g_variant_builder_end (&builder);
 
235
 
 
236
        bm_list_str = g_variant_print (bm_list, FALSE);
 
237
        g_variant_unref (bm_list);
 
238
        gd_metadata_set_string (self->metadata, "bookmarks", bm_list_str);
 
239
        g_free (bm_list_str);
 
240
}
 
241
 
 
242
/**
 
243
 * gd_bookmarks_find_bookmark:
 
244
 * @bookmarks:
 
245
 * @bookmark:
 
246
 *
 
247
 * Returns: (transfer none)
 
248
 */
 
249
GdBookmark *
 
250
gd_bookmarks_find_bookmark (GdBookmarks *bookmarks,
 
251
                            GdBookmark  *bookmark)
 
252
{
 
253
        GList *l;
 
254
 
 
255
        l = g_list_find_custom (bookmarks->items, bookmark, (GCompareFunc)gd_bookmark_compare);
 
256
        if (l != NULL)
 
257
                return l->data;
 
258
 
 
259
        return NULL;
 
260
}
 
261
 
 
262
/**
 
263
 * gd_bookmarks_get_bookmarks:
 
264
 * @bookmarks:
 
265
 *
 
266
 * Returns: (transfer container) (element-type GdBookmark): A list of #GdBookmark objects
 
267
 */
 
268
GList *
 
269
gd_bookmarks_get_bookmarks (GdBookmarks *bookmarks)
 
270
{
 
271
        g_return_val_if_fail (GD_IS_BOOKMARKS (bookmarks), NULL);
 
272
 
 
273
        return g_list_copy (bookmarks->items);
 
274
}
 
275
 
 
276
void
 
277
gd_bookmarks_add (GdBookmarks *bookmarks,
 
278
                  GdBookmark  *bookmark)
 
279
{
 
280
        GdBookmark *bm;
 
281
 
 
282
        g_return_if_fail (GD_IS_BOOKMARKS (bookmarks));
 
283
 
 
284
        bm = gd_bookmarks_find_bookmark (bookmarks, bookmark);
 
285
        if (bm != NULL) {
 
286
                return;
 
287
        }
 
288
 
 
289
        bookmarks->items = g_list_append (bookmarks->items, g_object_ref (bookmark));
 
290
        g_object_notify (G_OBJECT (bookmarks), "n-items");
 
291
        g_signal_emit (bookmarks, signals[CHANGED], 0);
 
292
        gd_bookmarks_save (bookmarks);
 
293
}
 
294
 
 
295
void
 
296
gd_bookmarks_remove (GdBookmarks *bookmarks,
 
297
                     GdBookmark  *bookmark)
 
298
{
 
299
        GdBookmark *bm;
 
300
 
 
301
        g_return_if_fail (GD_IS_BOOKMARKS (bookmarks));
 
302
 
 
303
        bm = gd_bookmarks_find_bookmark (bookmarks, bookmark);
 
304
        if (bm == NULL) {
 
305
                return;
 
306
        }
 
307
 
 
308
        bookmarks->items = g_list_remove (bookmarks->items, bm);
 
309
        g_object_unref (bm);
 
310
        g_object_notify (G_OBJECT (bookmarks), "n-items");
 
311
        g_signal_emit (bookmarks, signals[CHANGED], 0);
 
312
        gd_bookmarks_save (bookmarks);
 
313
}
 
314
 
 
315
void
 
316
gd_bookmarks_update (GdBookmarks *bookmarks,
 
317
                     GdBookmark  *bookmark)
 
318
{
 
319
        GList      *bm_link;
 
320
        GdBookmark *bm;
 
321
        const char *title_a;
 
322
        const char *title_b;
 
323
 
 
324
        g_return_if_fail (GD_IS_BOOKMARKS (bookmarks));
 
325
 
 
326
        bm_link = g_list_find_custom (bookmarks->items, bookmark, (GCompareFunc)gd_bookmark_compare);
 
327
        if (bm_link == NULL) {
 
328
                return;
 
329
        }
 
330
 
 
331
        bm = (GdBookmark *)bm_link->data;
 
332
 
 
333
        title_a = gd_bookmark_get_title (bm);
 
334
        title_b = gd_bookmark_get_title (bookmark);
 
335
 
 
336
        if (g_strcmp0 (title_a, title_b) == 0) {
 
337
                return;
 
338
        }
 
339
 
 
340
        g_signal_emit (bookmarks, signals[CHANGED], 0);
 
341
        gd_bookmarks_save (bookmarks);
 
342
}