No issues found
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) version 3.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with the program; if not, see <http://www.gnu.org/licenses/>
14 *
15 *
16 * Authors:
17 * Not Zed <notzed@lostzed.mmc.com.au>
18 * Jeffrey Stedfast <fejj@ximian.com>
19 *
20 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
21 *
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <string.h>
29 #include <stdlib.h>
30
31 #include "e-filter-element.h"
32 #include "e-filter-part.h"
33
34 struct _element_type {
35 gchar *name;
36
37 EFilterElementFunc create;
38 gpointer data;
39 };
40
41 G_DEFINE_TYPE (
42 EFilterElement,
43 e_filter_element,
44 G_TYPE_OBJECT)
45
46 static gboolean
47 filter_element_validate (EFilterElement *element,
48 EAlert **alert)
49 {
50 return TRUE;
51 }
52
53 static gint
54 filter_element_eq (EFilterElement *element_a,
55 EFilterElement *element_b)
56 {
57 return (g_strcmp0 (element_a->name, element_b->name) == 0);
58 }
59
60 static void
61 filter_element_xml_create (EFilterElement *element,
62 xmlNodePtr node)
63 {
64 element->name = (gchar *) xmlGetProp (node, (xmlChar *) "name");
65 }
66
67 static EFilterElement *
68 filter_element_clone (EFilterElement *element)
69 {
70 EFilterElement *clone;
71 xmlNodePtr node;
72
73 clone = g_object_new (G_OBJECT_TYPE (element), NULL);
74
75 node = e_filter_element_xml_encode (element);
76 e_filter_element_xml_decode (clone, node);
77 xmlFreeNodeList (node);
78
79 return clone;
80 }
81
82 /* This is somewhat hackish, implement all the base cases in here */
83 #include "e-filter-input.h"
84 #include "e-filter-option.h"
85 #include "e-filter-code.h"
86 #include "e-filter-color.h"
87 #include "e-filter-datespec.h"
88 #include "e-filter-int.h"
89 #include "e-filter-file.h"
90
91 static void
92 filter_element_copy_value (EFilterElement *dst_element,
93 EFilterElement *src_element)
94 {
95 if (E_IS_FILTER_INPUT (src_element)) {
96 EFilterInput *src_input;
97
98 src_input = E_FILTER_INPUT (src_element);
99
100 if (E_IS_FILTER_INPUT (dst_element)) {
101 EFilterInput *dst_input;
102
103 dst_input = E_FILTER_INPUT (dst_element);
104
105 if (src_input->values)
106 e_filter_input_set_value (
107 dst_input,
108 src_input->values->data);
109
110 } else if (E_IS_FILTER_INT (dst_element)) {
111 EFilterInt *dst_int;
112
113 dst_int = E_FILTER_INT (dst_element);
114
115 dst_int->val = atoi (src_input->values->data);
116 }
117
118 } else if (E_IS_FILTER_COLOR (src_element)) {
119 EFilterColor *src_color;
120
121 src_color = E_FILTER_COLOR (src_element);
122
123 if (E_IS_FILTER_COLOR (dst_element)) {
124 EFilterColor *dst_color;
125
126 dst_color = E_FILTER_COLOR (dst_element);
127
128 dst_color->color = src_color->color;
129 }
130
131 } else if (E_IS_FILTER_DATESPEC (src_element)) {
132 EFilterDatespec *src_datespec;
133
134 src_datespec = E_FILTER_DATESPEC (src_element);
135
136 if (E_IS_FILTER_DATESPEC (dst_element)) {
137 EFilterDatespec *dst_datespec;
138
139 dst_datespec = E_FILTER_DATESPEC (dst_element);
140
141 dst_datespec->type = src_datespec->type;
142 dst_datespec->value = src_datespec->value;
143 }
144
145 } else if (E_IS_FILTER_INT (src_element)) {
146 EFilterInt *src_int;
147
148 src_int = E_FILTER_INT (src_element);
149
150 if (E_IS_FILTER_INT (dst_element)) {
151 EFilterInt *dst_int;
152
153 dst_int = E_FILTER_INT (dst_element);
154
155 dst_int->val = src_int->val;
156
157 } else if (E_IS_FILTER_INPUT (dst_element)) {
158 EFilterInput *dst_input;
159 gchar *values;
160
161 dst_input = E_FILTER_INPUT (dst_element);
162
163 values = g_strdup_printf ("%d", src_int->val);
164 e_filter_input_set_value (dst_input, values);
165 g_free (values);
166 }
167
168 } else if (E_IS_FILTER_OPTION (src_element)) {
169 EFilterOption *src_option;
170
171 src_option = E_FILTER_OPTION (src_element);
172
173 if (E_IS_FILTER_OPTION (dst_element)) {
174 EFilterOption *dst_option;
175
176 dst_option = E_FILTER_OPTION (dst_element);
177
178 if (src_option->current)
179 e_filter_option_set_current (
180 dst_option,
181 src_option->current->value);
182 }
183 }
184 }
185
186 static void
187 filter_element_finalize (GObject *object)
188 {
189 EFilterElement *element = E_FILTER_ELEMENT (object);
190
191 xmlFree (element->name);
192
193 /* Chain up to parent's finalize () method. */
194 G_OBJECT_CLASS (e_filter_element_parent_class)->finalize (object);
195 }
196
197 static void
198 e_filter_element_class_init (EFilterElementClass *class)
199 {
200 GObjectClass *object_class;
201
202 object_class = G_OBJECT_CLASS (class);
203 object_class->finalize = filter_element_finalize;
204
205 class->validate = filter_element_validate;
206 class->eq = filter_element_eq;
207 class->xml_create = filter_element_xml_create;
208 class->clone = filter_element_clone;
209 class->copy_value = filter_element_copy_value;
210 }
211
212 static void
213 e_filter_element_init (EFilterElement *element)
214 {
215 }
216
217 /**
218 * filter_element_new:
219 *
220 * Create a new EFilterElement object.
221 *
222 * Return value: A new #EFilterElement object.
223 **/
224 EFilterElement *
225 e_filter_element_new (void)
226 {
227 return g_object_new (E_TYPE_FILTER_ELEMENT, NULL);
228 }
229
230 gboolean
231 e_filter_element_validate (EFilterElement *element,
232 EAlert **alert)
233 {
234 EFilterElementClass *class;
235
236 g_return_val_if_fail (E_IS_FILTER_ELEMENT (element), FALSE);
237
238 class = E_FILTER_ELEMENT_GET_CLASS (element);
239 g_return_val_if_fail (class->validate != NULL, FALSE);
240
241 return class->validate (element, alert);
242 }
243
244 gint
245 e_filter_element_eq (EFilterElement *element_a,
246 EFilterElement *element_b)
247 {
248 EFilterElementClass *class;
249
250 g_return_val_if_fail (E_IS_FILTER_ELEMENT (element_a), FALSE);
251 g_return_val_if_fail (E_IS_FILTER_ELEMENT (element_b), FALSE);
252
253 /* The elements must be the same type. */
254 if (G_OBJECT_TYPE (element_a) != G_OBJECT_TYPE (element_b))
255 return FALSE;
256
257 class = E_FILTER_ELEMENT_GET_CLASS (element_a);
258 g_return_val_if_fail (class->eq != NULL, FALSE);
259
260 return class->eq (element_a, element_b);
261 }
262
263 /**
264 * filter_element_xml_create:
265 * @fe: filter element
266 * @node: xml node
267 *
268 * Create a new filter element based on an xml definition of
269 * that element.
270 **/
271 void
272 e_filter_element_xml_create (EFilterElement *element,
273 xmlNodePtr node)
274 {
275 EFilterElementClass *class;
276
277 g_return_if_fail (E_IS_FILTER_ELEMENT (element));
278 g_return_if_fail (node != NULL);
279
280 class = E_FILTER_ELEMENT_GET_CLASS (element);
281 g_return_if_fail (class->xml_create != NULL);
282
283 class->xml_create (element, node);
284 }
285
286 /**
287 * filter_element_xml_encode:
288 * @fe: filter element
289 *
290 * Encode the values of a filter element into xml format.
291 *
292 * Return value:
293 **/
294 xmlNodePtr
295 e_filter_element_xml_encode (EFilterElement *element)
296 {
297 EFilterElementClass *class;
298
299 g_return_val_if_fail (E_IS_FILTER_ELEMENT (element), NULL);
300
301 class = E_FILTER_ELEMENT_GET_CLASS (element);
302 g_return_val_if_fail (class->xml_encode != NULL, NULL);
303
304 return class->xml_encode (element);
305 }
306
307 /**
308 * filter_element_xml_decode:
309 * @fe: filter element
310 * @node: xml node
311 *
312 * Decode the values of a fitler element from xml format.
313 *
314 * Return value:
315 **/
316 gint
317 e_filter_element_xml_decode (EFilterElement *element,
318 xmlNodePtr node)
319 {
320 EFilterElementClass *class;
321
322 g_return_val_if_fail (E_IS_FILTER_ELEMENT (element), FALSE);
323 g_return_val_if_fail (node != NULL, FALSE);
324
325 class = E_FILTER_ELEMENT_GET_CLASS (element);
326 g_return_val_if_fail (class->xml_decode != NULL, FALSE);
327
328 return class->xml_decode (element, node);
329 }
330
331 /**
332 * filter_element_clone:
333 * @fe: filter element
334 *
335 * Clones the EFilterElement @fe.
336 *
337 * Return value:
338 **/
339 EFilterElement *
340 e_filter_element_clone (EFilterElement *element)
341 {
342 EFilterElementClass *class;
343
344 g_return_val_if_fail (E_IS_FILTER_ELEMENT (element), NULL);
345
346 class = E_FILTER_ELEMENT_GET_CLASS (element);
347 g_return_val_if_fail (class->clone != NULL, NULL);
348
349 return class->clone (element);
350 }
351
352 /**
353 * filter_element_get_widget:
354 * @fe: filter element
355 * @node: xml node
356 *
357 * Create a widget to represent this element.
358 *
359 * Return value:
360 **/
361 GtkWidget *
362 e_filter_element_get_widget (EFilterElement *element)
363 {
364 EFilterElementClass *class;
365
366 g_return_val_if_fail (E_IS_FILTER_ELEMENT (element), NULL);
367
368 class = E_FILTER_ELEMENT_GET_CLASS (element);
369 g_return_val_if_fail (class->get_widget != NULL, NULL);
370
371 return class->get_widget (element);
372 }
373
374 /**
375 * filter_element_build_code:
376 * @fe: filter element
377 * @out: output buffer
378 * @ff:
379 *
380 * Add the code representing this element to the output string @out.
381 **/
382 void
383 e_filter_element_build_code (EFilterElement *element,
384 GString *out,
385 EFilterPart *part)
386 {
387 EFilterElementClass *class;
388
389 g_return_if_fail (E_IS_FILTER_ELEMENT (element));
390 g_return_if_fail (out != NULL);
391 g_return_if_fail (E_IS_FILTER_PART (part));
392
393 class = E_FILTER_ELEMENT_GET_CLASS (element);
394
395 /* This method is optional. */
396 if (class->build_code != NULL)
397 class->build_code (element, out, part);
398 }
399
400 /**
401 * filter_element_format_sexp:
402 * @fe: filter element
403 * @out: output buffer
404 *
405 * Format the value(s) of this element in a method suitable for the context of
406 * sexp where it is used. Usually as space separated, double-quoted strings.
407 **/
408 void
409 e_filter_element_format_sexp (EFilterElement *element,
410 GString *out)
411 {
412 EFilterElementClass *class;
413
414 g_return_if_fail (E_IS_FILTER_ELEMENT (element));
415 g_return_if_fail (out != NULL);
416
417 class = E_FILTER_ELEMENT_GET_CLASS (element);
418 g_return_if_fail (class->format_sexp != NULL);
419
420 class->format_sexp (element, out);
421 }
422
423 void
424 e_filter_element_set_data (EFilterElement *element,
425 gpointer data)
426 {
427 g_return_if_fail (E_IS_FILTER_ELEMENT (element));
428
429 element->data = data;
430 }
431
432 /* only copies the value, not the name/type */
433 void
434 e_filter_element_copy_value (EFilterElement *dst_element,
435 EFilterElement *src_element)
436 {
437 EFilterElementClass *class;
438
439 g_return_if_fail (E_IS_FILTER_ELEMENT (dst_element));
440 g_return_if_fail (E_IS_FILTER_ELEMENT (src_element));
441
442 class = E_FILTER_ELEMENT_GET_CLASS (dst_element);
443 g_return_if_fail (class->copy_value != NULL);
444
445 class->copy_value (dst_element, src_element);
446 }