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