~ubuntu-branches/ubuntu/oneiric/evince/oneiric-updates

« back to all changes in this revision

Viewing changes to shell/ev-bookmarks.c

  • Committer: Bazaar Package Importer
  • Author(s): Frederic Peters
  • Date: 2011-04-14 16:20:57 UTC
  • mfrom: (1.6.4 upstream)
  • mto: (1.3.5 experimental)
  • mto: This revision was merged to the branch mainline in revision 138.
  • Revision ID: james.westby@ubuntu.com-20110414162057-0ofhbd139zs6ev6y
ImportĀ upstreamĀ versionĀ 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ev-bookmarks.c
 
2
 *  this file is part of evince, a gnome document viewer
 
3
 *
 
4
 * Copyright (C) 2010 Carlos Garcia Campos  <carlosgc@gnome.org>
 
5
 *
 
6
 * Evince is free software; you can redistribute it and/or modify it
 
7
 * 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
 * Evince is distributed in the hope that it will be useful, but
 
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * 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 "ev-bookmarks.h"
 
26
 
 
27
enum {
 
28
        PROP_0,
 
29
        PROP_METADATA
 
30
};
 
31
 
 
32
enum {
 
33
        CHANGED,
 
34
        N_SIGNALS
 
35
};
 
36
 
 
37
struct _EvBookmarks {
 
38
        GObject base;
 
39
 
 
40
        EvMetadata *metadata;
 
41
        GList *items;
 
42
};
 
43
 
 
44
struct _EvBookmarksClass {
 
45
        GObjectClass base_class;
 
46
 
 
47
        void (*changed) (EvBookmarks *bookmarks);
 
48
};
 
49
 
 
50
G_DEFINE_TYPE (EvBookmarks, ev_bookmarks, G_TYPE_OBJECT)
 
51
 
 
52
static guint signals[N_SIGNALS];
 
53
 
 
54
static gint
 
55
ev_bookmark_compare (EvBookmark *a,
 
56
                     EvBookmark *b)
 
57
{
 
58
        if (a->page < b->page)
 
59
                return -1;
 
60
        if (a->page > b->page)
 
61
                return 1;
 
62
        return 0;
 
63
}
 
64
 
 
65
static void
 
66
ev_bookmark_free (EvBookmark *bm)
 
67
{
 
68
        if (G_UNLIKELY(!bm))
 
69
                return;
 
70
 
 
71
        g_free (bm->title);
 
72
        g_slice_free (EvBookmark, bm);
 
73
}
 
74
 
 
75
static void
 
76
ev_bookmarks_finalize (GObject *object)
 
77
{
 
78
        EvBookmarks *bookmarks = EV_BOOKMARKS (object);
 
79
 
 
80
        if (bookmarks->items) {
 
81
                g_list_free_full (bookmarks->items, (GDestroyNotify)ev_bookmark_free);
 
82
                bookmarks->items = NULL;
 
83
        }
 
84
 
 
85
        if (bookmarks->metadata) {
 
86
                g_object_unref (bookmarks->metadata);
 
87
                bookmarks->metadata = NULL;
 
88
        }
 
89
 
 
90
        G_OBJECT_CLASS (ev_bookmarks_parent_class)->finalize (object);
 
91
}
 
92
 
 
93
static void
 
94
ev_bookmarks_init (EvBookmarks *bookmarks)
 
95
{
 
96
}
 
97
 
 
98
static void
 
99
ev_bookmarks_set_property (GObject      *object,
 
100
                           guint         prop_id,
 
101
                           const GValue *value,
 
102
                           GParamSpec   *pspec)
 
103
{
 
104
        EvBookmarks *bookmarks = EV_BOOKMARKS (object);
 
105
 
 
106
        switch (prop_id) {
 
107
        case PROP_METADATA:
 
108
                bookmarks->metadata = (EvMetadata *)g_value_dup_object (value);
 
109
                break;
 
110
        default:
 
111
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
112
        }
 
113
}
 
114
 
 
115
static void
 
116
ev_bookmarks_constructed (GObject *object)
 
117
{
 
118
        EvBookmarks *bookmarks = EV_BOOKMARKS (object);
 
119
        gchar       *bm_list_str;
 
120
        GVariant    *bm_list;
 
121
        GVariantIter iter;
 
122
        GVariant    *child;
 
123
        GError      *error = NULL;
 
124
 
 
125
        if (!ev_metadata_get_string (bookmarks->metadata, "bookmarks", &bm_list_str))
 
126
                return;
 
127
 
 
128
        if (!bm_list_str || bm_list_str[0] == '\0')
 
129
                return;
 
130
 
 
131
        bm_list = g_variant_parse ((const GVariantType *)"a(us)",
 
132
                                   bm_list_str, NULL, NULL,
 
133
                                   &error);
 
134
        if (!bm_list) {
 
135
                g_warning ("Error getting bookmarks: %s\n", error->message);
 
136
                g_error_free (error);
 
137
 
 
138
                return;
 
139
        }
 
140
 
 
141
        g_variant_iter_init (&iter, bm_list);
 
142
        while ((child = g_variant_iter_next_value (&iter))) {
 
143
                EvBookmark *bm = g_slice_new (EvBookmark);
 
144
 
 
145
                g_variant_get (child, "(us)", &bm->page, &bm->title);
 
146
                if (bm->title && strlen (bm->title) > 0)
 
147
                        bookmarks->items = g_list_prepend (bookmarks->items, bm);
 
148
                g_variant_unref (child);
 
149
        }
 
150
        g_variant_unref (bm_list);
 
151
 
 
152
        bookmarks->items = g_list_reverse (bookmarks->items);
 
153
}
 
154
 
 
155
static void
 
156
ev_bookmarks_class_init (EvBookmarksClass *klass)
 
157
{
 
158
        GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
159
 
 
160
        gobject_class->set_property = ev_bookmarks_set_property;
 
161
        gobject_class->finalize = ev_bookmarks_finalize;
 
162
        gobject_class->constructed = ev_bookmarks_constructed;
 
163
 
 
164
        g_object_class_install_property (gobject_class,
 
165
                                         PROP_METADATA,
 
166
                                         g_param_spec_object ("metadata",
 
167
                                                              "Metadata",
 
168
                                                              "The document metadata",
 
169
                                                              EV_TYPE_METADATA,
 
170
                                                              G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
 
171
        /* Signals */
 
172
        signals[CHANGED] =
 
173
                g_signal_new ("changed",
 
174
                              EV_TYPE_BOOKMARKS,
 
175
                              G_SIGNAL_RUN_LAST,
 
176
                              G_STRUCT_OFFSET (EvBookmarksClass, changed),
 
177
                              NULL, NULL,
 
178
                              g_cclosure_marshal_VOID__VOID,
 
179
                              G_TYPE_NONE, 0);
 
180
}
 
181
 
 
182
EvBookmarks *
 
183
ev_bookmarks_new (EvMetadata *metadata)
 
184
{
 
185
        g_return_val_if_fail (EV_IS_METADATA (metadata), NULL);
 
186
 
 
187
        return EV_BOOKMARKS (g_object_new (EV_TYPE_BOOKMARKS,
 
188
                                           "metadata", metadata, NULL));
 
189
}
 
190
 
 
191
static void
 
192
ev_bookmarks_save (EvBookmarks *bookmarks)
 
193
{
 
194
        GList          *l;
 
195
        GVariantBuilder builder;
 
196
        GVariant       *bm_list;
 
197
        gchar          *bm_list_str;
 
198
 
 
199
        if (!bookmarks->items) {
 
200
                ev_metadata_set_string (bookmarks->metadata, "bookmarks", "");
 
201
                return;
 
202
        }
 
203
 
 
204
        g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
 
205
        for (l = bookmarks->items; l; l = g_list_next (l)) {
 
206
                EvBookmark *bm = (EvBookmark *)l->data;
 
207
 
 
208
                g_variant_builder_add (&builder, "(u&s)", bm->page, bm->title);
 
209
        }
 
210
        bm_list = g_variant_builder_end (&builder);
 
211
 
 
212
        bm_list_str = g_variant_print (bm_list, FALSE);
 
213
        g_variant_unref (bm_list);
 
214
        ev_metadata_set_string (bookmarks->metadata, "bookmarks", bm_list_str);
 
215
        g_free (bm_list_str);
 
216
}
 
217
 
 
218
GList *
 
219
ev_bookmarks_get_bookmarks (EvBookmarks *bookmarks)
 
220
{
 
221
        g_return_val_if_fail (EV_IS_BOOKMARKS (bookmarks), NULL);
 
222
 
 
223
        return g_list_copy (bookmarks->items);
 
224
}
 
225
 
 
226
void
 
227
ev_bookmarks_add (EvBookmarks *bookmarks,
 
228
                  EvBookmark  *bookmark)
 
229
{
 
230
        EvBookmark *bm;
 
231
 
 
232
        g_return_if_fail (EV_IS_BOOKMARKS (bookmarks));
 
233
        g_return_if_fail (bookmark->title != NULL);
 
234
 
 
235
        if (g_list_find_custom (bookmarks->items, bookmark, (GCompareFunc)ev_bookmark_compare))
 
236
                return;
 
237
 
 
238
        bm = g_slice_new (EvBookmark);
 
239
        *bm = *bookmark;
 
240
        bookmarks->items = g_list_append (bookmarks->items, bm);
 
241
        g_signal_emit (bookmarks, signals[CHANGED], 0);
 
242
        ev_bookmarks_save (bookmarks);
 
243
}
 
244
 
 
245
void
 
246
ev_bookmarks_delete (EvBookmarks *bookmarks,
 
247
                     EvBookmark  *bookmark)
 
248
{
 
249
        GList *bm_link;
 
250
 
 
251
        g_return_if_fail (EV_IS_BOOKMARKS (bookmarks));
 
252
 
 
253
        bm_link = g_list_find_custom (bookmarks->items, bookmark, (GCompareFunc)ev_bookmark_compare);
 
254
        if (!bm_link)
 
255
                return;
 
256
 
 
257
        bookmarks->items = g_list_delete_link (bookmarks->items, bm_link);
 
258
        g_signal_emit (bookmarks, signals[CHANGED], 0);
 
259
        ev_bookmarks_save (bookmarks);
 
260
}
 
261
 
 
262
void
 
263
ev_bookmarks_update (EvBookmarks *bookmarks,
 
264
                     EvBookmark  *bookmark)
 
265
{
 
266
        GList      *bm_link;
 
267
        EvBookmark *bm;
 
268
 
 
269
        g_return_if_fail (EV_IS_BOOKMARKS (bookmarks));
 
270
        g_return_if_fail (bookmark->title != NULL);
 
271
 
 
272
        bm_link = g_list_find_custom (bookmarks->items, bookmark, (GCompareFunc)ev_bookmark_compare);
 
273
        if (!bm_link)
 
274
                return;
 
275
 
 
276
        bm = (EvBookmark *)bm_link->data;
 
277
 
 
278
        if (strcmp (bookmark->title, bm->title) == 0)
 
279
                return;
 
280
 
 
281
        g_free (bm->title);
 
282
        *bm = *bookmark;
 
283
        g_signal_emit (bookmarks, signals[CHANGED], 0);
 
284
        ev_bookmarks_save (bookmarks);
 
285
}