Add get_default_attributes and get_run_attributes
[platform/core/uifw/eail.git] / eail / eail / eail_text.c
1 /*
2  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 /**
21  * @file eail_text.c
22  * @brief EailText implementation
23  */
24
25 #include <Elementary.h>
26
27 #include "eail_text.h"
28 #include "eail_factory.h"
29 #include "eail_utils.h"
30
31 /*
32  * Implementation of the *AtkObject* interface
33  */
34
35 static void atk_text_interface_init(AtkTextIface *iface);
36
37 /**
38  * @brief EailText type definition
39  */
40 G_DEFINE_TYPE_WITH_CODE(EailText,
41                         eail_text,
42                         EAIL_TYPE_WIDGET,
43                         G_IMPLEMENT_INTERFACE(ATK_TYPE_TEXT,
44                                               atk_text_interface_init));
45
46 /**
47  * @brief EailText initializer
48  *
49  * @param obj AtkObject instance
50  * @param data initialization data
51  */
52 static void
53 eail_text_initialize(AtkObject *obj, gpointer data)
54 {
55    ATK_OBJECT_CLASS(eail_text_parent_class)->initialize(obj, data);
56
57    obj->role = ATK_ROLE_TEXT;
58 }
59
60 /**
61  * @brief Gets the accessible name of obj
62  *
63  * Returns obj accessible name if assigned, obj text content otherwise
64  *
65  * @param obj AtkObject instance
66  * @returns string representing the accessible name of obj if assigned,
67  * obj text content otherwise
68  */
69 static const gchar*
70 eail_text_get_name(AtkObject *obj)
71 {
72    const gchar *name;
73    Evas_Object *widget;
74
75    name = ATK_OBJECT_CLASS(eail_text_parent_class)->get_name(obj);
76    if (NULL != name)
77      return name;
78
79    widget = eail_widget_get_widget(EAIL_WIDGET(obj));
80    if (widget)
81      name = (const gchar*)elm_object_text_get(widget);
82
83    return name;
84 }
85
86 /**
87  * @brief EailText instance initializer
88  *
89  * @param text EailText instance
90  */
91 static void
92 eail_text_init(EailText *text)
93 {
94 }
95
96 /**
97  * @brief EailText class initializer
98  *
99  * @param klass EailTextClass instance
100  */
101 static void
102 eail_text_class_init(EailTextClass *klass)
103 {
104    AtkObjectClass *atk_class = ATK_OBJECT_CLASS(klass);
105
106    atk_class->initialize = eail_text_initialize;
107    atk_class->get_name = eail_text_get_name;
108 }
109
110 /*
111  * Implementation of the *AtkText* interface
112  */
113
114 /**
115  * @brief Gets text bounded by start_offset and end_offset
116  *
117  * Use g_free() to free the returned string
118  *
119  * @param text AtkText instance
120  * @param start_offset start position
121  * @param end_offset end position, -1 for the end of the string
122  * @return string containing text from start_offset up to, but not including
123  * end_offset
124  */
125 static gchar*
126 eail_text_get_text(AtkText   *text,
127                    gint       start_offset,
128                    gint       end_offset)
129 {
130    gchar *string = NULL;
131    Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(text));
132
133    if (widget)
134      string = (gchar *)elm_object_text_get(widget);
135
136    return eail_get_substring(string, start_offset, end_offset);
137 }
138
139 /**
140  * @brief Gets the character at offset
141  *
142  * @param text AtkText instance
143  * @param offset character offset
144  * @return char representing the character at offset
145  */
146 static gunichar
147 eail_text_get_character_at_offset(AtkText    *text,
148                                   gint        offset)
149 {
150    gunichar character = '\0';
151    Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(text));
152
153    if (widget)
154      character = g_utf8_get_char(
155          g_utf8_offset_to_pointer(elm_object_text_get(widget), offset));
156
157    return character;
158 }
159
160 /**
161  * @brief Gets the text's length
162  *
163  * @param text AtkText instance
164  * @return integer representing the text length
165  */
166 static gint
167 eail_text_get_character_count(AtkText *text)
168 {
169    gint count = 0;
170    const gchar *string_text = NULL;
171
172    Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(text));
173
174    if (!widget) return count;
175
176    string_text = elm_object_text_get(widget);
177    if (!string_text) return count;
178
179    count = g_utf8_strlen(string_text, -1);
180
181    return count;
182 }
183
184 /**
185  * @brief Adds attribute to attribute set
186  *
187  * @param attrib_set AtkAttributeSet to add the attribute to
188  * @param attr AtkTextAttrribute to be added
189  * @param value attribute value
190  *
191  * Creates an AtkAttribute from attr and value, and adds it
192  * to attrib_set.
193  *
194  * @returns AtkAttributeSet containing set with added attribute
195  **/
196 AtkAttributeSet*
197 _eail_text_add_attribute(AtkAttributeSet *attrib_set,
198                          AtkTextAttribute attr,
199                          gchar           *value)
200 {
201    AtkAttributeSet *return_set;
202    AtkAttribute *at = g_malloc (sizeof (AtkAttribute));
203    at->name = g_strdup (atk_text_attribute_get_name (attr));
204    at->value = value;
205    return_set = g_slist_prepend(attrib_set, at);
206    return return_set;
207 }
208
209 /**
210  * @brief Creates an AtkAttributeSet which consists of the default values of
211  * attributes for the text.
212  *
213  * This AtkAttributeSet should be freed by a call to
214  * atk_attribute_set_free()
215  *
216  * @param text AtkText instance
217  *
218  * @returns AtkAttributeSet containing default values of attributes
219  * at offset.
220  */
221 AtkAttributeSet *
222 eail_text_get_default_attributes(AtkText *text)
223 {
224    AtkAttributeSet *at_set = NULL;
225
226    at_set = _eail_text_add_attribute
227        (at_set, ATK_TEXT_ATTR_WRAP_MODE,
228         g_strdup
229         (atk_text_attribute_get_value(ATK_TEXT_ATTR_WRAP_MODE, 0)));
230
231    at_set = _eail_text_add_attribute
232        (at_set, ATK_TEXT_ATTR_EDITABLE,
233         g_strdup
234         (atk_text_attribute_get_value
235          (ATK_TEXT_ATTR_EDITABLE, FALSE)));
236
237    return at_set;
238 }
239
240 /**
241  * @brief Creates an AtkAttributeSet which consists of the attributes
242  * explicitly set at the position offset in the text.
243  *
244  * start_offset and end_offset are set to the start and end of the range around offset
245  * where the attributes are invariant.
246  *
247  * Note that end_offset is the offset of the first character after the range.
248  *
249  * This AtkAttributeSet should be freed by a call to
250  * atk_attribute_set_free()
251  *
252  * @param text AtkText instance
253  * @param offset the offset at which to get the attributes
254  * @param [out] start_offset start offset of the range
255  * @param [out] end_offset end offset of the range
256  *
257  * @returns an AtkAttributeSet which contains the attributes explicitly set at
258  * offset.
259  */
260 AtkAttributeSet *
261 eail_text_get_run_attributes(AtkText *text,
262                              gint offset,
263                              gint *start_offset,
264                              gint *end_offset)
265 {
266    AtkAttributeSet *at_set = NULL;
267    Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(text));
268    gint len = eail_text_get_character_count(ATK_TEXT(text));
269
270    if (!widget || offset >= len)
271      {
272         *start_offset = -1;
273         *end_offset = -1;
274
275         return NULL;
276      }
277
278    *start_offset = 0;
279    *end_offset = len;
280
281    /* NOTE: Elm_Wrap_Type value is in 100% compatible with ATK wrap modes, so
282     * no additional conversion is needed*/
283    Elm_Wrap_Type wrap_type = ELM_WRAP_NONE;
284    at_set = _eail_text_add_attribute
285        (at_set, ATK_TEXT_ATTR_WRAP_MODE,
286         g_strdup
287         (atk_text_attribute_get_value
288          (ATK_TEXT_ATTR_WRAP_MODE, wrap_type)));
289
290
291    at_set = _eail_text_add_attribute
292        (at_set, ATK_TEXT_ATTR_EDITABLE,
293         g_strdup
294         (atk_text_attribute_get_value
295          (ATK_TEXT_ATTR_EDITABLE, FALSE)));
296
297    return at_set;
298 }
299 /**
300  * @brief AtkText interface initializer
301  *
302  * @param iface AtkTextIface instance
303  */
304 static void
305 atk_text_interface_init(AtkTextIface *iface)
306 {
307    iface->get_text = eail_text_get_text;
308    iface->get_character_at_offset = eail_text_get_character_at_offset;
309    iface->get_character_count = eail_text_get_character_count;
310    iface->get_default_attributes = eail_text_get_default_attributes;
311    iface->get_run_attributes = eail_text_get_run_attributes;
312 }