Merge lp:~eeejay/notify-osd/text_iface into lp:notify-osd/trunk

Proposed by Eitan Isaacson
Status: Merged
Merged at revision: not available
Proposed branch: lp:~eeejay/notify-osd/text_iface
Merge into: lp:notify-osd/trunk
Diff against target: None lines
To merge this branch: bzr merge lp:~eeejay/notify-osd/text_iface
Reviewer Review Type Date Requested Status
Notify OSD Developers Pending
Review via email: mp+5919@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Eitan Isaacson (eeejay) wrote :

This branch adds a text interface and relevant AT-SPI events for dynamic bubble messages and titles.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/bubble-window-accessible.c'
2--- src/bubble-window-accessible.c 2009-02-27 20:00:53 +0000
3+++ src/bubble-window-accessible.c 2009-04-27 08:45:53 +0000
4@@ -37,6 +37,7 @@
5 static void bubble_window_real_initialize (AtkObject* obj,
6 gpointer data);
7 static void atk_value_interface_init (AtkValueIface* iface);
8+static void atk_text_interface_init (AtkTextIface* iface);
9 static void bubble_window_get_current_value (AtkValue* obj,
10 GValue* value);
11 static void bubble_window_get_maximum_value (AtkValue* obj,
12@@ -46,6 +47,19 @@
13 static void bubble_value_changed_event (Bubble* bubble,
14 gint value,
15 AtkObject *obj);
16+static void bubble_message_body_deleted_event (Bubble* bubble,
17+ const gchar* text,
18+ AtkObject* obj);
19+static void bubble_message_body_inserted_event (Bubble* bubble,
20+ const gchar* text,
21+ AtkObject* obj);
22+
23+static gchar* bubble_window_get_text (AtkText *obj,
24+ gint start_offset,
25+ gint end_offset);
26+static gint bubble_window_get_character_count (AtkText *obj);
27+static gunichar bubble_window_get_character_at_offset (AtkText *obj,
28+ gint offset);
29
30 static void* bubble_window_accessible_parent_class;
31
32@@ -76,6 +90,13 @@
33 (GInterfaceFinalizeFunc) NULL,
34 NULL
35 };
36+
37+ const GInterfaceInfo atk_text_info =
38+ {
39+ (GInterfaceInitFunc) atk_text_interface_init,
40+ (GInterfaceFinalizeFunc) NULL,
41+ NULL
42+ };
43
44 /*
45 * Figure out the size of the class and instance
46@@ -100,6 +121,8 @@
47 "BubbleWindowAccessible", &tinfo, 0);
48
49 g_type_add_interface_static (type, ATK_TYPE_VALUE, &atk_value_info);
50+
51+ g_type_add_interface_static (type, ATK_TYPE_TEXT, &atk_text_info);
52 }
53
54 return type;
55@@ -116,6 +139,17 @@
56 }
57
58 static void
59+atk_text_interface_init (AtkTextIface* iface)
60+{
61+ g_return_if_fail (iface != NULL);
62+
63+ iface->get_text = bubble_window_get_text;
64+ iface->get_character_count = bubble_window_get_character_count;
65+ iface->get_character_at_offset = bubble_window_get_character_at_offset;
66+
67+}
68+
69+static void
70 bubble_window_accessible_init (BubbleWindowAccessible *object)
71 {
72 /* TODO: Add initialization code here */
73@@ -160,6 +194,16 @@
74 G_CALLBACK (bubble_value_changed_event),
75 obj);
76
77+ g_signal_connect (bubble,
78+ "message-body-deleted",
79+ G_CALLBACK (bubble_message_body_deleted_event),
80+ obj);
81+
82+ g_signal_connect (bubble,
83+ "message-body-inserted",
84+ G_CALLBACK (bubble_message_body_inserted_event),
85+ obj);
86+
87 }
88
89 AtkObject*
90@@ -286,3 +330,108 @@
91 {
92 g_object_notify (G_OBJECT (obj), "accessible-value");
93 }
94+
95+static void
96+bubble_message_body_deleted_event (Bubble* bubble,
97+ const gchar* text,
98+ AtkObject* obj)
99+{
100+ /* Not getting very fancy here, delete is always complete */
101+ g_signal_emit_by_name (
102+ obj, "text_changed::delete", 0, g_utf8_strlen (text, -1));
103+}
104+
105+static void
106+bubble_message_body_inserted_event (Bubble* bubble,
107+ const gchar* text,
108+ AtkObject* obj)
109+{
110+ const gchar* message_body;
111+
112+ message_body = bubble_get_message_body (bubble);
113+
114+ g_signal_emit_by_name (
115+ obj, "text_changed::insert",
116+ g_utf8_strlen (message_body, -1) - g_utf8_strlen (text, -1),
117+ g_utf8_strlen (message_body, -1));
118+}
119+
120+static gchar*
121+bubble_window_get_text (AtkText *obj,
122+ gint start_offset,
123+ gint end_offset)
124+{
125+ GtkAccessible* accessible;
126+ Bubble* bubble;
127+ const gchar* body_text;
128+ gsize char_length;
129+ glong body_strlen;
130+
131+ g_return_val_if_fail (BUBBLE_WINDOW_IS_ACCESSIBLE (obj), g_strdup(""));
132+
133+ accessible = GTK_ACCESSIBLE (obj);
134+
135+ g_return_val_if_fail (accessible->widget == NULL, g_strdup(""));
136+
137+ bubble = g_object_get_data (G_OBJECT(accessible->widget), "bubble");
138+
139+ if (end_offset <= start_offset)
140+ return g_strdup("");
141+
142+ body_text = bubble_get_message_body (bubble);
143+
144+ body_strlen = g_utf8_strlen(body_text, -1);
145+
146+ if (start_offset > body_strlen)
147+ start_offset = body_strlen;
148+
149+ if (end_offset > body_strlen || end_offset == -1)
150+ end_offset = body_strlen;
151+
152+
153+ char_length = g_utf8_offset_to_pointer (body_text, end_offset) -
154+ g_utf8_offset_to_pointer (body_text, start_offset);
155+
156+ return g_strndup (g_utf8_offset_to_pointer(body_text, start_offset),
157+ char_length);
158+}
159+
160+static gint
161+bubble_window_get_character_count (AtkText *obj)
162+{
163+ GtkAccessible* accessible;
164+ Bubble* bubble;
165+
166+ g_return_val_if_fail (BUBBLE_WINDOW_IS_ACCESSIBLE (obj), 0);
167+
168+ accessible = GTK_ACCESSIBLE (obj);
169+
170+ if (accessible->widget == NULL)
171+ return 0;
172+
173+ bubble = g_object_get_data (G_OBJECT(accessible->widget), "bubble");
174+
175+ return g_utf8_strlen(bubble_get_message_body (bubble), -1);
176+}
177+
178+static gunichar
179+bubble_window_get_character_at_offset (AtkText *obj,
180+ gint offset)
181+{
182+ GtkAccessible* accessible;
183+ Bubble* bubble;
184+ const gchar* body_text;
185+
186+ g_return_val_if_fail (BUBBLE_WINDOW_IS_ACCESSIBLE (obj), 0);
187+
188+ accessible = GTK_ACCESSIBLE (obj);
189+
190+ if (accessible->widget == NULL)
191+ return 0;
192+
193+ bubble = g_object_get_data (G_OBJECT(accessible->widget), "bubble");
194+
195+ body_text = bubble_get_message_body (bubble);
196+
197+ return g_utf8_get_char (g_utf8_offset_to_pointer (body_text, offset));
198+}
199
200=== modified file 'src/bubble.c'
201--- src/bubble.c 2009-04-16 14:13:47 +0000
202+++ src/bubble.c 2009-04-27 08:54:00 +0000
203@@ -94,6 +94,8 @@
204 {
205 TIMED_OUT,
206 VALUE_CHANGED,
207+ MESSAGE_BODY_DELETED,
208+ MESSAGE_BODY_INSERTED,
209 LAST_SIGNAL
210 };
211
212@@ -1903,6 +1905,30 @@
213 G_TYPE_NONE,
214 1,
215 G_TYPE_INT);
216+
217+ g_bubble_signals[MESSAGE_BODY_DELETED] = g_signal_new (
218+ "message-body-deleted",
219+ G_OBJECT_CLASS_TYPE (gobject_class),
220+ G_SIGNAL_RUN_LAST,
221+ G_STRUCT_OFFSET (BubbleClass, message_body_deleted),
222+ NULL,
223+ NULL,
224+ g_cclosure_marshal_VOID__STRING,
225+ G_TYPE_NONE,
226+ 1,
227+ G_TYPE_STRING);
228+
229+ g_bubble_signals[MESSAGE_BODY_INSERTED] = g_signal_new (
230+ "message-body-inserted",
231+ G_OBJECT_CLASS_TYPE (gobject_class),
232+ G_SIGNAL_RUN_LAST,
233+ G_STRUCT_OFFSET (BubbleClass, message_body_inserted),
234+ NULL,
235+ NULL,
236+ g_cclosure_marshal_VOID__STRING,
237+ G_TYPE_NONE,
238+ 1,
239+ G_TYPE_STRING);
240 }
241
242 /*-- public API --------------------------------------------------------------*/
243@@ -2066,6 +2092,10 @@
244 g_string_free (priv->title, TRUE);
245
246 priv->title = g_string_new (title);
247+
248+ g_object_notify (
249+ G_OBJECT (gtk_widget_get_accessible (GET_PRIVATE(self)->widget)),
250+ "accessible-name");
251 }
252
253 const gchar*
254@@ -2089,13 +2119,20 @@
255
256 priv = GET_PRIVATE (self);
257
258- if (priv->message_body->len != 0)
259+ if (priv->message_body->len != 0) {
260+ g_signal_emit (self, g_bubble_signals[MESSAGE_BODY_DELETED],
261+ 0, priv->message_body->str);
262 g_string_free (priv->message_body, TRUE);
263-
264+ }
265 /* filter out any HTML/markup if possible */
266 text = filter_text (body);
267
268 priv->message_body = g_string_new (text);
269+
270+ g_signal_emit (self, g_bubble_signals[MESSAGE_BODY_INSERTED], 0, text);
271+ g_object_notify (G_OBJECT (gtk_widget_get_accessible (priv->widget)),
272+ "accessible-description");
273+
274 g_free (text);
275 }
276
277@@ -3387,6 +3424,12 @@
278 /* append text to current message-body */
279 g_string_append (GET_PRIVATE (self)->message_body, text);
280
281+ g_signal_emit (self, g_bubble_signals[MESSAGE_BODY_INSERTED], 0, text);
282+
283+ g_object_notify (
284+ G_OBJECT (gtk_widget_get_accessible (GET_PRIVATE(self)->widget)),
285+ "accessible-description");
286+
287 g_free ((gpointer) text);
288 }
289
290
291=== modified file 'src/bubble.h'
292--- src/bubble.h 2009-04-09 10:44:07 +0000
293+++ src/bubble.h 2009-04-23 15:22:58 +0000
294@@ -76,6 +76,8 @@
295 /*< signals >*/
296 void (*timed_out) (Bubble* bubble);
297 void (*value_changed) (Bubble* bubble);
298+ void (*message_body_deleted) (Bubble* bubble);
299+ void (*message_body_inserted) (Bubble* bubble);
300 };
301
302 GType bubble_get_type (void);

Subscribers

People subscribed via source and target branches