Mercurial > projects > dwt-linux
annotate dwt/accessibility/AccessibleObject.d @ 55:93981635e709
Checked and inserted missing default switch cases.
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Fri, 11 Jan 2008 15:40:16 +0100 |
parents | 8f049b136add |
children | 8cec8f536af3 |
rev | line source |
---|---|
42 | 1 /******************************************************************************* |
2 * Copyright (c) 2000, 2007 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 *******************************************************************************/ | |
11 module dwt.accessibility.AccessibleObject; | |
12 | |
13 import dwt.internal.accessibility.gtk.ATK; | |
14 import dwt.internal.gtk.OS; | |
15 import dwt.accessibility.Accessible; | |
16 import dwt.accessibility.AccessibleListener; | |
17 import dwt.accessibility.AccessibleControlListener; | |
18 import dwt.accessibility.AccessibleTextListener; | |
19 import dwt.accessibility.AccessibleEvent; | |
20 import dwt.accessibility.AccessibleControlEvent; | |
21 import dwt.accessibility.AccessibleTextEvent; | |
22 import dwt.accessibility.ACC; | |
23 import dwt.accessibility.AccessibleFactory; | |
24 import dwt.widgets.Display; | |
25 import dwt.dwthelper.Integer; | |
26 import tango.io.Stdout; | |
27 import tango.stdc.stringz; | |
28 import tango.text.Util; | |
29 import Math = tango.math.Math; | |
30 | |
31 class AccessibleObject { | |
32 AtkObject* handle; | |
33 int /*long*/ parentType; | |
34 int index = -1, id = ACC.CHILDID_SELF; | |
35 Accessible accessible; | |
36 AccessibleObject parent; | |
37 AccessibleObject[AtkObject*] children; | |
38 /* | |
39 * a lightweight object does not correspond to a concrete gtk widget, but | |
40 * to a logical child of a widget (eg.- a CTabItem, which is simply drawn) | |
41 */ | |
42 bool isLightweight = false; | |
43 | |
44 static char[] actionNamePtr; | |
45 static char[] descriptionPtr; | |
46 static char[] keybindingPtr; | |
47 static char[] namePtr; | |
48 static AccessibleObject[AtkObject*] AccessibleObjects; | |
54 | 49 static /*const*/ uint ATK_ACTION_TYPE; |
50 static /*const*/ uint ATK_COMPONENT_TYPE; | |
51 static /*const*/ uint ATK_HYPERTEXT_TYPE; | |
52 static /*const*/ uint ATK_SELECTION_TYPE; | |
53 static /*const*/ uint ATK_TEXT_TYPE; | |
54 static /*const*/ bool DEBUG; | |
42 | 55 |
54 | 56 public static void static_this() { |
42 | 57 DEBUG = Display.DEBUG; |
58 ATK_ACTION_TYPE = ATK.g_type_from_name ("AtkAction"); | |
59 ATK_COMPONENT_TYPE = ATK.g_type_from_name ("AtkComponent"); | |
60 ATK_HYPERTEXT_TYPE = ATK.g_type_from_name ("AtkHypertext"); | |
61 ATK_SELECTION_TYPE = ATK.g_type_from_name ("AtkSelection"); | |
62 ATK_TEXT_TYPE = ATK.g_type_from_name ("AtkText"); | |
63 } | |
64 | |
65 this (int /*long*/ type, GtkWidget* widget, Accessible accessible, int /*long*/ parentType, bool isLightweight) { | |
66 handle = cast(AtkObject*)ATK.g_object_new (type, null); | |
67 this.parentType = parentType; | |
68 ATK.atk_object_initialize (handle, widget); | |
69 this.accessible = accessible; | |
70 this.isLightweight = isLightweight; | |
71 AccessibleObjects[handle] = this; | |
72 if (DEBUG) Stdout.formatln("new AccessibleObject: {}", handle); | |
73 } | |
74 | |
75 void addChild (AccessibleObject child) { | |
76 children[child.handle] = child; | |
77 child.setParent (this); | |
78 } | |
79 | |
80 package static extern(C) char* atkAction_get_keybinding (void* obj, int index) { | |
81 auto atkObject = cast(AtkObject*)obj; | |
82 if (DEBUG) Stdout.formatln ("-->atkAction_get_keybinding"); | |
83 AccessibleObject object = getAccessibleObject (atkObject); | |
84 if (object is null) return null; | |
85 char* parentResult; | |
86 if (ATK.g_type_is_a (object.parentType, ATK_ACTION_TYPE)) { | |
87 auto superType = cast(AtkActionIface*)ATK.g_type_interface_peek_parent (ATK.ATK_ACTION_GET_IFACE (object.handle)); | |
88 AtkActionIface* actionIface = superType; | |
89 if (actionIface.get_keybinding !is null) { | |
90 parentResult = actionIface.get_keybinding( object.handle, index ); | |
91 } | |
92 } | |
93 AccessibleListener[] listeners = object.getAccessibleListeners (); | |
94 if (listeners.length is 0) return parentResult; | |
95 | |
96 AccessibleEvent event = new AccessibleEvent (object); | |
97 event.childID = object.id; | |
98 if (parentResult !is null) { | |
99 char[] res = fromUtf8z( parentResult ); | |
100 event.result = res.dup; | |
101 } | |
102 for (int i = 0; i < listeners.length; i++) { | |
103 listeners [i].getKeyboardShortcut (event); | |
104 } | |
105 if (event.result is null) return parentResult; | |
106 if (keybindingPtr !is null ) OS.g_free (keybindingPtr.ptr); | |
107 char[] name = event.result.dup ~ \0; | |
108 char* p = cast(char*) OS.g_malloc (name.length); | |
109 keybindingPtr = p ? p[ 0 .. name.length ] : null; | |
110 return keybindingPtr.ptr; | |
111 } | |
112 | |
113 package static extern(C) char* atkAction_get_name (void* obj, int index) { | |
114 auto atkObject = cast(AtkObject*)obj; | |
115 if (DEBUG) Stdout.formatln ("-->atkAction_get_name"); | |
116 AccessibleObject object = getAccessibleObject (atkObject); | |
117 if (object is null) return null; | |
118 char* parentResult; | |
119 if (ATK.g_type_is_a (object.parentType, ATK_ACTION_TYPE)) { | |
120 auto actionIface = cast(AtkActionIface*)ATK.g_type_interface_peek_parent (ATK.ATK_ACTION_GET_IFACE (object.handle)); | |
121 if (actionIface.get_name !is null) { | |
122 parentResult = actionIface.get_name( object.handle, index); | |
123 } | |
124 } | |
125 AccessibleControlListener[] listeners = object.getControlListeners (); | |
126 if (listeners.length is 0) return parentResult; | |
127 | |
128 AccessibleControlEvent event = new AccessibleControlEvent (object); | |
129 event.childID = object.id; | |
130 if (parentResult !is null) { | |
131 char[] res = fromUtf8z( parentResult ); | |
132 event.result = res.dup; | |
133 } | |
134 for (int i = 0; i < listeners.length; i++) { | |
135 listeners [i].getDefaultAction (event); | |
136 } | |
137 if (event.result is null) return parentResult; | |
138 if (actionNamePtr !is null) OS.g_free (actionNamePtr.ptr); | |
139 | |
140 char[] name = event.result.dup ~ \0; | |
141 auto p = cast(char*)OS.g_malloc (name.length); | |
142 actionNamePtr = p ? p[ 0 .. name.length ] : null; | |
143 return actionNamePtr.ptr; | |
144 } | |
145 | |
146 package static extern(C) void atkComponent_get_extents (void* obj, int* x, int* y, int* width, int* height, int coord_type) { | |
147 auto atkObject = cast(AtkObject*)obj; | |
148 if (DEBUG) Stdout.formatln ("-->atkComponent_get_extents"); | |
149 AccessibleObject object = getAccessibleObject (atkObject); | |
150 if (object is null) return 0; | |
151 *x = 0; | |
152 *y = 0; | |
153 *width = 0; | |
154 *height = 0; | |
155 if (ATK.g_type_is_a (object.parentType, ATK_COMPONENT_TYPE)) { | |
156 auto componentIface = cast(AtkComponentIface*) ATK.g_type_interface_peek_parent (ATK.ATK_COMPONENT_GET_IFACE (object.handle)); | |
157 if (componentIface.get_extents !is null) { | |
158 componentIface.get_extents( object.handle, x, y, width, height, coord_type); | |
159 } | |
160 } | |
161 AccessibleControlListener[] listeners = object.getControlListeners (); | |
162 if (listeners.length is 0) return 0; | |
163 | |
164 int parentX = *x, parentY = *y; | |
165 int parentWidth = *width, parentHeight = *height; | |
166 AccessibleControlEvent event = new AccessibleControlEvent (object); | |
167 event.childID = object.id; | |
168 event.x = parentX; event.y = parentY; | |
169 event.width = parentWidth; event.height = parentHeight; | |
170 if (coord_type is ATK.ATK_XY_WINDOW) { | |
171 /* translate control -> display, for filling in event to be dispatched */ | |
172 auto gtkAccessible = ATK.GTK_ACCESSIBLE (object.handle); | |
173 auto topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget); | |
174 auto window = OS.GTK_WIDGET_WINDOW (topLevel); | |
175 int topWindowX, topWindowY; | |
176 OS.gdk_window_get_origin (window, &topWindowX, &topWindowY); | |
177 event.x += topWindowX; | |
178 event.y += topWindowY; | |
179 } | |
180 for (int i = 0; i < listeners.length; i++) { | |
181 listeners [i].getLocation (event); | |
182 } | |
183 if (coord_type is ATK.ATK_XY_WINDOW) { | |
184 /* translate display -> control, for answering to the OS */ | |
185 auto gtkAccessible = ATK.GTK_ACCESSIBLE (object.handle); | |
186 auto topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget); | |
187 auto window = OS.GTK_WIDGET_WINDOW (topLevel); | |
188 int topWindowX, topWindowY; | |
189 OS.gdk_window_get_origin (window, &topWindowX, &topWindowY); | |
190 event.x -= topWindowX; | |
191 event.y -= topWindowY; | |
192 } | |
193 *x = event.x; | |
194 *y = event.y; | |
195 *width = event.width; | |
196 *height = event.height; | |
197 //return 0; | |
198 } | |
199 | |
200 package static extern(C) void atkComponent_get_position (void* obj, int* x, int* y, int coord_type) { | |
201 auto atkObject = cast(AtkObject*)obj; | |
202 if (DEBUG) Stdout.formatln ("-->atkComponent_get_position, object: {} x:{} y:{} coord:{}", atkObject, x, y, coord_type); | |
203 AccessibleObject object = getAccessibleObject (atkObject); | |
204 if (object is null) return 0; | |
205 *x=0; | |
206 *y=0; | |
207 if (ATK.g_type_is_a (object.parentType, ATK_COMPONENT_TYPE)) { | |
208 auto componentIface = cast(AtkComponentIface*)ATK.g_type_interface_peek_parent (ATK.ATK_COMPONENT_GET_IFACE (object.handle)); | |
209 if (componentIface.get_extents !is null) { | |
210 componentIface.get_position( object.handle, x, y, coord_type); | |
211 } | |
212 } | |
213 AccessibleControlListener[] listeners = object.getControlListeners (); | |
214 if (listeners.length is 0) return 0; | |
215 | |
216 int parentX, parentY; | |
217 parentX = *x; | |
218 parentY = *y; | |
219 AccessibleControlEvent event = new AccessibleControlEvent (object); | |
220 event.childID = object.id; | |
221 event.x = parentX; event.y = parentY; | |
222 if (coord_type is ATK.ATK_XY_WINDOW) { | |
223 /* translate control -> display, for filling in event to be dispatched */ | |
224 auto gtkAccessible = ATK.GTK_ACCESSIBLE (object.handle); | |
225 auto topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget); | |
226 auto window = OS.GTK_WIDGET_WINDOW (topLevel); | |
227 int topWindowX, topWindowY; | |
228 OS.gdk_window_get_origin (window, &topWindowX, &topWindowY); | |
229 event.x += topWindowX; | |
230 event.y += topWindowY; | |
231 } | |
232 for (int i = 0; i < listeners.length; i++) { | |
233 listeners [i].getLocation (event); | |
234 } | |
235 if (coord_type is ATK.ATK_XY_WINDOW) { | |
236 /* translate display -> control, for answering to the OS */ | |
237 auto gtkAccessible = ATK.GTK_ACCESSIBLE (object.handle); | |
238 auto topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget); | |
239 auto window = OS.GTK_WIDGET_WINDOW (topLevel); | |
240 int topWindowX, topWindowY; | |
241 OS.gdk_window_get_origin (window, &topWindowX, &topWindowY); | |
242 event.x -= topWindowX; | |
243 event.y -= topWindowY; | |
244 } | |
245 *x=event.x; | |
246 *y=event.y; | |
247 //return 0; | |
248 } | |
249 | |
250 //PORTING_FIXME: what about the coord_type? componentIface.get_size( object.handle, width, height, coord_type); | |
251 //package static extern(C) void atkComponent_get_size (void* obj, int* width, int* height, int coord_type) { | |
252 package static extern(C) void atkComponent_get_size (void* obj, int* width, int* height) { | |
253 auto atkObject = cast(AtkObject*)obj; | |
254 if (DEBUG) Stdout.formatln ("-->atkComponent_get_size"); | |
255 AccessibleObject object = getAccessibleObject (atkObject); | |
256 if (object is null) return 0; | |
257 *width=0; | |
258 *height=0; | |
259 if (ATK.g_type_is_a (object.parentType, ATK_COMPONENT_TYPE)) { | |
260 auto componentIface = cast(AtkComponentIface*)ATK.g_type_interface_peek_parent (ATK.ATK_COMPONENT_GET_IFACE (object.handle)); | |
261 if (componentIface.get_extents !is null) { | |
262 //PORTING_FIXME: what about the coord_type? componentIface.get_size( object.handle, width, height, coord_type); | |
263 componentIface.get_size( object.handle, width, height); | |
264 } | |
265 } | |
266 AccessibleControlListener[] listeners = object.getControlListeners (); | |
267 if (listeners.length is 0) return 0; | |
268 | |
269 int parentWidth, parentHeight; | |
270 parentWidth= *width; | |
271 parentHeight= *height; | |
272 AccessibleControlEvent event = new AccessibleControlEvent (object); | |
273 event.childID = object.id; | |
274 event.width = parentWidth; event.height = parentHeight; | |
275 for (int i = 0; i < listeners.length; i++) { | |
276 listeners [i].getLocation (event); | |
277 } | |
278 *width=event.width; | |
279 *height=event.height; | |
280 //return 0; | |
281 } | |
282 | |
283 package static extern(C) AtkObject* atkComponent_ref_accessible_at_point (void* obj, int x, int y, int coord_type) { | |
284 auto atkObject = cast(AtkObject*)obj; | |
285 if (DEBUG) Stdout.formatln ("-->atkComponent_ref_accessible_at_point"); | |
286 AccessibleObject object = getAccessibleObject (atkObject); | |
287 if (object is null) return null; | |
288 AtkObject* parentResult; | |
289 if (ATK.g_type_is_a (object.parentType, ATK_COMPONENT_TYPE)) { | |
290 auto componentIface = cast(AtkComponentIface*)ATK.g_type_interface_peek_parent (ATK.ATK_COMPONENT_GET_IFACE (object.handle)); | |
291 if (componentIface.ref_accessible_at_point !is null) { | |
292 parentResult = componentIface.ref_accessible_at_point( object.handle, x, y, coord_type); | |
293 } | |
294 } | |
295 AccessibleControlListener[] listeners = object.getControlListeners (); | |
296 if (listeners.length is 0) return parentResult; | |
297 | |
298 AccessibleControlEvent event = new AccessibleControlEvent (object); | |
299 event.childID = object.id; | |
300 event.x = x; event.y = y; | |
301 if (coord_type is ATK.ATK_XY_WINDOW) { | |
302 /* translate control -> display, for filling in the event to be dispatched */ | |
303 auto gtkAccessible = ATK.GTK_ACCESSIBLE (object.handle); | |
304 auto topLevel = ATK.gtk_widget_get_toplevel (gtkAccessible.widget); | |
305 auto window = OS.GTK_WIDGET_WINDOW (topLevel); | |
306 int topWindowX, topWindowY; | |
307 OS.gdk_window_get_origin (window, &topWindowX, &topWindowY); | |
308 event.x += topWindowX; | |
309 event.y += topWindowY; | |
310 } | |
311 for (int i = 0; i < listeners.length; i++) { | |
312 listeners [i].getChildAtPoint (event); | |
313 } | |
314 if (event.childID is object.id) event.childID = ACC.CHILDID_SELF; | |
315 AccessibleObject accObj = object.getChildByID (event.childID); | |
316 if (accObj !is null) { | |
317 if (parentResult !is null) OS.g_object_unref (parentResult); | |
318 OS.g_object_ref (accObj.handle); | |
319 return accObj.handle; | |
320 } | |
321 return parentResult; | |
322 } | |
323 | |
324 package static extern(C) AtkHyperlink* atkHypertext_get_link (void* obj, int link_index) { | |
325 auto atkObject = cast(AtkObject*)obj; | |
326 if (DEBUG) Stdout.formatln ("-->atkHypertext_get_link"); | |
327 return null; | |
328 } | |
329 | |
330 package static extern(C) int atkHypertext_get_n_links (void* obj) { | |
331 auto atkObject = cast(AtkObject*)obj; | |
332 if (DEBUG) Stdout.formatln ("-->atkHypertext_get_n_links"); | |
333 return 0; /* read hyperlink's name */ | |
334 } | |
335 | |
336 package static extern(C) int atkHypertext_get_link_index (void* obj, int char_index) { | |
337 auto atkObject = cast(AtkObject*)obj; | |
338 if (DEBUG) Stdout.formatln ("-->atkHypertext_get_link_index"); | |
339 return 0; | |
340 } | |
341 | |
342 package static extern(C) char* atkObject_get_description (AtkObject* atkObject) { | |
343 if (DEBUG) Stdout.formatln ("-->atkObject_get_description"); | |
344 AccessibleObject object = getAccessibleObject (atkObject); | |
345 if (object is null) return null; | |
346 char* parentResult; | |
347 auto objectClass = cast(AtkObjectClass*)ATK.g_type_class_peek (object.parentType); | |
348 if (objectClass.get_description !is null) { | |
349 parentResult = objectClass.get_description(object.handle); | |
350 } | |
351 AccessibleListener[] listeners = object.getAccessibleListeners (); | |
352 if (listeners.length is 0) return parentResult; | |
353 | |
354 AccessibleEvent event = new AccessibleEvent (object); | |
355 event.childID = object.id; | |
356 if (parentResult !is null) { | |
357 event.result = fromUtf8z( parentResult ).dup; | |
358 } | |
359 for (int i = 0; i < listeners.length; i++) { | |
360 listeners [i].getDescription (event); | |
361 } | |
362 if (event.result is null) return parentResult; | |
363 if (descriptionPtr !is null) OS.g_free (descriptionPtr.ptr); | |
364 | |
365 char[] name = event.result.dup ~ \0; | |
366 char* p = cast(char*)OS.g_malloc (name.length); | |
367 descriptionPtr = p ? p[ 0 .. name.length ] : null; | |
368 return descriptionPtr.ptr; } | |
369 | |
370 package static extern(C) char* atkObject_get_name (AtkObject* atkObject) { | |
371 if (DEBUG) Stdout.formatln ("-->atkObject_get_name: {}", atkObject); | |
372 AccessibleObject object = getAccessibleObject (atkObject); | |
373 if (object is null) return null; | |
374 char* parentResult; | |
375 auto objectClass = cast(AtkObjectClass*)ATK.g_type_class_peek (object.parentType); | |
376 if (objectClass.get_name !is null) { | |
377 parentResult = objectClass.get_name( object.handle); | |
378 } | |
379 AccessibleListener[] listeners = object.getAccessibleListeners (); | |
380 if (listeners.length is 0) return parentResult; | |
381 | |
382 AccessibleEvent event = new AccessibleEvent (object); | |
383 event.childID = object.id; | |
384 if (parentResult !is null) { | |
385 event.result = fromUtf8z( parentResult ).dup; | |
386 } | |
387 for (int i = 0; i < listeners.length; i++) { | |
388 listeners [i].getName (event); | |
389 } | |
390 if (event.result is null) return parentResult; | |
391 if (namePtr !is null) OS.g_free (namePtr.ptr); | |
392 char[] name = event.result.dup ~ \0; | |
393 char* p = cast(char*)OS.g_malloc (name.length); | |
394 namePtr = p ? p[ 0 .. name.length ] : null; | |
395 return namePtr.ptr; | |
396 } | |
397 | |
398 package static extern(C) int atkObject_get_n_children (AtkObject* atkObject) { | |
399 if (DEBUG) Stdout.formatln ("-->atkObject_get_n_children: {}", atkObject); | |
400 AccessibleObject object = getAccessibleObject (atkObject); | |
401 if (object is null) return 0; | |
402 int /*long*/ parentResult = 0; | |
403 auto objectClass = cast(AtkObjectClass*)ATK.g_type_class_peek (object.parentType); | |
404 if (objectClass.get_n_children !is null) { | |
405 parentResult = objectClass.get_n_children( object.handle); | |
406 } | |
407 AccessibleControlListener[] listeners = object.getControlListeners (); | |
408 if (listeners.length is 0) return parentResult; | |
409 | |
410 AccessibleControlEvent event = new AccessibleControlEvent (object); | |
411 event.childID = object.id; | |
412 event.detail = cast(int)/*64*/parentResult; | |
413 for (int i = 0; i < listeners.length; i++) { | |
414 listeners [i].getChildCount (event); | |
415 } | |
416 return event.detail; | |
417 } | |
418 | |
419 package static extern(C) int atkObject_get_index_in_parent (AtkObject* atkObject) { | |
420 if (DEBUG) Stdout.formatln ("-->atkObjectCB_get_index_in_parent. "); | |
421 AccessibleObject object = getAccessibleObject (atkObject); | |
422 if (object is null) return 0; | |
423 if (object.index !is -1) return object.index; | |
424 auto objectClass = cast(AtkObjectClass*)ATK.g_type_class_peek (object.parentType); | |
425 if (objectClass.get_index_in_parent is null) return 0; | |
426 return objectClass.get_index_in_parent(object. handle); | |
427 } | |
428 | |
429 package static extern(C) AtkObject* atkObject_get_parent (AtkObject* atkObject) { | |
430 if (DEBUG) Stdout.formatln ("-->atkObject_get_parent: {}", atkObject); | |
431 AccessibleObject object = getAccessibleObject (atkObject); | |
432 if (object is null) return null; | |
433 if (object.parent !is null) return object.parent.handle; | |
434 auto objectClass = cast(AtkObjectClass*)ATK.g_type_class_peek (object.parentType); | |
435 if (objectClass.get_parent is null) return null; | |
436 return objectClass.get_parent( object.handle); | |
437 } | |
438 | |
439 package static extern(C) int atkObject_get_role (AtkObject* atkObject) { | |
440 if (DEBUG) Stdout.formatln ("-->atkObject_get_role: {}", atkObject); | |
441 AccessibleObject object = getAccessibleObject (atkObject); | |
442 if (object is null) return 0; | |
443 if (object.getAccessibleListeners ().length !is 0) { | |
444 AccessibleControlListener[] listeners = object.getControlListeners (); | |
445 AccessibleControlEvent event = new AccessibleControlEvent (object); | |
446 event.childID = object.id; | |
447 event.detail = -1; | |
448 for (int i = 0; i < listeners.length; i++) { | |
449 listeners [i].getRole (event); | |
450 } | |
451 if (event.detail !is -1) { | |
452 switch (event.detail) { | |
453 /* Convert from win32 role values to atk role values */ | |
454 case ACC.ROLE_CHECKBUTTON: return ATK.ATK_ROLE_CHECK_BOX; | |
455 case ACC.ROLE_CLIENT_AREA: return ATK.ATK_ROLE_DRAWING_AREA; | |
456 case ACC.ROLE_COMBOBOX: return ATK.ATK_ROLE_COMBO_BOX; | |
457 case ACC.ROLE_DIALOG: return ATK.ATK_ROLE_DIALOG; | |
458 case ACC.ROLE_LABEL: return ATK.ATK_ROLE_LABEL; | |
459 case ACC.ROLE_LINK: return ATK.ATK_ROLE_TEXT; | |
460 case ACC.ROLE_LIST: return ATK.ATK_ROLE_LIST; | |
461 case ACC.ROLE_LISTITEM: return ATK.ATK_ROLE_LIST_ITEM; | |
462 case ACC.ROLE_MENU: return ATK.ATK_ROLE_MENU; | |
463 case ACC.ROLE_MENUBAR: return ATK.ATK_ROLE_MENU_BAR; | |
464 case ACC.ROLE_MENUITEM: return ATK.ATK_ROLE_MENU_ITEM; | |
465 case ACC.ROLE_PROGRESSBAR: return ATK.ATK_ROLE_PROGRESS_BAR; | |
466 case ACC.ROLE_PUSHBUTTON: return ATK.ATK_ROLE_PUSH_BUTTON; | |
467 case ACC.ROLE_SCROLLBAR: return ATK.ATK_ROLE_SCROLL_BAR; | |
468 case ACC.ROLE_SEPARATOR: return ATK.ATK_ROLE_SEPARATOR; | |
469 case ACC.ROLE_SLIDER: return ATK.ATK_ROLE_SLIDER; | |
470 case ACC.ROLE_TABLE: return ATK.ATK_ROLE_TABLE; | |
471 case ACC.ROLE_TABLECELL: return ATK.ATK_ROLE_TABLE_CELL; | |
472 case ACC.ROLE_TABLECOLUMNHEADER: return ATK.ATK_ROLE_TABLE_COLUMN_HEADER; | |
473 case ACC.ROLE_TABLEROWHEADER: return ATK.ATK_ROLE_TABLE_ROW_HEADER; | |
474 case ACC.ROLE_TABFOLDER: return ATK.ATK_ROLE_PAGE_TAB_LIST; | |
475 case ACC.ROLE_TABITEM: return ATK.ATK_ROLE_PAGE_TAB; | |
476 case ACC.ROLE_TEXT: return ATK.ATK_ROLE_TEXT; | |
477 case ACC.ROLE_TOOLBAR: return ATK.ATK_ROLE_TOOL_BAR; | |
478 case ACC.ROLE_TOOLTIP: return ATK.ATK_ROLE_TOOL_TIP; | |
479 case ACC.ROLE_TREE: return ATK.ATK_ROLE_TREE; | |
480 case ACC.ROLE_TREEITEM: return ATK.ATK_ROLE_LIST_ITEM; | |
481 case ACC.ROLE_RADIOBUTTON: return ATK.ATK_ROLE_RADIO_BUTTON; | |
482 case ACC.ROLE_WINDOW: return ATK.ATK_ROLE_WINDOW; | |
55
93981635e709
Checked and inserted missing default switch cases.
Frank Benoit <benoit@tionex.de>
parents:
54
diff
changeset
|
483 default: |
42 | 484 } |
485 } | |
486 } | |
487 auto objectClass = cast(AtkObjectClass*)ATK.g_type_class_peek (object.parentType); | |
488 if (objectClass.get_role is null) return 0; | |
489 return objectClass.get_role( object.handle); | |
490 } | |
491 | |
492 package static extern(C) AtkObject* atkObject_ref_child (AtkObject* atkObject, int /*long*/ index) { | |
493 if (DEBUG) Stdout.formatln ("-->atkObject_ref_child: {} of: {}", index, atkObject); | |
494 AccessibleObject object = getAccessibleObject (atkObject); | |
495 if (object is null) return null; | |
496 object.updateChildren (); | |
497 AccessibleObject accObject = object.getChildByIndex (cast(int)/*64*/index); | |
498 if (accObject !is null) { | |
499 OS.g_object_ref (accObject.handle); | |
500 return accObject.handle; | |
501 } | |
502 auto objectClass = cast(AtkObjectClass*)ATK.g_type_class_peek (object.parentType); | |
503 if (objectClass.ref_child is null) return null; | |
504 return objectClass.ref_child( object.handle, index); | |
505 } | |
506 | |
507 package static extern(C) AtkStateSet * atkObject_ref_state_set (AtkObject* atkObject) { | |
508 if (DEBUG) Stdout.formatln ("-->atkObject_ref_state_set"); | |
509 AccessibleObject object = getAccessibleObject (atkObject); | |
510 if (object is null) return null; | |
511 AtkStateSet* parentResult; | |
512 auto objectClass = cast(AtkObjectClass*)ATK.g_type_class_peek (object.parentType); | |
513 if (objectClass.ref_state_set !is null) { | |
514 parentResult = objectClass.ref_state_set( object.handle); | |
515 } | |
516 AccessibleControlListener[] listeners = object.getControlListeners (); | |
517 if (listeners.length is 0) return parentResult; | |
518 | |
519 auto set = parentResult; | |
520 AccessibleControlEvent event = new AccessibleControlEvent (object); | |
521 event.childID = object.id; | |
522 event.detail = -1; | |
523 for (int i = 0; i < listeners.length; i++) { | |
524 listeners [i].getState (event); | |
525 } | |
526 if (event.detail !is -1) { | |
527 /* Convert from win32 state values to atk state values */ | |
528 int state = event.detail; | |
529 if ((state & ACC.STATE_BUSY) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_BUSY); | |
530 if ((state & ACC.STATE_CHECKED) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_CHECKED); | |
531 if ((state & ACC.STATE_EXPANDED) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_EXPANDED); | |
532 if ((state & ACC.STATE_FOCUSABLE) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_FOCUSABLE); | |
533 if ((state & ACC.STATE_FOCUSED) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_FOCUSED); | |
534 if ((state & ACC.STATE_HOTTRACKED) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_ARMED); | |
535 if ((state & ACC.STATE_INVISIBLE) is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_VISIBLE); | |
536 if ((state & ACC.STATE_MULTISELECTABLE) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_MULTISELECTABLE); | |
537 if ((state & ACC.STATE_OFFSCREEN) is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_SHOWING); | |
538 if ((state & ACC.STATE_PRESSED) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_PRESSED); | |
539 if ((state & ACC.STATE_READONLY) is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_EDITABLE); | |
540 if ((state & ACC.STATE_SELECTABLE) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_SELECTABLE); | |
541 if ((state & ACC.STATE_SELECTED) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_SELECTED); | |
542 if ((state & ACC.STATE_SIZEABLE) !is 0) ATK.atk_state_set_add_state (set, ATK.ATK_STATE_RESIZABLE); | |
543 /* Note: STATE_COLLAPSED, STATE_LINKED and STATE_NORMAL have no ATK equivalents */ | |
544 } | |
545 return set; | |
546 } | |
547 | |
548 package static extern(C) int atkSelection_is_child_selected (void* obj, int index) { | |
549 auto atkObject = cast(AtkObject*)obj; | |
550 if (DEBUG) Stdout.formatln ("-->atkSelection_is_child_selected"); | |
551 AccessibleObject object = getAccessibleObject (atkObject); | |
552 if (object is null) return 0; | |
553 int /*long*/ parentResult = 0; | |
554 if (ATK.g_type_is_a (object.parentType, ATK_SELECTION_TYPE)) { | |
555 auto selectionIface = cast(AtkSelectionIface*)ATK.g_type_interface_peek_parent (ATK.ATK_SELECTION_GET_IFACE (object.handle)); | |
556 if (selectionIface.is_child_selected !is null) { | |
557 parentResult = selectionIface.is_child_selected( object.handle, index); | |
558 } | |
559 } | |
560 AccessibleControlListener[] listeners = object.getControlListeners (); | |
561 if (listeners.length is 0) return parentResult; | |
562 | |
563 AccessibleControlEvent event = new AccessibleControlEvent (object); | |
564 event.childID = object.id; | |
565 for (int i = 0; i < listeners.length; i++) { | |
566 listeners [i].getSelection (event); | |
567 } | |
568 AccessibleObject accessibleObject = object.getChildByID (event.childID); | |
569 if (accessibleObject !is null) { | |
570 return accessibleObject.index is index ? 1 : 0; | |
571 } | |
572 return parentResult; | |
573 } | |
574 | |
575 package static extern(C) AtkObject* atkSelection_ref_selection (void* obj, int index) { | |
576 auto atkObject = cast(AtkObject*)obj; | |
577 if (DEBUG) Stdout.formatln ("-->atkSelection_ref_selection"); | |
578 AccessibleObject object = getAccessibleObject (atkObject); | |
579 if (object is null) return null; | |
580 AtkObject* parentResult; | |
581 if (ATK.g_type_is_a (object.parentType, ATK_SELECTION_TYPE)) { | |
582 auto selectionIface = cast(AtkSelectionIface*)ATK.g_type_interface_peek_parent (ATK.ATK_SELECTION_GET_IFACE (object.handle)); | |
583 if (selectionIface.ref_selection !is null) { | |
584 parentResult = selectionIface.ref_selection( object.handle, index); | |
585 } | |
586 } | |
587 AccessibleControlListener[] listeners = object.getControlListeners (); | |
588 if (listeners.length is 0) return parentResult; | |
589 | |
590 AccessibleControlEvent event = new AccessibleControlEvent (object); | |
591 event.childID = object.id; | |
592 for (int i = 0; i < listeners.length; i++) { | |
593 listeners [i].getSelection (event); | |
594 } | |
595 AccessibleObject accObj = object.getChildByID (event.childID); | |
596 if (accObj !is null) { | |
597 if (parentResult !is null) OS.g_object_unref (parentResult); | |
598 OS.g_object_ref (accObj.handle); | |
599 return accObj.handle; | |
600 } | |
601 return parentResult; | |
602 } | |
603 | |
604 package static extern(C) int atkText_get_caret_offset (void* obj) { | |
605 auto atkObject = cast(AtkObject*)obj; | |
606 if (DEBUG) Stdout.formatln ("-->atkText_get_caret_offset"); | |
607 AccessibleObject object = getAccessibleObject (atkObject); | |
608 if (object is null) return 0; | |
609 int /*long*/ parentResult = 0; | |
610 if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) { | |
611 auto textIface = cast(AtkTextIface*)ATK.g_type_interface_peek_parent (ATK.ATK_TEXT_GET_IFACE (object.handle)); | |
612 if (textIface.get_caret_offset !is null) { | |
613 parentResult = textIface.get_caret_offset( object.handle); | |
614 } | |
615 } | |
616 AccessibleTextListener[] listeners = object.getTextListeners (); | |
617 if (listeners.length is 0) return parentResult; | |
618 | |
619 AccessibleTextEvent event = new AccessibleTextEvent (object); | |
620 event.childID = object.id; | |
621 event.offset = cast(int)/*64*/parentResult; | |
622 for (int i = 0; i < listeners.length; i++) { | |
623 listeners [i].getCaretOffset (event); | |
624 } | |
625 return event.offset; | |
626 } | |
627 | |
628 package static extern(C) uint atkText_get_character_at_offset (void* obj, int offset) { | |
629 auto atkObject = cast(AtkObject*)obj; | |
630 if (DEBUG) Stdout.formatln ("-->atkText_get_character_at_offset"); | |
631 AccessibleObject object = getAccessibleObject (atkObject); | |
632 if (object is null) return 0; | |
633 char[] text = object.getText (); | |
634 if (text !is null) return text[cast(int)/*64*/offset ]; // TODO | |
635 if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) { | |
636 auto textIface = cast(AtkTextIface*)ATK.g_type_class_peek (object.parentType); | |
637 if (textIface.get_character_at_offset !is null) { | |
638 return textIface.get_character_at_offset( object.handle, offset); | |
639 } | |
640 } | |
641 return 0; | |
642 } | |
643 | |
644 package static extern(C) int atkText_get_character_count (void* obj) { | |
645 auto atkObject = cast(AtkObject*)obj; | |
646 if (DEBUG) Stdout.formatln ("-->atkText_get_character_count"); | |
647 AccessibleObject object = getAccessibleObject (atkObject); | |
648 if (object is null) return 0; | |
649 char[] text = object.getText (); | |
650 if (text !is null) return text.length; | |
651 if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) { | |
652 auto textIface = cast(AtkTextIface*)ATK.g_type_class_peek (object.parentType); | |
653 if (textIface.get_character_count !is null) { | |
654 return textIface.get_character_count( object.handle); | |
655 } | |
656 } | |
657 return 0; | |
658 } | |
659 | |
660 package static extern(C) int atkText_get_n_selections (void* obj) { | |
661 auto atkObject = cast(AtkObject*)obj; | |
662 if (DEBUG) Stdout.formatln("-->atkText_get_n_selections"); | |
663 AccessibleObject object = getAccessibleObject (atkObject); | |
664 if (object is null) return 0; | |
665 int /*long*/ parentResult = 0; | |
666 if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) { | |
667 auto textIface = cast(AtkTextIface*)ATK.g_type_interface_peek_parent (ATK.ATK_TEXT_GET_IFACE (object.handle)); | |
668 if (textIface.get_n_selections !is null) { | |
669 parentResult = textIface.get_n_selections( object.handle); | |
670 } | |
671 } | |
672 AccessibleTextListener[] listeners = object.getTextListeners (); | |
673 if (listeners.length is 0) return parentResult; | |
674 | |
675 AccessibleTextEvent event = new AccessibleTextEvent (object); | |
676 event.childID = object.id; | |
677 for (int i = 0; i < listeners.length; i++) { | |
678 listeners [i].getSelectionRange (event); | |
679 } | |
680 return event.length is 0 ? parentResult : 1; | |
681 } | |
682 | |
683 package static extern(C) char* atkText_get_selection (void* obj, int selection_num, int* start_offset, int* end_offset) { | |
684 auto atkObject = cast(AtkObject*)obj; | |
685 if (DEBUG) Stdout.formatln ("-->atkText_get_selection"); | |
686 AccessibleObject object = getAccessibleObject (atkObject); | |
687 if (object is null) return null; | |
688 *start_offset=0; | |
689 *end_offset=0; | |
690 if (ATK.g_type_is_a (object.parentType, ATK_TEXT_TYPE)) { | |
691 auto textIface = cast(AtkTextIface*)ATK.g_type_interface_peek_parent (ATK.ATK_TEXT_GET_IFACE (object.handle)); | |
692 if (textIface.get_selection !is null) { | |
693 textIface.get_selection( object.handle, selection_num, start_offset, end_offset ); | |
694 } | |
695 } | |
696 AccessibleTextListener[] listeners = object.getTextListeners (); | |
697 if (listeners.length is 0) return null; | |
698 | |
699 AccessibleTextEvent event = new AccessibleTextEvent (object); | |
700 event.childID = object.id; | |
701 int parentStart; | |
702 int parentEnd; | |
703 parentStart= *start_offset; | |
704 parentEnd= *end_offset; | |
705 event.offset = parentStart; | |
706 event.length = parentEnd - parentStart; | |
707 for (int i = 0; i < listeners.length; i++) { | |
708 listeners [i].getSelectionRange (event); | |
709 } | |
710 *start_offset = event.offset; | |
711 *end_offset = event.offset + event.length; | |
712 return null; | |
713 } | |
714 | |
715 package static extern(C) char* atkText_get_text (void* obj, int start_offset, int end_offset) { | |
716 auto atkObject = cast(AtkObject*)obj; | |
717 if (DEBUG) Stdout.formatln ("-->atkText_get_text: {},{}", start_offset, end_offset); | |
718 AccessibleObject object = getAccessibleObject (atkObject); | |
719 if (object is null) return null; | |
720 char[] text = object.getText (); | |
721 if (text.length > 0) { | |
722 if (end_offset is -1) { | |
723 end_offset = text.length ; | |
724 } else { | |
725 end_offset = Math.min (end_offset, text.length ); | |
726 } | |
727 start_offset = Math.min (start_offset, end_offset); | |
728 text = text[ start_offset .. end_offset ]; | |
729 auto result = cast(char*)OS.g_malloc (text.length+1); | |
730 result[ 0 .. text.length ] = text; | |
731 result[ text.length ] = '\0'; | |
732 return result; | |
733 } | |
734 return null; | |
735 } | |
736 | |
737 package static extern(C) char* atkText_get_text_after_offset (void* obj, int offset_value, int boundary_type, int* start_offset, int* end_offset) { | |
738 auto atkObject = cast(AtkObject*)obj; | |
739 if (DEBUG) Stdout.formatln ("-->atkText_get_text_after_offset"); | |
740 AccessibleObject object = getAccessibleObject (atkObject); | |
741 if (object is null) return null; | |
742 int offset = cast(int)/*64*/offset_value; | |
743 char[] text = object.getText (); | |
744 if (text.length > 0) { | |
745 int length = text.length ; | |
746 offset = Math.min (offset, length - 1); | |
747 int startBounds = offset; | |
748 int endBounds = offset; | |
749 switch (cast(int)/*64*/boundary_type) { | |
750 case ATK.ATK_TEXT_BOUNDARY_CHAR: { | |
751 if (length > offset) endBounds++; | |
752 break; | |
753 } | |
754 case ATK.ATK_TEXT_BOUNDARY_WORD_START: { | |
755 int wordStart1 = nextIndexOfChar (text, " !?.\n", offset - 1); | |
756 if (wordStart1 is -1) { | |
757 startBounds = endBounds = length; | |
758 break; | |
759 } | |
760 wordStart1 = nextIndexOfNotChar (text, " !?.\n", wordStart1); | |
761 if (wordStart1 is length) { | |
762 startBounds = endBounds = length; | |
763 break; | |
764 } | |
765 startBounds = wordStart1; | |
766 int wordStart2 = nextIndexOfChar (text, " !?.\n", wordStart1); | |
767 if (wordStart2 is -1) { | |
768 endBounds = length; | |
769 break; | |
770 } | |
771 endBounds = nextIndexOfNotChar (text, " !?.\n", wordStart2); | |
772 break; | |
773 } | |
774 case ATK.ATK_TEXT_BOUNDARY_WORD_END: { | |
775 int previousWordEnd = previousIndexOfNotChar (text, " \n", offset); | |
776 if (previousWordEnd is -1 || previousWordEnd !is offset - 1) { | |
777 offset = nextIndexOfNotChar (text, " \n", offset); | |
778 } | |
779 if (offset is -1) { | |
780 startBounds = endBounds = length; | |
781 break; | |
782 } | |
783 int wordEnd1 = nextIndexOfChar (text, " !?.\n", cast(int)/*64*/offset); | |
784 if (wordEnd1 is -1) { | |
785 startBounds = endBounds = length; | |
786 break; | |
787 } | |
788 wordEnd1 = nextIndexOfNotChar (text, "!?.", wordEnd1); | |
789 if (wordEnd1 is length) { | |
790 startBounds = endBounds = length; | |
791 break; | |
792 } | |
793 startBounds = wordEnd1; | |
794 int wordEnd2 = nextIndexOfNotChar (text, " \n", wordEnd1); | |
795 if (wordEnd2 is length) { | |
796 startBounds = endBounds = length; | |
797 break; | |
798 } | |
799 wordEnd2 = nextIndexOfChar (text, " !?.\n", wordEnd2); | |
800 if (wordEnd2 is -1) { | |
801 endBounds = length; | |
802 break; | |
803 } | |
804 endBounds = nextIndexOfNotChar (text, "!?.", wordEnd2); | |
805 break; | |
806 } | |
807 case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: { | |
808 int previousSentenceEnd = previousIndexOfChar (text, "!?.", offset); | |
809 int previousText = previousIndexOfNotChar (text, " !?.\n", offset); | |
810 int sentenceStart1 = 0; | |
811 if (previousSentenceEnd >= previousText) { | |
812 sentenceStart1 = nextIndexOfNotChar (text, " !?.\n", offset); | |
813 } else { | |
814 sentenceStart1 = nextIndexOfChar (text, "!?.", offset); | |
815 if (sentenceStart1 is -1) { | |
816 startBounds = endBounds = length; | |
817 break; | |
818 } | |
819 sentenceStart1 = nextIndexOfNotChar (text, " !?.\n", sentenceStart1); | |
820 } | |
821 if (sentenceStart1 is length) { | |
822 startBounds = endBounds = length; | |
823 break; | |
824 } | |
825 startBounds = sentenceStart1; | |
826 int sentenceStart2 = nextIndexOfChar (text, "!?.", sentenceStart1); | |
827 if (sentenceStart2 is -1) { | |
828 endBounds = length; | |
829 break; | |
830 } | |
831 endBounds = nextIndexOfNotChar (text, " !?.\n", sentenceStart2); | |
832 break; | |
833 } | |
834 case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: { | |
835 int sentenceEnd1 = nextIndexOfChar (text, "!?.", offset); | |
836 if (sentenceEnd1 is -1) { | |
837 startBounds = endBounds = length; | |
838 break; | |
839 } | |
840 sentenceEnd1 = nextIndexOfNotChar (text, "!?.", sentenceEnd1); | |
841 if (sentenceEnd1 is length) { | |
842 startBounds = endBounds = length; | |
843 break; | |
844 } | |
845 startBounds = sentenceEnd1; | |
846 int sentenceEnd2 = nextIndexOfNotChar (text, " \n", sentenceEnd1); | |
847 if (sentenceEnd2 is length) { | |
848 startBounds = endBounds = length; | |
849 break; | |
850 } | |
851 sentenceEnd2 = nextIndexOfChar (text, "!?.", sentenceEnd2); | |
852 if (sentenceEnd2 is -1) { | |
853 endBounds = length; | |
854 break; | |
855 } | |
856 endBounds = nextIndexOfNotChar (text, "!?.", sentenceEnd2); | |
857 break; | |
858 } | |
859 case ATK.ATK_TEXT_BOUNDARY_LINE_START: { | |
860 int lineStart1 = locate( text, '\n' ); | |
861 if( lineStart1 == text.length ) lineStart1 = -1; | |
862 if (lineStart1 is -1) { | |
863 startBounds = endBounds = length; | |
864 break; | |
865 } | |
866 lineStart1 = nextIndexOfNotChar (text, "\n", lineStart1); | |
867 if (lineStart1 is length) { | |
868 startBounds = endBounds = length; | |
869 break; | |
870 } | |
871 startBounds = lineStart1; | |
872 int lineStart2 = locate( text, '\n' ); | |
873 if( lineStart2 == text.length ) lineStart2 = -1; | |
874 if (lineStart2 is -1) { | |
875 endBounds = length; | |
876 break; | |
877 } | |
878 lineStart2 = nextIndexOfNotChar (text, "\n", lineStart2); | |
879 endBounds = lineStart2; | |
880 break; | |
881 } | |
882 case ATK.ATK_TEXT_BOUNDARY_LINE_END: { | |
883 int lineEnd1 = nextIndexOfChar (text, "\n", offset); | |
884 if (lineEnd1 is -1) { | |
885 startBounds = endBounds = length; | |
886 break; | |
887 } | |
888 startBounds = lineEnd1; | |
889 if (startBounds is length) { | |
890 endBounds = length; | |
891 break; | |
892 } | |
893 int lineEnd2 = nextIndexOfChar (text, "\n", lineEnd1 + 1); | |
894 if (lineEnd2 is -1) { | |
895 endBounds = length; | |
896 break; | |
897 } | |
898 endBounds = lineEnd2; | |
899 break; | |
900 } | |
55
93981635e709
Checked and inserted missing default switch cases.
Frank Benoit <benoit@tionex.de>
parents:
54
diff
changeset
|
901 default: |
42 | 902 } |
903 *start_offset=startBounds; | |
904 *end_offset=endBounds; | |
905 text = text[startBounds .. endBounds ]; | |
906 auto result = cast(char*)OS.g_malloc (text.length+1); | |
907 result[ 0 .. text.length ] = text; | |
908 result[ text.length ] = '\0'; | |
909 return result; | |
910 } | |
911 return null; | |
912 } | |
913 | |
914 package static extern(C) char* atkText_get_text_at_offset (void* obj, int offset_value, int boundary_type, int* start_offset, int* end_offset) { | |
915 auto atkObject = cast(AtkObject*)obj; | |
916 if (DEBUG) Stdout.formatln ("-->atkText_get_text_at_offset: {} start: {} end: {}", offset_value, start_offset, end_offset); | |
917 AccessibleObject object = getAccessibleObject (atkObject); | |
918 if (object is null) return null; | |
919 int offset = offset_value; | |
920 char[] text = object.getText (); | |
921 if (text.length > 0) { | |
922 int length = text.length; | |
923 offset = Math.min (offset, length - 1); | |
924 int startBounds = offset; | |
925 int endBounds = offset; | |
926 switch (boundary_type) { | |
927 case ATK.ATK_TEXT_BOUNDARY_CHAR: { | |
928 if (length > offset) endBounds++; | |
929 break; | |
930 } | |
931 case ATK.ATK_TEXT_BOUNDARY_WORD_START: { | |
932 int wordStart1 = previousIndexOfNotChar (text, " !?.\n", offset); | |
933 if (wordStart1 is -1) { | |
934 startBounds = endBounds = 0; | |
935 break; | |
936 } | |
937 wordStart1 = previousIndexOfChar (text, " !?.\n", wordStart1) + 1; | |
938 if (wordStart1 is -1) { | |
939 startBounds = 0; | |
940 break; | |
941 } | |
942 startBounds = wordStart1; | |
943 int wordStart2 = nextIndexOfChar (text, " !?.\n", wordStart1); | |
944 endBounds = nextIndexOfNotChar (text, " !?.\n", wordStart2); | |
945 break; | |
946 } | |
947 case ATK.ATK_TEXT_BOUNDARY_WORD_END: { | |
948 int wordEnd1 = previousIndexOfNotChar (text, "!?.", offset + 1); | |
949 wordEnd1 = previousIndexOfChar (text, " !?.\n", wordEnd1); | |
950 wordEnd1 = previousIndexOfNotChar (text, " \n", wordEnd1 + 1); | |
951 if (wordEnd1 is -1) { | |
952 startBounds = endBounds = 0; | |
953 break; | |
954 } | |
955 startBounds = wordEnd1 + 1; | |
956 int wordEnd2 = nextIndexOfNotChar (text, " \n", startBounds); | |
957 if (wordEnd2 is length) { | |
958 endBounds = startBounds; | |
959 break; | |
960 } | |
961 wordEnd2 = nextIndexOfChar (text, " !?.\n", wordEnd2); | |
962 if (wordEnd2 is -1) { | |
963 endBounds = startBounds; | |
964 break; | |
965 } | |
966 endBounds = nextIndexOfNotChar (text, "!?.", wordEnd2); | |
967 break; | |
968 } | |
969 case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: { | |
970 int sentenceStart1 = previousIndexOfNotChar (text, " !?.\n", offset + 1); | |
971 if (sentenceStart1 is -1) { | |
972 startBounds = endBounds = 0; | |
973 break; | |
974 } | |
975 sentenceStart1 = previousIndexOfChar (text, "!?.", sentenceStart1) + 1; | |
976 startBounds = nextIndexOfNotChar (text, " \n", sentenceStart1); | |
977 int sentenceStart2 = nextIndexOfChar (text, "!?.", startBounds); | |
978 endBounds = nextIndexOfNotChar (text, " !?.\n", sentenceStart2); | |
979 break; | |
980 } | |
981 case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: { | |
982 int sentenceEnd1 = previousIndexOfNotChar (text, "!?.", offset + 1); | |
983 sentenceEnd1 = previousIndexOfChar (text, "!?.", sentenceEnd1); | |
984 sentenceEnd1 = previousIndexOfNotChar (text, " \n", sentenceEnd1 + 1); | |
985 if (sentenceEnd1 is -1) { | |
986 startBounds = endBounds = 0; | |
987 break; | |
988 } | |
989 startBounds = sentenceEnd1 + 1; | |
990 int sentenceEnd2 = nextIndexOfNotChar (text, " \n", startBounds); | |
991 if (sentenceEnd2 is length) { | |
992 endBounds = startBounds; | |
993 break; | |
994 } | |
995 sentenceEnd2 = nextIndexOfChar (text, "!?.", sentenceEnd2); | |
996 if (sentenceEnd2 is -1) { | |
997 endBounds = startBounds; | |
998 break; | |
999 } | |
1000 endBounds = nextIndexOfNotChar (text, "!?.", sentenceEnd2); | |
1001 break; | |
1002 } | |
1003 case ATK.ATK_TEXT_BOUNDARY_LINE_START: { | |
1004 startBounds = previousIndexOfChar (text, "\n", offset) + 1; | |
1005 int lineEnd2 = nextIndexOfChar (text, "\n", startBounds); | |
1006 if (lineEnd2 < length) lineEnd2++; | |
1007 endBounds = lineEnd2; | |
1008 break; | |
1009 } | |
1010 case ATK.ATK_TEXT_BOUNDARY_LINE_END: { | |
1011 int lineEnd1 = previousIndexOfChar (text, "\n", offset); | |
1012 if (lineEnd1 is -1) { | |
1013 startBounds = endBounds = 0; | |
1014 break; | |
1015 } | |
1016 startBounds = lineEnd1; | |
1017 endBounds = nextIndexOfChar (text, "\n", lineEnd1 + 1); | |
1018 } | |
55
93981635e709
Checked and inserted missing default switch cases.
Frank Benoit <benoit@tionex.de>
parents:
54
diff
changeset
|
1019 default: |
42 | 1020 } |
1021 *start_offset=startBounds; | |
1022 *end_offset=endBounds; | |
1023 text = text[startBounds .. endBounds]; | |
1024 auto result = cast(char*) OS.g_malloc (text.length+1); | |
1025 result[ 0 .. text.length ] = text; | |
1026 result[ text.length ] = '\0'; | |
1027 return result; | |
1028 } | |
1029 return null; | |
1030 } | |
1031 | |
1032 package static extern(C) char* atkText_get_text_before_offset (void* obj, int offset_value, int boundary_type, int* start_offset, int* end_offset) { | |
1033 auto atkObject = cast(AtkObject*)obj; | |
1034 if (DEBUG) Stdout.formatln ("-->atkText_get_text_before_offset"); | |
1035 AccessibleObject object = getAccessibleObject (atkObject); | |
1036 if (object is null) return null; | |
1037 int offset = offset_value; | |
1038 char[] text = object.getText (); | |
1039 if (text.length > 0) { | |
1040 int length = text.length; | |
1041 offset = Math.min (offset, length - 1); | |
1042 int startBounds = offset; | |
1043 int endBounds = offset; | |
1044 switch (boundary_type) { | |
1045 case ATK.ATK_TEXT_BOUNDARY_CHAR: { | |
1046 if (length >= offset && offset > 0) startBounds--; | |
1047 break; | |
1048 } | |
1049 case ATK.ATK_TEXT_BOUNDARY_WORD_START: { | |
1050 int wordStart1 = previousIndexOfChar (text, " !?.\n", offset - 1); | |
1051 if (wordStart1 is -1) { | |
1052 startBounds = endBounds = 0; | |
1053 break; | |
1054 } | |
1055 int wordStart2 = previousIndexOfNotChar (text, " !?.\n", wordStart1); | |
1056 if (wordStart2 is -1) { | |
1057 startBounds = endBounds = 0; | |
1058 break; | |
1059 } | |
1060 endBounds = wordStart1 + 1; | |
1061 startBounds = previousIndexOfChar (text, " !?.\n", wordStart2) + 1; | |
1062 break; | |
1063 } | |
1064 case ATK.ATK_TEXT_BOUNDARY_WORD_END: { | |
1065 int wordEnd1 =previousIndexOfChar (text, " !?.\n", offset); | |
1066 if (wordEnd1 is -1) { | |
1067 startBounds = endBounds = 0; | |
1068 break; | |
1069 } | |
1070 wordEnd1 = previousIndexOfNotChar (text, " \n", wordEnd1 + 1); | |
1071 if (wordEnd1 is -1) { | |
1072 startBounds = endBounds = 0; | |
1073 break; | |
1074 } | |
1075 endBounds = wordEnd1 + 1; | |
1076 int wordEnd2 = previousIndexOfNotChar (text, " !?.\n", endBounds); | |
1077 wordEnd2 = previousIndexOfChar (text, " !?.\n", wordEnd2); | |
1078 if (wordEnd2 is -1) { | |
1079 startBounds = 0; | |
1080 break; | |
1081 } | |
1082 startBounds = previousIndexOfNotChar (text, " \n", wordEnd2 + 1) + 1; | |
1083 break; | |
1084 } | |
1085 case ATK.ATK_TEXT_BOUNDARY_SENTENCE_START: { | |
1086 int sentenceStart1 = previousIndexOfChar (text, "!?.", offset); | |
1087 if (sentenceStart1 is -1) { | |
1088 startBounds = endBounds = 0; | |
1089 break; | |
1090 } | |
1091 int sentenceStart2 = previousIndexOfNotChar (text, "!?.", sentenceStart1); | |
1092 if (sentenceStart2 is -1) { | |
1093 startBounds = endBounds = 0; | |
1094 break; | |
1095 } | |
1096 endBounds = sentenceStart1 + 1; | |
1097 startBounds = previousIndexOfChar (text, "!?.", sentenceStart2) + 1; | |
1098 break; | |
1099 } | |
1100 case ATK.ATK_TEXT_BOUNDARY_SENTENCE_END: { | |
1101 int sentenceEnd1 = previousIndexOfChar (text, "!?.", offset); | |
1102 if (sentenceEnd1 is -1) { | |
1103 startBounds = endBounds = 0; | |
1104 break; | |
1105 } | |
1106 sentenceEnd1 = previousIndexOfNotChar (text, " \n", sentenceEnd1 + 1); | |
1107 if (sentenceEnd1 is -1) { | |
1108 startBounds = endBounds = 0; | |
1109 break; | |
1110 } | |
1111 endBounds = sentenceEnd1 + 1; | |
1112 int sentenceEnd2 = previousIndexOfNotChar (text, "!?.", endBounds); | |
1113 sentenceEnd2 = previousIndexOfChar (text, "!?.", sentenceEnd2); | |
1114 if (sentenceEnd2 is -1) { | |
1115 startBounds = 0; | |
1116 break; | |
1117 } | |
1118 startBounds = previousIndexOfNotChar (text, " \n", sentenceEnd2 + 1) + 1; | |
1119 break; | |
1120 } | |
1121 case ATK.ATK_TEXT_BOUNDARY_LINE_START: { | |
1122 int lineStart1 = previousIndexOfChar (text, "\n", offset); | |
1123 if (lineStart1 is -1) { | |
1124 startBounds = endBounds = 0; | |
1125 break; | |
1126 } | |
1127 endBounds = lineStart1 + 1; | |
1128 startBounds = previousIndexOfChar (text, "\n", lineStart1) + 1; | |
1129 break; | |
1130 } | |
1131 case ATK.ATK_TEXT_BOUNDARY_LINE_END: { | |
1132 int lineEnd1 = previousIndexOfChar (text, "\n", offset); | |
1133 if (lineEnd1 is -1) { | |
1134 startBounds = endBounds = 0; | |
1135 break; | |
1136 } | |
1137 endBounds = lineEnd1; | |
1138 startBounds = previousIndexOfChar (text, "\n", lineEnd1); | |
1139 if (startBounds is -1) startBounds = 0; | |
1140 break; | |
1141 } | |
55
93981635e709
Checked and inserted missing default switch cases.
Frank Benoit <benoit@tionex.de>
parents:
54
diff
changeset
|
1142 default: |
42 | 1143 } |
1144 *start_offset=startBounds; | |
1145 *end_offset=endBounds; | |
1146 text = text[startBounds .. endBounds]; | |
1147 auto result = cast(char*)OS.g_malloc (text.length+1); | |
1148 result[ 0 .. text.length ] = text; | |
1149 result[ text.length ] = '\0'; | |
1150 return result; | |
1151 } | |
1152 return null; | |
1153 } | |
1154 | |
1155 AccessibleListener[] getAccessibleListeners () { | |
1156 if (accessible is null) return new AccessibleListener [0]; | |
1157 AccessibleListener[] result = accessible.getAccessibleListeners (); | |
1158 return result !is null ? result : new AccessibleListener [0]; | |
1159 } | |
1160 | |
1161 static AccessibleObject getAccessibleObject (AtkObject* atkObject) { | |
1162 return AccessibleObjects[atkObject]; | |
1163 } | |
1164 | |
1165 AccessibleObject getChildByHandle (AtkObject* handle) { | |
1166 return children[handle]; | |
1167 } | |
1168 | |
1169 AccessibleObject getChildByID (int childId) { | |
1170 if (childId is ACC.CHILDID_SELF) return this; | |
1171 foreach( object; children ){ | |
1172 if (object.id is childId) return object; | |
1173 } | |
1174 return null; | |
1175 } | |
1176 | |
1177 AccessibleObject getChildByIndex (int childIndex) { | |
1178 foreach( object; children ){ | |
1179 if (object.index is childIndex) return object; | |
1180 } | |
1181 return null; | |
1182 } | |
1183 | |
1184 AccessibleControlListener[] getControlListeners () { | |
1185 if (accessible is null) return new AccessibleControlListener [0]; | |
1186 AccessibleControlListener[] result = accessible.getControlListeners (); | |
1187 return result !is null ? result : new AccessibleControlListener [0]; | |
1188 } | |
1189 | |
1190 char[] getText () { | |
1191 char* parentResult; | |
1192 char[] parentText = ""; //$NON-NLS-1$ | |
1193 if (ATK.g_type_is_a (parentType, ATK_TEXT_TYPE)) { | |
1194 auto textIface = cast(AtkTextIface*)ATK.g_type_interface_peek_parent (ATK.ATK_TEXT_GET_IFACE (handle)); | |
1195 int /*long*/ characterCount = 0; | |
1196 if (textIface.get_character_count !is null) { | |
1197 characterCount = textIface.get_character_count( handle); | |
1198 } | |
1199 if (characterCount > 0 && textIface.get_text !is null) { | |
1200 parentResult = textIface.get_text( handle, 0, characterCount); | |
1201 if (parentResult !is null) { | |
1202 parentText = fromUtf8z( parentResult ).dup; | |
1203 } | |
1204 } | |
1205 } | |
1206 AccessibleControlListener[] controlListeners = getControlListeners (); | |
1207 if (controlListeners.length is 0) return parentText; | |
1208 AccessibleControlEvent event = new AccessibleControlEvent (this); | |
1209 event.childID = id; | |
1210 event.result = parentText; | |
1211 for (int i = 0; i < controlListeners.length; i++) { | |
1212 controlListeners [i].getValue (event); | |
1213 } | |
1214 return event.result; | |
1215 } | |
1216 | |
1217 AccessibleTextListener[] getTextListeners () { | |
1218 if (accessible is null) return new AccessibleTextListener [0]; | |
1219 AccessibleTextListener[] result = accessible.getTextListeners (); | |
1220 return result !is null ? result : new AccessibleTextListener [0]; | |
1221 } | |
1222 | |
1223 private static extern(C) void gObjectClass_finalize (GObject* atkObject) { | |
1224 auto superType = ATK.g_type_class_peek_parent (ATK.G_OBJECT_GET_CLASS (cast(GTypeInstance*)atkObject)); | |
1225 auto objectClassStruct = cast(GObjectClass*)ATK.G_OBJECT_CLASS (cast(GTypeClass*)superType); | |
1226 objectClassStruct.finalize(atkObject); | |
1227 AccessibleObject object = getAccessibleObject (cast(AtkObject*)atkObject); | |
1228 if (object !is null) { | |
1229 AccessibleObjects.remove (cast(AtkObject*)atkObject); | |
1230 object.release (); | |
1231 } | |
1232 } | |
1233 | |
1234 static int nextIndexOfChar (char[] string, char[] searchChars, int startIndex) { | |
1235 int result = string.length; | |
1236 for (int i = 0; i < searchChars.length; i++) { | |
1237 char current = searchChars[i]; | |
1238 int index = locate( string, current, startIndex ); | |
1239 if (index !is string.length ) result = Math.min (result, index); | |
1240 } | |
1241 return result; | |
1242 } | |
1243 | |
1244 static int nextIndexOfNotChar (char[] string, char[] searchChars, int startIndex) { | |
1245 int length = string.length; | |
1246 int index = startIndex; | |
1247 while (index < length) { | |
1248 char current = string[index]; | |
1249 if ( !contains( searchChars, current)) break; | |
1250 index++; | |
1251 } | |
1252 return index; | |
1253 } | |
1254 | |
1255 static int previousIndexOfChar (char[] string, char[] searchChars, int startIndex) { | |
1256 int result = -1; | |
1257 if (startIndex < 0) return result; | |
1258 string = string[0 .. startIndex]; | |
1259 for (int i = 0; i < searchChars.length ; i++) { | |
1260 char current = searchChars[i]; | |
1261 int index = locatePrior( string, current); | |
1262 if (index !is string.length ) result = Math.max (result, index); | |
1263 } | |
1264 return result; | |
1265 } | |
1266 | |
1267 static int previousIndexOfNotChar (char[] string, char[] searchChars, int startIndex) { | |
1268 if (startIndex < 0) return -1; | |
1269 int index = startIndex - 1; | |
1270 while (index >= 0) { | |
1271 char current = string[index]; | |
1272 if ( !contains(searchChars, current)) break; | |
1273 index--; | |
1274 } | |
1275 return index; | |
1276 } | |
1277 | |
1278 void release () { | |
1279 if (DEBUG) Stdout.formatln("AccessibleObject.release: {}", handle); | |
1280 accessible = null; | |
1281 foreach( child; children ){ | |
1282 if (child.isLightweight) OS.g_object_unref (child.handle); | |
1283 } | |
1284 if (parent !is null) parent.removeChild (this, false); | |
1285 } | |
1286 | |
1287 void removeChild (AccessibleObject child, bool unref) { | |
1288 children.remove (child.handle); | |
1289 if (unref && child.isLightweight) OS.g_object_unref (child.handle); | |
1290 } | |
1291 | |
1292 void selectionChanged () { | |
1293 OS.g_signal_emit_by_name0 (handle, ATK.selection_changed.ptr); | |
1294 } | |
1295 | |
1296 void setFocus (int childID) { | |
1297 updateChildren (); | |
1298 AccessibleObject accObject = getChildByID (childID); | |
1299 if (accObject !is null) { | |
1300 ATK.atk_focus_tracker_notify (accObject.handle); | |
1301 } | |
1302 } | |
1303 | |
1304 void setParent (AccessibleObject parent) { | |
1305 this.parent = parent; | |
1306 } | |
1307 | |
1308 void textCaretMoved(int index) { | |
1309 OS.g_signal_emit_by_name1 (handle, ATK.text_caret_moved.ptr, index); | |
1310 } | |
1311 | |
1312 void textChanged(int type, int startIndex, int length) { | |
1313 if (type is ACC.TEXT_DELETE) { | |
1314 OS.g_signal_emit_by_name2 (handle, ATK.text_changed_delete.ptr, startIndex, length); | |
1315 } else { | |
1316 OS.g_signal_emit_by_name2 (handle, ATK.text_changed_insert.ptr, startIndex, length); | |
1317 } | |
1318 } | |
1319 | |
1320 void textSelectionChanged() { | |
1321 OS.g_signal_emit_by_name0 (handle, ATK.text_selection_changed.ptr); | |
1322 } | |
1323 | |
1324 void updateChildren () { | |
1325 if (isLightweight) return; | |
1326 AccessibleControlListener[] listeners = getControlListeners (); | |
1327 if (listeners.length is 0) return; | |
1328 | |
1329 AccessibleControlEvent event = new AccessibleControlEvent (this); | |
1330 for (int i = 0; i < listeners.length; i++) { | |
1331 listeners [i].getChildren (event); | |
1332 } | |
1333 if (event.children !is null && event.children.length > 0) { | |
1334 AtkObject*[] idsToKeep = new AtkObject*[]( children.length ); | |
1335 idsToKeep.length = 0; | |
1336 if ( null !is (cast(Integer)event.children[0] )) { | |
1337 /* an array of child id's (Integers) was answered */ | |
1338 auto parentType = AccessibleFactory.getDefaultParentType (); | |
1339 for (int i = 0; i < event.children.length; i++) { | |
1340 AccessibleObject object = getChildByIndex (i); | |
1341 if (object is null) { | |
1342 auto childType = AccessibleFactory.getChildType (accessible, i); | |
1343 object = new AccessibleObject (childType, null, accessible, parentType, true); | |
1344 AccessibleObjects[object.handle] = object; | |
1345 addChild (object); | |
1346 object.index = i; | |
1347 } | |
1348 if( auto intChild = cast(Integer)event.children[i] ){ | |
1349 object.id = intChild.intValue (); | |
1350 } | |
1351 else { | |
1352 /* a non-ID value was given so don't set the ID */ | |
1353 } | |
1354 idsToKeep ~= object.handle; | |
1355 } | |
1356 } else { | |
1357 /* an array of Accessible children was answered */ | |
1358 int childIndex = 0; | |
1359 for (int i = 0; i < event.children.length; i++) { | |
1360 AccessibleObject object = null; | |
1361 if( auto accChild = cast(Accessible)event.children[i] ){ | |
1362 object = accChild.accessibleObject; | |
1363 } else { | |
1364 /* a non-Accessible value was given so nothing to do here */ | |
1365 } | |
1366 if (object !is null) { | |
1367 object.index = childIndex++; | |
1368 idsToKeep ~= object.handle; | |
1369 } | |
1370 } | |
1371 } | |
1372 /* remove old children that were not provided as children anymore */ | |
1373 foreach( id; children.keys ){ | |
1374 if ( !tango.core.Array.contains( idsToKeep, id )) { | |
1375 AccessibleObject object = cast(AccessibleObject) children[id]; | |
1376 removeChild (object, true); | |
1377 } | |
1378 } | |
1379 } | |
1380 } | |
1381 } |