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-period
23  * @short_description: An ECalComponentPeriod structure
24  * @include: libecal/libecal.h
25  *
26  * Contains functions to work with the #ECalComponentPeriod structure.
27  **/
28 
29 #include "e-cal-component-period.h"
30 
31 G_DEFINE_BOXED_TYPE (ECalComponentPeriod, e_cal_component_period, e_cal_component_period_copy, e_cal_component_period_free)
32 
33 struct _ECalComponentPeriod {
34 	ECalComponentPeriodKind kind;
35 
36 	ICalTime *start;
37 
38 	/* Only one of 'end' and 'duration' can be set, depending on the kind */
39 	ICalTime *end;
40 	ICalDuration *duration;
41 };
42 
43 /**
44  * e_cal_component_period_new_datetime:
45  * @start: (not nullable): an #ICalTime, the start of the period
46  * @end: (nullable): an #ICalTime, the end of the period
47  *
48  * Creates a new #ECalComponentPeriod of kind %E_CAL_COMPONENT_PERIOD_DATETIME.
49  * The returned structure should be freed with e_cal_component_period_free(),
50  * when no longer needed.
51  *
52  * Returns: (transfer full): a newly allocated #ECalComponentPeriod
53  *
54  * Since: 3.34
55  **/
56 ECalComponentPeriod *
e_cal_component_period_new_datetime(const ICalTime * start,const ICalTime * end)57 e_cal_component_period_new_datetime (const ICalTime *start,
58 				     const ICalTime *end)
59 {
60 	ECalComponentPeriod *period;
61 
62 	g_return_val_if_fail (I_CAL_IS_TIME ((ICalTime *) start), NULL);
63 
64 	period = g_slice_new0 (ECalComponentPeriod);
65 	period->kind = E_CAL_COMPONENT_PERIOD_DATETIME;
66 
67 	e_cal_component_period_set_datetime_full (period, start, end);
68 
69 	return period;
70 }
71 
72 /**
73  * e_cal_component_period_new_duration:
74  * @start: (not nullable): an #ICalTime, the start of the period
75  * @duration: (not nullable): an #ICalDuration, the duration of the period
76  *
77  * Creates a new #ECalComponentPeriod of kind %E_CAL_COMPONENT_PERIOD_DURATION.
78  * The returned structure should be freed with e_cal_component_period_free(),
79  * when no longer needed.
80  *
81  * Returns: (transfer full): a newly allocated #ECalComponentPeriod
82  *
83  * Since: 3.34
84  **/
85 ECalComponentPeriod *
e_cal_component_period_new_duration(const ICalTime * start,const ICalDuration * duration)86 e_cal_component_period_new_duration (const ICalTime *start,
87 				     const ICalDuration *duration)
88 {
89 	ECalComponentPeriod *period;
90 
91 	g_return_val_if_fail (I_CAL_IS_TIME ((ICalTime *) start), NULL);
92 	g_return_val_if_fail (I_CAL_IS_DURATION ((ICalDuration *) duration), NULL);
93 
94 	period = g_slice_new0 (ECalComponentPeriod);
95 	period->kind = E_CAL_COMPONENT_PERIOD_DURATION;
96 
97 	e_cal_component_period_set_duration_full (period, start, duration);
98 
99 	return period;
100 }
101 
102 /**
103  * e_cal_component_period_copy:
104  * @period: (not nullable): an #ECalComponentPeriod to copy
105  *
106  * Returns: (transfer full): a newly allocated #ECalComponentPeriod, copy of @period.
107  *    The returned structure should be freed with e_cal_component_period_free(),
108  *    when no longer needed.
109  *
110  * Since: 3.34
111  **/
112 ECalComponentPeriod *
e_cal_component_period_copy(const ECalComponentPeriod * period)113 e_cal_component_period_copy (const ECalComponentPeriod *period)
114 {
115 	ECalComponentPeriod *copy = NULL;
116 
117 	g_return_val_if_fail (period != NULL, NULL);
118 
119 	switch (e_cal_component_period_get_kind (period)) {
120 	case E_CAL_COMPONENT_PERIOD_DATETIME:
121 		copy = e_cal_component_period_new_datetime (
122 			e_cal_component_period_get_start (period),
123 			e_cal_component_period_get_end (period));
124 		break;
125 	case E_CAL_COMPONENT_PERIOD_DURATION:
126 		copy = e_cal_component_period_new_duration (
127 			e_cal_component_period_get_start (period),
128 			e_cal_component_period_get_duration (period));
129 		break;
130 	}
131 
132 	return copy;
133 }
134 
135 /**
136  * e_cal_component_period_free: (skip)
137  * @period: (type ECalComponentPeriod) (nullable): an #ECalComponentPeriod to free
138  *
139  * Free the @period, previously allocated by e_cal_component_period_new_datetime(),
140  * e_cal_component_period_new_duration() or e_cal_component_period_copy().
141  *
142  * Since: 3.34
143  **/
144 void
e_cal_component_period_free(gpointer period)145 e_cal_component_period_free (gpointer period)
146 {
147 	ECalComponentPeriod *pd = period;
148 
149 	if (pd) {
150 		g_clear_object (&pd->start);
151 		g_clear_object (&pd->end);
152 		g_clear_object (&pd->duration);
153 		g_slice_free (ECalComponentPeriod, pd);
154 	}
155 }
156 
157 /**
158  * e_cal_component_period_get_kind:
159  * @period: an #ECalComponentPeriod
160  *
161  * Returns kind of the @period, one of #ECalComponentPeriodKind. Depending
162  * on it either e_cal_component_period_get_end()/e_cal_component_period_set_end()
163  * or e_cal_component_period_get_duration()/e_cal_component_period_set_duration()
164  * can be used. The kind of an existing @period canbe changed with
165  * e_cal_component_period_set_datetime_full() and e_cal_component_period_set_duration_full().
166  *
167  * Returns: kind of the period, one of #ECalComponentPeriodKind
168  *
169  * Since: 3.34
170  **/
171 ECalComponentPeriodKind
e_cal_component_period_get_kind(const ECalComponentPeriod * period)172 e_cal_component_period_get_kind	(const ECalComponentPeriod *period)
173 {
174 	g_return_val_if_fail (period != NULL, E_CAL_COMPONENT_PERIOD_DATETIME);
175 
176 	return period->kind;
177 }
178 
179 /**
180  * e_cal_component_period_set_datetime_full:
181  * @period: an #ECalComponentPeriod
182  * @start: (not nullable): an #ICalTime, the start of the @period
183  * @end: (nullable): an #ICalTime, the end of the @period
184  *
185  * Set the kind of @period to be %E_CAL_COMPONENT_PERIOD_DATETIME
186  * and fills the content with @start and @end.
187  *
188  * Since: 3.34
189  **/
190 void
e_cal_component_period_set_datetime_full(ECalComponentPeriod * period,const ICalTime * start,const ICalTime * end)191 e_cal_component_period_set_datetime_full (ECalComponentPeriod *period,
192 					  const ICalTime *start,
193 					  const ICalTime *end)
194 {
195 	g_return_if_fail (period != NULL);
196 	g_return_if_fail (I_CAL_IS_TIME ((ICalTime *) start));
197 
198 	g_clear_object (&period->duration);
199 
200 	period->kind = E_CAL_COMPONENT_PERIOD_DATETIME;
201 
202 	e_cal_component_period_set_start (period, start);
203 	e_cal_component_period_set_end (period, end);
204 }
205 
206 /**
207  * e_cal_component_period_set_duration_full:
208  * @period: an #ECalComponentPeriod
209  * @start: (not nullable): an #ICalTime, the start of the @period
210  * @duration: (not nullable): an #ICalDuration, the duration of the @period
211  *
212  * Set the kind of @period to be %E_CAL_COMPONENT_PERIOD_DURATION
213  * and fills the content with @start and @duration.
214  *
215  * Since: 3.34
216  **/
217 void
e_cal_component_period_set_duration_full(ECalComponentPeriod * period,const ICalTime * start,const ICalDuration * duration)218 e_cal_component_period_set_duration_full (ECalComponentPeriod *period,
219 					  const ICalTime *start,
220 					  const ICalDuration *duration)
221 {
222 	g_return_if_fail (period != NULL);
223 	g_return_if_fail (I_CAL_IS_TIME ((ICalTime *) start));
224 	g_return_if_fail (I_CAL_IS_DURATION ((ICalDuration *) duration));
225 
226 	g_clear_object (&period->end);
227 
228 	period->kind = E_CAL_COMPONENT_PERIOD_DURATION;
229 
230 	e_cal_component_period_set_start (period, start);
231 	e_cal_component_period_set_duration (period, duration);
232 }
233 
234 /**
235  * e_cal_component_period_get_start:
236  * @period: an #ECalComponentPeriod
237  *
238  * Returns the start of the @period. The returned #ICalTime object
239  * is owned by @period and should not be freed. It's valid until the @period
240  * is freed or its start time changed.
241  *
242  * Returns: (transfer none): the start of the @period, as an #ICalTime
243  *
244  * Since: 3.34
245  **/
246 ICalTime *
e_cal_component_period_get_start(const ECalComponentPeriod * period)247 e_cal_component_period_get_start (const ECalComponentPeriod *period)
248 {
249 	g_return_val_if_fail (period != NULL, NULL);
250 
251 	return period->start;
252 }
253 
254 /**
255  * e_cal_component_period_set_start:
256  * @period: an #ECalComponentPeriod
257  * @start: (not nullable): an #ICalTime, the start of the @period
258  *
259  * Set the @start of the @period. This can be called on any kind of the @period.
260  *
261  * Since: 3.34
262  **/
263 void
e_cal_component_period_set_start(ECalComponentPeriod * period,const ICalTime * start)264 e_cal_component_period_set_start (ECalComponentPeriod *period,
265 				  const ICalTime *start)
266 {
267 	g_return_if_fail (period != NULL);
268 	g_return_if_fail (I_CAL_IS_TIME ((ICalTime *) start));
269 
270 	if (period->start != start) {
271 		g_clear_object (&period->start);
272 		period->start = i_cal_time_clone (start);
273 	}
274 }
275 
276 /**
277  * e_cal_component_period_get_end:
278  * @period: an #ECalComponentPeriod
279  *
280  * Returns the end of the @period. This can be called only on @period
281  * objects of kind %E_CAL_COMPONENT_PERIOD_DATETIME. The end time can
282  * be a null-time, in which case the @period corresponds to a single
283  * date/date-time value, not to a period.
284  *
285  * The returned #ICalTime object is owned by @period and should not
286  * be freed. It's valid until the @period is freed or its end time changed.
287  *
288  * Returns: (transfer none) (nullable): the end of the period, as an #ICalTime
289  *
290  * Since: 3.34
291  **/
292 ICalTime *
e_cal_component_period_get_end(const ECalComponentPeriod * period)293 e_cal_component_period_get_end (const ECalComponentPeriod *period)
294 {
295 	g_return_val_if_fail (period != NULL, NULL);
296 	g_return_val_if_fail (period->kind == E_CAL_COMPONENT_PERIOD_DATETIME, NULL);
297 
298 	return period->end;
299 }
300 
301 /**
302  * e_cal_component_period_set_end:
303  * @period: an #ECalComponentPeriod
304  * @end: (nullable): an #ICalTime, the end of the @period
305  *
306  * Set the end of the @period. This can be called only on @period
307  * objects of kind %E_CAL_COMPONENT_PERIOD_DATETIME.
308  *
309  * Since: 3.34
310  **/
311 void
e_cal_component_period_set_end(ECalComponentPeriod * period,const ICalTime * end)312 e_cal_component_period_set_end (ECalComponentPeriod *period,
313 				const ICalTime *end)
314 {
315 	g_return_if_fail (period != NULL);
316 	g_return_if_fail (period->kind == E_CAL_COMPONENT_PERIOD_DATETIME);
317 
318 	if (period->end != end) {
319 		g_clear_object (&period->end);
320 		if (end)
321 			period->end = i_cal_time_clone (end);
322 	}
323 }
324 
325 /**
326  * e_cal_component_period_get_duration:
327  * @period: an #ECalComponentPeriod
328  *
329  * Returns the duration of the @period. This can be called only on @period
330  * objects of kind %E_CAL_COMPONENT_PERIOD_DURATION.
331  * The returned #ICalDuration object is owned by @period and should not
332  * be freed. It's valid until the @period is freed or its duration changed.
333  *
334  * Returns: (transfer none): the duration of the period, as an #ICalDuration
335  *
336  * Since: 3.34
337  **/
338 ICalDuration *
e_cal_component_period_get_duration(const ECalComponentPeriod * period)339 e_cal_component_period_get_duration (const ECalComponentPeriod *period)
340 {
341 	g_return_val_if_fail (period != NULL, NULL);
342 	g_return_val_if_fail (period->kind == E_CAL_COMPONENT_PERIOD_DURATION, NULL);
343 
344 	return period->duration;
345 }
346 
347 /**
348  * e_cal_component_period_set_duration:
349  * @period: an #ECalComponentPeriod
350  * @duration: (not nullable): an #ICalDuration, the duration of the @period
351  *
352  * Set the duration of the @period. This can be called only on @period
353  * objects of kind %E_CAL_COMPONENT_PERIOD_DURATION.
354  *
355  * Since: 3.34
356  **/
357 void
e_cal_component_period_set_duration(ECalComponentPeriod * period,const ICalDuration * duration)358 e_cal_component_period_set_duration (ECalComponentPeriod *period,
359 				     const ICalDuration *duration)
360 {
361 	g_return_if_fail (period != NULL);
362 	g_return_if_fail (period->kind == E_CAL_COMPONENT_PERIOD_DURATION);
363 	g_return_if_fail (I_CAL_IS_DURATION ((ICalDuration *) duration));
364 
365 	if (period->duration != duration) {
366 		g_clear_object (&period->duration);
367 		period->duration = i_cal_duration_new_from_int (i_cal_duration_as_int ((ICalDuration *) duration));
368 	}
369 }
370