wmbiff: fixed possible null-pointer dereference.
[dockapps.git] / wmcalendar / Src / calendar.c
blobffadf0397c2a0cac6ca0f0ad3240b60ce5f65c0f
1 #include "calendar.h"
3 int get_datetype(int day){return datetype[day][0];}
5 /*------------------------------------------------------
6 * checkicalversion
7 -----------------------------------------------------*/
8 void checkicalversion()
10 GtkWidget* dialog;
11 GtkWidget* label;
12 char* msg = "\n\nWARNING:\nIt is highly recommended to upgrade to libical 0.24!\nOtherwise wmCalendar will not work stable!\n";
13 if(!strcmp(ICAL_VERSION, "0.23")){
14 printf("%s",msg);
15 dialog = gtk_dialog_new_with_buttons ("Warning",
16 NULL,
17 GTK_DIALOG_DESTROY_WITH_PARENT,
18 GTK_STOCK_OK,
19 GTK_RESPONSE_NONE,
20 NULL);
21 label = gtk_label_new (msg);
22 g_signal_connect_swapped (GTK_OBJECT (dialog),
23 "response",
24 G_CALLBACK (gtk_widget_destroy),
25 GTK_OBJECT (dialog));
26 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), label);
27 gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
28 GTK_SIGNAL_FUNC(gtk_main_quit ),
29 NULL);
30 gtk_widget_show_all (dialog);
31 gtk_main();
36 void move(GtkWidget *widget, GdkEventButton *event)
38 xr = event->x;
39 yr = event->y;
44 void move2(GtkWidget *widget, GdkEventMotion *event)
46 gtk_widget_set_uposition((GtkWidget*)gtk_widget_get_toplevel(widget),event->x_root - xr , event->y_root - yr);
51 void widget_kill (GtkWidget * widget)
53 gtk_widget_destroy ((GtkWidget*)gtk_widget_get_toplevel(widget));
54 gtk_main_quit ();
59 /*------------------------------------------------------
60 * calendar
61 -----------------------------------------------------*/
62 void calendar(){
63 int value;
64 char* line;
65 const char* text;
66 const char* transp="";
67 struct stat filestat;
68 icalproperty *prop, *reocc;
69 icalparser *parser;
70 icalcomponent *c, *d;
71 FILE *stream;
72 struct icaltimetype t1, t2;
73 if(get_debug())printf("check for new calendar data\n");
74 stream = fopen((const char*)get_icsfile(),"r");
75 if(stream == 0)
76 return;
77 fstat(fileno(stream), &filestat);
78 if(filestat.st_mtime == modtime){
79 fclose(stream);
80 return;
82 if(get_debug())printf("read calendar data\n");
83 deleteCalObjs();
84 modtime = filestat.st_mtime;
85 parser = icalparser_new();
86 /* Tell the parser what input routie it should use. */
87 icalparser_set_gen_data(parser, stream);
88 do{
89 line = icalparser_get_line(parser, read_stream);
90 c = icalparser_add_line(parser, line);
91 free(line);
92 if(c != 0){
93 for(d = icalcomponent_get_first_component(c, ICAL_ANY_COMPONENT);d != 0;
94 d = icalcomponent_get_next_component(c, ICAL_ANY_COMPONENT)){
96 /* get date */
97 t1 = icalcomponent_get_dtstart(d);
98 t2 = icalcomponent_get_dtend(d);
99 if(icaltime_is_null_time(t2)){
100 t2 = t1;
101 icaltime_adjust(&t2, 1,0,0,0);
104 /* get transparency */
105 prop = icalcomponent_get_first_property(d, ICAL_TRANSP_PROPERTY );
106 reocc = icalcomponent_get_first_property(d, ICAL_RRULE_PROPERTY);
107 if(prop)
108 transp = icalproperty_get_value_as_string(prop);
109 if(!strcmp(transp, "OPAQUE"))
110 value = 1;
111 else if(!strcmp(transp, "TRANSPARENT"))
112 value = 2;
113 else
114 value = 1 ;
117 /* get desciption */
118 prop = icalcomponent_get_first_property(d, ICAL_SUMMARY_PROPERTY);
119 if(prop) {
120 text = icalproperty_get_value_as_string(prop);
121 addCalObj(t1, t2, value, text, d);
122 if(get_debug())printf("read: %d.%d.%d - %d.%d.%d %s\n", t1.day, t1.month,
123 t1.year, t2.day, t2.month, t2.year, text);
125 icalcomponent_free(d);
127 icalcomponent_free(c);
129 } while(line != 0);
130 icalparser_free(parser);
131 fclose(stream);
136 /*------------------------------------------------------
137 * showDay
138 -----------------------------------------------------*/
139 void showDay(struct icaltimetype dt){
140 static GtkWidget *dayView;
141 static GtkWidget *table;
142 static GtkWidget *label1;
143 static GtkWidget *event_box;
144 static GtkWidget *event_box2;
145 char buf[28];
146 char buf2[28];
147 struct tm *timptr = NULL;
148 time_t tt = icaltime_as_timet(dt);
149 timptr = gmtime(&tt);
150 event_box = gtk_event_box_new ();
151 gtk_widget_show (event_box);
152 event_box2 = gtk_event_box_new ();
153 gtk_widget_show (event_box2);
155 /* create titlebartext */
156 strftime(buf, 26, "%A, %x", timptr);
157 sprintf(buf2, "<b>%s</b>",buf);
158 /* Create a new window with no boarder and day as titlebar*/
159 dayView = gtk_window_new(GTK_WINDOW_TOPLEVEL);
160 // xr =yr =0;
161 gtk_window_set_position(GTK_WINDOW (dayView),GTK_WIN_POS_MOUSE);
162 gtk_window_set_policy(GTK_WINDOW (dayView), FALSE, FALSE, FALSE);
163 gtk_window_set_decorated (GTK_WINDOW (dayView), FALSE);
164 gtk_window_set_title(GTK_WINDOW (dayView), buf);
165 /* create a table */
166 table = gtk_table_new(1, 4, FALSE);
167 gtk_table_set_row_spacings ((GtkTable*)table, 4);
168 gtk_table_set_col_spacings ((GtkTable*)table, 15);
169 gtk_table_set_col_spacing ((GtkTable*)table,2, 0);
171 gtk_table_attach_defaults (GTK_TABLE(table), event_box, 0, 3, 1, 2);
172 gtk_table_attach_defaults (GTK_TABLE(table), event_box2, 3, 4, 1, 2);
174 label1 = gtk_label_new (NULL);
175 gtk_label_set_markup ((GtkLabel*)label1, buf2);
176 gtk_container_add (GTK_CONTAINER (event_box), label1);
178 gtk_table_set_row_spacing ((GtkTable*)table,0, 1);
179 gtk_table_set_row_spacing ((GtkTable*)table,1, 1);
180 gtk_widget_show (label1);
181 label1 = gtk_label_new (" X ");
182 gtk_container_add (GTK_CONTAINER (event_box2), label1);
183 gtk_widget_show (label1);
185 /* fill table with events and draw window if there are any events */
186 if(dayevents(dt, table)){
187 gtk_widget_show (dayView);
189 gtk_widget_show (table);
190 gtk_container_add (GTK_CONTAINER (dayView), table);
191 gtk_signal_connect(GTK_OBJECT (event_box), "motion_notify_event",
192 GTK_SIGNAL_FUNC (move2), NULL);
193 gtk_signal_connect(GTK_OBJECT (event_box), "button_press_event",
194 GTK_SIGNAL_FUNC (move), NULL);
195 gtk_signal_connect(GTK_OBJECT (event_box2), "button_press_event",
196 (GtkSignalFunc) widget_kill, GTK_OBJECT(dayView));
198 gtk_widget_realize(dayView);
199 // gtk_window_set_position(GTK_WINDOW (dayView),GTK_WIN_POS_CENTER_ON_PARENT);
200 gtk_main ();
206 /*------------------------------------------------------
207 * dayevents
208 -----------------------------------------------------*/
209 int dayevents(struct icaltimetype dt, GtkWidget *table){
210 static GtkWidget *label1;
211 struct calobj* it;
212 struct icaltimetype t1, t2;
213 icalproperty *prop;
214 int j; /* tablerow */
215 char buftime1[30];
216 char buftime2[30];
217 char buf[1024];
218 struct tm *timptr = NULL;
219 time_t tt;
221 GtkWidget *separator;
222 j = 2;
223 it = calRoot;
224 while(it){
225 if(eventOnDay(dt, it)){
226 t1 = it->start;
227 t2 = it->end;
228 separator = gtk_hseparator_new ();
229 gtk_widget_show (separator);
230 gtk_table_attach_defaults (GTK_TABLE(table),separator, 0, 4, j, j+1);
231 j++;
232 if(daysEqual(t1, t2)){ /* single event */
233 /* create time entry */
234 tt = icaltime_as_timet(t1);
235 timptr = gmtime(&tt);
236 strftime(buftime1, 26, "%X", timptr);
237 tt = icaltime_as_timet(t2);
238 timptr = gmtime(&tt);
239 strftime(buftime2, 26, "%X", timptr);
240 sprintf(buf,"%s - %s",buftime1, buftime2);
241 label1 = gtk_label_new (NULL);
242 gtk_label_set_markup ((GtkLabel*)label1, buf);
243 gtk_table_attach_defaults (GTK_TABLE(table), label1, 1, 2, j, j+1);
244 gtk_widget_show (label1);
247 /* create description entry */
248 label1 = gtk_label_new (it->text);
249 gtk_table_attach_defaults (GTK_TABLE(table), label1, 2, 3, j, j+1);
250 gtk_widget_show (label1);
251 j++;
253 else {
254 /* multiday event or allday event*/
255 t2.day--; /* endtime always on the first day after the event ... */
256 if(t2.day == 0){
257 t2.month--;
258 if(t2.month == 0){
259 t2.month = 12;
260 t2.year--;
262 t2.day = icaltime_days_in_month(t2.month, t2.year);
264 if(t2.day < dt.day && t2.month == dt.month && t2.year == dt.year)
265 continue; /* event ended the day before ... */
266 if(daysEqual(t1,t2)){
267 /* allday event */
268 /* create description entry */
269 sprintf(buf, "<i>all day event</i>");
271 else{ /* multiday event */
272 /* create description with start and enddate */
273 tt = icaltime_as_timet(t1);
274 timptr = gmtime(&tt);
275 strftime(buftime1, 26, "%a, %x", timptr);
276 tt = icaltime_as_timet(t2);
277 timptr = gmtime(&tt);
278 strftime(buftime2, 26, "%a, %x", timptr);
279 sprintf(buf, "%s - %s", buftime1, buftime2);
281 label1 = gtk_label_new (NULL);
282 gtk_label_set_markup ((GtkLabel*)label1, buf);
284 gtk_table_attach_defaults (GTK_TABLE(table), label1, 1, 2, j, j+1);
285 gtk_widget_show (label1);
287 prop = icalcomponent_get_first_property(it->comp, ICAL_LOCATION_PROPERTY);
288 if(prop)
289 sprintf(buf, "%s\n%s", it->text, icalproperty_get_location(prop));
290 else
291 sprintf(buf, "%s", it->text);
292 label1 = gtk_label_new (buf);
293 gtk_label_set_justify(GTK_LABEL(label1),GTK_JUSTIFY_CENTER );
294 gtk_table_attach_defaults (GTK_TABLE(table), label1, 2, 3, j, j+1);
295 gtk_widget_show (label1);
296 j++;
299 it = it->next;
301 label1 = gtk_label_new (NULL);
302 gtk_table_attach_defaults (GTK_TABLE(table), label1, 2, 3, j+1, j+2);
303 gtk_table_set_row_spacing (GTK_TABLE(table),j, 0);
304 if(j==2) /* no entries for this day */
305 return FALSE;
306 return TRUE;
311 /*------------------------------------------------------
312 * deleteCalObjs
313 -----------------------------------------------------*/
314 void deleteCalObjs(){
315 int i;
316 struct calobj* help;
317 while(calRoot){
318 help = (struct calobj*) calRoot->next;
319 free(calRoot->text);
320 free(calRoot->comp);
321 free(calRoot);
322 calRoot = help;
324 for(i = 0; i < 32; i++)
325 datetype[i][1] = 0;
330 /*------------------------------------------------------
331 * addCalObj
332 -----------------------------------------------------*/
333 void addCalObj(struct icaltimetype start, struct icaltimetype end,
334 int type, const char *text, icalcomponent * d){
335 struct calobj *newobj;
336 icalcomponent *newcomp = malloc(sizeof(struct calobj));
337 char* buf = malloc (strlen(text) + 1);
338 newcomp = icalcomponent_new_clone(d);
339 strcpy(buf,text);
340 newobj = malloc(sizeof(struct calobj));
341 newobj->comp = newcomp;
342 newobj->start = start;
343 newobj->end = end;
344 newobj->type = type;
345 newobj->text = buf;
346 newobj->next = calRoot;
347 calRoot = newobj;
352 /*------------------------------------------------------
353 * getDayType
354 -----------------------------------------------------*/
355 int getDayType(struct icaltimetype dt){
356 int jd;
357 jd = civil_jdn(dt);
358 if(datetype[jd % 31][1] == jd)
359 return datetype[jd % 31][0];
361 return calcDayType(dt);
366 /*------------------------------------------------------
367 * isExluded
368 -----------------------------------------------------*/
369 int isExluded(icalcomponent *comp, struct icaltimetype dt){
370 icalproperty *prop;
371 prop = icalcomponent_get_first_property(comp, ICAL_EXDATE_PROPERTY);
372 while(prop){
373 if(daysEqual(icalproperty_get_exdate(prop), dt))
374 return 1;
375 prop = icalcomponent_get_next_property(comp, ICAL_EXDATE_PROPERTY);
377 return 0;
382 /*------------------------------------------------------
383 * eventOnDay
384 -----------------------------------------------------*/
385 int eventOnDay(struct icaltimetype dt, struct calobj* it)
387 icalrecur_iterator* ritr;
388 icalproperty *rrule;
389 struct icaltimetype next;
390 if((daysEarlierEqual(dt, it->start) && daysLater(dt, it->end))
391 || (daysEqual(dt, it->start) && daysEqual(dt, it->end)))
392 return 1;
393 rrule = icalcomponent_get_first_property((icalcomponent*)it->comp, ICAL_RRULE_PROPERTY);
395 if(rrule){
396 if(daysEarlierEqual(dt, it->start)){
397 ritr = icalrecur_iterator_new( icalproperty_get_rrule(rrule), it->start);
398 if(ritr)
399 next = icalrecur_iterator_next(ritr);
400 while(daysEarlierEqual(dt, next) && !icaltime_is_null_time(next)){
401 if(daysEqual(dt, next) && !isExluded((icalcomponent*)it->comp, dt))
403 free(ritr);
404 return 1;
406 next = icalrecur_iterator_next(ritr);
408 free(ritr);
411 return 0;
416 /*------------------------------------------------------
417 * calcDayType
418 -----------------------------------------------------*/
419 int calcDayType(struct icaltimetype dt){
420 int jd;
421 struct calobj* it;
422 jd = civil_jdn(dt);
423 datetype[jd % 31][1] = jd;
424 datetype[jd % 31][0] = 0;
425 it = calRoot;
426 while(it){
427 if(eventOnDay(dt, it))
428 if(datetype[jd % 31][0] != 1)
429 datetype[jd % 31][0] = it->type;
430 it = it->next;
432 return datetype[jd % 31][0];