No issues found
Tool | Failure ID | Location | Function | Message | Data |
---|---|---|---|---|---|
clang-analyzer | no-output-found | e-meeting-attendee.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None | |
clang-analyzer | no-output-found | e-meeting-attendee.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None |
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) version 3.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with the program; if not, see <http://www.gnu.org/licenses/>
14 *
15 *
16 * Authors:
17 * JP Rosevear <jpr@ximian.com>
18 *
19 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
20 *
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdlib.h>
28 #include <gtk/gtk.h>
29 #include "e-meeting-utils.h"
30 #include "e-meeting-attendee.h"
31
32 #define E_MEETING_ATTENDEE_GET_PRIVATE(obj) \
33 (G_TYPE_INSTANCE_GET_PRIVATE \
34 ((obj), E_TYPE_MEETING_ATTENDEE, EMeetingAttendeePrivate))
35
36 struct _EMeetingAttendeePrivate {
37 gchar *address;
38 gchar *member;
39 gchar *fburi;
40
41 icalparameter_cutype cutype;
42 icalparameter_role role;
43
44 gboolean rsvp;
45
46 gchar *delto;
47 gchar *delfrom;
48
49 icalparameter_partstat status;
50
51 gchar *sentby;
52 gchar *cn;
53 gchar *language;
54
55 EMeetingAttendeeEditLevel edit_level;
56
57 gboolean has_calendar_info;
58
59 GArray *busy_periods;
60 gboolean busy_periods_sorted;
61
62 EMeetingTime busy_periods_start;
63 EMeetingTime busy_periods_end;
64 gboolean start_busy_range_set;
65 gboolean end_busy_range_set;
66
67 gint longest_period_in_days;
68 };
69
70 enum {
71 CHANGED,
72 LAST_SIGNAL
73 };
74 static guint signals[LAST_SIGNAL];
75
76 static void e_meeting_attendee_finalize (GObject *obj);
77
78 G_DEFINE_TYPE (EMeetingAttendee, e_meeting_attendee, G_TYPE_OBJECT)
79
80 static gchar *
81 string_test (gchar *string)
82 {
83 return string != NULL ? string : g_strdup ("");
84 }
85
86 static gboolean
87 string_is_set (gchar *string)
88 {
89 if (string != NULL && *string != '\0')
90 return TRUE;
91
92 return FALSE;
93 }
94
95 static void
96 busy_periods_array_clear_func (gpointer data)
97 {
98 EMeetingFreeBusyPeriod *period = (EMeetingFreeBusyPeriod *) data;
99
100 /* We're expected to clear the data segment,
101 * but not deallocate the segment itself. The
102 * XFB data possibly attached to the
103 * EMeetingFreeBusyPeriod requires special
104 * care when removing elements from the GArray
105 */
106 e_meeting_xfb_data_clear (&(period->xfb));
107 }
108
109 static void
110 notify_changed (EMeetingAttendee *ia)
111 {
112 g_signal_emit_by_name (ia, "changed");
113 }
114
115 static void
116 e_meeting_attendee_finalize (GObject *object)
117 {
118 EMeetingAttendeePrivate *priv;
119
120 priv = E_MEETING_ATTENDEE_GET_PRIVATE (object);
121
122 g_free (priv->address);
123 g_free (priv->member);
124 g_free (priv->fburi);
125
126 g_free (priv->delto);
127 g_free (priv->delfrom);
128
129 g_free (priv->sentby);
130 g_free (priv->cn);
131 g_free (priv->language);
132
133 g_array_free (priv->busy_periods, TRUE);
134
135 /* Chain up to parent's finalize() method. */
136 G_OBJECT_CLASS (e_meeting_attendee_parent_class)->finalize (object);
137 }
138
139 static void
140 e_meeting_attendee_class_init (EMeetingAttendeeClass *class)
141 {
142 GObjectClass *object_class;
143
144 g_type_class_add_private (class, sizeof (EMeetingAttendeePrivate));
145
146 object_class = G_OBJECT_CLASS (class);
147 object_class->finalize = e_meeting_attendee_finalize;
148
149 signals[CHANGED] = g_signal_new (
150 "changed",
151 G_TYPE_FROM_CLASS (class),
152 G_SIGNAL_RUN_FIRST,
153 G_STRUCT_OFFSET (EMeetingAttendeeClass, changed),
154 NULL, NULL,
155 g_cclosure_marshal_VOID__VOID,
156 G_TYPE_NONE, 0);
157 }
158
159 static void
160 e_meeting_attendee_init (EMeetingAttendee *ia)
161 {
162 ia->priv = E_MEETING_ATTENDEE_GET_PRIVATE (ia);
163
164 ia->priv->address = string_test (NULL);
165 ia->priv->member = string_test (NULL);
166
167 ia->priv->cutype = ICAL_CUTYPE_NONE;
168 ia->priv->role = ICAL_ROLE_NONE;
169
170 ia->priv->rsvp = FALSE;
171
172 ia->priv->delto = string_test (NULL);
173 ia->priv->delfrom = string_test (NULL);
174
175 ia->priv->status = ICAL_PARTSTAT_NONE;
176
177 ia->priv->sentby = string_test (NULL);
178 ia->priv->cn = string_test (NULL);
179 ia->priv->language = string_test (NULL);
180
181 ia->priv->edit_level = E_MEETING_ATTENDEE_EDIT_FULL;
182 ia->priv->has_calendar_info = FALSE;
183
184 ia->priv->busy_periods = g_array_new (FALSE, FALSE, sizeof (EMeetingFreeBusyPeriod));
185 g_array_set_clear_func (ia->priv->busy_periods, busy_periods_array_clear_func);
186 ia->priv->busy_periods_sorted = FALSE;
187
188 g_date_clear (&ia->priv->busy_periods_start.date, 1);
189 ia->priv->busy_periods_start.hour = 0;
190 ia->priv->busy_periods_start.minute = 0;
191
192 g_date_clear (&ia->priv->busy_periods_end.date, 1);
193 ia->priv->busy_periods_end.hour = 0;
194 ia->priv->busy_periods_end.minute = 0;
195
196 ia->priv->start_busy_range_set = FALSE;
197 ia->priv->end_busy_range_set = FALSE;
198
199 ia->priv->longest_period_in_days = 0;
200 }
201
202 GObject *
203 e_meeting_attendee_new (void)
204 {
205 return g_object_new (E_TYPE_MEETING_ATTENDEE, NULL);
206 }
207
208 GObject *
209 e_meeting_attendee_new_from_e_cal_component_attendee (ECalComponentAttendee *ca)
210 {
211 EMeetingAttendee *ia;
212
213 ia = E_MEETING_ATTENDEE (g_object_new (E_TYPE_MEETING_ATTENDEE, NULL));
214
215 e_meeting_attendee_set_address (ia, g_strdup (ca->value));
216 e_meeting_attendee_set_member (ia, g_strdup (ca->member));
217 e_meeting_attendee_set_cutype (ia, ca->cutype);
218 e_meeting_attendee_set_role (ia, ca->role);
219 e_meeting_attendee_set_status (ia, ca->status);
220 e_meeting_attendee_set_rsvp (ia, ca->rsvp);
221 e_meeting_attendee_set_delto (ia, g_strdup (ca->delto));
222 e_meeting_attendee_set_delfrom (ia, g_strdup (ca->delfrom));
223 e_meeting_attendee_set_sentby (ia, g_strdup (ca->sentby));
224 e_meeting_attendee_set_cn (ia, g_strdup (ca->cn));
225 e_meeting_attendee_set_language (ia, g_strdup (ca->language));
226
227 return G_OBJECT (ia);
228 }
229
230 ECalComponentAttendee *
231 e_meeting_attendee_as_e_cal_component_attendee (EMeetingAttendee *ia)
232 {
233 EMeetingAttendeePrivate *priv;
234 ECalComponentAttendee *ca;
235
236 priv = ia->priv;
237
238 ca = g_new0 (ECalComponentAttendee, 1);
239
240 ca->value = priv->address;
241 ca->member = string_is_set (priv->member) ? priv->member : NULL;
242 ca->cutype= priv->cutype;
243 ca->role = priv->role;
244 ca->status = priv->status;
245 ca->rsvp = priv->rsvp;
246 ca->delto = string_is_set (priv->delto) ? priv->delto : NULL;
247 ca->delfrom = string_is_set (priv->delfrom) ? priv->delfrom : NULL;
248 ca->sentby = string_is_set (priv->sentby) ? priv->sentby : NULL;
249 ca->cn = string_is_set (priv->cn) ? priv->cn : NULL;
250 ca->language = string_is_set (priv->language) ? priv->language : NULL;
251
252 return ca;
253 }
254
255 const gchar *
256 e_meeting_attendee_get_fburi (EMeetingAttendee *ia)
257 {
258 EMeetingAttendeePrivate *priv;
259
260 priv = ia->priv;
261
262 return priv->fburi;
263 }
264
265 void
266 e_meeting_attendee_set_fburi (EMeetingAttendee *ia,
267 gchar *fburi)
268 {
269 EMeetingAttendeePrivate *priv;
270
271 priv = ia->priv;
272
273 if (priv->fburi != NULL)
274 g_free (priv->fburi);
275
276 priv->fburi = string_test (fburi);
277
278 notify_changed (ia);
279 }
280
281 const gchar *
282 e_meeting_attendee_get_address (EMeetingAttendee *ia)
283 {
284 EMeetingAttendeePrivate *priv;
285
286 priv = ia->priv;
287
288 return priv->address;
289 }
290
291 void
292 e_meeting_attendee_set_address (EMeetingAttendee *ia,
293 gchar *address)
294 {
295 EMeetingAttendeePrivate *priv;
296
297 priv = ia->priv;
298
299 if (priv->address != NULL)
300 g_free (priv->address);
301
302 priv->address = string_test (address);
303
304 notify_changed (ia);
305 }
306
307 gboolean
308 e_meeting_attendee_is_set_address (EMeetingAttendee *ia)
309 {
310 EMeetingAttendeePrivate *priv;
311
312 priv = ia->priv;
313
314 return string_is_set (priv->address);
315 }
316
317 const gchar *
318 e_meeting_attendee_get_member (EMeetingAttendee *ia)
319 {
320 EMeetingAttendeePrivate *priv;
321
322 priv = ia->priv;
323
324 return priv->member;
325 }
326
327 void
328 e_meeting_attendee_set_member (EMeetingAttendee *ia,
329 gchar *member)
330 {
331 EMeetingAttendeePrivate *priv;
332
333 priv = ia->priv;
334
335 if (priv->member != NULL)
336 g_free (priv->member);
337
338 priv->member = string_test (member);
339
340 notify_changed (ia);
341 }
342
343 gboolean
344 e_meeting_attendee_is_set_member (EMeetingAttendee *ia)
345 {
346 EMeetingAttendeePrivate *priv;
347
348 priv = ia->priv;
349
350 return string_is_set (priv->member);
351 }
352
353 icalparameter_cutype
354 e_meeting_attendee_get_cutype (EMeetingAttendee *ia)
355 {
356 EMeetingAttendeePrivate *priv;
357
358 priv = ia->priv;
359
360 return priv->cutype;
361 }
362
363 void
364 e_meeting_attendee_set_cutype (EMeetingAttendee *ia,
365 icalparameter_cutype cutype)
366 {
367 EMeetingAttendeePrivate *priv;
368
369 priv = ia->priv;
370
371 priv->cutype = cutype;
372
373 notify_changed (ia);
374 }
375
376 icalparameter_role
377 e_meeting_attendee_get_role (EMeetingAttendee *ia)
378 {
379 EMeetingAttendeePrivate *priv;
380
381 priv = ia->priv;
382
383 return priv->role;
384 }
385
386 void
387 e_meeting_attendee_set_role (EMeetingAttendee *ia,
388 icalparameter_role role)
389 {
390 EMeetingAttendeePrivate *priv;
391
392 priv = ia->priv;
393
394 priv->role = role;
395
396 notify_changed (ia);
397 }
398
399 gboolean
400 e_meeting_attendee_get_rsvp (EMeetingAttendee *ia)
401 {
402 EMeetingAttendeePrivate *priv;
403
404 priv = ia->priv;
405
406 return priv->rsvp;
407 }
408
409 void
410 e_meeting_attendee_set_rsvp (EMeetingAttendee *ia,
411 gboolean rsvp)
412 {
413 EMeetingAttendeePrivate *priv;
414
415 priv = ia->priv;
416
417 priv->rsvp = rsvp;
418
419 notify_changed (ia);
420 }
421
422 const gchar *
423 e_meeting_attendee_get_delto (EMeetingAttendee *ia)
424 {
425 EMeetingAttendeePrivate *priv;
426
427 priv = ia->priv;
428
429 return priv->delto;
430 }
431
432 void
433 e_meeting_attendee_set_delto (EMeetingAttendee *ia,
434 gchar *delto)
435 {
436 EMeetingAttendeePrivate *priv;
437
438 priv = ia->priv;
439
440 if (priv->delto != NULL)
441 g_free (priv->delto);
442
443 priv->delto = string_test (delto);
444
445 notify_changed (ia);
446 }
447
448 gboolean
449 e_meeting_attendee_is_set_delto (EMeetingAttendee *ia)
450 {
451 EMeetingAttendeePrivate *priv;
452
453 priv = ia->priv;
454
455 return string_is_set (priv->delto);
456 }
457
458 const gchar *
459 e_meeting_attendee_get_delfrom (EMeetingAttendee *ia)
460 {
461 EMeetingAttendeePrivate *priv;
462
463 priv = ia->priv;
464
465 return priv->delfrom;
466 }
467
468 void
469 e_meeting_attendee_set_delfrom (EMeetingAttendee *ia,
470 gchar *delfrom)
471 {
472 EMeetingAttendeePrivate *priv;
473
474 priv = ia->priv;
475
476 if (priv->delfrom != NULL)
477 g_free (priv->delfrom);
478
479 priv->delfrom = string_test (delfrom);
480
481 notify_changed (ia);
482 }
483
484 gboolean
485 e_meeting_attendee_is_set_delfrom (EMeetingAttendee *ia)
486 {
487 EMeetingAttendeePrivate *priv;
488
489 priv = ia->priv;
490
491 return string_is_set (priv->delfrom);
492 }
493
494 icalparameter_partstat
495 e_meeting_attendee_get_status (EMeetingAttendee *ia)
496 {
497 EMeetingAttendeePrivate *priv;
498
499 priv = ia->priv;
500
501 return priv->status;
502 }
503
504 void
505 e_meeting_attendee_set_status (EMeetingAttendee *ia,
506 icalparameter_partstat status)
507 {
508 EMeetingAttendeePrivate *priv;
509
510 priv = ia->priv;
511
512 priv->status = status;
513
514 notify_changed (ia);
515 }
516
517 const gchar *
518 e_meeting_attendee_get_sentby (EMeetingAttendee *ia)
519 {
520 EMeetingAttendeePrivate *priv;
521
522 priv = ia->priv;
523
524 return priv->sentby;
525 }
526
527 void
528 e_meeting_attendee_set_sentby (EMeetingAttendee *ia,
529 gchar *sentby)
530 {
531 EMeetingAttendeePrivate *priv;
532
533 priv = ia->priv;
534
535 if (priv->sentby != NULL)
536 g_free (priv->sentby);
537
538 priv->sentby = string_test (sentby);
539
540 notify_changed (ia);
541 }
542
543 gboolean
544 e_meeting_attendee_is_set_sentby (EMeetingAttendee *ia)
545 {
546 EMeetingAttendeePrivate *priv;
547
548 priv = ia->priv;
549
550 return string_is_set (priv->sentby);
551 }
552
553 const gchar *
554 e_meeting_attendee_get_cn (EMeetingAttendee *ia)
555 {
556 EMeetingAttendeePrivate *priv;
557
558 priv = ia->priv;
559
560 return priv->cn;
561 }
562
563 void
564 e_meeting_attendee_set_cn (EMeetingAttendee *ia,
565 gchar *cn)
566 {
567 EMeetingAttendeePrivate *priv;
568
569 priv = ia->priv;
570
571 if (priv->cn != NULL)
572 g_free (priv->cn);
573
574 priv->cn = string_test (cn);
575
576 notify_changed (ia);
577 }
578
579 gboolean
580 e_meeting_attendee_is_set_cn (EMeetingAttendee *ia)
581 {
582 EMeetingAttendeePrivate *priv;
583
584 priv = ia->priv;
585
586 return string_is_set (priv->cn);
587 }
588
589 const gchar *
590 e_meeting_attendee_get_language (EMeetingAttendee *ia)
591 {
592 EMeetingAttendeePrivate *priv;
593
594 priv = ia->priv;
595
596 return priv->language;
597 }
598
599 void
600 e_meeting_attendee_set_language (EMeetingAttendee *ia,
601 gchar *language)
602 {
603 EMeetingAttendeePrivate *priv;
604
605 priv = ia->priv;
606
607 if (priv->language != NULL)
608 g_free (priv->language);
609
610 priv->language = string_test (language);
611
612 notify_changed (ia);
613 }
614
615 gboolean
616 e_meeting_attendee_is_set_language (EMeetingAttendee *ia)
617 {
618 EMeetingAttendeePrivate *priv;
619
620 priv = ia->priv;
621
622 return string_is_set (priv->language);
623 }
624
625 EMeetingAttendeeType
626 e_meeting_attendee_get_atype (EMeetingAttendee *ia)
627 {
628 EMeetingAttendeePrivate *priv;
629
630 priv = ia->priv;
631
632 if (priv->cutype == ICAL_CUTYPE_ROOM
633 || priv->cutype == ICAL_CUTYPE_RESOURCE)
634 return E_MEETING_ATTENDEE_RESOURCE;
635
636 if (priv->role == ICAL_ROLE_CHAIR
637 || priv->role == ICAL_ROLE_REQPARTICIPANT)
638 return E_MEETING_ATTENDEE_REQUIRED_PERSON;
639
640 return E_MEETING_ATTENDEE_OPTIONAL_PERSON;
641 }
642
643 EMeetingAttendeeEditLevel
644 e_meeting_attendee_get_edit_level (EMeetingAttendee *ia)
645 {
646 EMeetingAttendeePrivate *priv;
647
648 g_return_val_if_fail (ia != NULL, E_MEETING_ATTENDEE_EDIT_NONE);
649 g_return_val_if_fail (E_IS_MEETING_ATTENDEE (ia), E_MEETING_ATTENDEE_EDIT_NONE);
650
651 priv = ia->priv;
652
653 return priv->edit_level;
654 }
655
656 void
657 e_meeting_attendee_set_edit_level (EMeetingAttendee *ia,
658 EMeetingAttendeeEditLevel level)
659 {
660 EMeetingAttendeePrivate *priv;
661
662 g_return_if_fail (ia != NULL);
663 g_return_if_fail (E_IS_MEETING_ATTENDEE (ia));
664
665 priv = ia->priv;
666
667 priv->edit_level = level;
668 }
669
670 static gint
671 compare_times (EMeetingTime *time1,
672 EMeetingTime *time2)
673 {
674 gint day_comparison;
675
676 day_comparison = g_date_compare (
677 &time1->date,
678 &time2->date);
679 if (day_comparison != 0)
680 return day_comparison;
681
682 if (time1->hour < time2->hour)
683 return -1;
684 if (time1->hour > time2->hour)
685 return 1;
686
687 if (time1->minute < time2->minute)
688 return -1;
689 if (time1->minute > time2->minute)
690 return 1;
691
692 /* The start times are exactly the same. */
693 return 0;
694 }
695
696 static gint
697 compare_period_starts (gconstpointer arg1,
698 gconstpointer arg2)
699 {
700 EMeetingFreeBusyPeriod *period1, *period2;
701
702 period1 = (EMeetingFreeBusyPeriod *) arg1;
703 period2 = (EMeetingFreeBusyPeriod *) arg2;
704
705 return compare_times (&period1->start, &period2->start);
706 }
707
708 static void
709 ensure_periods_sorted (EMeetingAttendee *ia)
710 {
711 EMeetingAttendeePrivate *priv;
712
713 priv = ia->priv;
714
715 if (priv->busy_periods_sorted)
716 return;
717
718 qsort (
719 priv->busy_periods->data, priv->busy_periods->len,
720 sizeof (EMeetingFreeBusyPeriod),
721 compare_period_starts);
722
723 priv->busy_periods_sorted = TRUE;
724 }
725
726 gboolean
727 e_meeting_attendee_get_has_calendar_info (EMeetingAttendee *ia)
728 {
729 EMeetingAttendeePrivate *priv;
730
731 priv = ia->priv;
732
733 return priv->has_calendar_info;
734 }
735
736 void
737 e_meeting_attendee_set_has_calendar_info (EMeetingAttendee *ia,
738 gboolean has_calendar_info)
739 {
740 EMeetingAttendeePrivate *priv;
741
742 priv = ia->priv;
743
744 priv->has_calendar_info = has_calendar_info;
745 }
746
747 const GArray *
748 e_meeting_attendee_get_busy_periods (EMeetingAttendee *ia)
749 {
750 EMeetingAttendeePrivate *priv;
751
752 priv = ia->priv;
753
754 ensure_periods_sorted (ia);
755
756 return priv->busy_periods;
757 }
758
759 gint
760 e_meeting_attendee_find_first_busy_period (EMeetingAttendee *ia,
761 GDate *date)
762 {
763 EMeetingAttendeePrivate *priv;
764 EMeetingFreeBusyPeriod *period;
765 gint lower, upper, middle = 0, cmp = 0;
766 GDate tmp_date;
767
768 priv = ia->priv;
769
770 /* Make sure the busy periods have been sorted. */
771 ensure_periods_sorted (ia);
772
773 /* Calculate the first day which could have a busy period which
774 * continues onto our given date. */
775 tmp_date = *date;
776 g_date_subtract_days (&tmp_date, priv->longest_period_in_days);
777
778 /* We want the first busy period which starts on tmp_date. */
779 lower = 0;
780 upper = priv->busy_periods->len;
781
782 if (upper == 0)
783 return -1;
784
785 while (lower < upper) {
786 middle = (lower + upper) >> 1;
787
788 period = &g_array_index (priv->busy_periods,
789 EMeetingFreeBusyPeriod, middle);
790
791 cmp = g_date_compare (&tmp_date, &period->start.date);
792
793 if (cmp == 0)
794 break;
795 else if (cmp < 0)
796 upper = middle;
797 else
798 lower = middle + 1;
799 }
800
801 /* There may be several busy periods on the same day so we step
802 * backwards to the first one. */
803 if (cmp == 0) {
804 while (middle > 0) {
805 period = &g_array_index (priv->busy_periods,
806 EMeetingFreeBusyPeriod, middle - 1);
807 if (g_date_compare (&tmp_date, &period->start.date) != 0)
808 break;
809 middle--;
810 }
811 } else if (cmp > 0) {
812 /* This means we couldn't find a period on the given day, and
813 * the last one we looked at was before it, so if there are
814 * any more periods after this one we return it. */
815 middle++;
816 if (priv->busy_periods->len <= middle)
817 return -1;
818 }
819
820 return middle;
821 }
822
823 gboolean
824 e_meeting_attendee_add_busy_period (EMeetingAttendee *ia,
825 gint start_year,
826 gint start_month,
827 gint start_day,
828 gint start_hour,
829 gint start_minute,
830 gint end_year,
831 gint end_month,
832 gint end_day,
833 gint end_hour,
834 gint end_minute,
835 EMeetingFreeBusyType busy_type,
836 const gchar *summary,
837 const gchar *location)
838 {
839 EMeetingAttendeePrivate *priv;
840 EMeetingFreeBusyPeriod period;
841 gint period_in_days;
842
843 g_return_val_if_fail (ia != NULL, FALSE);
844 g_return_val_if_fail (E_IS_MEETING_ATTENDEE (ia), FALSE);
845 g_return_val_if_fail (busy_type < E_MEETING_FREE_BUSY_LAST, FALSE);
846 /* summary may be NULL (optional XFB data) */
847 /* location may be NULL (optional XFB data) */
848
849 priv = ia->priv;
850
851 /* Check the dates are valid. */
852 if (!g_date_valid_dmy (start_day, start_month, start_year))
853 return FALSE;
854 if (!g_date_valid_dmy (end_day, end_month, end_year))
855 return FALSE;
856 if (start_hour < 0 || start_hour > 23)
857 return FALSE;
858 if (end_hour < 0 || end_hour > 23)
859 return FALSE;
860 if (start_minute < 0 || start_minute > 59)
861 return FALSE;
862 if (end_minute < 0 || end_minute > 59)
863 return FALSE;
864
865 g_date_clear (&period.start.date, 1);
866 g_date_clear (&period.end.date, 1);
867 g_date_set_dmy (&period.start.date, start_day, start_month, start_year);
868 g_date_set_dmy (&period.end.date, end_day, end_month, end_year);
869 period.start.hour = start_hour;
870 period.start.minute = start_minute;
871 period.end.hour = end_hour;
872 period.end.minute = end_minute;
873 period.busy_type = busy_type;
874
875 /* Check that the start time is before or equal to the end time. */
876 if (compare_times (&period.start, &period.end) > 0)
877 return FALSE;
878
879 /* If the busy_type is FREE, then there is no need to render it in UI */
880 if (busy_type == E_MEETING_FREE_BUSY_FREE)
881 goto done;
882
883 /* If the busy range is not set elsewhere, track it as best we can */
884 if (!priv->start_busy_range_set) {
885 if (!g_date_valid (&priv->busy_periods_start.date)) {
886 priv->busy_periods_start.date = period.start.date;
887 priv->busy_periods_start.hour = period.start.hour;
888 priv->busy_periods_start.minute = period.start.minute;
889 } else {
890 gint compare;
891
892 compare = g_date_compare (
893 &period.start.date,
894 &priv->busy_periods_start.date);
895
896 switch (compare) {
897 case -1:
898 priv->busy_periods_start.date = period.start.date;
899 priv->busy_periods_start.hour = period.start.hour;
900 priv->busy_periods_start.minute = period.start.minute;
901 break;
902 case 0:
903 if (period.start.hour < priv->busy_periods_start.hour
904 || (period.start.hour == priv->busy_periods_start.hour
905 && period.start.minute < priv->busy_periods_start.minute)) {
906 priv->busy_periods_start.date = period.start.date;
907 priv->busy_periods_start.hour = period.start.hour;
908 priv->busy_periods_start.minute = period.start.minute;
909 break;
910 }
911 break;
912 }
913 }
914 }
915
916 if (!priv->end_busy_range_set) {
917 if (!g_date_valid (&priv->busy_periods_end.date)) {
918 priv->busy_periods_end.date = period.end.date;
919 priv->busy_periods_end.hour = period.end.hour;
920 priv->busy_periods_end.minute = period.end.minute;
921 } else {
922 gint compare;
923
924 compare = g_date_compare (
925 &period.end.date,
926 &priv->busy_periods_end.date);
927
928 switch (compare) {
929 case 0:
930 if (period.end.hour > priv->busy_periods_end.hour
931 || (period.end.hour == priv->busy_periods_end.hour
932 && period.end.minute > priv->busy_periods_end.minute)) {
933 priv->busy_periods_end.date = period.end.date;
934 priv->busy_periods_end.hour = period.end.hour;
935 priv->busy_periods_end.minute = period.end.minute;
936 break;
937 }
938 break;
939 case 1:
940 priv->busy_periods_end.date = period.end.date;
941 priv->busy_periods_end.hour = period.end.hour;
942 priv->busy_periods_end.minute = period.end.minute;
943 break;
944 }
945 }
946 }
947
948 /* Setting of extended free/busy (XFB) data, if we have any. */
949 e_meeting_xfb_data_init (&(period.xfb));
950 e_meeting_xfb_data_set (&(period.xfb), summary, location);
951
952 g_array_append_val (priv->busy_periods, period);
953
954 period_in_days =
955 g_date_get_julian (&period.end.date) -
956 g_date_get_julian (&period.start.date) + 1;
957 priv->longest_period_in_days =
958 MAX (priv->longest_period_in_days, period_in_days);
959
960 done:
961 priv->has_calendar_info = TRUE;
962 priv->busy_periods_sorted = FALSE;
963
964 return TRUE;
965 }
966
967 EMeetingTime
968 e_meeting_attendee_get_start_busy_range (EMeetingAttendee *ia)
969 {
970 EMeetingAttendeePrivate *priv;
971
972 priv = ia->priv;
973
974 return priv->busy_periods_start;
975 }
976
977 EMeetingTime
978 e_meeting_attendee_get_end_busy_range (EMeetingAttendee *ia)
979 {
980 EMeetingAttendeePrivate *priv;
981
982 priv = ia->priv;
983
984 return priv->busy_periods_end;
985 }
986
987 gboolean
988 e_meeting_attendee_set_start_busy_range (EMeetingAttendee *ia,
989 gint start_year,
990 gint start_month,
991 gint start_day,
992 gint start_hour,
993 gint start_minute)
994 {
995 EMeetingAttendeePrivate *priv;
996
997 g_return_val_if_fail (E_IS_MEETING_ATTENDEE (ia), FALSE);
998
999 priv = ia->priv;
1000
1001 /* Check the dates are valid. */
1002 if (!g_date_valid_dmy (start_day, start_month, start_year))
1003 return FALSE;
1004 if (start_hour < 0 || start_hour > 23)
1005 return FALSE;
1006 if (start_minute < 0 || start_minute > 59)
1007 return FALSE;
1008
1009 g_date_clear (&priv->busy_periods_start.date, 1);
1010 g_date_set_dmy (
1011 &priv->busy_periods_start.date,
1012 start_day, start_month, start_year);
1013 priv->busy_periods_start.hour = start_hour;
1014 priv->busy_periods_start.minute = start_minute;
1015
1016 priv->start_busy_range_set = TRUE;
1017
1018 return TRUE;
1019 }
1020
1021 gboolean
1022 e_meeting_attendee_set_end_busy_range (EMeetingAttendee *ia,
1023 gint end_year,
1024 gint end_month,
1025 gint end_day,
1026 gint end_hour,
1027 gint end_minute)
1028 {
1029 EMeetingAttendeePrivate *priv;
1030
1031 g_return_val_if_fail (E_IS_MEETING_ATTENDEE (ia), FALSE);
1032
1033 priv = ia->priv;
1034
1035 /* Check the dates are valid. */
1036 if (!g_date_valid_dmy (end_day, end_month, end_year))
1037 return FALSE;
1038 if (end_hour < 0 || end_hour > 23)
1039 return FALSE;
1040 if (end_minute < 0 || end_minute > 59)
1041 return FALSE;
1042
1043 g_date_clear (&priv->busy_periods_end.date, 1);
1044 g_date_set_dmy (
1045 &priv->busy_periods_end.date,
1046 end_day, end_month, end_year);
1047 priv->busy_periods_end.hour = end_hour;
1048 priv->busy_periods_end.minute = end_minute;
1049
1050 priv->end_busy_range_set = TRUE;
1051
1052 return TRUE;
1053 }
1054
1055 /* Clears all busy times for the given attendee. */
1056 void
1057 e_meeting_attendee_clear_busy_periods (EMeetingAttendee *ia)
1058 {
1059 EMeetingAttendeePrivate *priv;
1060
1061 g_return_if_fail (E_IS_MEETING_ATTENDEE (ia));
1062
1063 priv = ia->priv;
1064
1065 g_array_set_size (priv->busy_periods, 0);
1066 priv->busy_periods_sorted = TRUE;
1067
1068 g_date_clear (&priv->busy_periods_start.date, 1);
1069 priv->busy_periods_start.hour = 0;
1070 priv->busy_periods_start.minute = 0;
1071
1072 g_date_clear (&priv->busy_periods_end.date, 1);
1073 priv->busy_periods_end.hour = 0;
1074 priv->busy_periods_end.minute = 0;
1075
1076 priv->longest_period_in_days = 0;
1077 }