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