No issues found
1 /*
2 * EWeekViewTitlesItem - displays the 'Monday', 'Tuesday' etc. at the top of
3 * the Month calendar view.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) version 3.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with the program; if not, see <http://www.gnu.org/licenses/>
17 *
18 * Authors:
19 * Damon Chaplin <damon@ximian.com>
20 *
21 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <string.h>
29 #include <e-util/e-util.h>
30 #include "e-week-view-titles-item.h"
31
32 #define E_WEEK_VIEW_TITLES_ITEM_GET_PRIVATE(obj) \
33 (G_TYPE_INSTANCE_GET_PRIVATE \
34 ((obj), E_TYPE_WEEK_VIEW_TITLES_ITEM, EWeekViewTitlesItemPrivate))
35
36 struct _EWeekViewTitlesItemPrivate {
37 EWeekView *week_view;
38 };
39
40 enum {
41 PROP_0,
42 PROP_WEEK_VIEW
43 };
44
45 G_DEFINE_TYPE (
46 EWeekViewTitlesItem,
47 e_week_view_titles_item,
48 GNOME_TYPE_CANVAS_ITEM)
49
50 static void
51 week_view_titles_item_set_property (GObject *object,
52 guint property_id,
53 const GValue *value,
54 GParamSpec *pspec)
55 {
56 switch (property_id) {
57 case PROP_WEEK_VIEW:
58 e_week_view_titles_item_set_week_view (
59 E_WEEK_VIEW_TITLES_ITEM (object),
60 g_value_get_object (value));
61 return;
62 }
63
64 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
65 }
66
67 static void
68 week_view_titles_item_get_property (GObject *object,
69 guint property_id,
70 GValue *value,
71 GParamSpec *pspec)
72 {
73 switch (property_id) {
74 case PROP_WEEK_VIEW:
75 g_value_set_object (
76 value,
77 e_week_view_titles_item_get_week_view (
78 E_WEEK_VIEW_TITLES_ITEM (object)));
79 return;
80 }
81
82 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
83 }
84
85 static void
86 week_view_titles_item_dispose (GObject *object)
87 {
88 EWeekViewTitlesItemPrivate *priv;
89
90 priv = E_WEEK_VIEW_TITLES_ITEM_GET_PRIVATE (object);
91
92 if (priv->week_view != NULL) {
93 g_object_unref (priv->week_view);
94 priv->week_view = NULL;
95 }
96
97 /* Chain up to parent's dispose() method. */
98 G_OBJECT_CLASS (e_week_view_titles_item_parent_class)->dispose (object);
99 }
100
101 static void
102 week_view_titles_item_update (GnomeCanvasItem *item,
103 const cairo_matrix_t *i2c,
104 gint flags)
105 {
106 GnomeCanvasItemClass *canvas_item_class;
107
108 /* Chain up to parent's update() method. */
109 canvas_item_class =
110 GNOME_CANVAS_ITEM_CLASS (e_week_view_titles_item_parent_class);
111 canvas_item_class->update (item, i2c, flags);
112
113 /* The item covers the entire canvas area. */
114 item->x1 = 0;
115 item->y1 = 0;
116 item->x2 = INT_MAX;
117 item->y2 = INT_MAX;
118 }
119
120 static void
121 week_view_titles_item_draw (GnomeCanvasItem *canvas_item,
122 cairo_t *cr,
123 gint x,
124 gint y,
125 gint width,
126 gint height)
127 {
128 EWeekViewTitlesItem *titles_item;
129 EWeekView *week_view;
130 GtkStyle *style;
131 gint col_width, col, date_width, date_x;
132 gchar buffer[128];
133 GtkAllocation allocation;
134 gboolean abbreviated;
135 gint weekday;
136 PangoLayout *layout;
137
138 titles_item = E_WEEK_VIEW_TITLES_ITEM (canvas_item);
139 week_view = e_week_view_titles_item_get_week_view (titles_item);
140 g_return_if_fail (week_view != NULL);
141
142 cairo_save (cr);
143 cairo_set_line_width (cr, 1.0);
144
145 gtk_widget_get_allocation (
146 GTK_WIDGET (canvas_item->canvas), &allocation);
147
148 style = gtk_widget_get_style (GTK_WIDGET (week_view));
149 layout = gtk_widget_create_pango_layout (GTK_WIDGET (week_view), NULL);
150
151 /* Draw the shadow around the dates. */
152 gdk_cairo_set_source_color (cr, &style->light[GTK_STATE_NORMAL]);
153 cairo_move_to (cr, 1.5 - x, 1.5 - y);
154 cairo_rel_line_to (cr, allocation.width - 1, 0);
155 cairo_move_to (cr, 1.5 - x, 2.5 - y);
156 cairo_rel_line_to (cr, 0, allocation.height - 1);
157 cairo_stroke (cr);
158
159 gdk_cairo_set_source_color (cr, &style->dark[GTK_STATE_NORMAL]);
160 cairo_rectangle (cr, 0.5 - x, 0.5 - y, allocation.width - 1, allocation.height);
161 cairo_stroke (cr);
162
163 /* Determine the format to use. */
164 col_width = allocation.width / week_view->columns;
165 abbreviated = (week_view->max_day_width + 2 >= col_width);
166
167 /* Shift right one pixel to account for the shadow around the main
168 * canvas. */
169 x--;
170
171 /* Draw the date. Set a clipping rectangle so we don't draw over the
172 * next day. */
173 weekday = week_view->display_start_day;
174 for (col = 0; col < week_view->columns; col++) {
175 if (weekday == 5 && week_view->compress_weekend)
176 g_snprintf (
177 buffer, sizeof (buffer), "%s/%s",
178 e_get_weekday_name (G_DATE_SATURDAY, TRUE),
179 e_get_weekday_name (G_DATE_SUNDAY, TRUE));
180 else
181 g_snprintf (
182 buffer, sizeof (buffer), "%s",
183 e_get_weekday_name (weekday + 1, abbreviated));
184
185 cairo_save (cr);
186
187 cairo_rectangle (
188 cr,
189 week_view->col_offsets[col] - x, 2 - y,
190 week_view->col_widths[col], allocation.height - 2);
191 cairo_clip (cr);
192
193 if (weekday == 5 && week_view->compress_weekend)
194 date_width = week_view->abbr_day_widths[5]
195 + week_view->slash_width
196 + week_view->abbr_day_widths[6];
197 else if (abbreviated)
198 date_width = week_view->abbr_day_widths[weekday];
199 else
200 date_width = week_view->day_widths[weekday];
201
202 date_x = week_view->col_offsets[col]
203 + (week_view->col_widths[col] - date_width) / 2;
204 date_x = MAX (date_x, week_view->col_offsets[col]);
205
206 pango_layout_set_text (layout, buffer, -1);
207 cairo_move_to (cr, date_x - x, 3 - y);
208 pango_cairo_show_layout (cr, layout);
209
210 cairo_restore (cr);
211
212 /* Draw the lines down the left and right of the date cols. */
213 if (col != 0) {
214 gdk_cairo_set_source_color (cr, &style->light[GTK_STATE_NORMAL]);
215 cairo_move_to (cr, week_view->col_offsets[col] - x + 0.5, 4.5 - y);
216 cairo_rel_line_to (cr, 0, allocation.height - 8);
217 cairo_stroke (cr);
218
219 gdk_cairo_set_source_color (cr, &style->dark[GTK_STATE_NORMAL]);
220 cairo_move_to (cr, week_view->col_offsets[col] - x - 0.5, 4.5 - y);
221 cairo_rel_line_to (cr, 0, allocation.height - 8);
222 cairo_stroke (cr);
223 }
224
225 /* Draw the lines between each column. */
226 if (col != 0) {
227 cairo_set_source_rgb (cr, 0, 0, 0);
228 cairo_rectangle (
229 cr, week_view->col_offsets[col] - x,
230 allocation.height - y, 1, 1);
231 cairo_fill (cr);
232 }
233
234 if (weekday == 5 && week_view->compress_weekend)
235 weekday += 2;
236 else
237 weekday++;
238
239 weekday = weekday % 7;
240 }
241
242 g_object_unref (layout);
243 cairo_restore (cr);
244 }
245
246 static GnomeCanvasItem *
247 week_view_titles_item_point (GnomeCanvasItem *item,
248 gdouble x,
249 gdouble y,
250 gint cx,
251 gint cy)
252 {
253 return item;
254 }
255
256 static void
257 e_week_view_titles_item_class_init (EWeekViewTitlesItemClass *class)
258 {
259 GObjectClass *object_class;
260 GnomeCanvasItemClass *item_class;
261
262 g_type_class_add_private (class, sizeof (EWeekViewTitlesItemPrivate));
263
264 object_class = G_OBJECT_CLASS (class);
265 object_class->set_property = week_view_titles_item_set_property;
266 object_class->get_property = week_view_titles_item_get_property;
267 object_class->dispose = week_view_titles_item_dispose;
268
269 item_class = GNOME_CANVAS_ITEM_CLASS (class);
270 item_class->update = week_view_titles_item_update;
271 item_class->draw = week_view_titles_item_draw;
272 item_class->point = week_view_titles_item_point;
273
274 g_object_class_install_property (
275 object_class,
276 PROP_WEEK_VIEW,
277 g_param_spec_object (
278 "week-view",
279 "Week View",
280 NULL,
281 E_TYPE_WEEK_VIEW,
282 G_PARAM_READWRITE));
283 }
284
285 static void
286 e_week_view_titles_item_init (EWeekViewTitlesItem *titles_item)
287 {
288 titles_item->priv = E_WEEK_VIEW_TITLES_ITEM_GET_PRIVATE (titles_item);
289 }
290
291 EWeekView *
292 e_week_view_titles_item_get_week_view (EWeekViewTitlesItem *titles_item)
293 {
294 g_return_val_if_fail (E_IS_WEEK_VIEW_TITLES_ITEM (titles_item), NULL);
295
296 return titles_item->priv->week_view;
297 }
298
299 void
300 e_week_view_titles_item_set_week_view (EWeekViewTitlesItem *titles_item,
301 EWeekView *week_view)
302 {
303 g_return_if_fail (E_IS_WEEK_VIEW_TITLES_ITEM (titles_item));
304 g_return_if_fail (E_IS_WEEK_VIEW (week_view));
305
306 if (titles_item->priv->week_view == week_view)
307 return;
308
309 if (titles_item->priv->week_view != NULL)
310 g_object_unref (titles_item->priv->week_view);
311
312 titles_item->priv->week_view = g_object_ref (week_view);
313
314 g_object_notify (G_OBJECT (titles_item), "week-view");
315 }