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