1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2002 CodeFactory AB
4  * Copyright (C) 2002 Mikael Hallendal <micke@imendio.com>
5  * Copyright (C) 2004-2008 Imendio AB
6  * Copyright (C) 2010 Lanedo GmbH
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of the
11  * License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public
19  * License along with this program; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23 
24 #include "config.h"
25 #include <string.h>
26 
27 #include "dh-link.h"
28 #include "dh-parser.h"
29 #include "dh-book.h"
30 
31 /* Structure defining basic contents to store about every book */
32 typedef struct {
33         /* File path of the book */
34         gchar    *path;
35         /* Enable or disabled? */
36         gboolean  enabled;
37         /* Book name */
38         gchar    *name;
39         /* Book title */
40         gchar    *title;
41         /* Generated book tree */
42         GNode    *tree;
43         /* Generated list of keywords in the book */
44         GList    *keywords;
45 } DhBookPriv;
46 
47 G_DEFINE_TYPE (DhBook, dh_book, G_TYPE_OBJECT);
48 
49 #define GET_PRIVATE(instance) G_TYPE_INSTANCE_GET_PRIVATE       \
50         (instance, DH_TYPE_BOOK, DhBookPriv)
51 
52 static void    dh_book_init       (DhBook      *book);
53 static void    dh_book_class_init (DhBookClass *klass);
54 
55 static void    unref_node_link    (GNode *node,
56                                    gpointer data);
57 
58 static void
book_finalize(GObject * object)59 book_finalize (GObject *object)
60 {
61         DhBookPriv *priv;
62 
63         priv = GET_PRIVATE (object);
64 
65         if (priv->tree) {
66                 g_node_traverse (priv->tree,
67                                  G_IN_ORDER,
68                                  G_TRAVERSE_ALL,
69                                  -1,
70                                  (GNodeTraverseFunc)unref_node_link,
71                                  NULL);
72                 g_node_destroy (priv->tree);
73         }
74 
75         if (priv->keywords) {
76                 g_list_foreach (priv->keywords, (GFunc)dh_link_unref, NULL);
77                 g_list_free (priv->keywords);
78         }
79 
80         g_free (priv->title);
81 
82         g_free (priv->path);
83 
84         G_OBJECT_CLASS (dh_book_parent_class)->finalize (object);
85 }
86 
87 static void
dh_book_class_init(DhBookClass * klass)88 dh_book_class_init (DhBookClass *klass)
89 {
90         GObjectClass *object_class = G_OBJECT_CLASS (klass);
91 
92         object_class->finalize = book_finalize;
93 
94 	g_type_class_add_private (klass, sizeof (DhBookPriv));
95 }
96 
97 static void
dh_book_init(DhBook * book)98 dh_book_init (DhBook *book)
99 {
100         DhBookPriv *priv = GET_PRIVATE (book);
101 
102         priv->name = NULL;
103         priv->path = NULL;
104         priv->title = NULL;
105         priv->enabled = TRUE;
106         priv->tree = NULL;
107         priv->keywords = NULL;
108 }
109 
110 static void
unref_node_link(GNode * node,gpointer data)111 unref_node_link (GNode *node,
112                  gpointer data)
113 {
114         dh_link_unref (node->data);
115 }
116 
117 DhBook *
dh_book_new(const gchar * book_path)118 dh_book_new (const gchar  *book_path)
119 {
120         DhBookPriv *priv;
121         DhBook     *book;
122         GError     *error = NULL;
123 
124         g_return_val_if_fail (book_path, NULL);
125 
126         book = g_object_new (DH_TYPE_BOOK, NULL);
127         priv = GET_PRIVATE (book);
128 
129         /* Parse file storing contents in the book struct */
130         if (!dh_parser_read_file  (book_path,
131                                    &priv->tree,
132                                    &priv->keywords,
133                                    &error)) {
134                 g_warning ("Failed to read '%s': %s",
135                            priv->path, error->message);
136                 g_error_free (error);
137 
138                 /* Deallocate the book, as we are not going to add it
139                  *  in the manager */
140                 g_object_unref (book);
141                 return NULL;
142         }
143 
144         /* Store path */
145         priv->path = g_strdup (book_path);
146 
147         /* Setup title */
148         priv->title = g_strdup (dh_link_get_name ((DhLink *)priv->tree->data));
149 
150         /* Setup name */
151         priv->name = g_strdup (dh_link_get_book_id ((DhLink *)priv->tree->data));
152 
153         return book;
154 }
155 
156 GList *
dh_book_get_keywords(DhBook * book)157 dh_book_get_keywords (DhBook *book)
158 {
159         DhBookPriv *priv;
160 
161         g_return_val_if_fail (DH_IS_BOOK (book), NULL);
162 
163         priv = GET_PRIVATE (book);
164 
165         return priv->enabled ? priv->keywords : NULL;
166 }
167 
168 GNode *
dh_book_get_tree(DhBook * book)169 dh_book_get_tree (DhBook *book)
170 {
171         DhBookPriv *priv;
172 
173         g_return_val_if_fail (DH_IS_BOOK (book), NULL);
174 
175         priv = GET_PRIVATE (book);
176 
177         return priv->enabled ? priv->tree : NULL;
178 }
179 
180 const gchar *
dh_book_get_name(DhBook * book)181 dh_book_get_name (DhBook *book)
182 {
183         DhBookPriv *priv;
184 
185         g_return_val_if_fail (DH_IS_BOOK (book), NULL);
186 
187         priv = GET_PRIVATE (book);
188 
189         return priv->name;
190 }
191 
192 const gchar *
dh_book_get_title(DhBook * book)193 dh_book_get_title (DhBook *book)
194 {
195         DhBookPriv *priv;
196 
197         g_return_val_if_fail (DH_IS_BOOK (book), NULL);
198 
199         priv = GET_PRIVATE (book);
200 
201         return priv->title;
202 }
203 
204 gboolean
dh_book_get_enabled(DhBook * book)205 dh_book_get_enabled (DhBook *book)
206 {
207         g_return_val_if_fail (DH_IS_BOOK (book), FALSE);
208 
209         return GET_PRIVATE (book)->enabled;
210 }
211 
212 void
dh_book_set_enabled(DhBook * book,gboolean enabled)213 dh_book_set_enabled (DhBook *book,
214                      gboolean enabled)
215 {
216         g_return_if_fail (DH_IS_BOOK (book));
217 
218         GET_PRIVATE (book)->enabled = enabled;
219 }
220 
221 gint
dh_book_cmp_by_path(const DhBook * a,const DhBook * b)222 dh_book_cmp_by_path (const DhBook *a,
223                      const DhBook *b)
224 {
225         return ((a && b) ?
226                 g_strcmp0 (GET_PRIVATE (a)->path, GET_PRIVATE (b)->path) :
227                 -1);
228 }
229 
230 gint
dh_book_cmp_by_name(const DhBook * a,const DhBook * b)231 dh_book_cmp_by_name (const DhBook *a,
232                      const DhBook *b)
233 {
234         return ((a && b) ?
235                 g_ascii_strcasecmp (GET_PRIVATE (a)->name, GET_PRIVATE (b)->name) :
236                 -1);
237 }
238 
239 gint
dh_book_cmp_by_title(const DhBook * a,const DhBook * b)240 dh_book_cmp_by_title (const DhBook *a,
241                       const DhBook *b)
242 {
243         return ((a && b) ?
244                 g_utf8_collate (GET_PRIVATE (a)->title, GET_PRIVATE (b)->title) :
245                 -1);
246 }
247