1 /*
2  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
3  * Copyright (C) 2019 Red Hat, Inc. (www.redhat.com)
4  *
5  * This library is free software: you can redistribute it and/or modify it
6  * under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation.
8  *
9  * This library is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
12  * for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library. If not, see <http://www.gnu.org/licenses/>.
16  *
17  */
18 
19 #include "evolution-data-server-config.h"
20 
21 /**
22  * SECTION:e-cal-component-organizer
23  * @short_description: An ECalComponentOrganizer structure
24  * @include: libecal/libecal.h
25  *
26  * Contains functions to work with the #ECalComponentOrganizer structure.
27  **/
28 
29 #include "e-cal-component-parameter-bag.h"
30 
31 #include "e-cal-component-organizer.h"
32 
33 G_DEFINE_BOXED_TYPE (ECalComponentOrganizer, e_cal_component_organizer, e_cal_component_organizer_copy, e_cal_component_organizer_free)
34 
35 struct _ECalComponentOrganizer {
36 	gchar *value;
37 	gchar *sentby;
38 	gchar *cn;
39 	gchar *language;
40 
41 	ECalComponentParameterBag *parameter_bag;
42 };
43 
44 /**
45  * e_cal_component_organizer_new:
46  *
47  * Creates a new empty #ECalComponentOrganizer structure. Free it
48  * with e_cal_component_organizer_free(), when no longer needed.
49  *
50  * Returns: (transfer full): a newly allocated #ECalComponentOrganizer
51  *
52  * Since: 3.34
53  **/
54 ECalComponentOrganizer *
e_cal_component_organizer_new(void)55 e_cal_component_organizer_new (void)
56 {
57 	ECalComponentOrganizer *organizer;
58 
59 	organizer = g_slice_new0 (ECalComponentOrganizer);
60 	organizer->parameter_bag = e_cal_component_parameter_bag_new ();
61 
62 	return organizer;
63 }
64 
65 /**
66  * e_cal_component_organizer_new_full:
67  * @value: (nullable): usually a "mailto:email" of the organizer
68  * @sentby: (nullable): sent by
69  * @cn: (nullable): common name
70  * @language: (nullable): language
71  *
72  * Creates a new #ECalComponentOrganizer structure, with all members filled
73  * with given values from the parameters. The %NULL and empty strings are
74  * treated as unset the value. Free the structure
75  * with e_cal_component_organizer_free(), when no longer needed.
76  *
77  * Returns: (transfer full): a newly allocated #ECalComponentOrganizer
78  *
79  * Since: 3.34
80  **/
81 ECalComponentOrganizer *
e_cal_component_organizer_new_full(const gchar * value,const gchar * sentby,const gchar * cn,const gchar * language)82 e_cal_component_organizer_new_full (const gchar *value,
83 				    const gchar *sentby,
84 				    const gchar *cn,
85 				    const gchar *language)
86 {
87 	ECalComponentOrganizer *organizer;
88 
89 	organizer = e_cal_component_organizer_new ();
90 	organizer->value = value && *value ? g_strdup (value) : NULL;
91 	organizer->sentby = sentby && *sentby ? g_strdup (sentby) : NULL;
92 	organizer->cn = cn && *cn ? g_strdup (cn) : NULL;
93 	organizer->language = language && *language ? g_strdup (language) : NULL;
94 
95 	return organizer;
96 }
97 
98 /**
99  * e_cal_component_organizer_new_from_property:
100  * @property: an #ICalProperty of kind %I_CAL_ORGANIZER_PROPERTY
101  *
102  * Creates a new #ECalComponentOrganizer, filled with values from @property,
103  * which should be of kind %I_CAL_ORGANIZER_PROPERTY. The function returns
104  * %NULL when it is not of the expected kind. Free the structure
105  * with e_cal_component_organizer_free(), when no longer needed.
106  *
107  * Returns: (transfer full) (nullable): a newly allocated #ECalComponentOrganizer
108  *
109  * Since: 3.34
110  **/
111 ECalComponentOrganizer *
e_cal_component_organizer_new_from_property(const ICalProperty * property)112 e_cal_component_organizer_new_from_property (const ICalProperty *property)
113 {
114 	ECalComponentOrganizer *organizer;
115 
116 	g_return_val_if_fail (I_CAL_IS_PROPERTY ((ICalProperty *) property), NULL);
117 
118 	if (i_cal_property_isa ((ICalProperty *) property) != I_CAL_ORGANIZER_PROPERTY)
119 		return NULL;
120 
121 	organizer = e_cal_component_organizer_new ();
122 
123 	e_cal_component_organizer_set_from_property (organizer, property);
124 
125 	return organizer;
126 }
127 
128 /**
129  * e_cal_component_organizer_copy:
130  * @organizer: (not nullable): an #ECalComponentOrganizer
131  *
132  * Returns a newly allocated copy of @organizer, which should be freed with
133  * e_cal_component_organizer_free(), when no longer needed.
134  *
135  * Returns: (transfer full): a newly allocated copy of @organizer
136  *
137  * Since: 3.34
138  **/
139 ECalComponentOrganizer *
e_cal_component_organizer_copy(const ECalComponentOrganizer * organizer)140 e_cal_component_organizer_copy (const ECalComponentOrganizer *organizer)
141 {
142 	ECalComponentOrganizer *copy;
143 
144 	g_return_val_if_fail (organizer != NULL, NULL);
145 
146 	copy = e_cal_component_organizer_new_full (organizer->value,
147 		organizer->sentby,
148 		organizer->cn,
149 		organizer->language);
150 
151 	e_cal_component_parameter_bag_assign (copy->parameter_bag, organizer->parameter_bag);
152 
153 	return copy;
154 }
155 
156 /**
157  * e_cal_component_organizer_free: (skip)
158  * @organizer: (type ECalComponentOrganizer) (nullable): an #ECalComponentOrganizer to free
159  *
160  * Free @organizer, previously created by e_cal_component_organizer_new(),
161  * e_cal_component_organizer_new_full(), e_cal_component_organizer_new_from_property()
162  * or e_cal_component_organizer_copy(). The function does nothing, if @organizer
163  * is %NULL.
164  *
165  * Since: 3.34
166  **/
167 void
e_cal_component_organizer_free(gpointer organizer)168 e_cal_component_organizer_free (gpointer organizer)
169 {
170 	ECalComponentOrganizer *org = organizer;
171 
172 	if (org) {
173 		e_cal_component_parameter_bag_free (org->parameter_bag);
174 		g_free (org->value);
175 		g_free (org->sentby);
176 		g_free (org->cn);
177 		g_free (org->language);
178 		g_slice_free (ECalComponentOrganizer, org);
179 	}
180 }
181 
182 static gboolean
e_cal_component_organizer_filter_params_cb(ICalParameter * param,gpointer user_data)183 e_cal_component_organizer_filter_params_cb (ICalParameter *param,
184 					    gpointer user_data)
185 {
186 	ICalParameterKind kind;
187 
188 	kind = i_cal_parameter_isa (param);
189 
190 	return kind != I_CAL_SENTBY_PARAMETER &&
191 	       kind != I_CAL_CN_PARAMETER &&
192 	       kind != I_CAL_LANGUAGE_PARAMETER;
193 }
194 
195 /**
196  * e_cal_component_organizer_set_from_property:
197  * @organizer: an #ECalComponentOrganizer
198  * @property: an #ICalProperty
199  *
200  * Fill the @organizer structure with the information from
201  * the @property, which should be of %I_CAL_ORGANIZER_PROPERTY kind.
202  *
203  * Since: 3.34
204  **/
205 void
e_cal_component_organizer_set_from_property(ECalComponentOrganizer * organizer,const ICalProperty * property)206 e_cal_component_organizer_set_from_property (ECalComponentOrganizer *organizer,
207 					     const ICalProperty *property)
208 {
209 	ICalProperty *prop = (ICalProperty *) property;
210 	ICalParameter *param;
211 
212 	g_return_if_fail (organizer != NULL);
213 	g_return_if_fail (I_CAL_IS_PROPERTY ((ICalProperty *) property));
214 	g_return_if_fail (i_cal_property_isa (prop) == I_CAL_ORGANIZER_PROPERTY);
215 
216 	e_cal_component_organizer_set_value (organizer, i_cal_property_get_organizer (prop));
217 
218 	param = i_cal_property_get_first_parameter (prop, I_CAL_SENTBY_PARAMETER);
219 	e_cal_component_organizer_set_sentby (organizer, param ? i_cal_parameter_get_sentby (param) : NULL);
220 	g_clear_object (&param);
221 
222 	param = i_cal_property_get_first_parameter (prop, I_CAL_CN_PARAMETER);
223 	e_cal_component_organizer_set_cn (organizer, param ? i_cal_parameter_get_cn (param) : NULL);
224 	g_clear_object (&param);
225 
226 	param = i_cal_property_get_first_parameter (prop, I_CAL_LANGUAGE_PARAMETER);
227 	e_cal_component_organizer_set_language (organizer, param ? i_cal_parameter_get_language (param) : NULL);
228 	g_clear_object (&param);
229 
230 	e_cal_component_parameter_bag_set_from_property (organizer->parameter_bag, prop, e_cal_component_organizer_filter_params_cb, NULL);
231 }
232 
233 /**
234  * e_cal_component_organizer_get_as_property:
235  * @organizer: an #ECalComponentOrganizer
236  *
237  * Converts information stored in @organizer into an #ICalProperty
238  * of %I_CAL_ORGANIZER_PROPERTY kind. The caller is responsible to free
239  * the returned object with g_object_unref(), when no longer needed.
240  *
241  * Returns: (transfer full): a newly created #ICalProperty, containing
242  *    information from the @organizer.
243  *
244  * Since: 3.34
245  **/
246 ICalProperty *
e_cal_component_organizer_get_as_property(const ECalComponentOrganizer * organizer)247 e_cal_component_organizer_get_as_property (const ECalComponentOrganizer *organizer)
248 {
249 	ICalProperty *prop;
250 
251 	g_return_val_if_fail (organizer != NULL, NULL);
252 
253 	prop = i_cal_property_new (I_CAL_ORGANIZER_PROPERTY);
254 	g_return_val_if_fail (prop != NULL, NULL);
255 
256 	e_cal_component_organizer_fill_property (organizer, prop);
257 
258 	return prop;
259 }
260 
261 /**
262  * e_cal_component_organizer_fill_property:
263  * @organizer: an #ECalComponentOrganizer
264  * @property: (inout) (not nullable): an #ICalProperty
265  *
266  * Fill @property with information from @organizer. The @property
267  * should be of kind %I_CAL_ORGANIZER_PROPERTY.
268  *
269  * Since: 3.34
270  **/
271 void
e_cal_component_organizer_fill_property(const ECalComponentOrganizer * organizer,ICalProperty * property)272 e_cal_component_organizer_fill_property (const ECalComponentOrganizer *organizer,
273 					 ICalProperty *property)
274 {
275 	ICalParameter *param;
276 
277 	g_return_if_fail (organizer != NULL);
278 	g_return_if_fail (I_CAL_IS_PROPERTY (property));
279 	g_return_if_fail (i_cal_property_isa (property) == I_CAL_ORGANIZER_PROPERTY);
280 
281 	i_cal_property_set_organizer (property, organizer->value ? organizer->value : "mailto:");
282 
283 	#define fill_param(_param, _val, _filled) \
284 		param = i_cal_property_get_first_parameter (property, _param); \
285 		if (_filled) { \
286 			if (!param) { \
287 				param = i_cal_parameter_new (_param); \
288 				i_cal_property_add_parameter (property, param); \
289 			} \
290 			i_cal_parameter_set_ ## _val (param, organizer-> _val); \
291 			g_clear_object (&param); \
292 		} else if (param) { \
293 			i_cal_property_remove_parameter_by_kind (property, _param); \
294 			g_clear_object (&param); \
295 		}
296 
297 	fill_param (I_CAL_SENTBY_PARAMETER, sentby, organizer->sentby && *organizer->sentby);
298 	fill_param (I_CAL_CN_PARAMETER, cn, organizer->cn && *organizer->cn);
299 	fill_param (I_CAL_LANGUAGE_PARAMETER, language, organizer->language && *organizer->language);
300 
301 	#undef fill_param
302 
303 	e_cal_component_parameter_bag_fill_property (organizer->parameter_bag, property);
304 }
305 
306 /**
307  * e_cal_component_organizer_get_value:
308  * @organizer: an #ECalComponentOrganizer
309  *
310  * Returns: (nullable): the @organizer URI, usually of "mailto:email" form
311  *
312  * Since: 3.34
313  **/
314 const gchar *
e_cal_component_organizer_get_value(const ECalComponentOrganizer * organizer)315 e_cal_component_organizer_get_value (const ECalComponentOrganizer *organizer)
316 {
317 	g_return_val_if_fail (organizer != NULL, NULL);
318 
319 	return organizer->value;
320 }
321 
322 /**
323  * e_cal_component_organizer_set_value:
324  * @organizer: an #ECalComponentOrganizer
325  * @value: (nullable): the value to set
326  *
327  * Set the @organizer URI, usually of "mailto:email" form. The %NULL
328  * and empty strings are treated as unset the value.
329  *
330  * Since: 3.34
331  **/
332 void
e_cal_component_organizer_set_value(ECalComponentOrganizer * organizer,const gchar * value)333 e_cal_component_organizer_set_value (ECalComponentOrganizer *organizer,
334 				     const gchar *value)
335 {
336 	g_return_if_fail (organizer != NULL);
337 
338 	if (value && !*value)
339 		value = NULL;
340 
341 	if (g_strcmp0 (organizer->value, value) != 0) {
342 		g_free (organizer->value);
343 		organizer->value = g_strdup (value);
344 	}
345 }
346 
347 /**
348  * e_cal_component_organizer_get_sentby:
349  * @organizer: an #ECalComponentOrganizer
350  *
351  * Returns: (nullable): the @organizer sentby parameter
352  *
353  * Since: 3.34
354  **/
355 const gchar *
e_cal_component_organizer_get_sentby(const ECalComponentOrganizer * organizer)356 e_cal_component_organizer_get_sentby (const ECalComponentOrganizer *organizer)
357 {
358 	g_return_val_if_fail (organizer != NULL, NULL);
359 
360 	return organizer->sentby;
361 }
362 
363 /**
364  * e_cal_component_organizer_set_sentby:
365  * @organizer: an #ECalComponentOrganizer
366  * @sentby: (nullable): the value to set
367  *
368  * Set the @organizer sentby parameter. The %NULL
369  * and empty strings are treated as unset the value.
370  *
371  * Since: 3.34
372  **/
373 void
e_cal_component_organizer_set_sentby(ECalComponentOrganizer * organizer,const gchar * sentby)374 e_cal_component_organizer_set_sentby (ECalComponentOrganizer *organizer,
375 				      const gchar *sentby)
376 {
377 	g_return_if_fail (organizer != NULL);
378 
379 	if (sentby && !*sentby)
380 		sentby = NULL;
381 
382 	if (g_strcmp0 (organizer->sentby, sentby) != 0) {
383 		g_free (organizer->sentby);
384 		organizer->sentby = g_strdup (sentby);
385 	}
386 }
387 
388 /**
389  * e_cal_component_organizer_get_cn:
390  * @organizer: an #ECalComponentOrganizer
391  *
392  * Returns: (nullable): the @organizer common name (cn) parameter
393  *
394  * Since: 3.34
395  **/
396 const gchar *
e_cal_component_organizer_get_cn(const ECalComponentOrganizer * organizer)397 e_cal_component_organizer_get_cn (const ECalComponentOrganizer *organizer)
398 {
399 	g_return_val_if_fail (organizer != NULL, NULL);
400 
401 	return organizer->cn;
402 }
403 
404 /**
405  * e_cal_component_organizer_set_cn:
406  * @organizer: an #ECalComponentOrganizer
407  * @cn: (nullable): the value to set
408  *
409  * Set the @organizer common name (cn) parameter. The %NULL
410  * and empty strings are treated as unset the value.
411  *
412  * Since: 3.34
413  **/
414 void
e_cal_component_organizer_set_cn(ECalComponentOrganizer * organizer,const gchar * cn)415 e_cal_component_organizer_set_cn (ECalComponentOrganizer *organizer,
416 				  const gchar *cn)
417 {
418 	g_return_if_fail (organizer != NULL);
419 
420 	if (cn && !*cn)
421 		cn = NULL;
422 
423 	if (g_strcmp0 (organizer->cn, cn) != 0) {
424 		g_free (organizer->cn);
425 		organizer->cn = g_strdup (cn);
426 	}
427 }
428 
429 /**
430  * e_cal_component_organizer_get_language:
431  * @organizer: an #ECalComponentOrganizer
432  *
433  * Returns: (nullable): the @organizer language parameter
434  *
435  * Since: 3.34
436  **/
437 const gchar *
e_cal_component_organizer_get_language(const ECalComponentOrganizer * organizer)438 e_cal_component_organizer_get_language (const ECalComponentOrganizer *organizer)
439 {
440 	g_return_val_if_fail (organizer != NULL, NULL);
441 
442 	return organizer->language;
443 }
444 
445 /**
446  * e_cal_component_organizer_set_language:
447  * @organizer: an #ECalComponentOrganizer
448  * @language: (nullable): the value to set
449  *
450  * Set the @organizer language parameter. The %NULL
451  * and empty strings are treated as unset the value.
452  *
453  * Since: 3.34
454  **/
455 void
e_cal_component_organizer_set_language(ECalComponentOrganizer * organizer,const gchar * language)456 e_cal_component_organizer_set_language (ECalComponentOrganizer *organizer,
457 					const gchar *language)
458 {
459 	g_return_if_fail (organizer != NULL);
460 
461 	if (language && !*language)
462 		language = NULL;
463 
464 	if (g_strcmp0 (organizer->language, language) != 0) {
465 		g_free (organizer->language);
466 		organizer->language = g_strdup (language);
467 	}
468 }
469 
470 /**
471  * e_cal_component_organizer_get_parameter_bag:
472  * @organizer: an #ECalComponentOrganizer
473  *
474  * Returns: (transfer none): an #ECalComponentParameterBag with additional
475  *    parameters stored with the organizer property, other than those accessible
476  *    with the other functions of the @organizer.
477  *
478  * Since: 3.34
479  **/
480 ECalComponentParameterBag *
e_cal_component_organizer_get_parameter_bag(const ECalComponentOrganizer * organizer)481 e_cal_component_organizer_get_parameter_bag (const ECalComponentOrganizer *organizer)
482 {
483 	g_return_val_if_fail (organizer != NULL, NULL);
484 
485 	return organizer->parameter_bag;
486 }
487