1 
2 /*
3  * Osmo - a handy personal organizer
4  *
5  * Copyright (C) 2007 Tomasz Maka <pasp@users.sourceforge.net>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21 
22 #include "calendar_fullyear.h"
23 #include "i18n.h"
24 #include "utils.h"
25 #include "utils_gui.h"
26 #include "utils_date.h"
27 #include "options_prefs.h"
28 #include "calendar.h"
29 #include "calendar_notes.h"
30 #include "calendar_ical.h"
31 #include "calendar_widget.h"
32 #include "calendar_utils.h"
33 #include "stock_icons.h"
34 
35 /*------------------------------------------------------------------------*/
36 
37 void
fullyear_window_close_cb(GtkWidget * widget,GdkEvent * event,gpointer user_data)38 fullyear_window_close_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data)
39 {
40 	GUI *appGUI = (GUI *) user_data;
41 
42 	appGUI->cal->last_selected_year = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (appGUI->cal->fy_spinbutton));
43 
44 	if (config.fullscreen == FALSE) {
45 		gtk_window_get_size (GTK_WINDOW (appGUI->cal->fullyear_window),
46 							 &config.fy_window_size_x, &config.fy_window_size_y);
47 	}
48 	gtk_widget_destroy (appGUI->cal->fullyear_window);
49 }
50 
51 /*------------------------------------------------------------------------------*/
52 
53 void
button_fullyear_window_close_cb(GtkButton * button,gpointer user_data)54 button_fullyear_window_close_cb (GtkButton *button, gpointer user_data)
55 {
56 	fullyear_window_close_cb (GTK_WIDGET (button), NULL, user_data);
57 }
58 
59 /*------------------------------------------------------------------------------*/
60 
61 void
select_date_day_cb(GtkWidget * widget,gpointer user_data)62 select_date_day_cb (GtkWidget *widget, gpointer user_data)
63 {
64 GDate *date;
65 
66 	MESSAGE *msg = (MESSAGE *) user_data;
67 	date = g_date_new_julian ((size_t) msg->data);
68 	g_return_if_fail (date != NULL);
69 
70 	cal_jump_to_date (date, msg->appGUI);
71 	g_date_free (date);
72 
73 	fullyear_window_close_cb (GTK_WIDGET (widget), NULL, msg->appGUI);
74 }
75 
76 /*------------------------------------------------------------------------*/
77 
78 void
display_calendar(guint year,GUI * appGUI)79 display_calendar (guint year, GUI *appGUI)
80 {
81 static MESSAGE selected_date[MAX_MONTHS * FULL_YEAR_COLS];
82 
83 GDate *cdate;
84 gint calendar_table[MAX_MONTHS * FULL_YEAR_COLS];
85 guint current_day, current_month, current_year;
86 guint month;
87 gint i, idx, day, first_day, days;
88 gchar tmpbuf[BUFFER_SIZE], tmpbuf2[BUFFER_SIZE];
89 
90 	for (i = 0; i < MAX_MONTHS * FULL_YEAR_COLS; i++) {
91 		calendar_table[i] = -1;
92 	}
93 
94 	cdate = g_date_new ();
95 	g_return_if_fail (cdate != NULL);
96 
97 	for (month = G_DATE_JANUARY; month <= G_DATE_DECEMBER; month++) {
98 		g_date_set_dmy (cdate, 1, month, year);
99 		first_day = g_date_get_weekday (cdate);
100 		days = g_date_get_days_in_month (month, year);
101 
102 		for (i = 1; i <= days; i++) {
103 			calendar_table[(month - 1) * FULL_YEAR_COLS + first_day + i - 2] = i;
104 		}
105 	}
106 
107 	g_date_set_time_t (cdate, time (NULL));
108 	current_day = g_date_get_day (cdate);
109 	current_month = g_date_get_month (cdate);
110 	current_year = g_date_get_year (cdate);
111 
112 	for (month = G_DATE_JANUARY; month <= G_DATE_DECEMBER; month++) {
113 
114 		for (i = 0; i < FULL_YEAR_COLS; i++) {
115 
116 			idx = (month - 1) * FULL_YEAR_COLS + i;
117 			g_signal_handlers_disconnect_by_func (G_OBJECT (appGUI->cal->calendar_buttons[idx]),
118 			                                      G_CALLBACK (select_date_day_cb), &selected_date[idx]);
119 			day = calendar_table[idx];
120 
121 			if (day > 0) {
122 
123 				if (day == current_day && month == current_month && year == current_year) {
124 					g_snprintf (tmpbuf2, BUFFER_SIZE, "<b><u>%2d</u></b>", day);
125 				} else {
126 					g_snprintf (tmpbuf2, BUFFER_SIZE, "%2d", day);
127 				}
128 
129 				if (i % 7 + 1 == G_DATE_SATURDAY || i % 7 + 1 == G_DATE_SUNDAY) {
130 					g_snprintf (tmpbuf, BUFFER_SIZE, "<span foreground='firebrick'>%s</span>", tmpbuf2);
131 				} else if (month % 2 == 0) {
132 					g_snprintf (tmpbuf, BUFFER_SIZE, "<span foreground='medium blue'>%s</span>", tmpbuf2);
133 				} else {
134 					g_strlcpy (tmpbuf, tmpbuf2, BUFFER_SIZE);
135 				}
136 
137 				g_date_set_dmy (cdate, (GDateDay) day, month,
138 				                (GDateYear) gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (appGUI->cal->fy_spinbutton)));
139 				selected_date[idx].data = (gpointer) ((size_t)g_date_get_julian (cdate));
140 				selected_date[idx].appGUI = appGUI;
141 				g_signal_connect (G_OBJECT (appGUI->cal->calendar_buttons[idx]), "clicked",
142 				                  G_CALLBACK (select_date_day_cb), &selected_date[idx]);
143 				GList *btnCh = gtk_container_get_children(GTK_CONTAINER (appGUI->cal->calendar_buttons[idx]));
144 				gtk_label_set_markup (GTK_LABEL (btnCh->data), tmpbuf);
145 				gtk_widget_show (appGUI->cal->calendar_buttons[idx]);
146 
147 			} else {
148 
149 				gtk_button_set_label (GTK_BUTTON (appGUI->cal->calendar_buttons[idx]), "");
150 				gtk_widget_hide (GTK_WIDGET (appGUI->cal->calendar_buttons[idx]));
151 
152 			}
153 		}
154 	}
155 
156 	g_date_free (cdate);
157 }
158 
159 /*------------------------------------------------------------------------*/
160 
161 void
change_to_current_year_cb(GtkWidget * widget,gpointer user_data)162 change_to_current_year_cb (GtkWidget *widget, gpointer user_data)
163 {
164 	GUI *appGUI = (GUI *) user_data;
165 	gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->cal->fy_spinbutton), utl_date_get_current_year ());
166 }
167 
168 /*------------------------------------------------------------------------*/
169 
170 void
change_to_next_year_cb(GtkWidget * widget,gpointer user_data)171 change_to_next_year_cb (GtkWidget *widget, gpointer user_data)
172 {
173 guint year;
174 
175 	GUI *appGUI = (GUI *) user_data;
176 
177 	year = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (appGUI->cal->fy_spinbutton));
178 	year++;
179 	gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->cal->fy_spinbutton), year);
180 }
181 
182 /*------------------------------------------------------------------------*/
183 
184 void
change_to_previous_year_cb(GtkWidget * widget,gpointer user_data)185 change_to_previous_year_cb (GtkWidget *widget, gpointer user_data)
186 {
187 guint year;
188 
189 	GUI *appGUI = (GUI *) user_data;
190 
191 	year = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (appGUI->cal->fy_spinbutton));
192 	if (year > JULIAN_GREGORIAN_YEAR) {
193 		year--;
194 	}
195 	gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->cal->fy_spinbutton), year);
196 }
197 
198 /*------------------------------------------------------------------------*/
199 
200 void
change_year_spin_button_cb(GtkSpinButton * spinbutton,gpointer user_data)201 change_year_spin_button_cb (GtkSpinButton *spinbutton, gpointer user_data)
202 {
203 guint i, month, year;
204 
205 	GUI *appGUI = (GUI *) user_data;
206 
207 	year = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinbutton));
208 
209 	if (year == utl_date_get_current_year ()) {
210 		gtk_widget_set_sensitive (appGUI->cal->cyear_button, FALSE);
211 	} else {
212 		gtk_widget_set_sensitive (appGUI->cal->cyear_button, TRUE);
213 	}
214 
215 	display_calendar (year, appGUI);
216 
217 	for (month = G_DATE_JANUARY; month <= G_DATE_DECEMBER; month++) {
218 		i = month - 1;
219 		gui_calendar_select_month (GUI_CALENDAR (appGUI->cal->fy_calendars[i]), month - 1, year);
220 		mark_events (appGUI->cal->fy_calendars[i], month - 1, year, appGUI);
221 	}
222 }
223 
224 /*------------------------------------------------------------------------*/
225 
226 void
year_info_cb(GtkWidget * widget,gpointer user_data)227 year_info_cb (GtkWidget *widget, gpointer user_data)
228 {
229 guint month, year, w_days;
230 gchar tmpbuf[BUFFER_SIZE];
231 
232 	GUI *appGUI = (GUI *) user_data;
233 
234 	year = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (appGUI->cal->fy_spinbutton));
235 	w_days = 0;
236 
237 	for (month = G_DATE_JANUARY; month <= G_DATE_DECEMBER; month++) {
238 		w_days += utl_get_weekend_days_in_month_my (month, year);
239 	}
240 
241 	g_snprintf (tmpbuf, BUFFER_SIZE, "<b>%s</b>: %d\n<b>%s</b>: %s\n\n<b>%s</b>: %s\n\n<b>%s</b>: %d\n<b>%s</b>: %d\n<b>%s</b>: %d (%.1f%%)",
242 	            _("Year"), year, _("Leap year"), g_date_is_leap_year (year) ? _("Yes"):_("No"),
243 	            _("Chinese year animal"), get_chinese_year_name (year),
244 	            _("Number of days"), utl_get_days_per_year (year),
245 	            _("Number of weeks"), utl_weeks_in_year (year),
246 	            _("Number of weekend days"), w_days, (double) w_days / utl_get_days_per_year (year) * 100.0);
247 
248 	utl_gui_create_dialog (GTK_MESSAGE_INFO, tmpbuf, GTK_WINDOW (appGUI->cal->fullyear_window));
249 }
250 
251 /*------------------------------------------------------------------------------*/
252 
253 gint
fullyear_key_press_cb(GtkWidget * widget,GdkEventKey * event,gpointer user_data)254 fullyear_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
255 {
256 	GUI *appGUI = (GUI *) user_data;
257 
258 	switch (event->keyval) {
259 		case GDK_KEY_Escape:
260 			gtk_widget_destroy (appGUI->cal->fullyear_window);
261 			return TRUE;
262 		case GDK_KEY_F1:
263 			g_signal_emit_by_name (G_OBJECT(appGUI->cal->fy_alternative_view_checkbutton), "clicked");
264 			return TRUE;
265 		case GDK_KEY_F2:
266 			year_info_cb (NULL, appGUI);
267 			return TRUE;
268 		case GDK_KEY_F3:
269 			change_to_current_year_cb (NULL, appGUI);
270 			return TRUE;
271 	}
272 
273 	return FALSE;
274 }
275 
276 /*------------------------------------------------------------------------------*/
277 
278 void
alternative_view_cb(GtkToggleButton * togglebutton,gpointer user_data)279 alternative_view_cb (GtkToggleButton *togglebutton, gpointer user_data)
280 {
281 	GUI *appGUI = (GUI *) user_data;
282 
283 	config.fy_alternative_view = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (togglebutton));
284 
285 	if (config.fy_alternative_view == TRUE) {
286 		gtk_widget_hide (appGUI->cal->fycal_table_1);
287 		gtk_widget_show (appGUI->cal->fycal_table_2);
288 	} else {
289 		gtk_widget_hide (appGUI->cal->fycal_table_2);
290 		gtk_widget_show (appGUI->cal->fycal_table_1);
291 	}
292 }
293 
294 /*------------------------------------------------------------------------------*/
295 
296 void
calendar_dbclick_cb(GtkWidget * widget,gpointer user_data)297 calendar_dbclick_cb (GtkWidget *widget, gpointer user_data)
298 {
299 	GUI *appGUI = (GUI *) user_data;
300 	GDate *date = g_date_new ();
301 
302 	gui_calendar_get_gdate (GUI_CALENDAR (widget), date);
303 	cal_jump_to_date (date, appGUI);
304 	g_date_free (date);
305 
306 	fullyear_window_close_cb (GTK_WIDGET (widget), NULL, appGUI);
307 }
308 
309 /*------------------------------------------------------------------------------*/
310 
311 void
calendar_create_fullyear_window(GUI * appGUI)312 calendar_create_fullyear_window (GUI *appGUI)
313 {
314 GtkWidget   *vbox1, *vbox2;
315 GtkWidget   *hseparator;
316 GtkWidget   *hbuttonbox;
317 GtkWidget   *close_button;
318 GtkWidget   *hbox1;
319 GtkWidget   *prev_button;
320 GtkWidget   *info_button;
321 GtkAdjustment   *fy_spinbutton_adj;
322 GtkWidget   *next_button;
323 GtkWidget   *fycal_scrolledwindow;
324 GtkWidget   *fycal_viewport;
325 GtkWidget   *vseparator;
326 GtkWidget   *label;
327 GtkWidget   *fycal_label, *fycal_vbox;
328 gchar       tmpbuf[BUFFER_SIZE], buffer[BUFFER_SIZE];
329 gint        i, j, x, y, idx;
330 GDate       *cdate;
331 guint       month, year;
332 gint rotate = FALSE;
333 
334 	cdate = g_date_new ();
335 	g_return_if_fail (cdate != NULL);
336 	g_date_set_time_t (cdate, time (NULL));
337 
338 	appGUI->cal->fullyear_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
339 	gtk_window_set_title (GTK_WINDOW (appGUI->cal->fullyear_window), _("Full-year calendar"));
340 	gtk_window_set_position (GTK_WINDOW (appGUI->cal->fullyear_window), GTK_WIN_POS_CENTER_ALWAYS);
341 	gtk_window_set_default_size (GTK_WINDOW (appGUI->cal->fullyear_window), config.fy_window_size_x, config.fy_window_size_y);
342 	gtk_window_set_modal (GTK_WINDOW (appGUI->cal->fullyear_window), TRUE);
343 	g_signal_connect (G_OBJECT (appGUI->cal->fullyear_window), "delete_event",
344 	                  G_CALLBACK (fullyear_window_close_cb), appGUI);
345 	if (config.fullscreen == FALSE) {
346 		gtk_window_set_transient_for (GTK_WINDOW (appGUI->cal->fullyear_window), GTK_WINDOW (appGUI->main_window));
347 	}
348 	gtk_container_set_border_width (GTK_CONTAINER (appGUI->cal->fullyear_window), 8);
349 	g_signal_connect (G_OBJECT (appGUI->cal->fullyear_window), "key_press_event",
350 	                  G_CALLBACK (fullyear_key_press_cb), appGUI);
351 
352 	vbox1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
353 	gtk_widget_show (vbox1);
354 	gtk_container_add (GTK_CONTAINER (appGUI->cal->fullyear_window), vbox1);
355 
356 	hbox1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
357 	gtk_widget_show (hbox1);
358 	gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, FALSE, 4);
359 
360 	g_snprintf (tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Year"));
361 	label = gtk_label_new (tmpbuf);
362 	gtk_widget_show (label);
363 	gtk_box_pack_start (GTK_BOX (hbox1), label, FALSE, TRUE, 0);
364 	gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
365         gtk_widget_set_margin_top (label, 4);
366         gtk_widget_set_margin_bottom (label, 4);
367 
368 	fy_spinbutton_adj = gtk_adjustment_new (utl_date_get_current_year (), JULIAN_GREGORIAN_YEAR, 9999, 1, 10, 0);
369 	appGUI->cal->fy_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (fy_spinbutton_adj), 1, 0);
370 	gtk_widget_show (appGUI->cal->fy_spinbutton);
371 	g_signal_connect(appGUI->cal->fy_spinbutton, "value-changed", G_CALLBACK(change_year_spin_button_cb), appGUI);
372 	gtk_box_pack_start (GTK_BOX (hbox1), appGUI->cal->fy_spinbutton, FALSE, FALSE, 8);
373 	gtk_widget_set_size_request (appGUI->cal->fy_spinbutton, 80, -1);
374 	gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (appGUI->cal->fy_spinbutton), TRUE);
375 	gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (appGUI->cal->fy_spinbutton), GTK_UPDATE_IF_VALID);
376 
377 	info_button = gtk_button_new_from_icon_name ("dialog-information", GTK_ICON_SIZE_BUTTON);
378 	gtk_widget_set_can_focus(info_button, FALSE);
379 	gtk_widget_show (info_button);
380 	g_signal_connect (info_button, "clicked", G_CALLBACK (year_info_cb), appGUI);
381 	if (config.enable_tooltips) {
382 		gtk_widget_set_tooltip_text (info_button, _("Year info"));
383 	}
384 	gtk_button_set_relief (GTK_BUTTON (info_button), GTK_RELIEF_NONE);
385 	gtk_box_pack_start (GTK_BOX (hbox1), info_button, FALSE, FALSE, 2);
386 
387 	vseparator = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
388 	gtk_widget_show (vseparator);
389 	gtk_box_pack_start (GTK_BOX (hbox1), vseparator, FALSE, FALSE, 8);
390 
391 	prev_button = gtk_button_new_from_icon_name ("go-previous", GTK_ICON_SIZE_BUTTON);
392 	gtk_widget_set_can_focus (prev_button, FALSE);
393 	gtk_widget_show (prev_button);
394 	g_signal_connect (prev_button, "clicked", G_CALLBACK (change_to_previous_year_cb), appGUI);
395 	if (config.enable_tooltips) {
396 		gtk_widget_set_tooltip_text (prev_button, _("Previous year"));
397 	}
398 	gtk_button_set_relief (GTK_BUTTON (prev_button), GTK_RELIEF_NONE);
399 	gtk_box_pack_start (GTK_BOX (hbox1), prev_button, FALSE, FALSE, 2);
400 
401 	appGUI->cal->cyear_button = gtk_button_new_from_icon_name ("go-home", GTK_ICON_SIZE_BUTTON);
402 	gtk_widget_set_can_focus (appGUI->cal->cyear_button, FALSE);
403 	gtk_widget_show (appGUI->cal->cyear_button);
404 	g_signal_connect (appGUI->cal->cyear_button, "clicked", G_CALLBACK (change_to_current_year_cb), appGUI);
405 	if (config.enable_tooltips) {
406 		gtk_widget_set_tooltip_text (appGUI->cal->cyear_button, _("Current year"));
407 	}
408 	gtk_button_set_relief (GTK_BUTTON (appGUI->cal->cyear_button), GTK_RELIEF_NONE);
409 	gtk_box_pack_start (GTK_BOX (hbox1), appGUI->cal->cyear_button, FALSE, FALSE, 2);
410 
411 	next_button = gtk_button_new_from_icon_name ("go-next", GTK_ICON_SIZE_BUTTON);
412 	gtk_widget_set_can_focus(next_button, FALSE);
413 	gtk_widget_show (next_button);
414 	g_signal_connect (next_button, "clicked", G_CALLBACK (change_to_next_year_cb), appGUI);
415 	if (config.enable_tooltips) {
416 		gtk_widget_set_tooltip_text (next_button, _("Next year"));
417 	}
418 	gtk_button_set_relief (GTK_BUTTON (next_button), GTK_RELIEF_NONE);
419 	gtk_box_pack_start (GTK_BOX (hbox1), next_button, FALSE, FALSE, 2);
420 
421 	vseparator = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
422 	gtk_widget_show (vseparator);
423 	gtk_box_pack_start (GTK_BOX (hbox1), vseparator, FALSE, FALSE, 8);
424 
425 	appGUI->cal->fy_alternative_view_checkbutton = gtk_check_button_new_with_mnemonic (_("Alternative view"));
426 	gtk_widget_set_can_focus (appGUI->cal->fy_alternative_view_checkbutton, FALSE);
427 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (appGUI->cal->fy_alternative_view_checkbutton), config.fy_alternative_view);
428 	g_signal_connect (G_OBJECT (appGUI->cal->fy_alternative_view_checkbutton), "toggled",
429 	                  G_CALLBACK (alternative_view_cb), appGUI);
430 	gtk_box_pack_start (GTK_BOX (hbox1), appGUI->cal->fy_alternative_view_checkbutton, FALSE, FALSE, 2);
431 	gtk_widget_show (appGUI->cal->fy_alternative_view_checkbutton);
432 
433 	fycal_scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
434 	gtk_widget_show (fycal_scrolledwindow);
435 	gtk_box_pack_start (GTK_BOX (vbox1), fycal_scrolledwindow, TRUE, TRUE, 0);
436 	gtk_container_set_border_width (GTK_CONTAINER (fycal_scrolledwindow), 4);
437 	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (fycal_scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
438 
439 	fycal_viewport = gtk_viewport_new (NULL, NULL);
440 	gtk_widget_show (fycal_viewport);
441 	gtk_container_add (GTK_CONTAINER (fycal_scrolledwindow), fycal_viewport);
442 
443 	vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
444 	gtk_widget_show (vbox2);
445 	gtk_container_add (GTK_CONTAINER (fycal_viewport), vbox2);
446 
447 	/*-------------------------------------------------------------------------------------*/
448 	/* First view */
449 
450 	appGUI->cal->fycal_table_1 = gtk_grid_new ();
451 
452 	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->cal->fy_alternative_view_checkbutton)) == FALSE) {
453 		gtk_widget_show (appGUI->cal->fycal_table_1);
454 	}
455 	gtk_box_pack_start (GTK_BOX (vbox2), appGUI->cal->fycal_table_1, TRUE, TRUE, 0);
456 
457 	vseparator = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
458 	gtk_widget_show (vseparator);
459         gtk_widget_set_hexpand(vseparator, TRUE);
460         gtk_widget_set_vexpand(vseparator, TRUE);
461 	if (config.fy_simple_view == TRUE) {
462 		gtk_grid_attach (GTK_GRID (appGUI->cal->fycal_table_1), vseparator, 1, 0, 1, 14);
463 	} else {
464 		gtk_grid_attach (GTK_GRID (appGUI->cal->fycal_table_1), vseparator, 1, 0, 1, 16);
465 	}
466 
467 	hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
468 	gtk_widget_show (hseparator);
469 	gtk_widget_set_hexpand(hseparator, TRUE);
470 	gtk_grid_attach (GTK_GRID (appGUI->cal->fycal_table_1), hseparator, 2, 1, 37, 1);
471 
472 	hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
473 	gtk_widget_show (hseparator);
474 	gtk_widget_set_hexpand(hseparator, TRUE);
475 	gtk_grid_attach (GTK_GRID (appGUI->cal->fycal_table_1), hseparator, 0, 1, 1, 1);
476 
477 	if (config.fy_simple_view == FALSE) {
478 
479 		vseparator = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
480 		gtk_widget_show (vseparator);
481 		gtk_widget_set_hexpand(vseparator, TRUE);
482 		gtk_widget_set_vexpand(vseparator, TRUE);
483 		gtk_grid_attach (GTK_GRID (appGUI->cal->fycal_table_1), vseparator, FULL_YEAR_COLS + 2, 0, 1, 16);
484 		hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
485 		gtk_widget_show (hseparator);
486 		gtk_widget_set_hexpand(hseparator, TRUE);
487 		gtk_grid_attach (GTK_GRID (appGUI->cal->fycal_table_1), hseparator, 2, MAX_MONTHS + 2, 37, 1);
488 		hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
489 		gtk_widget_show (hseparator);
490 		gtk_widget_set_hexpand(hseparator, TRUE);
491 		gtk_grid_attach (GTK_GRID (appGUI->cal->fycal_table_1), hseparator, 0, MAX_MONTHS + 2, 1, 1);
492 		hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
493 		gtk_widget_show (hseparator);
494 		gtk_widget_set_hexpand(hseparator, TRUE);
495 		gtk_grid_attach (GTK_GRID (appGUI->cal->fycal_table_1), hseparator, FULL_YEAR_COLS + 3, 1, 1, 1);
496 		hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
497 		gtk_widget_show (hseparator);
498 		gtk_widget_set_hexpand(hseparator, TRUE);
499 		gtk_grid_attach (GTK_GRID (appGUI->cal->fycal_table_1), hseparator, FULL_YEAR_COLS + 3, MAX_MONTHS + 2, 1, 1);
500 	}
501 
502 	g_date_set_day (cdate, 1);
503 
504 	for (month = G_DATE_JANUARY; month <= G_DATE_DECEMBER; month++) {
505 
506 		g_date_set_month (cdate, month);
507 		g_date_strftime (buffer, BUFFER_SIZE, config.fy_simple_view ? "%b" : "%B", cdate);
508 		g_snprintf (tmpbuf, BUFFER_SIZE, (month % 2) ? "%s" : "<span foreground='medium blue'>%s</span>", buffer);
509 
510 		label = gtk_label_new (NULL);
511 		gtk_widget_show (label);
512 		gtk_grid_attach (GTK_GRID (appGUI->cal->fycal_table_1), label, 0, month + 1, 1, 1);
513 
514         gtk_widget_set_margin_left (label, 8);
515         gtk_widget_set_margin_right (label, 8);
516 		gtk_label_set_markup (GTK_LABEL (label), tmpbuf);
517 
518 		if (config.fy_simple_view == FALSE) {
519 			label = gtk_label_new (NULL);
520 			gtk_widget_show (label);
521 			gtk_grid_attach (GTK_GRID (appGUI->cal->fycal_table_1), label, FULL_YEAR_COLS + 3, month + 1, 1, 1);
522             gtk_widget_set_margin_left (label, 8);
523             gtk_widget_set_margin_right (label, 8);
524 			gtk_label_set_markup (GTK_LABEL (label), tmpbuf);
525 		}
526 	}
527 
528 	/* start with monday */
529 	g_date_set_dmy (cdate, 1, 1, 2007);
530 
531 	for (i = 0; i < FULL_YEAR_COLS; i++) {
532 
533 		g_date_set_day (cdate, (i % DAYS_PER_WEEK) + 1);
534 		g_date_strftime (buffer, BUFFER_SIZE, "%a", cdate);
535 		if (g_utf8_strlen (buffer, -1) > 2) rotate = TRUE;
536 
537 		if (i % 7 + 1 == G_DATE_SATURDAY || i % 7 + 1 == G_DATE_SUNDAY) {
538 			g_snprintf (tmpbuf, BUFFER_SIZE, "<span foreground='firebrick'>%s</span>", buffer);
539 		} else {
540 			g_snprintf (tmpbuf, BUFFER_SIZE, "%s", buffer);
541 		}
542 
543 		label = gtk_label_new (NULL);
544 		gtk_widget_show (label);
545 		gtk_grid_attach (GTK_GRID (appGUI->cal->fycal_table_1), label, i + 2, 0, 1, 1);
546         gtk_widget_set_margin_left (label, 4);
547         gtk_widget_set_margin_right (label, 4);
548 		if (rotate)
549 			gtk_label_set_angle (GTK_LABEL (label), 90);
550 		gtk_label_set_markup (GTK_LABEL (label), tmpbuf);
551 
552 		if (config.fy_simple_view == FALSE) {
553 			label = gtk_label_new (NULL);
554 			gtk_widget_show (label);
555 			gtk_grid_attach (GTK_GRID (appGUI->cal->fycal_table_1), label, i + 2, MAX_MONTHS + 3, 1, 1);
556             gtk_widget_set_margin_left (label, 4);
557             gtk_widget_set_margin_right (label, 4);
558 			if (rotate)
559 				gtk_label_set_angle (GTK_LABEL (label), 90);
560 			gtk_label_set_markup (GTK_LABEL (label), tmpbuf);
561 		}
562 	}
563 
564 	for (month = G_DATE_JANUARY; month <= G_DATE_DECEMBER; month++) {
565 
566 		for (j = 0; j < FULL_YEAR_COLS; j++) {
567 
568 			i = month - 1;
569 			idx = i * FULL_YEAR_COLS + j;
570 
571 			appGUI->cal->calendar_buttons[idx] = gtk_button_new_with_label ("");
572 			gtk_widget_set_can_focus (appGUI->cal->calendar_buttons[idx], FALSE);
573 			gtk_button_set_relief (GTK_BUTTON (appGUI->cal->calendar_buttons[idx]), GTK_RELIEF_NONE);
574 			gtk_widget_show (appGUI->cal->calendar_buttons[idx]);
575 			gtk_grid_attach (GTK_GRID (appGUI->cal->fycal_table_1), appGUI->cal->calendar_buttons[idx], j+2, i+2, 1, 1);
576 		}
577 	}
578 
579 	display_calendar (utl_date_get_current_year (), appGUI);
580 	gtk_widget_set_sensitive (appGUI->cal->cyear_button, FALSE);
581 
582 	/*-------------------------------------------------------------------------------------*/
583 	/* Second view */
584 
585 	appGUI->cal->fycal_table_2 = gtk_grid_new ();
586 
587 	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->cal->fy_alternative_view_checkbutton)) == TRUE) {
588 		gtk_widget_show (appGUI->cal->fycal_table_2);
589 	}
590 	gtk_box_pack_start (GTK_BOX (vbox2), appGUI->cal->fycal_table_2, TRUE, TRUE, 0);
591 
592 	for (i = y = 0; y < 3; y++) {
593 
594 		for (x = 0; x < 4; x++, i++) {
595 
596 			fycal_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
597 			gtk_widget_show (fycal_vbox);
598                         gtk_widget_set_hexpand(fycal_vbox, TRUE);
599 			gtk_grid_attach (GTK_GRID (appGUI->cal->fycal_table_2), fycal_vbox, x, y, 1, 1);
600 			fycal_label = gtk_label_new (NULL);
601 			gtk_widget_show (fycal_label);
602 			gtk_box_pack_start (GTK_BOX (fycal_vbox), fycal_label, FALSE, FALSE, 0);
603 			appGUI->cal->fy_calendars[i] = gui_calendar_new ();
604 			g_signal_connect (appGUI->cal->fy_calendars[i],
605 							  "day_selected_double_click", G_CALLBACK (calendar_dbclick_cb), appGUI);
606 			gtk_widget_show (appGUI->cal->fy_calendars[i]);
607 			gtk_widget_set_can_focus (appGUI->cal->fy_calendars[i], FALSE);
608 			gui_calendar_set_display_options (GUI_CALENDAR (appGUI->cal->fy_calendars[i]),
609 			                                  (config.display_options & (GUI_CALENDAR_SHOW_DAY_NAMES |
610 			                                  GUI_CALENDAR_WEEK_START_MONDAY)) | GUI_CALENDAR_NO_MONTH_CHANGE);
611 			gui_calendar_enable_cursor (GUI_CALENDAR (appGUI->cal->fy_calendars[i]), FALSE);
612             gui_set_calendar_defaults(appGUI->cal->fy_calendars[i]);
613 
614 			year = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (appGUI->cal->fy_spinbutton));
615 			month = i + 1;
616 
617 			gui_calendar_select_month (GUI_CALENDAR (appGUI->cal->fy_calendars[i]), month - 1, year);
618 			mark_events (appGUI->cal->fy_calendars[i], month - 1, year, appGUI);
619 			g_date_set_dmy (cdate, 1, month, year);
620 			g_date_strftime (buffer, BUFFER_SIZE, "%B", cdate);
621 			gtk_label_set_text (GTK_LABEL (fycal_label), buffer);
622 			gtk_box_pack_start (GTK_BOX (fycal_vbox), appGUI->cal->fy_calendars[i], FALSE, FALSE, 0);
623 		}
624 	}
625 
626 	if (appGUI->cal->last_selected_year == -1) {
627 		gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->cal->fy_spinbutton), utl_date_get_current_year ());
628 	} else {
629 		gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->cal->fy_spinbutton), appGUI->cal->last_selected_year);
630 	}
631 
632 	/*-------------------------------------------------------------------------------------*/
633 
634 	hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
635 	gtk_widget_show (hseparator);
636 	gtk_box_pack_start (GTK_BOX (vbox1), hseparator, FALSE, TRUE, 4);
637 
638 	hbuttonbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
639 	gtk_widget_show (hbuttonbox);
640 	gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox, FALSE, TRUE, 0);
641 	gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_END);
642 	gtk_box_set_spacing (GTK_BOX (hbuttonbox), 4);
643 
644 	close_button = gtk_button_new_with_mnemonic (_("_Close"));
645 	gtk_widget_show (close_button);
646 	g_signal_connect (close_button, "clicked", G_CALLBACK (button_fullyear_window_close_cb), appGUI);
647 	gtk_container_add (GTK_CONTAINER (hbuttonbox), close_button);
648 
649 	gtk_widget_show (appGUI->cal->fullyear_window);
650 
651 }
652 
653 /*------------------------------------------------------------------------*/
654 
655