1 /* Fo
2 * fo-property-force-page-count.c: 'force-page-count' property
3 *
4 * Copyright (C) 2001-2006 Sun Microsystems
5 * Copyright (C) 2007-2010 Menteith Consulting Ltd
6 * Copyright (C) 2011 Mentea
7 *
8 * See COPYING for the status of this software.
9 */
10
11 #include <string.h>
12 #include "fo-utils.h"
13 #include "fo-context.h"
14 #include "datatype/fo-datatype.h"
15 #include "property/fo-property-private.h"
16 #include "property/fo-property-font-size.h"
17 #include "property/fo-property-force-page-count.h"
18
19 /**
20 * SECTION:fo-property-force-page-count
21 * @short_description: 'force-page-count' property
22 *
23 * Inherited: FALSE
24 *
25 * Shorthand: FALSE
26 *
27 * Value: auto | even | odd | end-on-even | end-on-odd | no-force | inherit
28 *
29 * Initial value: auto
30 *
31 * Definition: <ulink url="http://www.w3.org/TR/xsl11/#force-page-count">http://www.w3.org/TR/xsl11/#force-page-count</ulink>
32 */
33
34 struct _FoPropertyForcePageCount
35 {
36 FoProperty parent_instance;
37 };
38
39 struct _FoPropertyForcePageCountClass
40 {
41 FoPropertyClass parent_class;
42 };
43
44 static void _init (FoPropertyForcePageCount *property_force_page_count);
45 static void _class_init (FoPropertyForcePageCountClass *klass);
46
47 static FoDatatype * _resolve_enum (const gchar *token,
48 FoContext *context,
49 GError **error);
50 static FoDatatype * _validate (FoDatatype *datatype,
51 FoContext *context,
52 GError **error);
53
54 static const gchar class_name[] = "force-page-count";
55 static gpointer parent_class;
56
57 /**
58 * fo_property_force_page_count_get_type:
59 *
60 * Register the #FoPropertyForcePageCount type if not already registered and
61 * return its #GType value.
62 *
63 * Return value: #GType of #FoPropertyForcePageCount.
64 **/
65 GType
fo_property_force_page_count_get_type(void)66 fo_property_force_page_count_get_type (void)
67 {
68 static GType object_type = 0;
69
70 if (!object_type)
71 {
72 static const GTypeInfo object_info =
73 {
74 sizeof (FoPropertyForcePageCountClass),
75 NULL, /* base_init */
76 NULL, /* base_finalize */
77 (GClassInitFunc) _class_init,
78 NULL, /* class_finalize */
79 NULL, /* class_data */
80 sizeof (FoPropertyForcePageCount),
81 0, /* n_preallocs */
82 (GInstanceInitFunc) _init,
83 NULL /* value_table */
84 };
85
86 object_type = g_type_register_static (FO_TYPE_PROPERTY,
87 class_name,
88 &object_info, 0);
89 }
90
91 return object_type;
92 }
93
94 /**
95 * _init:
96 * @force_page_count: #FoPropertyForcePageCount object to initialise.
97 *
98 * Implements #GInstanceInitFunc for #FoPropertyForcePageCount.
99 **/
100 static void
_init(FoPropertyForcePageCount * force_page_count)101 _init (FoPropertyForcePageCount *force_page_count)
102 {
103 FO_PROPERTY (force_page_count)->value =
104 g_object_ref (fo_enum_factory_get_enum_by_value (FO_ENUM_ENUM_AUTO));
105 }
106
107 /**
108 * _class_init:
109 * @klass: #FoPropertyForcePageCountClass object to initialise.
110 *
111 * Implements #GClassInitFunc for #FoPropertyForcePageCountClass.
112 **/
113 static void
_class_init(FoPropertyForcePageCountClass * klass)114 _class_init (FoPropertyForcePageCountClass *klass)
115 {
116 GObjectClass *object_class = G_OBJECT_CLASS (klass);
117 FoPropertyClass *property_class = FO_PROPERTY_CLASS (klass);
118
119 parent_class = g_type_class_peek_parent (klass);
120
121
122 property_class->is_inherited = FALSE;
123 property_class->is_shorthand = FALSE;
124 property_class->resolve_enum =
125 _resolve_enum;
126 property_class->validate =
127 _validate;
128 property_class->get_initial =
129 fo_property_force_page_count_get_initial;
130 }
131
132
133 /**
134 * fo_property_force_page_count_new:
135 *
136 * Creates a new #FoPropertyForcePageCount initialized to default value.
137 *
138 * Return value: the new #FoPropertyForcePageCount.
139 **/
140 FoProperty*
fo_property_force_page_count_new(void)141 fo_property_force_page_count_new (void)
142 {
143 FoProperty* force_page_count;
144
145 force_page_count =
146 FO_PROPERTY (g_object_new (fo_property_force_page_count_get_type (),
147 NULL));
148
149 return force_page_count;
150 }
151
152 /**
153 * _resolve_enum:
154 * @token: Token from the XML attribute value to be evaluated as an
155 * enumeration token.
156 * @context: #FoContext object from which to possibly inherit values.
157 * @error: Information about any error that has occurred.
158 *
159 * Compare @token against the enumeration tokens that are valid for the
160 * current FO property. If @token is valid, returns either an #FoEnum datatype
161 * representing the enumeration token or a different datatype representing
162 * the enumeration token's resolved value. If @token is not valid,
163 * sets @error and returns NULL.
164 *
165 * Return value: Resolved enumeration value or NULL.
166 **/
167 static FoDatatype *
_resolve_enum(const gchar * token,FoContext * context,GError ** error)168 _resolve_enum (const gchar *token,
169 FoContext *context,
170 GError **error)
171 {
172 g_return_val_if_fail (token != NULL, NULL);
173 g_return_val_if_fail (FO_IS_CONTEXT (context), NULL);
174 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
175
176 if ((strcmp (token, "auto") == 0) ||
177 (strcmp (token, "even") == 0) ||
178 (strcmp (token, "odd") == 0) ||
179 (strcmp (token, "end-on-even") == 0) ||
180 (strcmp (token, "end-on-odd") == 0) ||
181 (strcmp (token, "no-force") == 0))
182 {
183 return g_object_ref (fo_enum_factory_get_enum_by_nick (token));
184 }
185 else
186 {
187 g_set_error (error,
188 FO_FO_ERROR,
189 FO_FO_ERROR_ENUMERATION_TOKEN,
190 _(fo_fo_error_messages[FO_FO_ERROR_ENUMERATION_TOKEN]),
191 class_name,
192 token);
193 return NULL;
194 }
195 }
196
197 /**
198 * _validate:
199 * @datatype: #FoDatatype to be validated against allowed datatypes and
200 * values for current property.
201 * @context: #FoContext object from which to possibly inherit values.
202 * @error: Information about any error that has occurred.
203 *
204 * Validates @datatype against allowed values. Returns @datatype, a
205 * replacement datatype value, or NULL if validation failed.
206 *
207 * Return value: Valid datatype value or NULL.
208 **/
209 FoDatatype*
_validate(FoDatatype * datatype,FoContext * context,GError ** error)210 _validate (FoDatatype *datatype,
211 FoContext *context,
212 GError **error)
213 {
214 FoDatatype *new_datatype;
215 GError *tmp_error = NULL;
216 gchar *token;
217
218 g_return_val_if_fail (datatype != NULL, NULL);
219 g_return_val_if_fail (FO_IS_DATATYPE (datatype), NULL);
220 g_return_val_if_fail (context != NULL, NULL);
221 g_return_val_if_fail (FO_IS_CONTEXT (context), NULL);
222 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
223
224 if (FO_IS_ENUM (datatype))
225 {
226 FoEnumEnum value = fo_enum_get_value (datatype);
227
228 if ((value == FO_ENUM_ENUM_AUTO) ||
229 (value == FO_ENUM_ENUM_EVEN) ||
230 (value == FO_ENUM_ENUM_ODD) ||
231 (value == FO_ENUM_ENUM_END_ON_EVEN) ||
232 (value == FO_ENUM_ENUM_END_ON_ODD) ||
233 (value == FO_ENUM_ENUM_NO_FORCE))
234 {
235 return datatype;
236 }
237 else
238 {
239 gchar *datatype_sprintf = fo_object_sprintf (datatype);
240
241 g_set_error (error,
242 FO_FO_ERROR,
243 FO_FO_ERROR_ENUMERATION_TOKEN,
244 _(fo_fo_error_messages[FO_FO_ERROR_ENUMERATION_TOKEN]),
245 class_name,
246 datatype_sprintf,
247 g_type_name (G_TYPE_FROM_INSTANCE (datatype)));
248
249 g_object_unref (datatype);
250
251 g_free (datatype_sprintf);
252
253 return NULL;
254 }
255 }
256 else if (FO_IS_STRING (datatype))
257 {
258 token = fo_string_get_value (datatype);
259
260 new_datatype =
261 _resolve_enum (token, context, &tmp_error);
262
263 g_object_unref (datatype);
264
265 fo_propagate_and_return_val_if_error (error, tmp_error, NULL);
266
267 return new_datatype;
268 }
269 else if (FO_IS_NAME (datatype))
270 {
271 token = fo_name_get_value (datatype);
272
273 new_datatype =
274 _resolve_enum (token, context, &tmp_error);
275
276 g_object_unref (datatype);
277
278 fo_propagate_and_return_val_if_error (error, tmp_error, NULL);
279
280 return new_datatype;
281 }
282 else
283 {
284 gchar *datatype_sprintf = fo_object_sprintf (datatype);
285
286 g_set_error (error,
287 FO_FO_ERROR,
288 FO_FO_ERROR_DATATYPE,
289 _(fo_fo_error_messages[FO_FO_ERROR_DATATYPE]),
290 class_name,
291 datatype_sprintf,
292 g_type_name (G_TYPE_FROM_INSTANCE (datatype)));
293
294 g_object_unref (datatype);
295
296 g_free (datatype_sprintf);
297
298 return NULL;
299 }
300 }
301
302 /**
303 * fo_property_force_page_count_get_initial:
304 *
305 * Get an instance of the property with the correct initial value.
306 *
307 * Return value: An instance of the property.
308 **/
309 FoProperty*
fo_property_force_page_count_get_initial(void)310 fo_property_force_page_count_get_initial (void)
311 {
312 static FoProperty *force_page_count = NULL;
313
314 if (force_page_count == NULL)
315 {
316 force_page_count =
317 fo_property_force_page_count_new ();
318 }
319
320 return force_page_count;
321 }
322