summaryrefslogtreecommitdiff
path: root/examples/access_components.c
blob: 597e5e7da3e54f38ba281b693c661d480075a49c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
/* Access_component.c

  SPDX-FileCopyrightText: <eric@civicknowledge.com>
  SPDX-License-Identifier: LGPL-2.1-only OR MPL-2.0
*/

#include <libical/ical.h>

void do_something(icalcomponent *c);

/* Creating iCal Components

   There are two ways to create new component in libical. You can
   build the component from primitive parts, or you can create it
   from a string.

   There are two variations of the API for building the component from
   primitive parts. In the first variation, you add each parameter and
   value to a property, and then add each property to a
   component. This results in a long series of function calls. This
   style is show in create_new_component()

   The second variation uses vargs lists to nest many primitive part
   constructors, resulting in a compact, neatly formatted way to create
   components. This style is shown in create_new_component_with_va_args()

*/

icalcomponent* create_new_component(void)
{
    /* variable definitions */
    icalcomponent* calendar;
    icalcomponent* event;
    struct icaltimetype atime = icaltime_from_timet_with_zone(time(0), 0, icaltimezone_get_utc_timezone());
    struct icalperiodtype rtime;
    icalproperty* property;

    /* Define a time type that will use as data later. */
    rtime.start = icaltime_from_timet_with_zone(time(0), 0, icaltimezone_get_utc_timezone());
    rtime.end = icaltime_from_timet_with_zone(time(0), 0, icaltimezone_get_utc_timezone());
    rtime.end.hour++;

    /* Create calendar and add properties */

    calendar = icalcomponent_new(ICAL_VCALENDAR_COMPONENT);

    /* Nearly every libical function call has the same general
       form. The first part of the name defines the 'class' for the
       function, and the first argument will be a pointer to a struct
       of that class. So, icalcomponent_ functions will all take
       icalcomponent* as their first argument. */

    /* The next call creates a new property and immediately adds it to the
       'calendar' component. */

    icalcomponent_add_property(
        calendar,
        icalproperty_new_version("2.0")
        );

    /* Here is the short version of the memory rules:

         If the routine name has "new" in it:
             Caller owns the returned memory.
             If you pass in a string, the routine takes the memory.

         If the routine name has "add" in it:
             The routine takes control of the component, property,
             parameter or value memory.

         If the routine returns a string ( "get" and "as_ical_string" )
             The library owns the returned memory.

          There are more rules, so refer to the documentation for more
          details.

    */

    icalcomponent_add_property(
        calendar,
        icalproperty_new_prodid("-//RDU Software//NONSGML HandCal//EN")
        );

    /* Add an event */

    event = icalcomponent_new(ICAL_VEVENT_COMPONENT);

    icalcomponent_add_property(
        event,
        icalproperty_new_dtstamp(atime)
        );

    /* In the previous call, atime is a struct, and it is passed in by value.
       This is how all compound types of values are handled. */

    icalcomponent_add_property(
        event,
        icalproperty_new_uid("guid-1.host1.com")
        );

    /* add a property that has parameters */
    property = icalproperty_new_organizer("mailto:mrbig@host.com");

    icalproperty_add_parameter(
        property,
        icalparameter_new_role(ICAL_ROLE_CHAIR)
        );

    icalcomponent_add_property(event,property);

    /* In this style of component creation, you need to use an extra
       call to add parameters to properties, but the form of this
       operation is the same as adding a property to a component */

    /* add another property that has parameters */
    property = icalproperty_new_attendee("mailto:employee-A@host.com");

    icalproperty_add_parameter(
        property,
        icalparameter_new_role(ICAL_ROLE_REQPARTICIPANT)
        );

    icalproperty_add_parameter(
        property,
        icalparameter_new_rsvp(1)
        );

    icalproperty_add_parameter(
        property,
        icalparameter_new_cutype(ICAL_CUTYPE_GROUP)
        );

    icalcomponent_add_property(event,property);

    /* more properties */

    icalcomponent_add_property(
        event,
        icalproperty_new_description("Project XYZ Review Meeting")
        );

    icalcomponent_add_property(
        event,
        icalproperty_new_categories("MEETING")
        );

    icalcomponent_add_property(
        event,
        icalproperty_new_class(ICAL_CLASS_PUBLIC)
        );

    icalcomponent_add_property(
        event,
        icalproperty_new_created(atime)
        );

    icalcomponent_add_property(
        event,
        icalproperty_new_summary("XYZ Project Review")
        );

    property = icalproperty_new_dtstart(atime);

    icalproperty_add_parameter(
        property,
        icalparameter_new_tzid("US-Eastern")
        );

    icalcomponent_add_property(event,property);

    property = icalproperty_new_dtend(atime);

    icalproperty_add_parameter(
        property,
        icalparameter_new_tzid("US-Eastern")
        );

    icalcomponent_add_property(event,property);

    icalcomponent_add_property(
        event,
        icalproperty_new_location("1CP Conference Room 4350")
        );

    icalcomponent_add_component(calendar,event);

    return calendar;
}

/* Now, create the same component as in the previous routine, but use
the constructor style. */

icalcomponent* create_new_component_with_va_args(void)
{
    /* This is a similar set up to the last routine */
    icalcomponent* calendar;
    struct icaltimetype atime = icaltime_from_timet_with_zone(time(0), 0, icaltimezone_get_utc_timezone());
    struct icalperiodtype rtime;

    rtime.start = icaltime_from_timet_with_zone(time(0), 0, icaltimezone_get_utc_timezone());
    rtime.end = icaltime_from_timet_with_zone(time(0), 0, icaltimezone_get_utc_timezone());
    rtime.end.hour++;

    /* Some of these routines are the same as those in the previous
       routine, but we've also added several 'vanew' routines. These
       'vanew' routines take a list of properties, parameters or
       values and add each of them to the parent property or
       component. */

    calendar =
        icalcomponent_vanew(
            ICAL_VCALENDAR_COMPONENT,
            icalproperty_new_version("2.0"),
            icalproperty_new_prodid("-//RDU Software//NONSGML HandCal//EN"),
            icalcomponent_vanew(
                ICAL_VEVENT_COMPONENT,
                icalproperty_new_dtstamp(atime),
                icalproperty_new_uid("guid-1.host1.com"),
                icalproperty_vanew_organizer(
                    "mailto:mrbig@host.com",
                    icalparameter_new_role(ICAL_ROLE_CHAIR),
                    NULL
                    ),
                icalproperty_vanew_attendee(
                    "mailto:employee-A@host.com",
                    icalparameter_new_role(ICAL_ROLE_REQPARTICIPANT),
                    icalparameter_new_rsvp(1),
                    icalparameter_new_cutype(ICAL_CUTYPE_GROUP),
                    NULL
                    ),
                icalproperty_new_description("Project XYZ Review Meeting"),

                icalproperty_new_categories("MEETING"),
                icalproperty_new_class(ICAL_CLASS_PUBLIC),
                icalproperty_new_created(atime),
                icalproperty_new_summary("XYZ Project Review"),
                icalproperty_vanew_dtstart(
                    atime,
                    icalparameter_new_tzid("US-Eastern"),
                    NULL
                    ),
                icalproperty_vanew_dtend(
                    atime,
                    icalparameter_new_tzid("US-Eastern"),
                    NULL
                    ),
                icalproperty_new_location("1CP Conference Room 4350"),
                0
                ),
            0
            );

    /* Note that properties with no parameters can use the regular
       'new' constructor, while those with parameters use the 'vanew'
       constructor. And, be sure that the last argument in the 'vanew'
       call is a zero. Without, your program will probably crash. */

    return calendar;
}

void find_sub_components(icalcomponent* comp)
{
    icalcomponent *c;

    /* The second parameter to icalcomponent_get_first_component
       indicates the type of component to search for. This will
       iterate through all sub-components */
    for(c = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT);
        c != 0;
        c = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)){

        do_something(c);
    }

    /* This will iterate only though VEVENT sub-components */

    for(c = icalcomponent_get_first_component(comp,ICAL_VEVENT_COMPONENT);
        c != 0;
        c = icalcomponent_get_next_component(comp,ICAL_VEVENT_COMPONENT)){

        do_something(c);
    }
}

/* Ical components only have one internal iterator, so removing the
   object that the iterator points to can cause problems. Here is the
   right way to remove components */

void remove_vevent_sub_components(icalcomponent* comp){

    icalcomponent *c, *next;

    for( c = icalcomponent_get_first_component(comp,ICAL_VEVENT_COMPONENT);
         c != 0;
         c = next)
    {
        next  = icalcomponent_get_next_component(comp,ICAL_VEVENT_COMPONENT);

        icalcomponent_remove_component(comp,c);

        do_something(c);
    }
}