Merge "custom eail widget implementation" into tizen
[platform/core/uifw/eail.git] / 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 Creates an AtkAttributeSet which consists of the default values of
186  * attributes for the text.
187  *
188  * This AtkAttributeSet should be freed by a call to
189  * atk_attribute_set_free()
190  *
191  * @param text AtkText instance
192  *
193  * @returns AtkAttributeSet containing default values of attributes
194  * at offset.
195  */
196 static AtkAttributeSet *
197 eail_text_get_default_attributes(AtkText *text)
198 {
199    AtkAttributeSet *at_set = NULL;
200
201    at_set = eail_utils_text_add_attribute
202        (at_set, ATK_TEXT_ATTR_WRAP_MODE,
203         atk_text_attribute_get_value(ATK_TEXT_ATTR_WRAP_MODE, 0));
204
205    at_set = eail_utils_text_add_attribute
206        (at_set, ATK_TEXT_ATTR_EDITABLE,
207         atk_text_attribute_get_value
208          (ATK_TEXT_ATTR_EDITABLE, FALSE));
209
210    return at_set;
211 }
212
213 /**
214  * @brief Creates an AtkAttributeSet which consists of the attributes
215  * explicitly set at the position offset in the text.
216  *
217  * start_offset and end_offset are set to the start and end of the range around offset
218  * where the attributes are invariant.
219  *
220  * Note that end_offset is the offset of the first character after the range.
221  *
222  * This AtkAttributeSet should be freed by a call to
223  * atk_attribute_set_free()
224  *
225  * @param text AtkText instance
226  * @param offset the offset at which to get the attributes
227  * @param [out] start_offset start offset of the range
228  * @param [out] end_offset end offset of the range
229  *
230  * @returns an AtkAttributeSet which contains the attributes explicitly set at
231  * offset.
232  */
233 static AtkAttributeSet *
234 eail_text_get_run_attributes(AtkText *text,
235                              gint offset,
236                              gint *start_offset,
237                              gint *end_offset)
238 {
239    AtkAttributeSet *at_set = NULL;
240    Evas_Object *widget = eail_widget_get_widget(EAIL_WIDGET(text));
241    gint len = eail_text_get_character_count(ATK_TEXT(text));
242
243    if (!widget || offset >= len)
244      {
245         *start_offset = -1;
246         *end_offset = -1;
247
248         return NULL;
249      }
250
251    *start_offset = 0;
252    *end_offset = len;
253
254    /* NOTE: Elm_Wrap_Type value is in 100% compatible with ATK wrap modes, so
255     * no additional conversion is needed*/
256    Elm_Wrap_Type wrap_type = ELM_WRAP_NONE;
257    at_set = eail_utils_text_add_attribute
258        (at_set, ATK_TEXT_ATTR_WRAP_MODE,
259         atk_text_attribute_get_value
260          (ATK_TEXT_ATTR_WRAP_MODE, wrap_type));
261
262
263    at_set = eail_utils_text_add_attribute
264        (at_set, ATK_TEXT_ATTR_EDITABLE,
265         atk_text_attribute_get_value
266          (ATK_TEXT_ATTR_EDITABLE, FALSE));
267
268    return at_set;
269 }
270 /**
271  * @brief AtkText interface initializer
272  *
273  * @param iface AtkTextIface instance
274  */
275 static void
276 atk_text_interface_init(AtkTextIface *iface)
277 {
278    iface->get_text = eail_text_get_text;
279    iface->get_character_at_offset = eail_text_get_character_at_offset;
280    iface->get_character_count = eail_text_get_character_count;
281    iface->get_default_attributes = eail_text_get_default_attributes;
282    iface->get_run_attributes = eail_text_get_run_attributes;
283 }