No issues found
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 |
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 }