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.
21 * @file eail_multibuttonentry.c
22 * @brief EailMultibuttonentry implementation
25 #include <Elementary.h>
27 #include "eail_multibuttonentry.h"
28 #include "eail_factory.h"
29 #include "eail_item_parent.h"
30 #include "eail_priv.h"
31 #include "eail_utils.h"
32 #include "eail_clipboard.h"
34 static void eail_item_parent_interface_init(EailItemParentIface *iface);
35 static void atk_editable_text_interface_init(AtkEditableTextIface *iface);
36 static void atk_text_interface_init(AtkTextIface *iface);
39 * @brief EailMultibuttonentry type definition
41 G_DEFINE_TYPE_WITH_CODE(EailMultibuttonentry,
42 eail_multibuttonentry,
43 EAIL_TYPE_ACTION_WIDGET,
44 G_IMPLEMENT_INTERFACE(ATK_TYPE_TEXT,
45 atk_text_interface_init)
46 G_IMPLEMENT_INTERFACE(ATK_TYPE_EDITABLE_TEXT,
47 atk_editable_text_interface_init)
48 G_IMPLEMENT_INTERFACE(EAIL_TYPE_ITEM_PARENT,
49 eail_item_parent_interface_init));
52 * @brief Checks if content get is supported
54 * Implementation of EailItemParent->is_content_get_supported callback.
56 * @param parent EailItemParent instance
57 * @param item EailItem instance
58 * @returns always FALSE
61 eail_multibuttonentry_content_get_support(EailItemParent *parent,
68 * @brief Gets the name of a multibuttonentry's child
70 * Implementation of get_item_name callback of EailItemParent interface.
72 * @param parent EailItemParent instance representing a multibuttonentry
73 * @param item Multibuttonentry EailItem instance representing a child
75 * @returns string representing the name of the child
78 eail_multibuttonentry_item_name_get(EailItemParent *parent, EailItem *item)
80 Elm_Object_Item *it = eail_item_get_item(item);
81 /*that will work only for default theme*/
84 return elm_object_item_part_text_get(it, NULL);
88 * @brief EailItemParent interface initializer
90 * Initialization of callbacks used by EailItemParent interface.
92 * @param iface EailItemParentIface instance
95 eail_item_parent_interface_init(EailItemParentIface *iface)
97 iface->is_content_get_supported = eail_multibuttonentry_content_get_support;
98 iface->get_item_name = eail_multibuttonentry_item_name_get;
102 * @brief Helper function for getting multibuttonentry text
104 * @param text an AtkText (EailMultibutton object)
106 * @return string representation of multibutton entry text
109 _eail_multibuttonentry_get_entry_string(AtkText *text)
111 const gchar *string = NULL;
112 Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(text));
113 Evas_Object *entry = elm_multibuttonentry_entry_get(widget);
116 string = elm_entry_entry_get(entry);
118 /* if entry string is empty then trying to return "guide" part*/
119 if (!string || 0 == g_strcmp0(string, ""))
121 /* If there are some children of widget, then it means that guide
122 * is not visible. So returning guide as text only if no children
124 if (!elm_multibuttonentry_items_get(widget))
125 string = elm_object_part_text_get(widget, "guide");
132 * @brief Gets text bounded by start_offset and end_offset
134 * Use g_free() to free the returned string.
136 * @param text AtkText instance
137 * @param start_offset start position
138 * @param end_offset end position or -1 for the end of the string
139 * @return string containing text from start_offset up to, but not including
143 eail_multibuttonentry_get_text(AtkText *text,
147 const gchar *string = NULL;
149 string = _eail_multibuttonentry_get_entry_string(text);
151 return eail_get_substring(string, start_offset, end_offset);
155 * @brief Gets the character at offset
157 * @param text AtkText instance
158 * @param offset offset to obtain the character from
159 * @return char representing the character at given offset
162 eail_multibuttonentry_get_character_at_offset(AtkText *text,
165 gunichar character = '\0';
167 character = g_utf8_get_char(
168 g_utf8_offset_to_pointer
169 (_eail_multibuttonentry_get_entry_string(text), offset));
175 * @brief Gets the length of text
177 * @param text AtkText instance
178 * @return integer representing text's length
181 eail_multibuttonentry_get_character_count(AtkText *text)
184 const gchar *string_text = NULL;
186 string_text = _eail_multibuttonentry_get_entry_string(text);
187 if (!string_text) return count;
189 count = g_utf8_strlen(string_text, -1);
195 * @brief AktText initialization function
197 * @param iface AtkTextIface instance
200 atk_text_interface_init(AtkTextIface *iface)
202 iface->get_text = eail_multibuttonentry_get_text;
203 iface->get_character_at_offset = eail_multibuttonentry_get_character_at_offset;
204 iface->get_character_count = eail_multibuttonentry_get_character_count;
208 * @brief Sets text contents of text
210 * @param text AtkEditableText instance
211 * @param string new text to be set
214 eail_multibuttonentry_set_text_contents(AtkEditableText *text,
220 widget = eail_widget_get_widget(EAIL_WIDGET(text));
223 entry = elm_multibuttonentry_entry_get(widget);
226 if (elm_multibuttonentry_editable_get(widget))
227 elm_entry_entry_set(entry, string);
231 * @brief Copies text content from entry to clipboard
233 * @param text AtkEditableText instance
234 * @param start_pos index of copied text's first character
235 * @param end_pos index of last copied text's last character
238 eail_multibuttonentry_copy_text(AtkEditableText *text,
244 const char *entry_text;
248 widget = eail_widget_get_widget(EAIL_WIDGET(text));
251 entry = elm_multibuttonentry_entry_get(widget);
252 entry_text = elm_entry_entry_get(entry);
253 tmp = eail_get_substring(entry_text, start_pos, end_pos);
254 eail_clipboard_set_text(tmp);
259 * @brief Cuts text content from entry to clipboard
261 * @param text AtkEditableText instance
262 * @param start_pos index of cut text's first character
263 * @param end_pos index of cut text's last character
266 eail_multibuttonentry_cut_text(AtkEditableText *text,
272 const char *entry_text;
277 widget = eail_widget_get_widget(EAIL_WIDGET(text));
278 if (!widget || !elm_multibuttonentry_editable_get(widget)) return;
280 entry = elm_multibuttonentry_entry_get(widget);
281 entry_text = elm_entry_entry_get(entry);
282 tmp = eail_get_substring(entry_text, start_pos, end_pos);
283 eail_clipboard_set_text(tmp);
286 s = g_string_new(entry_text);
287 s = g_string_erase(s, start_pos, end_pos - start_pos);
289 elm_entry_entry_set(entry, s->str);
290 g_string_free(s, TRUE);
294 * @brief Pastes text content from clipboard into entry
296 * @param text AtkEditableText instance
297 * @param position index of pasted text's first character
300 eail_multibuttonentry_paste_text(AtkEditableText *text,
304 Evas_Object *entry = NULL;
308 widget = eail_widget_get_widget(EAIL_WIDGET(text));
309 if (!widget || !elm_multibuttonentry_editable_get(entry))
312 entry = elm_multibuttonentry_entry_get(widget);
313 s = g_string_new(elm_entry_entry_get(entry));
314 tmp = eail_clipboard_get_text();
315 s = g_string_insert(s, position, tmp);
316 elm_entry_entry_set(entry, s->str);
317 g_string_free(s, TRUE);
321 * @brief Deletes text between start_pos and end_pos but not
324 * @param text AtkEditableText instance
325 * @param start_pos start position
326 * @param end_pos end position
329 eail_multibuttonentry_delete_text(AtkEditableText *text,
337 widget = eail_widget_get_widget(EAIL_WIDGET(text));
338 if (!widget || !elm_multibuttonentry_editable_get(widget)) return;
340 entry = elm_multibuttonentry_entry_get(widget);
341 s = g_string_new(elm_entry_entry_get(entry));
342 s = g_string_erase(s, start_pos, end_pos-start_pos);
343 elm_entry_entry_set(entry, s->str);
344 g_string_free(s, TRUE);
348 * @brief Inserts text at the given position
350 * After the call it points at the position after the newly inserted text.
352 * @param text AtkEditableText instance
353 * @param string string to insert
354 * @param length string length
355 * @param [out] position position to insert the text
359 eail_multibuttonentry_insert_text(AtkEditableText *text,
368 widget = eail_widget_get_widget(EAIL_WIDGET(text));
369 if (!widget || !elm_multibuttonentry_editable_get(widget))
372 entry = elm_multibuttonentry_entry_get(widget);
373 s = g_string_new(elm_entry_entry_get(entry));
374 s = g_string_insert_len(s, *position, string, length);
375 elm_entry_entry_set(entry, s->str);
376 g_string_free(s, TRUE);
381 * @brief Initialization for AtkEditableTextIface interface
383 * Function called upon instance creation.
385 * It initializes AtkText interface
386 * implementation i.e hooks method pointers in the interface structure
387 * to the implementing class's implementation.
389 * @param iface AtkEditableTextIface instance
392 atk_editable_text_interface_init(AtkEditableTextIface *iface)
394 iface->set_text_contents = eail_multibuttonentry_set_text_contents;
395 iface->copy_text = eail_multibuttonentry_copy_text;
396 iface->cut_text = eail_multibuttonentry_cut_text;
397 iface->paste_text = eail_multibuttonentry_paste_text;
398 iface->delete_text = eail_multibuttonentry_delete_text;
399 iface->insert_text = eail_multibuttonentry_insert_text;
403 * @brief 'expand' action callback
405 * @param action AtkAction instance
406 * @param data user data passed to callback
408 * @returns TRUE on action success, FALSE otherwise
411 eail_multibuttonentry_action_expand_cb(AtkAction *action, void *data)
415 widget = eail_widget_get_widget(EAIL_WIDGET(action));
416 if (!widget) return FALSE;
418 if ((elm_object_disabled_get(widget)) || (!evas_object_visible_get(widget)))
421 if (elm_multibuttonentry_expanded_get(widget)) return FALSE;
423 elm_multibuttonentry_expanded_set(widget, EINA_TRUE);
424 atk_object_notify_state_change(ATK_OBJECT(action), ATK_STATE_EXPANDED, TRUE);
430 * @brief 'shrink' action callback
432 * @param action AtkAction instance
433 * @param data user data passed to callback
435 * @returns TRUE on action success, FALSE otherwise
438 eail_multibuttonentry_action_shrink_cb(AtkAction *action, void *data)
442 widget = eail_widget_get_widget(EAIL_WIDGET(action));
443 if (!widget) return FALSE;
445 if ((elm_object_disabled_get(widget)) || (!evas_object_visible_get(widget)))
448 if (!elm_multibuttonentry_expanded_get(widget)) return FALSE;
450 elm_multibuttonentry_expanded_set(widget, EINA_FALSE);
451 atk_object_notify_state_change(ATK_OBJECT(action), ATK_STATE_EXPANDED, FALSE);
457 * @brief Registers multibuttonentry's actions
459 * @param action_widget EailActionWidget instance
461 static void eail_multibuttonentry_actions_init(EailActionWidget *action_widget)
463 eail_action_widget_action_append(action_widget, "expand", NULL,
464 eail_multibuttonentry_action_expand_cb);
465 eail_action_widget_action_append(action_widget, "shrink", NULL,
466 eail_multibuttonentry_action_shrink_cb);
470 * @brief Handler for "item,added" event, used to notify about multibuttonentry
473 * @param data passed to callback
474 * @param obj object that raised event
475 * @param event_info additional event info (item is passed here)
478 eail_multibuttonentry_item_handle_added_event(void *data,
482 Elm_Object_Item *item = (Elm_Object_Item *) event_info;
483 AtkObject *atk_item = NULL, *atk_parent = NULL;
485 atk_parent = ATK_OBJECT(data);
486 if (!atk_parent) return;
488 atk_item = eail_factory_get_item_atk_obj
489 (item, ATK_ROLE_LABEL, atk_parent);
491 if (!atk_item) return;
493 eail_emit_children_changed_obj(TRUE, atk_parent, atk_item);
497 * @brief Handler for "item,deleted" event, used to notify about
498 * multibuttonentry content changes
500 * @param data passed to callback
501 * @param obj object that raised event
502 * @param event_info additional event info (item is passed here)
505 eail_multibuttonentry_item_handle_removed_event(void *data,
509 Elm_Object_Item *item = (Elm_Object_Item *) event_info;
510 AtkObject *atk_item = NULL, *atk_parent = NULL;
512 atk_parent = ATK_OBJECT(data);
513 if (!atk_parent) return;
515 atk_item = eail_factory_get_item_atk_obj
516 (item, ATK_ROLE_LABEL, atk_parent);
518 if (!atk_item) return;
520 eail_emit_children_changed_obj(FALSE, atk_parent, atk_item);
521 atk_object_notify_state_change(atk_item, ATK_STATE_DEFUNCT, TRUE);
523 DBG("Unregistering item from cache...");
524 eail_factory_unregister_item_from_cache(item);
528 * @brief EailMultibuttonentry type initializer
529 * @param obj AtkObject instance
530 * @param data initialization data
533 eail_multibuttonentry_initialize(AtkObject *obj, gpointer data)
535 Evas_Object *nested_widget = NULL;
536 ATK_OBJECT_CLASS(eail_multibuttonentry_parent_class)->initialize(obj, data);
537 obj->role = ATK_ROLE_ENTRY;
539 eail_multibuttonentry_actions_init(EAIL_ACTION_WIDGET(obj));
541 nested_widget = eail_widget_get_widget(EAIL_WIDGET(obj));
544 ERR("No evas object inside EailWidget was found");
548 evas_object_smart_callback_add(nested_widget, "item,added",
549 eail_multibuttonentry_item_handle_added_event, obj);
550 evas_object_smart_callback_add(nested_widget, "item,deleted",
551 eail_multibuttonentry_item_handle_removed_event, obj);
555 * @brief EailMultibuttonentry instance initializer
557 * @param multibuttonentry EailMultibuttonentry instance
560 eail_multibuttonentry_init(EailMultibuttonentry *multibuttonentry)
565 * @brief Gets obj's state set
567 * The caller must unreference it when it is no longer needed.
569 * @param obj AtkObject instance
570 * @return AtkStateSet containing object's state set
573 eail_multibuttonentry_ref_state_set(AtkObject *obj)
575 AtkStateSet *state_set;
578 g_return_val_if_fail(EAIL_MULTIBUTTONENTRY(obj), NULL);
580 widget = eail_widget_get_widget(EAIL_WIDGET(obj));
581 state_set = ATK_OBJECT_CLASS(eail_multibuttonentry_parent_class)->ref_state_set(obj);
583 if (!widget) return state_set;
585 if (elm_multibuttonentry_expanded_get(widget))
587 atk_state_set_add_state(state_set, ATK_STATE_EXPANDED);
589 if (elm_multibuttonentry_editable_get(widget))
590 atk_state_set_add_state(state_set, ATK_STATE_EDITABLE);
594 atk_state_set_add_state(state_set, ATK_STATE_DEFAULT);
601 * @brief Gets the list of multibuttonentry's items
603 * @param multibuttonentry EailMultibuttonentry instance
604 * @return Eina_List containing multibuttonentry's items
606 static const Eina_List *
607 eail_multibuttonentry_get_items(EailMultibuttonentry *multibuttonentry)
609 Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(multibuttonentry));
610 if (!widget) return NULL;
612 return elm_multibuttonentry_items_get(widget);
616 * @brief Gets the number of accessible children of the accessible
618 * @param obj AtkObject instance
619 * @return integer representing the number of accessible children of the accessible
622 eail_multibuttonentry_get_n_children(AtkObject *obj)
625 const Eina_List *items;
627 items = eail_multibuttonentry_get_items(EAIL_MULTIBUTTONENTRY(obj));
628 n_items = eina_list_count(items);
634 * @brief Gets a reference to the specified child of obj
636 * The caller must unreference it when it is no longer needed.
638 * @param obj AtkObject instance
639 * @param i child index
640 * @return AtkObject containing reference to the specified child of obj
643 eail_multibuttonentry_ref_child(AtkObject *obj, gint i)
645 const Eina_List *items;
646 AtkObject *child = NULL;
648 items = eail_multibuttonentry_get_items(EAIL_MULTIBUTTONENTRY(obj));
649 if (eina_list_count(items) > i)
651 child = eail_factory_get_item_atk_obj
652 (eina_list_nth(items, i), ATK_ROLE_LABEL, obj);
657 ERR("Tried to ref child with index %d out of bounds!", i);
663 * @brief EailMultibuttonentry class initializer
665 * @param klass EailMultibuttonentryClass instance
668 eail_multibuttonentry_class_init(EailMultibuttonentryClass *klass)
670 AtkObjectClass *class = ATK_OBJECT_CLASS(klass);
672 class->initialize = eail_multibuttonentry_initialize;
673 class->get_n_children = eail_multibuttonentry_get_n_children;
674 class->ref_child = eail_multibuttonentry_ref_child;
675 class->ref_state_set = eail_multibuttonentry_ref_state_set;