1 #include "calendar.h"
2 
get_datetype(int day)3 int  get_datetype(int day){return datetype[day][0];}
4 
5 /*------------------------------------------------------
6  *   checkicalversion
7  -----------------------------------------------------*/
checkicalversion()8 void checkicalversion()
9 {
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(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();
32     }
33 }
34 
35 
move(GtkWidget * widget,GdkEventButton * event)36 void move(GtkWidget *widget, GdkEventButton *event)
37 {
38     xr = event->x;
39     yr = event->y;
40 }
41 
42 
43 
move2(GtkWidget * widget,GdkEventMotion * event)44 void move2(GtkWidget *widget, GdkEventMotion *event)
45 {
46     gtk_widget_set_uposition((GtkWidget*)gtk_widget_get_toplevel(widget),event->x_root - xr , event->y_root - yr);
47 }
48 
49 
50 
wmkill(GtkWidget * widget)51 void wmkill (GtkWidget * widget)
52 {
53     gtk_widget_destroy ((GtkWidget*)gtk_widget_get_toplevel(widget));
54     gtk_main_quit ();
55 }
56 
57 
58 
59 /*------------------------------------------------------
60  *   calendar
61  -----------------------------------------------------*/
calendar()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;
81     }
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)){
95 
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);
102 		}
103 
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 ;
115 
116 
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);
124 	       }
125 		icalcomponent_free(d);
126 	    }
127 	    icalcomponent_free(c);
128 	}
129     } while(line != 0);
130     icalparser_free(parser);
131     fclose(stream);
132 }
133 
134 
135 
136 /*------------------------------------------------------
137  *   showDay
138  -----------------------------------------------------*/
showDay(struct icaltimetype dt)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);
154 
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);
170 
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);
173 
174     label1 = gtk_label_new (NULL);
175     gtk_label_set_markup ((GtkLabel*)label1, buf2);
176     gtk_container_add (GTK_CONTAINER (event_box), label1);
177 
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);
184 
185     /* fill table with events and draw window if there are any events */
186     if(dayevents(dt, table)){
187 	gtk_widget_show (dayView);
188 
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) wmkill, GTK_OBJECT(dayView));
197 
198 	gtk_widget_realize(dayView);
199 	//	gtk_window_set_position(GTK_WINDOW (dayView),GTK_WIN_POS_CENTER_ON_PARENT);
200 	gtk_main ();
201     }
202 }
203 
204 
205 
206 /*------------------------------------------------------
207  *   dayevents
208  -----------------------------------------------------*/
dayevents(struct icaltimetype dt,GtkWidget * table)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;
220 
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);
245 
246 
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++;
252 	    }
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--;
261 		    }
262 		    t2.day = icaltime_days_in_month(t2.month, t2.year);
263 		}
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>");
270 		}
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);
280 		}
281 		label1 = gtk_label_new (NULL);
282 		gtk_label_set_markup ((GtkLabel*)label1, buf);
283 
284 		gtk_table_attach_defaults (GTK_TABLE(table), label1, 1, 2, j, j+1);
285 		gtk_widget_show (label1);
286 
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++;
297 	    }
298 	}
299 	it = it->next;
300     }
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;
307 }
308 
309 
310 
311 /*------------------------------------------------------
312  *   deleteCalObjs
313  -----------------------------------------------------*/
deleteCalObjs()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;
323     }
324     for(i = 0; i < 32; i++)
325 	datetype[i][1] = 0;
326 }
327 
328 
329 
330 /*------------------------------------------------------
331  *  addCalObj
332  -----------------------------------------------------*/
addCalObj(struct icaltimetype start,struct icaltimetype end,int type,const char * text,icalcomponent * d)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;
348 }
349 
350 
351 
352 /*------------------------------------------------------
353  *   getDayType
354  -----------------------------------------------------*/
getDayType(struct icaltimetype dt)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];
360 
361     return calcDayType(dt);
362 }
363 
364 
365 
366 /*------------------------------------------------------
367  *   isExluded
368  -----------------------------------------------------*/
isExluded(icalcomponent * comp,struct icaltimetype dt)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);
376     }
377     return 0;
378 }
379 
380 
381 
382 /*------------------------------------------------------
383  *   eventOnDay
384  -----------------------------------------------------*/
eventOnDay(struct icaltimetype dt,struct calobj * it)385 int eventOnDay(struct icaltimetype dt, struct calobj* it)
386 {
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);
394 
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))
402 		    {
403 			free(ritr);
404 			return 1;
405 		    }
406 		next = icalrecur_iterator_next(ritr);
407 	    }
408 	    free(ritr);
409 	}
410     }
411     return 0;
412 }
413 
414 
415 
416 /*------------------------------------------------------
417  *   calcDayType
418  -----------------------------------------------------*/
calcDayType(struct icaltimetype dt)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;
431     }
432     return datetype[jd % 31][0];
433 }
434