2 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
22 * @brief EailItem implementation
24 * In general - this object represents all kinds of objects that have form of
25 * a Elm_Obj_Item* and need ATK accessible representation. It stores
26 * Elm_Obj_Item* inside - unlike Evas_Object like those components that are
27 * extending EailWidget.
30 #include "eail_item.h"
31 #include "eail_item_parent.h"
32 #include "eail_factory.h"
33 #include "eail_utils.h"
34 #include "eail_priv.h"
36 static void atk_component_interface_init(AtkComponentIface *iface);
37 static void atk_action_interface_init(AtkActionIface *iface);
38 static void atk_text_interface_init(AtkTextIface *iface);
40 #define EAIL_ITEM_CLICK_NAME "click" /**< @brief 'click' action name*/
41 #define EAIL_ITEM_PRESS_NAME "press" /**< @brief 'press' action name*/
42 #define EAIL_ITEM_RELEASE_NAME "release" /**< @brief 'release' action name*/
43 #define EAIL_ITEM_EXPAND_NAME "expand" /**< @brief 'expand' action name*/
44 #define EAIL_ITEM_SHRINK_NAME "shrink" /**< @brief 'shrink' action name*/
45 #define EAIL_ITEM_PART_FIRST "start" /**< @brief 'start' action name*/
46 #define EAIL_ITEM_PART_SECOND "end" /**< @brief 'end' action name*/
47 #define EAIL_ITEM_PART_ICON "elm.swallow.icon" /**< @brief icon item part*/
48 #define EAIL_ITEM_PART_END "elm.swallow.end" /**< @brief end item part*/
49 #define EAIL_TXT_SEPARATOR " " /**< @brief separator for text content*/
52 * @brief EailItem GObject definition
54 * It extends ATK_TYPE_OBJECT class and implements ATK_TYPE_COMPONENT,
55 * ATK_TYPE_TEXT and ATK_TYPE_ACTION interfaces
57 G_DEFINE_TYPE_WITH_CODE(EailItem,
60 G_IMPLEMENT_INTERFACE(ATK_TYPE_COMPONENT,
61 atk_component_interface_init)
62 G_IMPLEMENT_INTERFACE(ATK_TYPE_ACTION,
63 atk_action_interface_init)
64 G_IMPLEMENT_INTERFACE(ATK_TYPE_TEXT,
65 atk_text_interface_init));
68 * @brief Callback used for tracking show-changes for items
70 * @param data data passed to callback
71 * @param e Evas instance that has been shown
72 * @param obj Evas_Object instance that has been shown
73 * @param event_info additional event info
76 eail_item_on_show(void *data, Evas *e, Evas_Object *obj, void *event_info)
78 g_return_if_fail(ATK_IS_OBJECT(data));
80 atk_object_notify_state_change(ATK_OBJECT(data), ATK_STATE_SHOWING, TRUE);
81 atk_object_notify_state_change(ATK_OBJECT(data), ATK_STATE_VISIBLE, TRUE);
85 * @brief Callback used for tracking hide-changes for items
87 * @param data data passed to callback
88 * @param e Evas instance that has been shown
89 * @param obj Evas_Object instance that has been shown
90 * @param event_info additional event info
93 eail_item_on_hide(void *data, Evas *e, Evas_Object *obj, void *event_info)
95 g_return_if_fail(ATK_IS_OBJECT(data));
97 atk_object_notify_state_change(ATK_OBJECT(data), ATK_STATE_SHOWING, FALSE);
98 atk_object_notify_state_change(ATK_OBJECT(data), ATK_STATE_VISIBLE, FALSE);
101 * @brief Initializer for AtkObjectClass
103 * @param obj AtkObject instance
104 * @param data additional initialization data
107 eail_item_initialize(AtkObject *obj, gpointer data)
109 EailItem *item = EAIL_ITEM(obj);
111 ATK_OBJECT_CLASS(eail_item_parent_class)->initialize(obj, data);
113 item->item = (Elm_Object_Item *)data;
115 Evas_Object *widget = elm_object_item_widget_get(item->item);
117 evas_object_event_callback_add(widget, EVAS_CALLBACK_SHOW,
118 eail_item_on_show, item);
119 evas_object_event_callback_add(widget, EVAS_CALLBACK_HIDE,
120 eail_item_on_hide, item);
121 /* NOTE: initializing role is being done only in eail_item_new(..) */
126 * @param item EailItem to take nested Elm_Object_Item from
128 * @returns Elm_Object_Item * representing nested item or NULL if an error occured
131 eail_item_get_item(EailItem *item)
133 g_return_val_if_fail(EAIL_IS_ITEM(item), NULL);
139 * Implementation of the *AtkObject* interface
143 * @brief Gets the accessible name of the accessible.
145 * Implementation of AtkObject->get_name callback.
147 * @param obj AtkObject for EailItem
148 * @returns string representing the accessible description of
152 eail_item_get_name(AtkObject *obj)
154 const gchar *atk_name_default = NULL;
155 AtkObject *parent = atk_object_get_parent(obj);
157 if (!parent) return NULL;
159 /* returning name from default atk implementation when it available (it
160 * means that it was set by user)*/
161 atk_name_default = ATK_OBJECT_CLASS(eail_item_parent_class)->get_name(obj);
162 if (atk_name_default) return atk_name_default;
164 return eail_item_parent_get_item_name(EAIL_ITEM_PARENT(parent),
169 * @brief Gets the role of the accessible
171 * Implementation of AtkObject->get_role callback.
173 * @param obj AtkObject for EailItem
174 * @returns AtkRole representing the parameter's role
177 eail_item_get_role(AtkObject *obj)
179 AtkObject *parent = atk_object_get_parent(obj);
181 if (!parent) return ATK_ROLE_INVALID;
183 return eail_item_parent_get_item_role(EAIL_ITEM_PARENT(parent),
188 * @brief Gets the 0-based index of this accessible in its parent.
190 * Implementation of AtkObject->get_index_in_parent callback.
192 * @param obj AtkObject for EailItem
193 * @returns integer representing the index of the accessible in its parent or -1 if the accessible does not have an accessible parent
196 eail_item_get_index_in_parent(AtkObject *obj)
198 AtkObject *parent = atk_object_get_parent(obj);
200 if (!parent) return -1;
202 return eail_item_parent_get_item_index_in_parent(EAIL_ITEM_PARENT(parent),
207 * @brief Gets a reference to the state set of the accessible.
209 * The caller must unreference it when it is no longer needed.
211 * Implementation of AtkObject->ref_state_set callback.
213 * @param obj AtkObject for EailItem
214 * @returns AtkStateSet containing a reference to the state set of the
218 eail_item_ref_state_set(AtkObject *obj)
220 AtkStateSet *state_set;
221 AtkObject *parent = atk_object_get_parent(obj);
222 EailItem *item = EAIL_ITEM(obj);
223 Elm_Object_Item *it = eail_item_get_item(item);
225 state_set = ATK_OBJECT_CLASS(eail_item_parent_class)->ref_state_set(obj);
229 atk_state_set_add_state(state_set, ATK_STATE_DEFUNCT);
233 if (!elm_object_item_disabled_get(it))
235 atk_state_set_add_state(state_set, ATK_STATE_SENSITIVE);
236 atk_state_set_add_state(state_set, ATK_STATE_ENABLED);
239 return eail_item_parent_ref_item_state_set(EAIL_ITEM_PARENT(parent),
245 * @brief Initializer for GObject class
246 * @param item EailItem instance
249 eail_item_init(EailItem *item)
251 item->click_description = NULL;
252 item->press_description = NULL;
253 item->release_description = NULL;
254 item->expand_description = NULL;
255 item->shrink_description = NULL;
259 * @brief Finalizes implementation for GObject class
260 * @param obj AtkObject for EailItem instance that needs to be finalized
263 eail_item_class_finalize(GObject *obj)
265 EailItem *eail_item = EAIL_ITEM(obj);
266 Elm_Object_Item *obj_item = eail_item_get_item(eail_item);
269 eail_factory_unregister_item_from_cache(obj_item);
271 if (eail_item->click_description) free(eail_item->click_description);
272 if (eail_item->press_description) free(eail_item->press_description);
273 if (eail_item->release_description) free(eail_item->release_description);
274 if (eail_item->expand_description) free(eail_item->expand_description);
275 if (eail_item->shrink_description) free(eail_item->shrink_description);
277 G_OBJECT_CLASS(eail_item_parent_class)->finalize(obj);
281 * @brief Helper function used for adding Evas_Object* content to the item's list
282 * if the content is available.
284 * @param eail_obj_item item used for browsing for given content part
285 * @param items list of items that will be extended by the content part
286 * @param part_str name of content part to be found
288 * @returns Eina_List filled with Evas_Object* objects
291 _eail_item_append_part_if_exist(Elm_Object_Item *eail_obj_item,
295 Evas_Object *content = NULL;
297 content = elm_object_item_part_content_get
298 (eail_obj_item, part_str);
300 items = eina_list_append(items, content);
306 * @brief Checks if content_get is supported by the given EailItem object
308 * @param atk_object AtkObject instance
310 * @returns TRUE if content_get is supported, FALSE otherwise
313 _eail_item_is_content_get_supported(AtkObject *atk_object)
315 AtkObject *parent = NULL;
318 parent = atk_object_get_parent(atk_object);
319 g_return_val_if_fail(parent, FALSE);
321 return eail_item_parent_is_is_content_get_supported
322 (EAIL_ITEM_PARENT(parent),EAIL_ITEM(atk_object));
326 * @brief Gets list of item's content parts with well documented content strings
328 * @param eail_item item to get content from
330 * @returns Eina_List filled with the content parts that have been found
333 _eail_item_get_basic_parts(EailItem *eail_item)
335 Eina_List *items = NULL;
336 Elm_Object_Item *obj_item = NULL;
338 /* if content_get is not supported then content from basic parts will be
339 * always empty. This checking is being done, because elementary library
340 * don't want to ask for some widget usign content_get API */
341 if (!_eail_item_is_content_get_supported(ATK_OBJECT(eail_item)))
344 obj_item = eail_item_get_item(EAIL_ITEM(eail_item));
345 items = _eail_item_append_part_if_exist
346 (obj_item, items, EAIL_ITEM_PART_FIRST);
347 items = _eail_item_append_part_if_exist
348 (obj_item, items, EAIL_ITEM_PART_SECOND);
349 items = _eail_item_append_part_if_exist
350 (obj_item, items, EAIL_ITEM_PART_ICON);
351 items = _eail_item_append_part_if_exist
352 (obj_item, items, EAIL_ITEM_PART_END);
358 * @brief Helper function for adding unique entries from one list to another
360 * @param item_list list which unique items will be appended to
361 * @param additional_items source list with items to be added to item_list
363 * @returns Eina_List filled with unique entries from both lists
366 _eail_add_unique_listsparts(Eina_List *item_list,
367 Eina_List *additional_items)
370 Elm_Object_Item *item_edj;
372 EINA_LIST_FOREACH(additional_items, l, item_edj)
374 if (!eina_list_data_find(item_list, item_edj))
375 item_list = eina_list_append(item_list, item_edj);
382 * @brief Gets content part items from the given EailItem object
384 * List should be freed when results will be processed.
386 * @param eail_item EailItem object used to get content from
388 * @returns Eina_List containing content parts for the given item.
391 _eail_item_get_part_items(EailItem *eail_item)
393 Eina_List *items = NULL, *edje_items = NULL;
394 Elm_Object_Item *obj_item = NULL;
396 obj_item = eail_item_get_item(eail_item);
397 g_return_val_if_fail(obj_item, NULL);
399 /* parts from well documented default content parts - there are being used
400 * mostly by desktop applications. Some of these parts are not listed in
401 * edje objects (used below), so results from both list need to be merged
402 * to list full item content */
403 items = _eail_item_get_basic_parts(eail_item);
405 /* content parts from taken from edje object*/
406 edje_items = eail_get_edje_parts_for_item(obj_item);
408 /* adding unique edje items to content list*/
409 items = _eail_add_unique_listsparts(items, edje_items);
411 eina_list_free(edje_items);
417 * @brief Gets the number of accessible children of the accessible.
419 * Implementation AtkObject->get_n_children callback.
421 * @param obj AtkObject (EailItem) instance
423 * @returns integer representing the number of accessible children of
427 eail_item_get_n_children(AtkObject *obj)
429 gint n_items, parent_n_items;
431 AtkObject *parent = atk_object_get_parent(obj);
433 if (!parent) return 0;
434 parent_n_items = eail_item_parent_get_n_children(EAIL_ITEM_PARENT(parent),
436 /* if there is item parent impl, then returning item count
438 if (parent_n_items != -1) return parent_n_items;
440 items = _eail_item_get_part_items(EAIL_ITEM(obj));
441 n_items = eina_list_count(items);
443 eina_list_free(items);
449 * @brief Gets a reference to the specified accessible child of the object.
451 * The accessible children are 0-based so the first accessible child is at index 0,
452 * the second at index 1 and so on.
454 * Implementation of AtkObject->ref_child callback.
456 * @param obj AtkObject for EailItem instance
457 * @param i index of item to reference
459 * @returns AtkObject representing the specified accessible child of the
463 eail_item_ref_child(AtkObject *obj, gint i)
466 AtkObject *child = NULL;
467 AtkObject *parent = atk_object_get_parent(obj);
468 AtkObject *ref_child_from_parent = NULL;
470 if (!parent) return NULL;
472 ref_child_from_parent = eail_item_parent_ref_n_child
473 (EAIL_ITEM_PARENT(parent), EAIL_ITEM(obj), i);
475 /* if there is item parent implementation for ref child, then returning
476 * object using that parent implementation*/
477 if (ref_child_from_parent)
479 g_object_ref(ref_child_from_parent);
480 return ref_child_from_parent;
483 items = _eail_item_get_part_items(EAIL_ITEM(obj));
484 if (eina_list_count(items) > i)
485 child = eail_factory_get_accessible(eina_list_nth(items, i));
487 ERR("Tried to ref child with index %d out of bounds!", i);
489 eina_list_free(items);
494 DBG("Child could not created in factory");
500 * @brief Gets obj's attributes set
502 * The caller must free attribute set when it is no longer needed.
504 * @param obj AtkObject instance
505 * @return AtkAttributeSet containing obj's attributes
507 static AtkAttributeSet *
508 eail_item_get_attributes(AtkObject *obj)
511 AtkAttributeSet *attributes;
512 Elm_Object_Item *obj_item = NULL;
514 obj_item = eail_item_get_item(EAIL_ITEM(obj));
519 Evas_Object *widget = elm_object_item_widget_get(obj_item);
525 attr = g_new(AtkAttribute, 1);
526 attr->name = g_strdup("parent-type");
527 attr->value = g_strdup(elm_object_widget_type_get(widget));
529 attributes = g_slist_append(NULL, attr);
534 * @brief Initializer for GObject class
536 * Defines callbacks for base AtkObject.
538 * @param klass EailItemClass instance
541 eail_item_class_init(EailItemClass *klass)
543 AtkObjectClass *class = ATK_OBJECT_CLASS(klass);
544 GObjectClass *g_object_class = G_OBJECT_CLASS(klass);
546 class->initialize = eail_item_initialize;
547 class->get_name = eail_item_get_name;
548 class->get_role = eail_item_get_role;
549 class->get_index_in_parent = eail_item_get_index_in_parent;
550 class->ref_state_set = eail_item_ref_state_set;
551 class->get_n_children = eail_item_get_n_children;
552 class->ref_child = eail_item_ref_child;
553 class->get_attributes = eail_item_get_attributes;
555 g_object_class->finalize = eail_item_class_finalize;
559 * Implementation of the *AtkComponent* interface
563 * @brief Grabs focus for this component.
565 * Implementation of AtkComponent->grab_focus callback.
567 * @param component AtkComponent (EailItem) instance
568 * @returns TRUE on success, FALSE otherwise.
571 eail_item_grab_focus(AtkComponent *component)
573 AtkObject *obj = ATK_OBJECT(component);
574 AtkObject *parent = atk_object_get_parent(obj);
576 if (!parent) return FALSE;
578 return eail_item_parent_grab_item_focus(EAIL_ITEM_PARENT(parent),
583 * @brief Gets the rectangle which gives the extent of the component.
585 * Implementation of AtkComponent->get_extents callback.
587 * @param component AtkComponent instance
588 * @param [out] x rectangle upper left x coordinate
589 * @param [out] y rectangle upper left y coordinate
590 * @param [out] width width of the rectangle
591 * @param [out] height height of the rectangle
592 * @param coord_type specifies whether the coordinates are relative to the
593 * screen or to the components top level window
596 eail_item_get_extents(AtkComponent *component,
601 AtkCoordType coord_type)
603 AtkObject *obj = ATK_OBJECT(component);
604 AtkObject *parent = atk_object_get_parent(obj);
607 *width = *height = -1;
611 eail_item_parent_get_item_extents(EAIL_ITEM_PARENT(parent),
613 x, y, width, height, coord_type);
617 * @brief AtkComponent interface initialization
619 * @param iface EailNaviframPage instance
622 atk_component_interface_init(AtkComponentIface *iface)
624 iface->grab_focus = eail_item_grab_focus;
625 iface->get_extents = eail_item_get_extents;
629 * AtkAction interface init
633 * @brief Gets actions supported by given EailItem object
635 * @param action AtkAction instance
637 * @returns EailActionSupported enum entry that shows what kind of actions are
641 _eail_item_get_actions_supported(AtkAction *action)
643 AtkObject *parent = NULL;
645 parent = atk_object_get_parent(ATK_OBJECT(action));
646 g_return_val_if_fail(parent, FALSE);
648 return eail_item_parent_get_actions_supported
649 (EAIL_ITEM_PARENT(parent),EAIL_ITEM(action));
654 * @brief Returns the number of implemented ATK actions.
656 * Implementation of AtkActionIface get_n_actions callback.
658 * @param action object that implements AtkAction interface
659 * @returns integer representing number of implemented actions
662 eail_item_n_actions_get(AtkAction *action)
665 /* if parent item does not support click action, then return no action */
666 if (_eail_item_get_actions_supported(action) == EAIL_ACTION_SUPPORTED_NONE)
669 if (_eail_item_get_actions_supported(action) & EAIL_ACTION_SUPPORTED_CLICK)
672 if (_eail_item_get_actions_supported(action) & EAIL_ACTION_SUPPORTED_PRESS)
675 if (_eail_item_get_actions_supported(action) & EAIL_ACTION_SUPPORTED_RELEASE)
678 if (_eail_item_get_actions_supported(action) & EAIL_ACTION_SUPPORTED_EXPAND)
681 if (_eail_item_get_actions_supported(action) & EAIL_ACTION_SUPPORTED_SHRINK)
688 * @brief Returns the accessible name of the specified action
690 * @param action object that implements AtkAction interface
691 * @param i index (number) of action
692 * @returns string containing the accessible name of the specified action
695 eail_item_action_name_get(AtkAction *action, int i)
697 const char* action_name;
700 /* if parent item does not support click action, then return no action */
701 if (_eail_item_get_actions_supported(action) == EAIL_ACTION_SUPPORTED_NONE)
704 actions_num = atk_action_get_n_actions(action);
705 if (i >= actions_num) return NULL;
710 /*"click": the user clicked the item*/
711 action_name = EAIL_ITEM_CLICK_NAME;
714 /*"press": the user pressed the item*/
715 action_name = EAIL_ITEM_PRESS_NAME;
718 /*"release": the user pressed the item*/
719 action_name = EAIL_ITEM_RELEASE_NAME;
722 /*"expand": the user expand the item*/
723 action_name = EAIL_ITEM_EXPAND_NAME;
726 /*"shrink": the user shrink the item*/
727 action_name = EAIL_ITEM_SHRINK_NAME;
738 * @brief Gets the clickable Evas_Object for the given EailItem
740 * @param atk_item EailItem instance
742 * @returns clickable Evas_Object or NULL of no clickable content was found
745 _eail_item_get_clickable_evas_obj(AtkObject *atk_item)
747 AtkObject *parent = NULL;
748 Evas_Object *widget = NULL;
749 Eina_List *parts = NULL;
751 parent = atk_object_get_parent(atk_item);
752 g_return_val_if_fail(parent, FALSE);
754 widget = eail_item_parent_get_evas_obj
755 (EAIL_ITEM_PARENT(parent), EAIL_ITEM(atk_item));
756 if (widget) return widget;
758 /* if not supported from parent, then trying to get content widget nested
760 parts = _eail_item_get_part_items(EAIL_ITEM(atk_item));
761 if (parts && eina_list_count(parts) > 0)
763 /* getting first widget from content */
764 widget = eina_list_nth(parts, 0);
766 eina_list_free(parts);
767 if (widget) return widget;
769 /* if no nested widget, then getting evas clickable area */
770 return eail_get_edje_obj_from_item
771 (eail_item_get_item(EAIL_ITEM(atk_item)));
775 * @brief Expand or shrink the item
777 * @param atk_item item object to expand
778 * @param expand info if item should be expanded or shrinked
780 * @returns TRUE if operation was successful, FALSE otherwise
782 static gboolean _eail_item_expand(AtkObject *atk_item, Eina_Bool expand)
784 Elm_Object_Item *item = eail_item_get_item(EAIL_ITEM(atk_item));
786 if(elm_genlist_item_type_get(item) != ELM_GENLIST_ITEM_TREE ||
787 elm_genlist_item_expanded_get(item) == expand)
791 elm_genlist_item_expanded_set(item, expand);
796 * @brief Performs an action with the given name on given item
798 * @param atk_item item object to perform the action on
799 * @param action_name name of the action (eg. 'click', 'press'...)
801 * @returns TRUE if operation was successful, FALSE otherwise
804 _eail_item_perform_action(AtkObject *atk_item, const gchar *action_name)
806 AtkObject *parent = NULL;
807 Evas_Object *widget = NULL;
810 parent = atk_object_get_parent(atk_item);
811 g_return_val_if_fail(parent, FALSE);
813 widget =_eail_item_get_clickable_evas_obj(atk_item);
817 ERR("No widget for click found");
821 if (0 == g_strcmp0(action_name, EAIL_ITEM_CLICK_NAME))
823 DBG("Calling 'click' on item");
824 eail_get_coords_widget_center(widget, &x, &y);
825 eail_mouse_click_on_coords(widget, x, y);
827 else if (0 == g_strcmp0(action_name, EAIL_ITEM_PRESS_NAME))
829 DBG("Calling 'press' on item");
830 eail_get_coords_widget_center(widget, &x, &y);
831 eail_mouse_press_on_coords(widget, x, y);
833 else if (0 == g_strcmp0(action_name, EAIL_ITEM_RELEASE_NAME))
835 DBG("Calling 'release' on item");
836 eail_get_coords_widget_center(widget, &x, &y);
837 eail_mouse_release_on_coords(widget, x, y);
839 else if (0 == g_strcmp0(action_name, EAIL_ITEM_EXPAND_NAME))
841 DBG("Calling 'expand' on item");
842 return _eail_item_expand(atk_item, EINA_TRUE);
844 else if (0 == g_strcmp0(action_name, EAIL_ITEM_SHRINK_NAME))
846 DBG("Calling 'shrink' on item");
847 return _eail_item_expand(atk_item, EINA_FALSE);
851 DBG("Action name not found: %s", action_name);
859 * \brief Launches action with given index
861 * @param action AtkAction instance
862 * @param i index (number) of the action
864 * @returns TRUE if action was successfully launched, FALSE otherwise
867 eail_item_do_action(AtkAction *action, int i)
869 const char *action_name = atk_action_get_name(action, i);
871 /* if parent item does not support click action, then return immediately */
872 if (_eail_item_get_actions_supported(action) == EAIL_ACTION_SUPPORTED_NONE)
875 if (action_name == NULL) return FALSE;
877 return _eail_item_perform_action(ATK_OBJECT(action), action_name);;
881 * @brief Gets the description string of the specified action
883 * Implementation of get_description from AtkAction interface.
885 * @param action EailBubble instance
886 * @param i action index
888 * @return string representing the specified action's description
891 eail_item_description_get(AtkAction *action,
894 EailItem *item = EAIL_ITEM(action);
895 const char *action_description;
898 if (!item) return NULL;
900 actions_num = atk_action_get_n_actions(action);
901 if (i >= actions_num) return NULL;
906 /*"click": the user clicked the item*/
907 action_description = item->click_description;
910 /*"press": the user pressed the item*/
911 action_description = item->press_description;
914 /*"release": the user released the item*/
915 action_description = item->release_description;
918 /*"expand": the user expand the item*/
919 action_description = item->expand_description;
922 /*"shrink": the user shrink the item*/
923 action_description = item->shrink_description;
926 action_description = NULL;
930 return action_description;
934 * @brief Sets a description of the specified action of the object
936 * Implementation of set_description from AtkAction interface.
938 * @param action AtkAction instance
939 * @param i action index
940 * @param description action description
942 * @return TRUE on success, FALSE otherwise
945 eail_item_description_set(AtkAction *action,
947 const char *description)
949 EailItem *item = EAIL_ITEM(action);
953 if (!item) return FALSE;
955 actions_num = atk_action_get_n_actions(action);
956 if (i >= actions_num) return FALSE;
961 /*"click": the user clicked the item*/
962 value = &item->click_description;
965 /*"press": the user pressed the item*/
966 value = &item->press_description;
969 /*"release": the user released the item*/
970 value = &item->release_description;
973 /*"expand": the user expand the item*/
974 value = &item->expand_description;
977 /*"shrink": the user shrink the item*/
978 value = &item->shrink_description;
988 *value = g_strdup(description);
996 * @brief Initializer for AtkActionIface
997 * @param iface AtkActionIface instance to fill
1000 atk_action_interface_init(AtkActionIface *iface)
1002 g_return_if_fail(iface != NULL);
1004 iface->do_action = eail_item_do_action;
1005 iface->get_n_actions = eail_item_n_actions_get;
1006 iface->get_name = eail_item_action_name_get;
1007 iface->get_description = eail_item_description_get;
1008 iface->set_description = eail_item_description_set;
1012 * @brief Gets text content from item
1014 * Implementation of AtkTextIface->get_text callback.
1016 * Use g_free() to free the returned.
1018 * @param text AtkText instance
1019 * @param start_offset start position
1020 * @param end_offset end position, or -1 for the end of the string.
1022 * @returns a newly allocated string containing the text from start_offset
1023 * up to, but not including end_offset.
1027 eail_item_get_text(AtkText *text,
1031 Eina_Strbuf *buf = NULL;
1032 Elm_Object_Item *obj_item = NULL;
1033 Eina_List *string_parts = NULL, *l = NULL;
1034 gchar *string_part = NULL;
1035 gchar *ret_str = NULL;
1036 gboolean first_part = TRUE;
1038 obj_item = eail_item_get_item(EAIL_ITEM(text));
1039 g_return_val_if_fail(obj_item, NULL);
1041 string_parts = eail_item_get_content_strings(obj_item);
1042 if (!string_parts) return NULL;
1044 buf = eina_strbuf_new();
1045 EINA_LIST_FOREACH(string_parts, l, string_part)
1048 eina_strbuf_append(buf, EAIL_TXT_SEPARATOR);
1050 eina_strbuf_append(buf, string_part);
1054 /* ret_str is newly allocated */
1055 ret_str = eail_get_substring
1056 (eina_strbuf_string_get(buf), start_offset, end_offset);
1058 eina_list_free(string_parts);
1059 eina_strbuf_free(buf);
1065 * @brief Gets character from an item at the given offset
1067 * Implementation of AtkTextIface->get_character_at_offset callback.
1069 * @param text AtkText instance
1070 * @param offset offset to get the character from
1072 * @returns char located at offset
1075 eail_item_get_character_at_offset(AtkText *text, gint offset)
1077 gunichar character = '\0';
1078 gchar* time_str = NULL;
1080 time_str = eail_item_get_text(text, 0, -1);
1084 character = g_utf8_get_char
1085 (g_utf8_offset_to_pointer(time_str, offset));
1093 * @brief Gets the character count from text content in item
1095 * Implementation of AtkTextIface->get_character_count callback.
1097 * @param text AtkText instance
1099 * @returns integer representing the character count
1102 eail_item_get_character_count(AtkText *text)
1107 str = eail_item_get_text(text, 0, -1);
1111 count = g_utf8_strlen(str, -1);
1119 * @brief Creates an AtkAttributeSet which consists of the attributes
1120 * explicitly set at the position offset in the text.
1122 * start_offset and end_offset are set to the start and end of the range around offset
1123 * where the attributes are invariant.
1125 * Note that end_offset is the offset of the first character after the range.
1127 * This AtkAttributeSet should be freed by a call to
1128 * atk_attribute_set_free()
1130 * @param text AtkText instance
1131 * @param offset the offset at which to get the attributes
1132 * @param [out] start_offset start offset of the range
1133 * @param [out] end_offset end offset of the range
1135 * @returns an AtkAttributeSet which contains the attributes explicitly set at
1138 static AtkAttributeSet *
1139 eail_item_get_run_attributes(AtkText *text,
1144 AtkAttributeSet *at_set = NULL;
1145 Elm_Object_Item *obj_item = NULL;
1146 obj_item = eail_item_get_item(EAIL_ITEM(text));
1147 gint len = eail_item_get_character_count(text);
1149 if (!obj_item || offset >= len)
1160 /* NOTE: Elm_Wrap_Type value is in 100% compatible with ATK wrap modes, so
1161 * no additional conversion is needed*/
1162 Elm_Wrap_Type wrap_type = ELM_WRAP_NONE;
1163 at_set = eail_utils_text_add_attribute
1164 (at_set, ATK_TEXT_ATTR_WRAP_MODE,
1165 atk_text_attribute_get_value
1166 (ATK_TEXT_ATTR_WRAP_MODE, wrap_type));
1168 at_set = eail_utils_text_add_attribute
1169 (at_set, ATK_TEXT_ATTR_EDITABLE,
1170 atk_text_attribute_get_value
1171 (ATK_TEXT_ATTR_EDITABLE, FALSE));
1177 * @brief Creates an AtkAttributeSet which consists of the default values of
1178 * attributes for the text.
1180 * This AtkAttributeSet should be freed by a call to
1181 * atk_attribute_set_free()
1183 * @param text AtkText instance
1185 * @returns AtkAttributeSet containing default values of attributes
1188 static AtkAttributeSet *
1189 eail_item_get_default_attributes(AtkText *text)
1191 AtkAttributeSet *at_set = NULL;
1193 at_set = eail_utils_text_add_attribute
1194 (at_set, ATK_TEXT_ATTR_WRAP_MODE,
1195 atk_text_attribute_get_value(ATK_TEXT_ATTR_WRAP_MODE, 0));
1197 at_set = eail_utils_text_add_attribute
1198 (at_set, ATK_TEXT_ATTR_EDITABLE,
1199 atk_text_attribute_get_value
1200 (ATK_TEXT_ATTR_EDITABLE, FALSE));
1206 * @brief Initializer for AtkTextinterface
1207 * @param iface AtkTextIface instance to fill
1210 atk_text_interface_init(AtkTextIface *iface)
1212 iface->get_text = eail_item_get_text;
1213 iface->get_character_at_offset = eail_item_get_character_at_offset;
1214 iface->get_character_count = eail_item_get_character_count;
1215 iface->get_run_attributes = eail_item_get_run_attributes;
1216 iface->get_default_attributes = eail_item_get_default_attributes;