evolution-3.6.4/calendar/gui/e-day-view-main-item.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found e-day-view-main-item.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
clang-analyzer no-output-found e-day-view-main-item.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
   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  *		Damon Chaplin <damon@ximian.com>
  18  *
  19  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  20  *
  21  */
  22 
  23 /*
  24  * EDayViewMainItem - canvas item which displays most of the appointment
  25  * data in the main Day/Work Week display.
  26  */
  27 
  28 #ifdef HAVE_CONFIG_H
  29 #include <config.h>
  30 #endif
  31 
  32 #include <e-calendar-view.h>
  33 
  34 #include "e-util/e-categories-config.h"
  35 #include "e-util/e-util.h"
  36 #include "e-day-view-layout.h"
  37 #include "e-day-view-main-item.h"
  38 #include "ea-calendar.h"
  39 #include "e-calendar-view.h"
  40 #include "comp-util.h"
  41 
  42 #define E_DAY_VIEW_MAIN_ITEM_GET_PRIVATE(obj) \
  43 	(G_TYPE_INSTANCE_GET_PRIVATE \
  44 	((obj), E_TYPE_DAY_VIEW_MAIN_ITEM, EDayViewMainItemPrivate))
  45 
  46 struct _EDayViewMainItemPrivate {
  47 	EDayView *day_view;
  48 };
  49 
  50 enum {
  51 	PROP_0,
  52 	PROP_DAY_VIEW
  53 };
  54 
  55 G_DEFINE_TYPE (
  56 	EDayViewMainItem,
  57 	e_day_view_main_item,
  58 	GNOME_TYPE_CANVAS_ITEM)
  59 
  60 static gboolean
  61 can_draw_in_region (cairo_region_t *draw_region,
  62                     gint x,
  63                     gint y,
  64                     gint width,
  65                     gint height)
  66 {
  67 	GdkRectangle rect;
  68 
  69 	g_return_val_if_fail (draw_region != NULL, FALSE);
  70 
  71 	rect.x = x;
  72 	rect.y = y;
  73 	rect.width = width;
  74 	rect.height = height;
  75 
  76 	return cairo_region_contains_rectangle (draw_region, &rect) !=
  77 		CAIRO_REGION_OVERLAP_OUT;
  78 }
  79 
  80 static gboolean
  81 icalcomp_is_transparent (icalcomponent *icalcomp)
  82 {
  83 	icalproperty *transp_prop;
  84 	icalproperty_transp ical_transp = ICAL_TRANSP_NONE;
  85 
  86 	g_return_val_if_fail (icalcomp != NULL, TRUE);
  87 
  88 	transp_prop = icalcomponent_get_first_property (icalcomp, ICAL_TRANSP_PROPERTY);
  89 	if (transp_prop)
  90 		ical_transp = icalproperty_get_transp (transp_prop);
  91 
  92 	return transp_prop && (ical_transp == ICAL_TRANSP_TRANSPARENT || ical_transp == ICAL_TRANSP_TRANSPARENTNOCONFLICT);
  93 }
  94 
  95 static void
  96 day_view_main_item_draw_long_events_in_vbars (EDayViewMainItem *main_item,
  97                                               cairo_t *cr,
  98                                               gint x,
  99                                               gint y,
 100                                               gint width,
 101                                               gint height,
 102                                               cairo_region_t *draw_region)
 103 {
 104 	EDayView *day_view;
 105 	EDayViewEvent *event;
 106 	ECalendarView *cal_view;
 107 	gint time_divisions;
 108 	gint event_num, start_day, end_day, day, bar_y1, bar_y2, grid_x;
 109 	GdkColor bg_color;
 110 
 111 	day_view = e_day_view_main_item_get_day_view (main_item);
 112 
 113 	cal_view = E_CALENDAR_VIEW (day_view);
 114 	time_divisions = e_calendar_view_get_time_divisions (cal_view);
 115 
 116 	for (event_num = 0; event_num < day_view->long_events->len; event_num++) {
 117 		gboolean first = TRUE;
 118 		event = &g_array_index (day_view->long_events, EDayViewEvent, event_num);
 119 
 120 		if (!is_comp_data_valid (event))
 121 			continue;
 122 
 123 		/* If the event is TRANSPARENT, skip it. */
 124 		if (icalcomp_is_transparent (event->comp_data->icalcomp)) {
 125 			continue;
 126 		}
 127 
 128 		if (!e_day_view_find_long_event_days (event,
 129 						      day_view->days_shown,
 130 						      day_view->day_starts,
 131 						      &start_day, &end_day)) {
 132 			continue;
 133 		}
 134 
 135 		for (day = start_day; day <= end_day; day++) {
 136 			grid_x = day_view->day_offsets[day] + 1 - x;
 137 
 138 			/* Skip if it isn't visible. */
 139 			if (grid_x >= width
 140 			    || grid_x + E_DAY_VIEW_BAR_WIDTH <= 0)
 141 				continue;
 142 
 143 			if (event->start <= day_view->day_starts[day]) {
 144 				bar_y1 = 0;
 145 			} else {
 146 				bar_y1 = event->start_minute * day_view->row_height / time_divisions - y;
 147 			}
 148 
 149 			if (event->end >= day_view->day_starts[day + 1]) {
 150 				bar_y2 = height;
 151 			} else {
 152 				bar_y2 = event->end_minute * day_view->row_height / time_divisions - y;
 153 			}
 154 
 155 			if (bar_y1 < height && bar_y2 > 0 && bar_y2 > bar_y1 && can_draw_in_region (draw_region, grid_x, bar_y1, E_DAY_VIEW_BAR_WIDTH - 2, bar_y2 - bar_y1)) {
 156 				cairo_save (cr);
 157 				gdk_cairo_set_source_color (cr, &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND]);
 158 
 159 				if (first) {
 160 					first = FALSE;
 161 
 162 					if (gdk_color_parse (e_cal_model_get_color_for_component (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), event->comp_data), &bg_color)) {
 163 						gdk_cairo_set_source_color (cr, &bg_color);
 164 					}
 165 				}
 166 
 167 				cairo_rectangle (cr, grid_x, bar_y1, E_DAY_VIEW_BAR_WIDTH - 2, bar_y2 - bar_y1);
 168 				cairo_fill (cr);
 169 				cairo_restore (cr);
 170 			}
 171 		}
 172 	}
 173 }
 174 
 175 static void
 176 day_view_main_item_draw_day_event (EDayViewMainItem *main_item,
 177                                    cairo_t *cr,
 178                                    gint x,
 179                                    gint y,
 180                                    gint width,
 181                                    gint height,
 182                                    gint day,
 183                                    gint event_num,
 184                                    cairo_region_t *draw_region)
 185 {
 186 	EDayView *day_view;
 187 	EDayViewEvent *event;
 188 	ECalModel *model;
 189 	ECalendarView *cal_view;
 190 	gint time_divisions;
 191 	gint item_x, item_y, item_w, item_h, bar_y1, bar_y2;
 192 	GdkColor bg_color;
 193 	ECalComponent *comp;
 194 	gint num_icons, icon_x = 0, icon_y, icon_x_inc = 0, icon_y_inc = 0;
 195 	gint max_icon_w, max_icon_h;
 196 	gboolean draw_reminder_icon, draw_recurrence_icon, draw_timezone_icon, draw_meeting_icon;
 197 	gboolean draw_attach_icon;
 198 	ECalComponentTransparency transparency;
 199 	cairo_pattern_t *pat;
 200 	guint16 red, green, blue;
 201 	gint i;
 202 	gdouble radius, x0, y0, rect_height, rect_width, text_x_offset = 0.0;
 203 	gdouble cc = 65535.0;
 204 	gdouble date_fraction;
 205 	gboolean short_event = FALSE, resize_flag = FALSE, is_editing;
 206 	const gchar *end_resize_suffix;
 207 	gchar *end_regsizeime;
 208 	gint start_hour, start_display_hour, start_minute, start_suffix_width;
 209 	gint end_hour, end_display_hour, end_minute, end_suffix_width;
 210 	gboolean show_span = FALSE, format_time;
 211 	gint offset, interval;
 212 	const gchar *start_suffix;
 213 	const gchar *end_suffix;
 214 	gchar *text = NULL;
 215 	gint scroll_flag = 0;
 216 	gint row_y;
 217 
 218 	day_view = e_day_view_main_item_get_day_view (main_item);
 219 
 220 	cal_view = E_CALENDAR_VIEW (day_view);
 221 	model = e_calendar_view_get_model (cal_view);
 222 	time_divisions = e_calendar_view_get_time_divisions (cal_view);
 223 
 224 	/* If the event is currently being dragged, don't draw it. It will
 225 	 * be drawn in the special drag items. */
 226 	if (day_view->drag_event_day == day && day_view->drag_event_num == event_num)
 227 		return;
 228 
 229 	/* Get the position of the event. If it is not shown skip it.*/
 230 	if (!e_day_view_get_event_position (day_view, day, event_num,
 231 					    &item_x, &item_y,
 232 					    &item_w, &item_h))
 233 		return;
 234 
 235 	item_x -= x;
 236 	item_y -= y;
 237 
 238 	if (!can_draw_in_region (draw_region, item_x, item_y, item_w, item_h))
 239 		return;
 240 
 241 	gdk_cairo_set_source_color (
 242 		cr,
 243 		&day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR]);
 244 
 245 	if (!is_array_index_in_bounds (day_view->events[day], event_num))
 246 		return;
 247 
 248 	event = &g_array_index (
 249 		day_view->events[day], EDayViewEvent, event_num);
 250 
 251 	if (!is_comp_data_valid (event))
 252 		return;
 253 
 254 	/* Fill in the event background. Note that for events in the first
 255 	 * column of the day, we might not want to paint over the vertical bar,
 256 	 * since that is used for multiple events. But then you can't see
 257 	 * where the event in the first column finishes. The border is drawn
 258 	 * along with the event using cairo */
 259 
 260 	red = day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].red;
 261 	green = day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].green;
 262 	blue = day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].blue;
 263 
 264 	if (gdk_color_parse (e_cal_model_get_color_for_component (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), event->comp_data),
 265 			     &bg_color)) {
 266 		red = bg_color.red;
 267 		green = bg_color.green;
 268 		blue = bg_color.blue;
 269 	}
 270 
 271 	is_editing = day_view->editing_event_day == day && day_view->editing_event_num == event_num;
 272 
 273 	if (event->canvas_item)
 274 		g_object_get (event->canvas_item, "x_offset", &text_x_offset, NULL);
 275 
 276 	/* Draw shadow around the event when selected */
 277 	if (is_editing && (gtk_widget_has_focus (day_view->main_canvas))) {
 278 		/* For embossing Item selection */
 279 		item_x -= 1;
 280 		item_y -= 2;
 281 
 282 		if (MAX (0, item_w - 31.5) != 0) {
 283 			/* Vertical Line */
 284 			cairo_save (cr);
 285 			pat = cairo_pattern_create_linear (
 286 				item_x + item_w - E_DAY_VIEW_BAR_WIDTH + 6.5, item_y + 13.75,
 287 				item_x + item_w - E_DAY_VIEW_BAR_WIDTH + 13.75, item_y + 13.75);
 288 			cairo_pattern_add_color_stop_rgba (pat, 0, 0, 0, 0, 1);
 289 			cairo_pattern_add_color_stop_rgba (pat, 0.7, 0, 0, 0, 0.2);
 290 			cairo_pattern_add_color_stop_rgba (pat, 1, 1, 1, 1, 0.3);
 291 			cairo_set_source (cr, pat);
 292 			cairo_rectangle (cr, item_x + item_w - E_DAY_VIEW_BAR_WIDTH + 6.5, item_y + 14.75, 7.0, item_h - 22.0);
 293 			cairo_fill (cr);
 294 			cairo_pattern_destroy (pat);
 295 
 296 			/* Arc at the right */
 297 			pat = cairo_pattern_create_radial (
 298 				item_x + item_w - E_DAY_VIEW_BAR_WIDTH + 3, item_y + 13.5, 5.0,
 299 				item_x + item_w - E_DAY_VIEW_BAR_WIDTH + 5, item_y + 13.5, 12.0);
 300 			cairo_pattern_add_color_stop_rgba (pat, 1, 1, 1, 1, 0.3);
 301 			cairo_pattern_add_color_stop_rgba (pat, 0.25, 0, 0, 0, 0.2);
 302 			cairo_pattern_add_color_stop_rgba (pat, 0, 0, 0, 0, 1);
 303 			cairo_set_source (cr, pat);
 304 			cairo_arc (cr, item_x + item_w - E_DAY_VIEW_BAR_WIDTH + 5, item_y + 13.5, 8.0, 11 * G_PI / 8, G_PI / 8);
 305 			cairo_fill (cr);
 306 			cairo_pattern_destroy (pat);
 307 
 308 			cairo_set_source_rgb (cr, 0, 0, 0);
 309 			cairo_set_line_width (cr, 1.25);
 310 			cairo_move_to (cr, item_x + item_w - E_DAY_VIEW_BAR_WIDTH + 5, item_y + 9.5);
 311 			cairo_line_to (cr, item_x + item_w - E_DAY_VIEW_BAR_WIDTH + 9.5, item_y + 15);
 312 			cairo_stroke (cr);
 313 
 314 			/* Horizontal line */
 315 			pat = cairo_pattern_create_linear (
 316 				item_x + E_DAY_VIEW_BAR_WIDTH + 15, item_y + item_h,
 317 				item_x + E_DAY_VIEW_BAR_WIDTH + 15, item_y + item_h + 7);
 318 			cairo_pattern_add_color_stop_rgba (pat, 0, 0, 0, 0, 1);
 319 			cairo_pattern_add_color_stop_rgba (pat, 0.7, 0, 0, 0, 0.2);
 320 			cairo_pattern_add_color_stop_rgba (pat, 1, 1, 1, 1, 0.3);
 321 			cairo_set_source (cr, pat);
 322 			cairo_rectangle (cr, item_x + E_DAY_VIEW_BAR_WIDTH + 16.5, item_y + item_h, item_w - 31.5, 7.0);
 323 			cairo_fill (cr);
 324 			cairo_pattern_destroy (pat);
 325 
 326 			/* Bottom arc */
 327 			pat = cairo_pattern_create_radial (
 328 				item_x + E_DAY_VIEW_BAR_WIDTH + 12.5, item_y + item_h - 5, 5.0,
 329 				item_x + E_DAY_VIEW_BAR_WIDTH + 12.5, item_y + item_h - 5, 12.0);
 330 			cairo_pattern_add_color_stop_rgba (pat, 1, 1, 1, 1, 0.3);
 331 			cairo_pattern_add_color_stop_rgba (pat, 0.7, 0, 0, 0, 0.2);
 332 			cairo_pattern_add_color_stop_rgba (pat, 0, 0, 0, 0, 1);
 333 			cairo_set_source (cr, pat);
 334 			cairo_arc (cr, item_x + E_DAY_VIEW_BAR_WIDTH + 13, item_y + item_h - 5, 12.0, 3 * G_PI / 8, 9 * G_PI / 8);
 335 			cairo_fill (cr);
 336 			cairo_pattern_destroy (pat);
 337 
 338 			cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
 339 			cairo_set_line_width (cr, 2);
 340 			cairo_move_to (cr, item_x + E_DAY_VIEW_BAR_WIDTH + 14, item_y + item_h + 2);
 341 			cairo_line_to (cr, item_x + E_DAY_VIEW_BAR_WIDTH + 15.5, item_y + item_h + 3);
 342 			cairo_stroke (cr);
 343 			cairo_set_source_rgba (cr, 0, 0, 0, 0.27);
 344 			cairo_move_to (cr, item_x + E_DAY_VIEW_BAR_WIDTH + 15, item_y + item_h + 3.5);
 345 			cairo_line_to (cr, item_x + E_DAY_VIEW_BAR_WIDTH + 17, item_y + item_h + 3.5);
 346 			cairo_stroke (cr);
 347 
 348 			/* Arc in middle */
 349 			pat = cairo_pattern_create_radial (
 350 				item_x + item_w - E_DAY_VIEW_BAR_WIDTH + 1, item_y + item_h - 4.5, 1.0,
 351 						item_x + item_w - E_DAY_VIEW_BAR_WIDTH + 1, item_y + item_h - 4.5, 12.0);
 352 			cairo_pattern_add_color_stop_rgba (pat, 1, 1, 1, 1, 0.3);
 353 			cairo_pattern_add_color_stop_rgba (pat, 0.8, 0, 0, 0, 0.2);
 354 			cairo_pattern_add_color_stop_rgba (pat, 0, 0, 0, 0, 1);
 355 			cairo_set_source (cr, pat);
 356 			cairo_arc (cr, item_x + item_w - E_DAY_VIEW_BAR_WIDTH + 1, item_y + item_h - 4.5, 12.0, 15 * G_PI / 8,  5 * G_PI / 8);
 357 			cairo_fill (cr);
 358 			cairo_pattern_destroy (pat);
 359 
 360 			cairo_set_source_rgba (cr, 0, 0, 0, 0.27);
 361 			cairo_move_to (cr, item_x + item_w - E_DAY_VIEW_BAR_WIDTH - 1, item_y + item_h + 3);
 362 			cairo_line_to (cr, item_x + item_w - E_DAY_VIEW_BAR_WIDTH , item_y + item_h + 3);
 363 			cairo_stroke (cr);
 364 
 365 			cairo_set_source_rgba (cr, 0, 0, 0, 0.27);
 366 			cairo_move_to (cr, item_x + item_w - E_DAY_VIEW_BAR_WIDTH + 9, item_y + item_h - 6);
 367 			cairo_line_to (cr, item_x + item_w - E_DAY_VIEW_BAR_WIDTH + 10, item_y + item_h - 6);
 368 			cairo_stroke (cr);
 369 
 370 			cairo_restore (cr);
 371 
 372 			/* Black border */
 373 			cairo_save (cr);
 374 			x0	   = item_x + E_DAY_VIEW_BAR_WIDTH + 9;
 375 			y0	   = item_y + 10;
 376 			rect_width = MAX (item_w - E_DAY_VIEW_BAR_WIDTH - 7, 0);
 377 			rect_height = item_h - 7;
 378 
 379 			radius = 20;
 380 
 381 			draw_curved_rectangle (cr, x0, y0, rect_width, rect_height, radius);
 382 
 383 			cairo_set_source_rgb (cr, 0, 0, 0);
 384 			cairo_fill (cr);
 385 			cairo_restore (cr);
 386 
 387 			/* Extra Grid lines when clicked */
 388 			cairo_save (cr);
 389 
 390 			x0	   = item_x + E_DAY_VIEW_BAR_WIDTH + 1;
 391 			y0	   = item_y + 2;
 392 			rect_width  = MAX (item_w - E_DAY_VIEW_BAR_WIDTH - 3, 0);
 393 			rect_height = item_h - 4.;
 394 
 395 			radius = 16;
 396 
 397 			draw_curved_rectangle (cr, x0, y0, rect_width, rect_height, radius);
 398 
 399 			cairo_set_source_rgb (cr, 1, 1, 1);
 400 			cairo_fill (cr);
 401 
 402 			gdk_cairo_set_source_color (
 403 				cr,
 404 				&day_view->colors[E_DAY_VIEW_COLOR_BG_GRID]);
 405 
 406 			for (row_y = y0;
 407 			     row_y < rect_height + y0;
 408 			     row_y += day_view->row_height) {
 409 				if (row_y >= 0 && row_y < rect_height + y0) {
 410 					cairo_set_line_width (cr, 0.7);
 411 					cairo_move_to (cr, item_x + E_DAY_VIEW_BAR_WIDTH + 1 , row_y);
 412 					cairo_line_to (cr, item_x + item_w -2, row_y);
 413 					cairo_stroke (cr);
 414 				}
 415 			}
 416 			cairo_restore (cr);
 417 		}
 418 
 419 		item_x += 1;
 420 		item_y += 2;
 421 	}
 422 
 423 	/* Draw the background of the event with white to play with transparency */
 424 	cairo_save (cr);
 425 
 426 	x0	   = item_x + E_DAY_VIEW_BAR_WIDTH + 1;
 427 	y0	   = item_y + 2;
 428 	rect_width  = MAX (item_w - E_DAY_VIEW_BAR_WIDTH - 3, 0);
 429 	rect_height = item_h - 4.;
 430 
 431 	radius = 16;
 432 
 433 	draw_curved_rectangle (cr, x0, y0, rect_width, rect_height, radius);
 434 
 435 	cairo_set_source_rgba (cr, 1, 1, 1, 1.0);
 436 	cairo_fill (cr);
 437 
 438 	cairo_restore (cr);
 439 
 440 	/* Here we draw the border in event color */
 441 	cairo_save (cr);
 442 
 443 	x0	   = item_x + E_DAY_VIEW_BAR_WIDTH;
 444 	y0	   = item_y + 1.;
 445 	rect_width  = MAX (item_w - E_DAY_VIEW_BAR_WIDTH - 1., 0);
 446 	rect_height = item_h - 2.;
 447 
 448 	radius = 16;
 449 
 450 	draw_curved_rectangle (cr, x0, y0, rect_width,rect_height, radius);
 451 	cairo_set_line_width (cr, 2.);
 452 	cairo_set_source_rgb (cr, red / cc, green / cc, blue / cc);
 453 	cairo_stroke (cr);
 454 	cairo_restore (cr);
 455 
 456 	/* Fill in the Event */
 457 
 458 	cairo_save (cr);
 459 
 460 	x0	   = item_x + E_DAY_VIEW_BAR_WIDTH + 1.75;
 461 	y0	   = item_y + 2.75;
 462 	rect_width  = item_w - E_DAY_VIEW_BAR_WIDTH - 4.5;
 463 	rect_height = item_h - 5.5;
 464 
 465 	radius = 14;
 466 
 467 	draw_curved_rectangle (cr, x0, y0, rect_width, rect_height, radius);
 468 
 469 	date_fraction = rect_height / day_view->row_height;
 470 	interval = event->end_minute - event->start_minute;
 471 
 472 	if ((interval / time_divisions) >= 2)
 473 		short_event = FALSE;
 474 	else if ((interval % time_divisions) == 0) {
 475 		if (((event->end_minute % time_divisions) == 0) ||
 476 		    ((event->start_minute % time_divisions) == 0))
 477 			short_event = TRUE;
 478 		}
 479 	else
 480 		short_event = FALSE;
 481 
 482 	if (is_editing)
 483 		short_event = TRUE;
 484 
 485 	pat = cairo_pattern_create_linear (
 486 		item_x + E_DAY_VIEW_BAR_WIDTH + 1.75, item_y + 7.75,
 487 		item_x + E_DAY_VIEW_BAR_WIDTH + 1.75, item_y + item_h - 7.75);
 488 	if (!short_event) {
 489 		cairo_pattern_add_color_stop_rgba (pat, 1, red / cc, green / cc, blue / cc, 0.8);
 490 		cairo_pattern_add_color_stop_rgba (pat, 1 / (date_fraction + (rect_height / 18)), red / cc, green / cc, blue / cc, 0.8);
 491 		cairo_pattern_add_color_stop_rgba (pat, 1 / (date_fraction + (rect_height / 18)), red / cc, green / cc, blue / cc, 0.4);
 492 		cairo_pattern_add_color_stop_rgba (pat, 1, red / cc, green / cc, blue / cc, 0.8);
 493 	} else {
 494 		cairo_pattern_add_color_stop_rgba (pat, 1, red / cc, green / cc, blue / cc, 0.8);
 495 		cairo_pattern_add_color_stop_rgba (pat, 0, red / cc, green / cc, blue / cc, 0.4);
 496 	}
 497 	cairo_set_source (cr, pat);
 498 	cairo_fill_preserve (cr);
 499 	cairo_pattern_destroy (pat);
 500 
 501 	cairo_set_source_rgba (cr, red / cc, green / cc, blue / cc, 0.2);
 502 	cairo_set_line_width (cr, 0.5);
 503 	cairo_stroke (cr);
 504 	cairo_restore (cr);
 505 
 506 	/* Draw the right edge of the vertical bar. */
 507 	cairo_save (cr);
 508 	gdk_cairo_set_source_color (
 509 		cr,
 510 		&day_view->colors[E_DAY_VIEW_COLOR_BG_GRID]);
 511 	cairo_set_line_width (cr, 0.7);
 512 	cairo_move_to (cr, item_x + E_DAY_VIEW_BAR_WIDTH - 1, item_y + 1);
 513 	cairo_line_to (cr, item_x + E_DAY_VIEW_BAR_WIDTH - 1, item_y + item_h - 2);
 514 	cairo_stroke (cr);
 515 	cairo_restore (cr);
 516 
 517 	gdk_cairo_set_source_color (
 518 		cr,
 519 		&day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR]);
 520 
 521 	/* Draw the vertical colored bar showing when the appointment
 522 	 * begins & ends. */
 523 	bar_y1 = event->start_minute * day_view->row_height / time_divisions - y;
 524 	bar_y2 = event->end_minute * day_view->row_height / time_divisions - y;
 525 
 526 	scroll_flag = bar_y2;
 527 
 528 	/* When an item is being resized, we fill the bar up to the new row. */
 529 	if (day_view->resize_drag_pos != E_CALENDAR_VIEW_POS_NONE
 530 	    && day_view->resize_event_day == day
 531 	    && day_view->resize_event_num == event_num) {
 532 		resize_flag = TRUE;
 533 
 534 		if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_TOP_EDGE)
 535 			bar_y1 = item_y + 1;
 536 
 537 		else if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_BOTTOM_EDGE) {
 538 			bar_y2 = item_y + item_h - 1;
 539 
 540 			end_minute = event->end_minute;
 541 
 542 			end_hour   = end_minute / 60;
 543 			end_minute = end_minute % 60;
 544 
 545 			e_day_view_convert_time_to_display (
 546 				day_view, end_hour,
 547 				&end_display_hour,
 548 				&end_resize_suffix,
 549 				&end_suffix_width);
 550 
 551 			cairo_save (cr);
 552 			cairo_rectangle (
 553 				cr, item_x + E_DAY_VIEW_BAR_WIDTH + 1.75, item_y + 2.75,
 554 				item_w - E_DAY_VIEW_BAR_WIDTH - 4.5,
 555 				item_h - 5.5);
 556 			cairo_clip (cr);
 557 			cairo_new_path (cr);
 558 
 559 			if (e_cal_model_get_use_24_hour_format (model)) {
 560 				cairo_translate (cr, item_x + item_w - E_DAY_VIEW_BAR_WIDTH - 32, item_y + item_h - 8);
 561 				end_regsizeime = g_strdup_printf (
 562 					"%2i:%02i",
 563 					end_display_hour, end_minute);
 564 
 565 			} else {
 566 				cairo_translate (cr, item_x + item_w - E_DAY_VIEW_BAR_WIDTH - 48, item_y + item_h - 8);
 567 				end_regsizeime = g_strdup_printf (
 568 					"%2i:%02i%s",
 569 					end_display_hour, end_minute,
 570 					end_resize_suffix);
 571 			}
 572 			cairo_set_font_size (cr, 14);
 573 			if ((red / cc > 0.7) || (green / cc > 0.7) || (blue / cc > 0.7))
 574 				cairo_set_source_rgb (cr, 0, 0, 0);
 575 			else
 576 				cairo_set_source_rgb (cr, 1, 1, 1);
 577 			cairo_show_text (cr, end_regsizeime);
 578 			cairo_close_path (cr);
 579 			cairo_restore (cr);
 580 		}
 581 	}
 582 
 583 	if (bar_y2 > scroll_flag)
 584 		event->end_minute += time_divisions;
 585 	else if (bar_y2 < scroll_flag)
 586 		event->end_minute -= time_divisions;
 587 
 588 	comp = e_cal_component_new ();
 589 	e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
 590 
 591 	/* Only fill it in if the event isn't TRANSPARENT. */
 592 	e_cal_component_get_transparency (comp, &transparency);
 593 	if (transparency != E_CAL_COMPONENT_TRANSP_TRANSPARENT) {
 594 		cairo_save (cr);
 595 		pat = cairo_pattern_create_linear (
 596 			item_x + E_DAY_VIEW_BAR_WIDTH, item_y + 1,
 597 			item_x + E_DAY_VIEW_BAR_WIDTH, item_y + item_h - 1);
 598 		cairo_pattern_add_color_stop_rgba (pat, 1, red / cc, green / cc, blue / cc, 0.7);
 599 		cairo_pattern_add_color_stop_rgba (pat, 0.5, red / cc, green / cc, blue / cc, 0.7);
 600 		cairo_pattern_add_color_stop_rgba (pat, 0, red / cc, green / cc, blue / cc, 0.2);
 601 
 602 		cairo_rectangle (
 603 			cr, item_x + 1, bar_y1,
 604 			E_DAY_VIEW_BAR_WIDTH - 2, bar_y2 - bar_y1);
 605 
 606 		cairo_set_source (cr, pat);
 607 		cairo_fill (cr);
 608 		cairo_pattern_destroy (pat);
 609 		cairo_restore (cr);
 610 
 611 		/* This is for achieving the white stripes in vbar across event color */
 612 		for (i = 0; i <= (bar_y2 - bar_y1); i+=4) {
 613 			cairo_set_source_rgb (cr, 1, 1, 1);
 614 			cairo_set_line_width (cr, 0.3);
 615 			cairo_move_to (cr, item_x + 1, bar_y1 + i);
 616 			cairo_line_to (cr, item_x + E_DAY_VIEW_BAR_WIDTH - 1, bar_y1 + i);
 617 			cairo_stroke (cr);
 618 		}
 619 	}
 620 
 621 	gdk_cairo_set_source_color (
 622 		cr,
 623 		&day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR]);
 624 
 625 	/* Draw the reminder & recurrence icons, if needed. */
 626 	if (!resize_flag && (!is_editing || text_x_offset > E_DAY_VIEW_ICON_X_PAD)) {
 627 		GSList *categories_pixbufs = NULL, *pixbufs;
 628 
 629 		num_icons = 0;
 630 		draw_reminder_icon = FALSE;
 631 		draw_recurrence_icon = FALSE;
 632 		draw_timezone_icon = FALSE;
 633 		draw_meeting_icon = FALSE;
 634 		draw_attach_icon = FALSE;
 635 		icon_x = item_x + E_DAY_VIEW_BAR_WIDTH + E_DAY_VIEW_ICON_X_PAD;
 636 		icon_y = item_y + E_DAY_VIEW_EVENT_BORDER_HEIGHT
 637 			+ E_DAY_VIEW_ICON_Y_PAD;
 638 
 639 		if (e_cal_component_has_alarms (comp)) {
 640 			draw_reminder_icon = TRUE;
 641 			num_icons++;
 642 		}
 643 
 644 		if (e_cal_component_has_recurrences (comp) || e_cal_component_is_instance (comp)) {
 645 			draw_recurrence_icon = TRUE;
 646 			num_icons++;
 647 		}
 648 		if (e_cal_component_has_attachments (comp)) {
 649 			draw_attach_icon = TRUE;
 650 			num_icons++;
 651 		}
 652 		/* If the DTSTART or DTEND are in a different timezone to our current
 653 		 * timezone, we display the timezone icon. */
 654 		if (event->different_timezone) {
 655 			draw_timezone_icon = TRUE;
 656 			num_icons++;
 657 		}
 658 
 659 		if (e_cal_component_has_attendees (comp)) {
 660 			draw_meeting_icon = TRUE;
 661 			num_icons++;
 662 		}
 663 
 664 		num_icons += cal_comp_util_get_n_icons (comp, &categories_pixbufs);
 665 
 666 		if (num_icons != 0) {
 667 			if (item_h >= (E_DAY_VIEW_ICON_HEIGHT + E_DAY_VIEW_ICON_Y_PAD) * num_icons) {
 668 				icon_x_inc = 0;
 669 				icon_y_inc = E_DAY_VIEW_ICON_HEIGHT
 670 					+ E_DAY_VIEW_ICON_Y_PAD;
 671 			} else {
 672 				icon_x_inc = E_DAY_VIEW_ICON_WIDTH
 673 					+ E_DAY_VIEW_ICON_X_PAD;
 674 				icon_y_inc = 0;
 675 			}
 676 
 677 			#define fit_in_event() (icon_x + icon_x_inc < item_x + item_w && icon_y + icon_y_inc < item_y + item_h)
 678 			#define draw_pixbuf(pf)	\
 679 				max_icon_w = item_x + item_w - icon_x - E_DAY_VIEW_EVENT_BORDER_WIDTH;		\
 680 				max_icon_h = item_y + item_h - icon_y - E_DAY_VIEW_EVENT_BORDER_HEIGHT;		\
 681 														\
 682 				if (can_draw_in_region (draw_region, icon_x, icon_y, max_icon_w, max_icon_h)) {	\
 683 					cairo_save (cr);							\
 684 					cairo_rectangle (cr, icon_x, icon_y, max_icon_w, max_icon_h);		\
 685 					cairo_clip (cr);							\
 686 					cairo_new_path (cr);							\
 687 					gdk_cairo_set_source_pixbuf (cr, pf, icon_x, icon_y);			\
 688 					cairo_paint (cr);							\
 689 					cairo_close_path (cr);							\
 690 					cairo_restore (cr);							\
 691 				}										\
 692 														\
 693 				icon_x += icon_x_inc;								\
 694 				icon_y += icon_y_inc;
 695 
 696 			if (draw_reminder_icon && fit_in_event ()) {
 697 				draw_pixbuf (day_view->reminder_icon);
 698 			}
 699 
 700 			if (draw_recurrence_icon && fit_in_event ()) {
 701 				draw_pixbuf (day_view->recurrence_icon);
 702 			}
 703 			if (draw_attach_icon && fit_in_event ()) {
 704 				draw_pixbuf (day_view->attach_icon);
 705 			}
 706 			if (draw_timezone_icon && fit_in_event ()) {
 707 				draw_pixbuf (day_view->timezone_icon);
 708 			}
 709 
 710 			if (draw_meeting_icon && fit_in_event ()) {
 711 				draw_pixbuf (day_view->meeting_icon);
 712 			}
 713 
 714 			/* draw categories icons */
 715 			for (pixbufs = categories_pixbufs;
 716 			     pixbufs && fit_in_event ();
 717 			     pixbufs = pixbufs->next) {
 718 				GdkPixbuf *pixbuf = pixbufs->data;
 719 
 720 				draw_pixbuf (pixbuf);
 721 			}
 722 
 723 			#undef draw_pixbuf
 724 			#undef fit_in_event
 725 		}
 726 
 727 		/* free memory */
 728 		g_slist_foreach (categories_pixbufs, (GFunc) g_object_unref, NULL);
 729 		g_slist_free (categories_pixbufs);
 730 	}
 731 
 732 	if (!short_event)
 733 	{
 734 		if (event->start_minute % time_divisions != 0
 735 			|| (day_view->show_event_end_times
 736 			&& event->end_minute % time_divisions != 0)) {
 737 				offset = day_view->first_hour_shown * 60
 738 				+ day_view->first_minute_shown;
 739 				show_span = TRUE;
 740 			} else {
 741 				offset = 0;
 742 		}
 743 		start_minute = offset + event->start_minute;
 744 		end_minute = offset + event->end_minute;
 745 
 746 		format_time = (((end_minute - start_minute) / time_divisions) >= 2) ? TRUE : FALSE;
 747 
 748 		start_hour = start_minute / 60;
 749 		start_minute = start_minute % 60;
 750 
 751 		end_hour = end_minute / 60;
 752 		end_minute = end_minute % 60;
 753 
 754 		e_day_view_convert_time_to_display (
 755 			day_view, start_hour,
 756 			&start_display_hour,
 757 			&start_suffix,
 758 			&start_suffix_width);
 759 		e_day_view_convert_time_to_display (
 760 			day_view, end_hour,
 761 			&end_display_hour,
 762 			&end_suffix,
 763 			&end_suffix_width);
 764 
 765 		if (e_cal_model_get_use_24_hour_format (model)) {
 766 			if (day_view->show_event_end_times && show_span) {
 767 				/* 24 hour format with end time. */
 768 				text = g_strdup_printf
 769 					("%2i:%02i-%2i:%02i",
 770 					 start_display_hour, start_minute,
 771 					 end_display_hour, end_minute);
 772 			} else {
 773 				if (format_time) {
 774 				/* 24 hour format without end time. */
 775 				text = g_strdup_printf
 776 					("%2i:%02i",
 777 					 start_display_hour, start_minute);
 778 				}
 779 			}
 780 		} else {
 781 			if (day_view->show_event_end_times && show_span) {
 782 				/* 12 hour format with end time. */
 783 				text = g_strdup_printf
 784 					("%2i:%02i%s-%2i:%02i%s",
 785 					 start_display_hour, start_minute,
 786 					 start_suffix,
 787 					 end_display_hour, end_minute, end_suffix);
 788 			} else {
 789 				/* 12 hour format without end time. */
 790 				text = g_strdup_printf
 791 					("%2i:%02i%s",
 792 					 start_display_hour, start_minute,
 793 					 start_suffix);
 794 			}
 795 		}
 796 
 797 		cairo_save (cr);
 798 		cairo_rectangle (
 799 			cr, item_x + E_DAY_VIEW_BAR_WIDTH + 1.75, item_y + 2.75,
 800 			item_w - E_DAY_VIEW_BAR_WIDTH - 4.5,
 801 			14);
 802 
 803 		cairo_clip (cr);
 804 		cairo_new_path (cr);
 805 
 806 		if (icon_x_inc == 0)
 807 			icon_x += 14;
 808 
 809 		if (resize_flag)
 810 			cairo_move_to (cr, item_x + E_DAY_VIEW_BAR_WIDTH + 10, item_y + 13);
 811 		else
 812 			cairo_move_to (cr, icon_x, item_y + 13);
 813 		if ((red / cc > 0.7) || (green / cc > 0.7) || (blue / cc > 0.7))
 814 			cairo_set_source_rgb (cr, 0, 0, 0);
 815 		else
 816 			cairo_set_source_rgb (cr, 1, 1, 1);
 817 		cairo_set_font_size (cr, 14.0);
 818 		cairo_show_text (cr, text);
 819 		cairo_close_path (cr);
 820 		cairo_restore (cr);
 821 	}
 822 
 823 	g_free (text);
 824 	g_object_unref (comp);
 825 }
 826 
 827 static void
 828 day_view_main_item_draw_day_events (EDayViewMainItem *main_item,
 829                                     cairo_t *cr,
 830                                     gint x,
 831                                     gint y,
 832                                     gint width,
 833                                     gint height,
 834                                     gint day,
 835                                     cairo_region_t *draw_region)
 836 {
 837 	EDayView *day_view;
 838 	gint event_num;
 839 
 840 	day_view = e_day_view_main_item_get_day_view (main_item);
 841 
 842 	for (event_num = 0; event_num < day_view->events[day]->len;
 843 	     event_num++) {
 844 		day_view_main_item_draw_day_event (
 845 			main_item, cr, x, y, width, height,
 846 			day, event_num, draw_region);
 847 	}
 848 }
 849 
 850 static void
 851 day_view_main_item_draw_events_in_vbars (EDayViewMainItem *main_item,
 852                                          cairo_t *cr,
 853                                          gint x,
 854                                          gint y,
 855                                          gint width,
 856                                          gint height,
 857                                          gint day,
 858                                          cairo_region_t *draw_region)
 859 {
 860 	EDayView *day_view;
 861 	EDayViewEvent *event;
 862 	ECalendarView *cal_view;
 863 	gint time_divisions;
 864 	gint grid_x, event_num, bar_y, bar_h;
 865 	GdkColor bg_color;
 866 
 867 	day_view = e_day_view_main_item_get_day_view (main_item);
 868 
 869 	cal_view = E_CALENDAR_VIEW (day_view);
 870 	time_divisions = e_calendar_view_get_time_divisions (cal_view);
 871 
 872 	grid_x = day_view->day_offsets[day] + 1 - x;
 873 
 874 	/* Draw the busy times corresponding to the events in the day. */
 875 	for (event_num = 0; event_num < day_view->events[day]->len; event_num++) {
 876 		event = &g_array_index (day_view->events[day], EDayViewEvent, event_num);
 877 
 878 		if (!is_comp_data_valid (event))
 879 			continue;
 880 
 881 		/* We can skip the events in the first column since they will
 882 		 * draw over this anyway. */
 883 		if (event->num_columns > 0 && event->start_row_or_col == 0) {
 884 			continue;
 885 		}
 886 
 887 		bar_y = event->start_minute * day_view->row_height / time_divisions;
 888 		bar_h = event->end_minute * day_view->row_height / time_divisions - bar_y;
 889 		bar_y -= y;
 890 
 891 		/* Skip it if it isn't visible. */
 892 		if (bar_y >= height || bar_y + bar_h <= 0 || !can_draw_in_region (draw_region, grid_x, bar_y, E_DAY_VIEW_BAR_WIDTH - 2, bar_h)) {
 893 			continue;
 894 		}
 895 
 896 		/* If the event is TRANSPARENT, skip it. */
 897 		if (icalcomp_is_transparent (event->comp_data->icalcomp)) {
 898 			continue;
 899 		}
 900 
 901 		cairo_save (cr);
 902 
 903 		gdk_cairo_set_source_color (cr, &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND]);
 904 
 905 		if (gdk_color_parse (e_cal_model_get_color_for_component (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), event->comp_data), &bg_color)) {
 906 			gdk_cairo_set_source_color (cr, &bg_color);
 907 		}
 908 
 909 		cairo_rectangle (cr, grid_x, bar_y, E_DAY_VIEW_BAR_WIDTH - 2, bar_h);
 910 
 911 		cairo_fill (cr);
 912 
 913 		cairo_restore (cr);
 914 	}
 915 }
 916 
 917 static void
 918 day_view_main_item_set_property (GObject *object,
 919                                  guint property_id,
 920                                  const GValue *value,
 921                                  GParamSpec *pspec)
 922 {
 923 	switch (property_id) {
 924 		case PROP_DAY_VIEW:
 925 			e_day_view_main_item_set_day_view (
 926 				E_DAY_VIEW_MAIN_ITEM (object),
 927 				g_value_get_object (value));
 928 			return;
 929 	}
 930 
 931 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 932 }
 933 
 934 static void
 935 day_view_main_item_get_property (GObject *object,
 936                                  guint property_id,
 937                                  GValue *value,
 938                                  GParamSpec *pspec)
 939 {
 940 	switch (property_id) {
 941 		case PROP_DAY_VIEW:
 942 			g_value_set_object (
 943 				value, e_day_view_main_item_get_day_view (
 944 				E_DAY_VIEW_MAIN_ITEM (object)));
 945 			return;
 946 	}
 947 
 948 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 949 }
 950 
 951 static void
 952 day_view_main_item_dispose (GObject *object)
 953 {
 954 	EDayViewMainItemPrivate *priv;
 955 
 956 	priv = E_DAY_VIEW_MAIN_ITEM_GET_PRIVATE (object);
 957 
 958 	if (priv->day_view != NULL) {
 959 		g_object_unref (priv->day_view);
 960 		priv->day_view = NULL;
 961 	}
 962 
 963 	/* Chain up to parent's dispose() method. */
 964 	G_OBJECT_CLASS (e_day_view_main_item_parent_class)->dispose (object);
 965 }
 966 
 967 static void
 968 day_view_main_item_update (GnomeCanvasItem *item,
 969                            const cairo_matrix_t *i2c,
 970                            gint flags)
 971 {
 972 	GnomeCanvasItemClass *canvas_item_class;
 973 
 974 	/* Chain up to parent's update() method. */
 975 	canvas_item_class =
 976 		GNOME_CANVAS_ITEM_CLASS (e_day_view_main_item_parent_class);
 977 	canvas_item_class->update (item, i2c, flags);
 978 
 979 	/* The item covers the entire canvas area. */
 980 	item->x1 = 0;
 981 	item->y1 = 0;
 982 	item->x2 = INT_MAX;
 983 	item->y2 = INT_MAX;
 984 }
 985 
 986 static void
 987 day_view_main_item_draw (GnomeCanvasItem *canvas_item,
 988                          cairo_t *cr,
 989                          gint x,
 990                          gint y,
 991                          gint width,
 992                          gint height)
 993 {
 994 	EDayViewMainItem *main_item;
 995 	EDayView *day_view;
 996 	ECalendarView *cal_view;
 997 	ECalModel *model;
 998 	gint time_divisions;
 999 	gint work_day_start_hour;
1000 	gint work_day_start_minute;
1001 	gint work_day_end_hour;
1002 	gint work_day_end_minute;
1003 	gint row, row_y, grid_x1, grid_x2;
1004 	gint day, grid_y1, grid_y2;
1005 	gint work_day_start_y, work_day_end_y;
1006 	gint day_x, day_w, work_day;
1007 	gint start_row, end_row, rect_x, rect_y, rect_width, rect_height;
1008 	struct icaltimetype day_start_tt, today_tt;
1009 	gint weekday;
1010 	gboolean today = FALSE;
1011 	cairo_region_t *draw_region;
1012 	GdkRectangle rect;
1013 
1014 	main_item = E_DAY_VIEW_MAIN_ITEM (canvas_item);
1015 	day_view = e_day_view_main_item_get_day_view (main_item);
1016 	g_return_if_fail (day_view != NULL);
1017 
1018 	cal_view = E_CALENDAR_VIEW (day_view);
1019 	time_divisions = e_calendar_view_get_time_divisions (cal_view);
1020 
1021 	model = e_calendar_view_get_model (cal_view);
1022 	work_day_start_hour = e_cal_model_get_work_day_start_hour (model);
1023 	work_day_start_minute = e_cal_model_get_work_day_start_minute (model);
1024 	work_day_end_hour = e_cal_model_get_work_day_end_hour (model);
1025 	work_day_end_minute = e_cal_model_get_work_day_end_minute (model);
1026 
1027 	rect.x = 0;
1028 	rect.y = 0;
1029 	rect.width = width;
1030 	rect.height = height;
1031 	if (rect.width > 0 && rect.height > 0)
1032 		draw_region = cairo_region_create_rectangle (&rect);
1033 	else
1034 		draw_region = cairo_region_create ();
1035 
1036 	/* Paint the background colors. */
1037 	work_day_start_y = e_day_view_convert_time_to_position (
1038 		day_view, work_day_start_hour, work_day_start_minute) - y;
1039 	work_day_end_y = e_day_view_convert_time_to_position (
1040 		day_view, work_day_end_hour, work_day_end_minute) - y;
1041 
1042 	today_tt = icaltime_from_timet_with_zone (
1043 		time (NULL), FALSE,
1044 		e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view)));
1045 
1046 	for (day = 0; day < day_view->days_shown; day++) {
1047 		day_start_tt = icaltime_from_timet_with_zone (
1048 			day_view->day_starts[day], FALSE,
1049 			e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view)));
1050 		weekday = icaltime_day_of_week (day_start_tt) - 1;
1051 
1052 		work_day = day_view->working_days & (1 << weekday);
1053 
1054 		day_x = day_view->day_offsets[day] - x;
1055 		day_w = day_view->day_widths[day];
1056 
1057 		if (work_day) {
1058 			if (can_draw_in_region (draw_region, day_x, 0 - y, day_w, work_day_start_y - (0 - y))) {
1059 				cairo_save (cr);
1060 				gdk_cairo_set_source_color (cr, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]);
1061 				cairo_rectangle (cr, day_x, 0 - y, day_w, work_day_start_y - (0 - y));
1062 				cairo_fill (cr);
1063 				cairo_restore (cr);
1064 			}
1065 
1066 			if (day_view->days_shown > 1) {
1067 				/* Check if we are drawing today */
1068 				today =  day_start_tt.year == today_tt.year
1069 					&& day_start_tt.month == today_tt.month
1070 					&& day_start_tt.day == today_tt.day;
1071 			} else {
1072 				today = FALSE;
1073 			}
1074 
1075 			if (can_draw_in_region (draw_region, day_x, work_day_start_y, day_w, work_day_end_y - work_day_start_y)) {
1076 				cairo_save (cr);
1077 				gdk_cairo_set_source_color (cr, &day_view->colors[today ? E_DAY_VIEW_COLOR_BG_MULTIDAY_TODAY : E_DAY_VIEW_COLOR_BG_WORKING]);
1078 				cairo_rectangle (cr, day_x, work_day_start_y, day_w, work_day_end_y - work_day_start_y);
1079 				cairo_fill (cr);
1080 				cairo_restore (cr);
1081 			}
1082 
1083 			if (can_draw_in_region (draw_region, day_x, work_day_end_y, day_w, height - work_day_end_y)) {
1084 				cairo_save (cr);
1085 				gdk_cairo_set_source_color (cr, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]);
1086 				cairo_rectangle (cr, day_x, work_day_end_y, day_w, height - work_day_end_y);
1087 				cairo_fill (cr);
1088 				cairo_restore (cr);
1089 			}
1090 		} else if (can_draw_in_region (draw_region, day_x, 0, day_w, height)) {
1091 			cairo_save (cr);
1092 			gdk_cairo_set_source_color (cr, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]);
1093 			cairo_rectangle (cr, day_x, 0, day_w, height);
1094 			cairo_fill (cr);
1095 			cairo_restore (cr);
1096 		}
1097 	}
1098 
1099 	/* Paint the selection background. */
1100 	if (day_view->selection_start_day != -1
1101 	    && !day_view->selection_in_top_canvas) {
1102 		for (day = day_view->selection_start_day;
1103 		     day <= day_view->selection_end_day;
1104 		     day++) {
1105 			if (day == day_view->selection_start_day
1106 			    && day_view->selection_start_row != -1)
1107 				start_row = day_view->selection_start_row;
1108 			else
1109 				start_row = 0;
1110 			if (day == day_view->selection_end_day
1111 			    && day_view->selection_end_row != -1)
1112 				end_row = day_view->selection_end_row;
1113 			else
1114 				end_row = day_view->rows - 1;
1115 
1116 			rect_x = day_view->day_offsets[day] - x;
1117 			rect_width = day_view->day_widths[day];
1118 			rect_y = start_row * day_view->row_height - y;
1119 			rect_height = (end_row - start_row + 1) * day_view->row_height;
1120 
1121 			if (can_draw_in_region (draw_region, rect_x, rect_y, rect_width, rect_height)) {
1122 				cairo_save (cr);
1123 				gdk_cairo_set_source_color (cr, &day_view->colors[gtk_widget_has_focus (GTK_WIDGET (day_view)) ? E_DAY_VIEW_COLOR_BG_SELECTED : E_DAY_VIEW_COLOR_BG_SELECTED_UNFOCUSSED]);
1124 				cairo_rectangle (cr, rect_x, rect_y, rect_width, rect_height);
1125 				cairo_fill (cr);
1126 				cairo_restore (cr);
1127 			}
1128 		}
1129 	}
1130 
1131 	/* Drawing the horizontal grid lines. */
1132 	grid_x1 = day_view->day_offsets[0] - x;
1133 	grid_x2 = day_view->day_offsets[day_view->days_shown] - x;
1134 
1135 	cairo_save (cr);
1136 	gdk_cairo_set_source_color (
1137 		cr,
1138 		&day_view->colors[E_DAY_VIEW_COLOR_BG_GRID]);
1139 
1140 	for (row = 0, row_y = 0 - y;
1141 	     row < day_view->rows && row_y < height;
1142 	     row++, row_y += day_view->row_height) {
1143 		if (row_y >= 0 && row_y < height) {
1144 			cairo_set_line_width (cr, 0.7);
1145 			cairo_move_to (cr, grid_x1, row_y);
1146 			cairo_line_to (cr, grid_x2, row_y);
1147 			cairo_stroke (cr);
1148 		}
1149 	}
1150 	cairo_restore (cr);
1151 
1152 	/* Draw the vertical bars down the left of each column. */
1153 	grid_y1 = 0;
1154 	grid_y2 = height;
1155 	for (day = 0; day < day_view->days_shown; day++) {
1156 		grid_x1 = day_view->day_offsets[day] - x;
1157 
1158 		/* Skip if it isn't visible. */
1159 		if (grid_x1 >= width || grid_x1 + E_DAY_VIEW_BAR_WIDTH <= 0)
1160 			continue;
1161 		cairo_save (cr);
1162 
1163 		gdk_cairo_set_source_color (
1164 			cr,
1165 			&day_view->colors[E_DAY_VIEW_COLOR_BG_GRID]);
1166 		cairo_move_to (cr, grid_x1, grid_y1);
1167 		cairo_line_to (cr, grid_x1, grid_y2);
1168 		cairo_stroke (cr);
1169 
1170 		gdk_cairo_set_source_color (
1171 			cr,
1172 			&day_view->colors[E_DAY_VIEW_COLOR_BG_GRID]);
1173 
1174 		cairo_move_to (cr, grid_x1 + E_DAY_VIEW_BAR_WIDTH - 1, grid_y1);
1175 		cairo_line_to (cr, grid_x1 + E_DAY_VIEW_BAR_WIDTH - 1, grid_y2);
1176 		cairo_stroke (cr);
1177 
1178 		cairo_set_source_rgb (cr, 1, 1, 1);
1179 
1180 		cairo_rectangle (
1181 			cr, grid_x1 + 1, grid_y1,
1182 			E_DAY_VIEW_BAR_WIDTH - 2, grid_y2 - grid_y1);
1183 
1184 		cairo_fill (cr);
1185 
1186 		cairo_restore (cr);
1187 
1188 		/* Fill in the bars when the user is busy. */
1189 		day_view_main_item_draw_events_in_vbars (
1190 			main_item, cr, x, y,
1191 			width, height, day, draw_region);
1192 	}
1193 
1194 	/* Fill in the vertical bars corresponding to the busy times from the
1195 	 * long events. */
1196 	day_view_main_item_draw_long_events_in_vbars (
1197 		main_item, cr, x, y, width, height, draw_region);
1198 
1199 	/* Draw the event borders and backgrounds, and the vertical bars
1200 	 * down the left edges. */
1201 	for (day = 0; day < day_view->days_shown; day++)
1202 		day_view_main_item_draw_day_events (
1203 			main_item, cr, x, y,
1204 			width, height, day, draw_region);
1205 
1206 	if (e_day_view_marcus_bains_get_show_line (day_view)) {
1207 		icaltimezone *zone;
1208 		struct icaltimetype time_now, day_start;
1209 		gint marcus_bains_y;
1210 		GdkColor mb_color;
1211 
1212 		cairo_save (cr);
1213 		gdk_cairo_set_source_color (
1214 			cr,
1215 			&day_view->colors[E_DAY_VIEW_COLOR_MARCUS_BAINS_LINE]);
1216 
1217 		if (day_view->marcus_bains_day_view_color && gdk_color_parse (day_view->marcus_bains_day_view_color, &mb_color)) {
1218 			gdk_cairo_set_source_color (cr, &mb_color);
1219 		}
1220 		zone = e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view));
1221 		time_now = icaltime_current_time_with_zone (zone);
1222 
1223 		for (day = 0; day < day_view->days_shown; day++) {
1224 			day_start = icaltime_from_timet_with_zone (day_view->day_starts[day], FALSE, zone);
1225 
1226 			if ((day_start.year  == time_now.year) &&
1227 			    (day_start.month == time_now.month) &&
1228 			    (day_start.day   == time_now.day)) {
1229 
1230 				grid_x1 = day_view->day_offsets[day] - x + E_DAY_VIEW_BAR_WIDTH;
1231 				grid_x2 = day_view->day_offsets[day + 1] - x - 1;
1232 				marcus_bains_y = (time_now.hour * 60 + time_now.minute) * day_view->row_height / time_divisions - y;
1233 				cairo_set_line_width (cr, 1.5);
1234 				cairo_move_to (cr, grid_x1, marcus_bains_y);
1235 				cairo_line_to (cr, grid_x2, marcus_bains_y);
1236 				cairo_stroke (cr);
1237 			}
1238 		}
1239 		cairo_restore (cr);
1240 	}
1241 	cairo_region_destroy (draw_region);
1242 }
1243 
1244 static GnomeCanvasItem *
1245 day_view_main_item_point (GnomeCanvasItem *item,
1246                           gdouble x,
1247                           gdouble y,
1248                           gint cx,
1249                           gint cy)
1250 {
1251 	return item;
1252 }
1253 
1254 static void
1255 e_day_view_main_item_class_init (EDayViewMainItemClass *class)
1256 {
1257 	GObjectClass *object_class;
1258 	GnomeCanvasItemClass *item_class;
1259 
1260 	g_type_class_add_private (class, sizeof (EDayViewMainItemPrivate));
1261 
1262 	object_class = G_OBJECT_CLASS (class);
1263 	object_class->set_property = day_view_main_item_set_property;
1264 	object_class->get_property = day_view_main_item_get_property;
1265 	object_class->dispose = day_view_main_item_dispose;
1266 
1267 	item_class = GNOME_CANVAS_ITEM_CLASS (class);
1268 	item_class->update = day_view_main_item_update;
1269 	item_class->draw = day_view_main_item_draw;
1270 	item_class->point = day_view_main_item_point;
1271 
1272 	g_object_class_install_property (
1273 		object_class,
1274 		PROP_DAY_VIEW,
1275 		g_param_spec_object (
1276 			"day-view",
1277 			"Day View",
1278 			NULL,
1279 			E_TYPE_DAY_VIEW,
1280 			G_PARAM_READWRITE));
1281 
1282 	/* init the accessibility support for e_day_view */
1283 	e_day_view_main_item_a11y_init ();
1284 }
1285 
1286 static void
1287 e_day_view_main_item_init (EDayViewMainItem *main_item)
1288 {
1289 	main_item->priv = E_DAY_VIEW_MAIN_ITEM_GET_PRIVATE (main_item);
1290 }
1291 
1292 EDayView *
1293 e_day_view_main_item_get_day_view (EDayViewMainItem *main_item)
1294 {
1295 	g_return_val_if_fail (E_IS_DAY_VIEW_MAIN_ITEM (main_item), NULL);
1296 
1297 	return main_item->priv->day_view;
1298 }
1299 
1300 void
1301 e_day_view_main_item_set_day_view (EDayViewMainItem *main_item,
1302                                    EDayView *day_view)
1303 {
1304 	g_return_if_fail (E_IS_DAY_VIEW_MAIN_ITEM (main_item));
1305 	g_return_if_fail (E_IS_DAY_VIEW (day_view));
1306 
1307 	if (main_item->priv->day_view == day_view)
1308 		return;
1309 
1310 	if (main_item->priv->day_view != NULL)
1311 		g_object_unref (main_item->priv->day_view);
1312 
1313 	main_item->priv->day_view = g_object_ref (day_view);
1314 
1315 	g_object_notify (G_OBJECT (main_item), "day-view");
1316 }