1 /*
2  * This program is free software; you can redistribute it and/or modify it
3  * under the terms of the GNU Lesser General Public License as published by
4  * the Free Software Foundation.
5  *
6  * This program is distributed in the hope that it will be useful, but
7  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
8  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
9  * for more details.
10  *
11  * You should have received a copy of the GNU Lesser General Public License
12  * along with this program; if not, see <http://www.gnu.org/licenses/>.
13  *
14  *
15  * Authors:
16  *		Bolian Yin <bolian.yin@sun.com>
17  *
18  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
19  *
20  */
21 
22 #include "evolution-config.h"
23 
24 #include "ea-week-view.h"
25 
26 #include <glib/gi18n.h>
27 
28 #include "ea-cal-view-event.h"
29 #include "ea-calendar-helpers.h"
30 #include "e-month-view.h"
31 
32 static const gchar * ea_week_view_get_name (AtkObject *accessible);
33 static const gchar * ea_week_view_get_description (AtkObject *accessible);
34 static gint         ea_week_view_get_n_children      (AtkObject *obj);
35 static AtkObject *   ea_week_view_ref_child           (AtkObject *obj,
36 						      gint i);
37 
38 static gpointer parent_class = NULL;
39 
G_DEFINE_TYPE(EaWeekView,ea_week_view,EA_TYPE_CAL_VIEW)40 G_DEFINE_TYPE (EaWeekView, ea_week_view, EA_TYPE_CAL_VIEW)
41 
42 static void
43 ea_week_view_init (EaWeekView *view)
44 {
45 }
46 
47 static void
ea_week_view_class_init(EaWeekViewClass * klass)48 ea_week_view_class_init (EaWeekViewClass *klass)
49 {
50 	AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
51 
52 	parent_class = g_type_class_peek_parent (klass);
53 
54 	class->get_name = ea_week_view_get_name;
55 	class->get_description = ea_week_view_get_description;
56 
57 	class->get_n_children = ea_week_view_get_n_children;
58 	class->ref_child = ea_week_view_ref_child;
59 }
60 
61 AtkObject *
ea_week_view_new(GtkWidget * widget)62 ea_week_view_new (GtkWidget *widget)
63 {
64 	GObject *object;
65 	AtkObject *accessible;
66 
67 	g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
68 
69 	object = g_object_new (EA_TYPE_WEEK_VIEW, NULL);
70 
71 	accessible = ATK_OBJECT (object);
72 	atk_object_initialize (accessible, widget);
73 
74 #ifdef ACC_DEBUG
75 	printf ("EvoAcc: ea_week_view created %p\n", (gpointer) accessible);
76 #endif
77 
78 	return accessible;
79 }
80 
81 static const gchar *
ea_week_view_get_name(AtkObject * accessible)82 ea_week_view_get_name (AtkObject *accessible)
83 {
84 	EWeekView *week_view;
85 	gchar *label_text;
86 	GtkWidget *widget;
87 	gint n_events;
88 	gchar *event_str, *name_str;
89 
90 	g_return_val_if_fail (EA_IS_WEEK_VIEW (accessible), NULL);
91 
92 	widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
93 	if (widget == NULL)
94 		return NULL;
95 
96 	week_view = E_WEEK_VIEW (widget);
97 
98 	label_text = e_calendar_view_get_description_text (E_CALENDAR_VIEW (week_view));
99 
100 	n_events = atk_object_get_n_accessible_children (accessible);
101 	/* the child main item is always there */
102 	--n_events;
103 	if (n_events >= 1)
104 		event_str = g_strdup_printf (
105 			ngettext ("It has %d event.", "It has %d events.",
106 			n_events), n_events);
107 	else
108 		event_str = g_strdup (_("It has no events."));
109 
110 	if (E_IS_MONTH_VIEW (week_view))
111 		name_str = g_strdup_printf (
112 			_("Month View: %s. %s"),
113 			label_text, event_str);
114 
115 	else
116 		name_str = g_strdup_printf (
117 			_("Week View: %s. %s"),
118 			label_text, event_str);
119 
120 	ATK_OBJECT_CLASS (parent_class)->set_name (accessible, name_str);
121 	g_free (name_str);
122 	g_free (event_str);
123 	g_free (label_text);
124 
125 	return accessible->name;
126 }
127 
128 static const gchar *
ea_week_view_get_description(AtkObject * accessible)129 ea_week_view_get_description (AtkObject *accessible)
130 {
131 	EWeekView *week_view;
132 	GtkWidget *widget;
133 
134 	g_return_val_if_fail (EA_IS_WEEK_VIEW (accessible), NULL);
135 
136 	widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
137 	if (widget == NULL)
138 		return NULL;
139 
140 	week_view = E_WEEK_VIEW (widget);
141 
142 	if (accessible->description)
143 		return accessible->description;
144 	else {
145 		if (E_IS_MONTH_VIEW (week_view))
146 			return _("calendar view for a month");
147 		else
148 			return _("calendar view for one or more weeks");
149 	}
150 }
151 
152 static gint
ea_week_view_get_n_children(AtkObject * accessible)153 ea_week_view_get_n_children (AtkObject *accessible)
154 {
155 	EWeekView *week_view;
156 	GtkWidget *widget;
157 	gint i, count = 0;
158 	gint event_index;
159 
160 	g_return_val_if_fail (EA_IS_WEEK_VIEW (accessible), -1);
161 
162 	widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
163 	if (widget == NULL)
164 		return -1;
165 
166 	week_view = E_WEEK_VIEW (widget);
167 
168 	for (event_index = 0; event_index < week_view->events->len;
169 	     ++event_index) {
170 		EWeekViewEvent *event;
171 		EWeekViewEventSpan *span;
172 
173                 /* If week_view->spans == NULL, there is no visible events. */
174 		if (!week_view->spans)
175 			break;
176 
177 		event = &g_array_index (week_view->events,
178 					EWeekViewEvent, event_index);
179 		if (event->spans_index >= 0 && event->spans_index < week_view->spans->len) {
180 			span = &g_array_index (week_view->spans, EWeekViewEventSpan,
181 					       event->spans_index + 0);
182 
183 			/* at least one of the event spans is visible, count it */
184 			if (span->text_item)
185 				++count;
186 		}
187 	}
188 
189 	/* add the number of visible jump buttons */
190 	for (i = 0; i < E_WEEK_VIEW_MAX_WEEKS * 7; i++) {
191 		if (week_view->jump_buttons[i]->flags & GNOME_CANVAS_ITEM_VISIBLE)
192 			++count;
193 	}
194 
195 	/* "+1" for the main item */
196 	count++;
197 
198 #ifdef ACC_DEBUG
199 	printf ("AccDebug: week view %p has %d children\n", (gpointer) week_view, count);
200 #endif
201 	return count;
202 }
203 
204 static AtkObject *
ea_week_view_ref_child(AtkObject * accessible,gint index)205 ea_week_view_ref_child (AtkObject *accessible,
206                         gint index)
207 {
208 	EWeekView *week_view;
209 	gint child_num, max_count;
210 	AtkObject *atk_object = NULL;
211 	GtkWidget *widget;
212 	gint event_index;
213 	gint jump_button = -1;
214 	gint span_num = 0;
215 	gint count = 0;
216 
217 	g_return_val_if_fail (EA_IS_WEEK_VIEW (accessible), NULL);
218 
219 	child_num = atk_object_get_n_accessible_children (accessible);
220 	if (child_num <= 0 || index < 0 || index >= child_num)
221 		return NULL;
222 
223 	widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
224 	if (widget == NULL)
225 		return NULL;
226 
227 	week_view = E_WEEK_VIEW (widget);
228 	max_count = week_view->events->len;
229 
230 	if (index == 0) {
231 		/* index == 0 is the main item */
232 		atk_object = atk_gobject_accessible_for_object (
233 			G_OBJECT (week_view->main_canvas_item));
234 		g_object_ref (atk_object);
235 	} else
236 	for (event_index = 0; event_index < max_count; ++event_index) {
237 		EWeekViewEvent *event;
238 		EWeekViewEventSpan *span;
239 		gint current_day;
240 
241 		event = &g_array_index (week_view->events,
242 					EWeekViewEvent, event_index);
243 
244 		if (event->spans_index < 0 || !week_view->spans || event->spans_index >= week_view->spans->len)
245 			continue;
246 
247 		span = &g_array_index (week_view->spans, EWeekViewEventSpan,
248 				       event->spans_index + span_num);
249 
250 		current_day = span->start_day;
251 		if (span->text_item)
252 			++count;
253 		else if  (current_day != jump_button) {
254 			/* we should go to the jump button */
255 			jump_button = current_day;
256 			++count;
257 		}
258 		else
259 			continue;
260 
261 		if (count == index) {
262 			if (span->text_item) {
263 				/* Not use atk_gobject_accessible_for_object for event
264 				 * text_item we need to do special thing here
265 				 */
266 				atk_object =
267 					ea_calendar_helpers_get_accessible_for (
268 					span->text_item);
269 			} else {
270 				gint jump_index;
271 
272 				jump_index = (current_day != -1) ? current_day : 0;
273 				atk_object =
274 					ea_calendar_helpers_get_accessible_for (
275 					week_view->jump_buttons[jump_index]);
276 			}
277 			g_object_ref (atk_object);
278 			break;
279 		}
280 	}
281 
282 #ifdef ACC_DEBUG
283 	printf (
284 		"EvoAcc: ea_week_view_ref_child [%d]=%p\n",
285 		index, (gpointer) atk_object);
286 #endif
287 	return atk_object;
288 }
289