create rotation job and EAPI e_border_rotation_set
[platform/core/uifw/e17.git] / src / bin / e_editable.c
1 #include "e.h"
2
3 #define E_EDITABLE_CURSOR_MARGIN 5
4
5 #define E_EDITABLE_BLOCK_SIZE    128
6 #define E_EDITABLE_SIZE_TO_ALLOC(length) \
7   (((length) + (E_EDITABLE_BLOCK_SIZE - 1)) / E_EDITABLE_BLOCK_SIZE) * E_EDITABLE_BLOCK_SIZE
8
9 typedef struct _E_Editable_Smart_Data E_Editable_Smart_Data;
10
11 struct _E_Editable_Smart_Data
12 {
13    Evas_Object *clip_object;
14    Evas_Object *event_object;
15    Evas_Object *text_object;
16    Evas_Object *cursor_object;
17    Evas_Object *selection_object;
18
19    int          cursor_pos;
20    int          cursor_visible;
21    int          selection_pos;
22    int          selection_visible;
23    int          password_mode;
24
25    char        *text;
26    int          char_length;
27    int          unicode_length;
28    int          allocated_length;
29
30    int          cursor_width;
31    int          selection_on_fg;
32    int          average_char_w;
33    int          average_char_h;
34 };
35
36 /* local subsystem functions */
37 static int  _e_editable_text_insert(Evas_Object *editable, int pos, const char *text);
38 static int  _e_editable_text_delete(Evas_Object *editable, int start, int end);
39 static void _e_editable_cursor_update(Evas_Object *editable);
40 static void _e_editable_selection_update(Evas_Object *editable);
41 static void _e_editable_text_update(Evas_Object *editable);
42 static void _e_editable_text_position_update(Evas_Object *editable, Evas_Coord real_w);
43 static int  _e_editable_char_geometry_get_from_pos(Evas_Object *editable, int utf_pos, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch);
44
45 static void _e_editable_smart_add(Evas_Object *object);
46 static void _e_editable_smart_del(Evas_Object *object);
47 static void _e_editable_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y);
48 static void _e_editable_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h);
49 static void _e_editable_smart_show(Evas_Object *object);
50 static void _e_editable_smart_hide(Evas_Object *object);
51 static void _e_editable_color_set(Evas_Object *object, int r, int g, int b, int a);
52 static void _e_editable_clip_set(Evas_Object *object, Evas_Object *clip);
53 static void _e_editable_clip_unset(Evas_Object *object);
54
55 /* local subsystem globals */
56 static Evas_Smart *_e_editable_smart = NULL;
57 static int _e_editable_smart_use = 0;
58
59 /* externally accessible functions */
60
61 /**
62  * Creates a new editable object. An editable object is an evas smart object in
63  * which the user can type some single-line text, select it and delete it.
64  *
65  * @param evas The evas where to add the editable object
66  * @return Returns the new editable object
67  */
68 EAPI Evas_Object *
69 e_editable_add(Evas *evas)
70 {
71    if (!_e_editable_smart)
72      {
73         static const Evas_Smart_Class sc =
74         {
75            "e_editable",
76            EVAS_SMART_CLASS_VERSION,
77            _e_editable_smart_add,
78            _e_editable_smart_del,
79            _e_editable_smart_move,
80            _e_editable_smart_resize,
81            _e_editable_smart_show,
82            _e_editable_smart_hide,
83            _e_editable_color_set,
84            _e_editable_clip_set,
85            _e_editable_clip_unset,
86            NULL,
87            NULL,
88            NULL,
89            NULL,
90            NULL,
91            NULL,
92            NULL
93         };
94         _e_editable_smart = evas_smart_class_new(&sc);
95         _e_editable_smart_use = 0;
96      }
97
98    return evas_object_smart_add(evas, _e_editable_smart);
99 }
100
101 /**
102  * Sets the theme group to be used by the editable object.
103  * This function has to be called, or the cursor and the selection won't be
104  * visible.
105  *
106  * @param editable an editable object
107  * @param category the theme category to use for the editable object
108  * @param group the theme group to use for the editable object
109  */
110 EAPI void
111 e_editable_theme_set(Evas_Object *editable, const char *category, const char *group)
112 {
113    E_Editable_Smart_Data *sd;
114    char *obj_group;
115    const char *data;
116
117    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
118    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
119      return;
120    if ((!category) || (!group)) return;
121    obj_group = alloca(strlen(group) + strlen("/selection") + 1);
122
123    /* Gets the theme for the text object */
124    sprintf(obj_group, "%s/text", group);
125    e_theme_edje_object_set(sd->text_object, category, obj_group);
126    sd->average_char_w = -1;
127    sd->average_char_h = -1;
128
129    /* Gets the theme for the cursor */
130    sprintf(obj_group, "%s/cursor", group);
131    e_theme_edje_object_set(sd->cursor_object, category, obj_group);
132
133    edje_object_size_min_get(sd->cursor_object, &sd->cursor_width, NULL);
134    if (sd->cursor_width < 1) sd->cursor_width = 1;
135
136    /* Gets the theme for the selection */
137    sprintf(obj_group, "%s/selection", group);
138    e_theme_edje_object_set(sd->selection_object, category, obj_group);
139
140    data = edje_object_data_get(sd->selection_object, "on_foreground");
141    if ((data) && (strcmp(data, "1") == 0))
142      {
143         sd->selection_on_fg = 1;
144         evas_object_stack_above(sd->selection_object, sd->text_object);
145      }
146    else
147      {
148         sd->selection_on_fg = 0;
149         evas_object_stack_below(sd->selection_object, sd->text_object);
150      }
151
152    _e_editable_text_update(editable);
153    _e_editable_cursor_update(editable);
154 }
155
156 /**
157  * Sets whether or not the editable object is in password mode. In password
158  * mode, the editable object displays '*' instead of the characters
159  *
160  * @param editable an editable object
161  * @param password_mode 1 to turn on the password mode of the editable object,
162  * 0 to turn it off
163  */
164 EAPI void
165 e_editable_password_set(Evas_Object *editable, int password_mode)
166 {
167    E_Editable_Smart_Data *sd;
168
169    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
170    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
171      return;
172    if (sd->password_mode == password_mode) return;
173
174    sd->password_mode = password_mode;
175    _e_editable_text_update(editable);
176    _e_editable_cursor_update(editable);
177 }
178
179 /**
180  * Gets whether or not the editable is in password mode
181  *
182  * @param editable an editable object
183  * @return Returns 1 if the editable object is in the password mode, 0 otherwise
184  */
185 EAPI int
186 e_editable_password_get(Evas_Object *editable)
187 {
188    E_Editable_Smart_Data *sd;
189
190    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(0);
191    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
192      return 0;
193    return sd->password_mode;
194 }
195
196 /**
197  * Sets the text of the editable object
198  *
199  * @param editable an editable object
200  * @param text the text to set
201  */
202 EAPI void
203 e_editable_text_set(Evas_Object *editable, const char *text)
204 {
205    E_Editable_Smart_Data *sd;
206
207    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
208    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
209      return;
210
211    if (sd->password_mode) memset(sd->text, 0, sd->char_length);
212    E_FREE(sd->text);
213    sd->char_length = 0;
214    sd->unicode_length = 0;
215    sd->allocated_length = -1;
216
217    if (_e_editable_text_insert(editable, 0, text) <= 0)
218      {
219         sd->text = malloc((E_EDITABLE_BLOCK_SIZE + 1) * sizeof(char));
220         sd->text[0] = '\0';
221         sd->char_length = 0;
222         sd->unicode_length = 0;
223         sd->allocated_length = E_EDITABLE_BLOCK_SIZE;
224         _e_editable_text_update(editable);
225      }
226
227    sd->cursor_pos = sd->unicode_length;
228    sd->selection_pos = sd->unicode_length;
229    _e_editable_cursor_update(editable);
230 }
231
232 /**
233  * Gets the entire text of the editable object
234  *
235  * @param editable an editable object
236  * @return Returns the entire text of the editable object
237  */
238 EAPI const char *
239 e_editable_text_get(Evas_Object *editable)
240 {
241    E_Editable_Smart_Data *sd;
242
243    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(NULL);
244    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
245      return NULL;
246    return sd->text;
247 }
248
249 /**
250  * Gets a range of the text of the editable object, from position @a start to
251  * position @a end
252  *
253  * @param editable an editable object
254  * @param start the start position of the text range to get
255  * @param end the end position of the text range to get
256  * @return Returns the range of text. The returned string will have to be freed
257  */
258 EAPI char *
259 e_editable_text_range_get(Evas_Object *editable, int start, int end)
260 {
261    E_Editable_Smart_Data *sd;
262    char *range;
263    int start_id = 0, end_id = 0, i;
264
265    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(NULL);
266    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
267      return NULL;
268
269    start = E_CLAMP(start, 0, sd->unicode_length);
270    end = E_CLAMP(end, 0, sd->unicode_length);
271    if (end <= start) return NULL;
272
273    for (i = 0; i < end; i++)
274      {
275         end_id = evas_string_char_next_get(sd->text, end_id, NULL);
276         if (i < start) start_id = end_id;
277      }
278
279    if (end_id <= start_id) return NULL;
280
281    range = malloc((end_id - start_id + 1) * sizeof(char));
282    if (!range) return NULL;
283
284    strncpy(range, &sd->text[start_id], end_id - start_id);
285    range[end_id - start_id] = '\0';
286
287    return range;
288 }
289
290 /**
291  * Gets the unicode length of the text of the editable object. The unicode
292  * length is not always the length returned by strlen() since a UTF-8 char can
293  * take several bytes
294  *
295  * @param editable an editable object
296  * @return Returns the unicode length of the text of the editable object
297  */
298 EAPI int
299 e_editable_text_length_get(Evas_Object *editable)
300 {
301    E_Editable_Smart_Data *sd;
302
303    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(0);
304    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
305      return 0;
306    return sd->unicode_length;
307 }
308
309 /**
310  * Inserts some text at the given position in the editable object
311  *
312  * @param editable the editable object in which the text should be inserted
313  * @param pos the position where to insert the text
314  * @param text the text to insert
315  * @return Returns 1 if the text has been modified, 0 otherwise
316  */
317 EAPI int
318 e_editable_insert(Evas_Object *editable, int pos, const char *text)
319 {
320    E_Editable_Smart_Data *sd;
321    int unicode_length;
322
323    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(0);
324    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
325      return 0;
326
327    unicode_length = _e_editable_text_insert(editable, pos, text);
328    if (unicode_length <= 0) return 0;
329
330    if (sd->cursor_pos >= pos)
331      e_editable_cursor_pos_set(editable, sd->cursor_pos + unicode_length);
332    if (sd->selection_pos >= pos)
333      e_editable_selection_pos_set(editable, sd->selection_pos + unicode_length);
334
335    _e_editable_text_position_update(editable, -1);
336    return 1;
337 }
338
339 /**
340  * Deletes the text of the editable object, between position "start" and
341  * position "end"
342  *
343  * @param editable the editable object in which the text should be deleted
344  * @param start the position of the first char to delete
345  * @param end the position of the last char to delete
346  * @return Returns 1 if the text has been modified, 0 otherwise
347  */
348 EAPI int
349 e_editable_delete(Evas_Object *editable, int start, int end)
350 {
351    E_Editable_Smart_Data *sd;
352    int unicode_length;
353
354    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(0);
355    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
356      return 0;
357
358    unicode_length = _e_editable_text_delete(editable, start, end);
359    if (unicode_length <= 0) return 0;
360
361    if (sd->cursor_pos > end)
362      e_editable_cursor_pos_set(editable, sd->cursor_pos - unicode_length);
363    else if (sd->cursor_pos > start)
364      e_editable_cursor_pos_set(editable, start);
365
366    if (sd->selection_pos > end)
367      e_editable_selection_pos_set(editable, sd->selection_pos - unicode_length);
368    else if (sd->selection_pos > start)
369      e_editable_selection_pos_set(editable, start);
370
371    _e_editable_text_position_update(editable, -1);
372    return 1;
373 }
374
375 /**
376  * Moves the cursor of the editable object to the given position
377  *
378  * @param editable an editable object
379  * @param pos the position where to move the cursor
380  */
381 EAPI void
382 e_editable_cursor_pos_set(Evas_Object *editable, int pos)
383 {
384    E_Editable_Smart_Data *sd;
385
386    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
387    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
388      return;
389
390    pos = E_CLAMP(pos, 0, sd->unicode_length);
391    if (sd->cursor_pos == pos) return;
392
393    sd->cursor_pos = pos;
394    _e_editable_cursor_update(editable);
395 }
396
397 /**
398  * Gets the position of the cursor of the editable object
399  *
400  * @param editable an editable object
401  * @return Returns the position of the cursor of the editable object
402  */
403 EAPI int
404 e_editable_cursor_pos_get(Evas_Object *editable)
405 {
406    E_Editable_Smart_Data *sd;
407
408    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(0);
409    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
410      return 0;
411    return sd->cursor_pos;
412 }
413
414 /**
415  * Gets the geometry of the cursor of the editable object
416  *
417  * @param editable an editable object
418  * @param cx the x of the cursor
419  * @param cy the y of the cursor
420  * @param cw the width of the cursor
421  * @param ch the height of the cursor
422  */
423 EAPI void
424 e_editable_cursor_geometry_get(Evas_Object *editable, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
425 {
426    E_Editable_Smart_Data *sd;
427
428    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
429    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
430      return;
431
432    evas_object_geometry_get(sd->cursor_object, cx, cy, cw, ch);
433 }
434
435 /**
436  * Moves the cursor to the start of the editable object
437  *
438  * @param editable an editable object
439  */
440 EAPI void
441 e_editable_cursor_move_to_start(Evas_Object *editable)
442 {
443    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
444    if (!editable)
445      return;
446    e_editable_cursor_pos_set(editable, 0);
447 }
448
449 /**
450  * Moves the cursor to the end of the editable object
451  *
452  * @param editable an editable object
453  */
454 EAPI void
455 e_editable_cursor_move_to_end(Evas_Object *editable)
456 {
457    E_Editable_Smart_Data *sd;
458
459    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
460    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
461      return;
462    e_editable_cursor_pos_set(editable, sd->unicode_length);
463 }
464
465 /**
466  * Moves the cursor backward by one character offset
467  *
468  * @param editable an editable object
469  */
470 EAPI void
471 e_editable_cursor_move_left(Evas_Object *editable)
472 {
473    E_Editable_Smart_Data *sd;
474
475    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
476    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
477      return;
478    e_editable_cursor_pos_set(editable, sd->cursor_pos - 1);
479 }
480
481 /**
482  * Moves the cursor forward by one character offset
483  *
484  * @param editable an editable object
485  */
486 EAPI void
487 e_editable_cursor_move_right(Evas_Object *editable)
488 {
489    E_Editable_Smart_Data *sd;
490
491    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
492    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
493      return;
494    e_editable_cursor_pos_set(editable, sd->cursor_pos + 1);
495 }
496
497 /**
498  * Shows the cursor of the editable object
499  *
500  * @param editable the editable object whose cursor should be shown
501  */
502 EAPI void
503 e_editable_cursor_show(Evas_Object *editable)
504 {
505    E_Editable_Smart_Data *sd;
506
507    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
508    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
509      return;
510    if (sd->cursor_visible) return;
511
512    sd->cursor_visible = 1;
513    if (evas_object_visible_get(editable))
514      {
515         evas_object_show(sd->cursor_object);
516         edje_object_signal_emit(sd->cursor_object, "e,action,show,cursor", "e");
517      }
518 }
519
520 /**
521  * Hides the cursor of the editable object
522  *
523  * @param editable the editable object whose cursor should be hidden
524  */
525 EAPI void
526 e_editable_cursor_hide(Evas_Object *editable)
527 {
528    E_Editable_Smart_Data *sd;
529
530    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
531    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
532      return;
533    if (!sd->cursor_visible) return;
534
535    sd->cursor_visible = 0;
536    evas_object_hide(sd->cursor_object);
537 }
538
539 /**
540  * Moves the selection bound of the editable object to the given position
541  *
542  * @param editable an editable object
543  * @param pos the position where to move the selection bound
544  */
545 EAPI void
546 e_editable_selection_pos_set(Evas_Object *editable, int pos)
547 {
548    E_Editable_Smart_Data *sd;
549
550    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
551    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
552      return;
553
554    pos = E_CLAMP(pos, 0, sd->unicode_length);
555    if (sd->selection_pos == pos) return;
556
557    sd->selection_pos = pos;
558    _e_editable_selection_update(editable);
559 }
560
561 /**
562  * Gets the position of the selection bound of the editable object
563  *
564  * @param editable an editable object
565  * @return Returns the position of the selection bound of the editable object
566  */
567 EAPI int
568 e_editable_selection_pos_get(Evas_Object *editable)
569 {
570    E_Editable_Smart_Data *sd;
571
572    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(0);
573    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
574      return 0;
575    return sd->selection_pos;
576 }
577
578 /**
579  * Moves the selection bound to the start of the editable object
580  *
581  * @param editable an editable object
582  */
583 EAPI void
584 e_editable_selection_move_to_start(Evas_Object *editable)
585 {
586    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
587    if (!editable)
588      return;
589    e_editable_selection_pos_set(editable, 0);
590 }
591
592 /**
593  * Moves the selection bound to the end of the editable object
594  *
595  * @param editable an editable object
596  */
597 EAPI void
598 e_editable_selection_move_to_end(Evas_Object *editable)
599 {
600    E_Editable_Smart_Data *sd;
601
602    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
603    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
604      return;
605    e_editable_selection_pos_set(editable, sd->unicode_length);
606 }
607
608 /**
609  * Moves the selection bound backward by one character offset
610  *
611  * @param editable an editable object
612  */
613 EAPI void
614 e_editable_selection_move_left(Evas_Object *editable)
615 {
616    E_Editable_Smart_Data *sd;
617
618    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
619    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
620      return;
621    e_editable_selection_pos_set(editable, sd->selection_pos - 1);
622 }
623
624 /**
625  * Moves the selection bound forward by one character offset
626  *
627  * @param editable an editable object
628  */
629 EAPI void
630 e_editable_selection_move_right(Evas_Object *editable)
631 {
632    E_Editable_Smart_Data *sd;
633
634    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
635    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
636      return;
637    e_editable_selection_pos_set(editable, sd->selection_pos + 1);
638 }
639
640 /**
641  * Selects all the text of the editable object. The selection bound will be
642  * moved to the start of the editable object and the cursor will be moved to
643  * the end
644  *
645  * @param editable an editable object
646  */
647 EAPI void
648 e_editable_select_all(Evas_Object *editable)
649 {
650    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
651    e_editable_selection_move_to_start(editable);
652    e_editable_cursor_move_to_end(editable);
653 }
654
655 /**
656  * Unselects all the text of the editable object. The selection bound will be
657  * moved to the cursor position
658  *
659  * @param editable an editable object
660  */
661 EAPI void
662 e_editable_unselect_all(Evas_Object *editable)
663 {
664    E_Editable_Smart_Data *sd;
665
666    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
667    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
668      return;
669    e_editable_selection_pos_set(editable, sd->cursor_pos);
670 }
671
672 /**
673  * Selects the word at the provided character index
674  */
675 EAPI void
676 e_editable_select_word(Evas_Object *editable, int idx)
677 {
678    E_Editable_Smart_Data *sd;
679    int spos = 0, epos = -1, i = 0, pos = 0;
680
681    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
682    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
683      return;
684    if ((idx < 0) || (idx >= sd->unicode_length)) return;
685
686    while (i < sd->char_length)
687      {
688         if (sd->text[i] == ' ')
689           {
690              if (pos < idx) spos = pos + 1;
691              else if (pos > idx)
692                {
693                   epos = pos;
694                   break;
695                }
696           }
697         i = evas_string_char_next_get(sd->text, i, NULL);
698         pos++;
699      }
700    if (epos == -1) epos = pos;
701    e_editable_selection_pos_set(editable, spos);
702    e_editable_cursor_pos_set(editable, epos);
703 }
704
705 /**
706  * Shows the selection of the editable object
707  *
708  * @param editable an editable object
709  */
710 EAPI void
711 e_editable_selection_show(Evas_Object *editable)
712 {
713    E_Editable_Smart_Data *sd;
714
715    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
716    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
717      return;
718    if (sd->selection_visible) return;
719    sd->selection_visible = 1;
720    if ((evas_object_visible_get(editable)) &&
721        (sd->cursor_pos != sd->selection_pos))
722      evas_object_show(sd->selection_object);
723 }
724
725 /**
726  * Hides the selection of the editable object
727  *
728  * @param editable an editable object
729  */
730 EAPI void
731 e_editable_selection_hide(Evas_Object *editable)
732 {
733    E_Editable_Smart_Data *sd;
734
735    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
736    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
737      return;
738    if (!sd->selection_visible) return;
739    sd->selection_visible = 0;
740    evas_object_hide(sd->selection_object);
741 }
742
743 /**
744  * Gets the cursor position at the coords ( @a x, @a y ). It's used to know
745  * where to place the cursor or the selection bound on mouse evevents.
746  *
747  * @param editable an editable object
748  * @param x the x coord, relative to the editable object
749  * @param y the y coord, relative to the editable object
750  * @return Returns the position where to place the cursor according to the
751  * given coords
752  */
753 EAPI int
754 e_editable_pos_get_from_coords(Evas_Object *editable, Evas_Coord x, Evas_Coord y)
755 {
756    E_Editable_Smart_Data *sd;
757    const Evas_Object *text_obj;
758    Evas_Coord ox, oy;
759    Evas_Coord tx, ty, tw, th;
760    Evas_Coord cx, cw;
761    Evas_Coord canvas_x, canvas_y;
762    int idx, pos, i, j;
763    const char *text;
764
765    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(0);
766    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
767      return 0;
768    if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
769      return 0;
770
771    evas_object_geometry_get(editable, &ox, &oy, NULL, NULL);
772    evas_object_geometry_get(text_obj, &tx, &ty, &tw, &th);
773    canvas_x = ox + x;
774    canvas_y = oy + y;
775
776    if ((canvas_y < ty) || (canvas_x < tx))
777      pos = 0;
778    else if ((canvas_y > (ty + th)) || (canvas_x > (tx + tw)))
779      pos = sd->unicode_length;
780    else
781      {
782         idx = evas_object_text_char_coords_get(text_obj,
783                                                canvas_x - tx, canvas_y - ty,
784                                                &cx, NULL, &cw, NULL);
785         text = evas_object_text_text_get(text_obj);
786         if ((idx >= 0) && (text))
787           {
788              if ((canvas_x - tx) > (cx + (cw / 2))) idx++;
789
790              i = 0;
791              j = -1;
792              pos = 0;
793              while ((i < idx) && (j != i))
794                {
795                   pos++;
796                   j = i;
797                   i = evas_string_char_next_get(text, i, NULL);
798                }
799              if (pos > sd->unicode_length) pos = sd->unicode_length;
800           }
801         else pos = 0;
802      }
803    return pos;
804 }
805
806 /**
807  * A utility function to get the average size of a character written inside
808  * the editable object
809  *
810  * @param editable an editable object
811  * @param w the location where to store the average width of a character
812  * @param h the location where to store the average height of a character
813  */
814 EAPI void
815 e_editable_char_size_get(Evas_Object *editable, int *w, int *h)
816 {
817    int tw = 0, th = 0;
818    Evas *evas;
819    const Evas_Object *text_obj;
820    Evas_Object *obj;
821    E_Editable_Smart_Data *sd;
822    char *text = "Tout est bon dans l'abricot sauf le noyau!"
823                 "Wakey wakey! Eggs and Bakey!";
824    const char *font, *font_source;
825    Evas_Text_Style_Type style;
826    int font_size;
827
828    if (w) *w = 0;
829    if (h) *h = 0;
830    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
831    if ((!editable) || (!(evas = evas_object_evas_get(editable))))
832      return;
833    if (!(sd = evas_object_smart_data_get(editable))) return;
834    if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
835      return;
836
837    if ((sd->average_char_w <= 0) || (sd->average_char_h <= 0))
838      {
839         font_source = evas_object_text_font_source_get(text_obj);
840         evas_object_text_font_get(text_obj, &font, &font_size);
841         style = evas_object_text_style_get(text_obj);
842
843         obj = evas_object_text_add(evas);
844         evas_object_scale_set(obj, edje_scale_get());
845         evas_object_text_font_source_set(obj, font_source);
846         evas_object_text_font_set(obj, font, font_size);
847         evas_object_text_style_set(obj, style);
848         evas_object_text_text_set(obj, text);
849         evas_object_geometry_get(obj, NULL, NULL, &tw, &th);
850         evas_object_del(obj);
851         sd->average_char_w = (tw / strlen(text));
852         sd->average_char_h = th;
853      }
854    if (w) *w = sd->average_char_w;
855    if (h) *h = sd->average_char_h;
856 }
857
858 EAPI void
859 e_editable_enable(Evas_Object *editable)
860 {
861    E_Editable_Smart_Data *sd;
862
863    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
864    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
865      return;
866
867    edje_object_signal_emit(sd->text_object, "e,state,enabled", "e");
868 }
869
870 EAPI void
871 e_editable_disable(Evas_Object *editable)
872 {
873    E_Editable_Smart_Data *sd;
874
875    if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
876    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
877      return;
878
879    edje_object_signal_emit(sd->text_object, "e,state,disabled", "e");
880 }
881
882 /* Private functions */
883
884 /* A utility function to insert some text inside the editable object.
885  * It doesn't update the position of the cursor, nor the selection... */
886 static int
887 _e_editable_text_insert(Evas_Object *editable, int pos, const char *text)
888 {
889    E_Editable_Smart_Data *sd;
890    int char_length = -1, unicode_length = -1;
891    int prev_char_length, new_char_length, new_unicode_length;
892    int idx = 0, i = 0;
893
894    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
895      return 0;
896    if ((!text) || (*text == '\0')) return 0;
897
898    if (pos < 0) pos = 0;
899    else if (pos > sd->unicode_length)
900      pos = sd->unicode_length;
901
902    for (i = 0; i != char_length; i = evas_string_char_next_get(text, i, NULL))
903      {
904         char_length = i;
905         unicode_length++;
906      }
907
908    for (i = 0; i < pos; i++)
909      idx = evas_string_char_next_get(sd->text, idx, NULL);
910
911    if ((unicode_length <= 0) || (char_length <= 0)) return 0;
912
913    prev_char_length = sd->char_length;
914    new_char_length = sd->char_length + char_length;
915    new_unicode_length = sd->unicode_length + unicode_length;
916
917    if (new_char_length > sd->allocated_length)
918      {
919         int new_allocated_length = E_EDITABLE_SIZE_TO_ALLOC(new_char_length);
920         char *old = sd->text;
921
922         if (sd->password_mode)
923           {
924              /* security -- copy contents into new buffer, and overwrite old contents */
925              sd->text = malloc(new_allocated_length + 1);
926              if (!sd->text)
927                {
928                   sd->text = old;
929                   return 0;
930                }
931              if (old)
932                {
933                   memcpy(sd->text, old, prev_char_length + 1);
934                   memset(old, 0, prev_char_length);
935                   free(old);
936                }
937           }
938         else
939           {
940              char *p = realloc(sd->text, new_allocated_length + 1);
941              if (!p)
942                {
943                   sd->text = old;
944                   return 0;
945                }
946              sd->text = p;
947           }
948         sd->allocated_length = new_allocated_length;
949      }
950    sd->unicode_length = new_unicode_length;
951    sd->char_length = new_char_length;
952
953    if (prev_char_length > idx)
954      memmove(&sd->text[idx + char_length], &sd->text[idx], prev_char_length - idx);
955    strncpy(&sd->text[idx], text, char_length);
956    sd->text[sd->char_length] = '\0';
957
958    _e_editable_text_update(editable);
959    return unicode_length;
960 }
961
962 /* A utility function to delete a range of text from the editable object.
963  * It doesn't update the position of the cursor, nor the selection... */
964 static int
965 _e_editable_text_delete(Evas_Object *editable, int start, int end)
966 {
967    E_Editable_Smart_Data *sd;
968    int start_id = 0, end_id = 0, i = 0;
969
970    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
971      return 0;
972
973    start = E_CLAMP(start, 0, sd->unicode_length);
974    end = E_CLAMP(end, 0, sd->unicode_length);
975    if (end <= start) return 0;
976
977    for (i = 0; i < end; i++)
978      {
979         end_id = evas_string_char_next_get(sd->text, end_id, NULL);
980         if (i < start) start_id = end_id;
981      }
982
983    if (end_id <= start_id) return 0;
984
985    memmove(&sd->text[start_id], &sd->text[end_id], sd->char_length - end_id);
986    sd->char_length -= (end_id - start_id);
987    sd->unicode_length -= (end - start);
988    sd->text[sd->char_length] = '\0';
989
990    _e_editable_text_update(editable);
991
992    return end - start;
993 }
994
995 /* Updates the position of the cursor
996  * It also updates automatically the text position and the selection */
997 static void
998 _e_editable_cursor_update(Evas_Object *editable)
999 {
1000    E_Editable_Smart_Data *sd;
1001    const Evas_Object *text_obj;
1002    Evas_Coord tx, ty;
1003    Evas_Coord cx, cy, ch;
1004
1005    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
1006      return;
1007    if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
1008      return;
1009
1010    evas_object_geometry_get(text_obj, &tx, &ty, NULL, NULL);
1011    _e_editable_char_geometry_get_from_pos(editable, sd->cursor_pos,
1012                                           &cx, &cy, NULL, &ch);
1013
1014    evas_object_move(sd->cursor_object, tx + cx, ty + cy);
1015    evas_object_resize(sd->cursor_object, sd->cursor_width, ch);
1016
1017    if (sd->cursor_visible && evas_object_visible_get(editable))
1018      {
1019         evas_object_show(sd->cursor_object);
1020         edje_object_signal_emit(sd->cursor_object, "e,action,show,cursor", "e");
1021      }
1022
1023    _e_editable_selection_update(editable);
1024    _e_editable_text_position_update(editable, -1);
1025 }
1026
1027 /* Updates the selection of the editable object */
1028 static void
1029 _e_editable_selection_update(Evas_Object *editable)
1030 {
1031    E_Editable_Smart_Data *sd;
1032    const Evas_Object *text_obj;
1033    Evas_Coord tx, ty;
1034    Evas_Coord cx, cy;
1035    Evas_Coord sx, sy, sw, sh;
1036    int start_pos, end_pos;
1037
1038    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
1039      return;
1040    if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
1041      return;
1042
1043    if ((sd->cursor_pos == sd->selection_pos) || (!sd->selection_visible))
1044      evas_object_hide(sd->selection_object);
1045    else
1046      {
1047         evas_object_geometry_get(text_obj, &tx, &ty, NULL, NULL);
1048         start_pos = (sd->cursor_pos <= sd->selection_pos) ?
1049           sd->cursor_pos : sd->selection_pos;
1050         end_pos = (sd->cursor_pos >= sd->selection_pos) ?
1051           sd->cursor_pos : sd->selection_pos;
1052
1053         _e_editable_char_geometry_get_from_pos(editable, start_pos,
1054                                                &cx, &cy, NULL, NULL);
1055         sx = tx + cx;
1056         sy = ty + cy;
1057
1058         _e_editable_char_geometry_get_from_pos(editable, end_pos,
1059                                                &cx, NULL, NULL, &sh);
1060         sw = tx + cx - sx;
1061
1062         evas_object_move(sd->selection_object, sx, sy);
1063         evas_object_resize(sd->selection_object, sw, sh);
1064         evas_object_show(sd->selection_object);
1065      }
1066 }
1067
1068 /* Updates the text of the text object of the editable object
1069  * (it fills it with '*' if the editable is in password mode)
1070  * It does not update the position of the text */
1071 static void
1072 _e_editable_text_update(Evas_Object *editable)
1073 {
1074    E_Editable_Smart_Data *sd;
1075    Evas_Coord minw, minh;
1076
1077    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
1078      return;
1079
1080    if (sd->password_mode)
1081      {
1082         char *text;
1083
1084         text = malloc((sd->unicode_length + 1) * sizeof(char));
1085         if (!text) return;
1086
1087         memset(text, '*', sd->unicode_length * sizeof(char));
1088         text[sd->unicode_length] = '\0';
1089         edje_object_part_text_set(sd->text_object, "e.text.text", text);
1090         free(text);
1091      }
1092    else
1093      edje_object_part_text_set(sd->text_object, "e.text.text", sd->text);
1094
1095    edje_object_size_min_calc(sd->text_object, &minw, &minh);
1096    evas_object_resize(sd->text_object, minw, minh);
1097 }
1098
1099 /* Updates the position of the text object according to the position of the
1100  * cursor (we make sure the cursor is visible) */
1101 static void
1102 _e_editable_text_position_update(Evas_Object *editable, Evas_Coord real_w)
1103 {
1104    E_Editable_Smart_Data *sd;
1105    Evas_Coord ox, oy, ow;
1106    Evas_Coord tx, ty, tw;
1107    Evas_Coord cx, cy, cw;
1108    Evas_Coord sx, sy;
1109    Evas_Coord offset_x = 0;
1110
1111    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
1112      return;
1113
1114    evas_object_geometry_get(editable, &ox, &oy, &ow, NULL);
1115    if (real_w >= 0) ow = real_w;
1116    evas_object_geometry_get(sd->text_object, &tx, &ty, &tw, NULL);
1117    evas_object_geometry_get(sd->cursor_object, &cx, &cy, &cw, NULL);
1118    evas_object_geometry_get(sd->selection_object, &sx, &sy, NULL, NULL);
1119
1120    if (tw <= ow)
1121      offset_x = ox - tx;
1122    else if (cx < (ox + E_EDITABLE_CURSOR_MARGIN))
1123      offset_x = ox + E_EDITABLE_CURSOR_MARGIN - cx;
1124    else if ((cx + cw + E_EDITABLE_CURSOR_MARGIN) > (ox + ow))
1125      offset_x = (ox + ow) - (cx + cw + E_EDITABLE_CURSOR_MARGIN);
1126
1127    if (tw > ow)
1128      {
1129         if ((tx + offset_x) > ox)
1130           offset_x = ox - tx;
1131         else if ((tx + tw + offset_x) < (ox + ow))
1132           offset_x = (ox + ow) - (tx + tw);
1133      }
1134
1135    if (offset_x != 0)
1136      {
1137         evas_object_move(sd->text_object, tx + offset_x, ty);
1138         evas_object_move(sd->cursor_object, cx + offset_x, cy);
1139         evas_object_move(sd->selection_object, sx + offset_x, sy);
1140      }
1141 }
1142
1143 /* Gets the geometry of the char according to its utf-8 pos */
1144 static int
1145 _e_editable_char_geometry_get_from_pos(Evas_Object *editable, int utf_pos, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
1146 {
1147    E_Editable_Smart_Data *sd;
1148    const Evas_Object *text_obj;
1149    const char *text;
1150    Evas_Coord x, w;
1151    int idx = 0, i, last_pos, ret;
1152
1153    if (cx) *cx = 0;
1154    if (cy) *cy = 0;
1155    if (cw) *cw = 0;
1156    if (ch) *ch = 0;
1157
1158    if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
1159      return 0;
1160    if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
1161      return 0;
1162
1163    text = evas_object_text_text_get(text_obj);
1164    if ((!text) || (sd->unicode_length <= 0) || (utf_pos <= 0))
1165      {
1166         e_editable_char_size_get(editable, cw, ch);
1167         return 1;
1168      }
1169    else
1170      {
1171         if (utf_pos >= sd->unicode_length)
1172           {
1173              utf_pos = sd->unicode_length - 1;
1174              last_pos = 1;
1175           }
1176         else
1177           last_pos = 0;
1178
1179         for (i = 0; i < utf_pos; i++)
1180           idx = evas_string_char_next_get(text, idx, NULL);
1181
1182         ret = evas_object_text_char_pos_get(text_obj, idx, &x, cy, &w, ch);
1183         if (cx) *cx = x - 1 + (last_pos ? w : 0);
1184         if (cw) *cw = last_pos ? 1 : w;
1185         return ret;
1186      }
1187 }
1188
1189 /* Editable object's smart methods */
1190
1191 static void
1192 _e_editable_smart_add(Evas_Object *object)
1193 {
1194    Evas *evas;
1195    E_Editable_Smart_Data *sd;
1196    Evas_Coord ox, oy;
1197
1198    if ((!object) || !(evas = evas_object_evas_get(object)))
1199      return;
1200
1201    sd = malloc(sizeof(E_Editable_Smart_Data));
1202    if (!sd) return;
1203
1204    _e_editable_smart_use++;
1205    evas_object_smart_data_set(object, sd);
1206    evas_object_geometry_get(object, &ox, &oy, NULL, NULL);
1207
1208    sd->text = malloc((E_EDITABLE_BLOCK_SIZE + 1) * sizeof(char));
1209    if (!sd->text) return;
1210
1211    sd->text[0] = '\0';
1212    sd->char_length = 0;
1213    sd->unicode_length = 0;
1214    sd->allocated_length = E_EDITABLE_BLOCK_SIZE;
1215
1216    sd->cursor_width = 1;
1217    sd->selection_on_fg = 0;
1218    sd->average_char_w = -1;
1219    sd->average_char_h = -1;
1220
1221    sd->cursor_pos = 0;
1222    sd->cursor_visible = 1;
1223    sd->selection_pos = 0;
1224    sd->selection_visible = 1;
1225    sd->password_mode = 0;
1226
1227    sd->clip_object = evas_object_rectangle_add(evas);
1228    evas_object_move(sd->clip_object, ox, oy);
1229    evas_object_smart_member_add(sd->clip_object, object);
1230
1231    sd->event_object = evas_object_rectangle_add(evas);
1232    evas_object_color_set(sd->event_object, 0, 0, 0, 0);
1233    evas_object_clip_set(sd->event_object, sd->clip_object);
1234    evas_object_move(sd->event_object, ox, oy);
1235    evas_object_smart_member_add(sd->event_object, object);
1236
1237    sd->text_object = edje_object_add(evas);
1238    evas_object_pass_events_set(sd->text_object, 1);
1239    evas_object_clip_set(sd->text_object, sd->clip_object);
1240    evas_object_move(sd->text_object, ox, oy);
1241    evas_object_smart_member_add(sd->text_object, object);
1242
1243    sd->selection_object = edje_object_add(evas);
1244    evas_object_pass_events_set(sd->selection_object, 1);
1245    evas_object_clip_set(sd->selection_object, sd->clip_object);
1246    evas_object_move(sd->selection_object, ox, oy);
1247    evas_object_smart_member_add(sd->selection_object, object);
1248
1249    sd->cursor_object = edje_object_add(evas);
1250    evas_object_pass_events_set(sd->cursor_object, 1);
1251    evas_object_clip_set(sd->cursor_object, sd->clip_object);
1252    evas_object_move(sd->cursor_object, ox, oy);
1253    evas_object_smart_member_add(sd->cursor_object, object);
1254
1255    _e_editable_cursor_update(object);
1256 }
1257
1258 /* Deletes the editable */
1259 static void
1260 _e_editable_smart_del(Evas_Object *object)
1261 {
1262    E_Editable_Smart_Data *sd;
1263
1264    if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1265      return;
1266
1267    evas_object_del(sd->clip_object);
1268    evas_object_del(sd->event_object);
1269    evas_object_del(sd->text_object);
1270    evas_object_del(sd->cursor_object);
1271    evas_object_del(sd->selection_object);
1272    /* Security - clear out memory that contained a password */
1273    if (sd->password_mode) memset(sd->text, 0, sd->char_length);
1274    free(sd->text);
1275    free(sd);
1276
1277    _e_editable_smart_use--;
1278    if (_e_editable_smart_use <= 0)
1279      {
1280         evas_smart_free(_e_editable_smart);
1281         _e_editable_smart = NULL;
1282      }
1283 }
1284
1285 /* Moves the editable object */
1286 static void
1287 _e_editable_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y)
1288 {
1289    E_Editable_Smart_Data *sd;
1290    Evas_Coord prev_x, prev_y;
1291    Evas_Coord ox, oy;
1292
1293    if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1294      return;
1295
1296    evas_object_geometry_get(object, &prev_x, &prev_y, NULL, NULL);
1297    evas_object_move(sd->clip_object, x, y);
1298    evas_object_move(sd->event_object, x, y);
1299    evas_object_geometry_get(sd->text_object, &ox, &oy, NULL, NULL);
1300    evas_object_move(sd->text_object, ox + (x - prev_x), oy + (y - prev_y));
1301    evas_object_geometry_get(sd->cursor_object, &ox, &oy, NULL, NULL);
1302    evas_object_move(sd->cursor_object, ox + (x - prev_x), oy + (y - prev_y));
1303    evas_object_geometry_get(sd->selection_object, &ox, &oy, NULL, NULL);
1304    evas_object_move(sd->selection_object, ox + (x - prev_x), oy + (y - prev_y));
1305 }
1306
1307 /* Resizes the editable object */
1308 static void
1309 _e_editable_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h)
1310 {
1311    E_Editable_Smart_Data *sd;
1312
1313    if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1314      return;
1315
1316    evas_object_resize(sd->clip_object, w, h);
1317    evas_object_resize(sd->event_object, w, h);
1318    _e_editable_text_position_update(object, w);
1319 }
1320
1321 /* Shows the editable object */
1322 static void
1323 _e_editable_smart_show(Evas_Object *object)
1324 {
1325    E_Editable_Smart_Data *sd;
1326
1327    if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1328      return;
1329
1330    evas_object_show(sd->clip_object);
1331    evas_object_show(sd->event_object);
1332    evas_object_show(sd->text_object);
1333
1334    if (sd->cursor_visible)
1335      {
1336         evas_object_show(sd->cursor_object);
1337         edje_object_signal_emit(sd->cursor_object, "e,action,show,cursor", "e");
1338      }
1339
1340    if ((sd->selection_visible) && (sd->cursor_pos != sd->selection_pos))
1341      evas_object_show(sd->selection_object);
1342 }
1343
1344 /* Hides the editable object */
1345 static void
1346 _e_editable_smart_hide(Evas_Object *object)
1347 {
1348    E_Editable_Smart_Data *sd;
1349
1350    if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1351      return;
1352
1353    evas_object_hide(sd->clip_object);
1354    evas_object_hide(sd->event_object);
1355    evas_object_hide(sd->text_object);
1356    evas_object_hide(sd->cursor_object);
1357    evas_object_hide(sd->selection_object);
1358 }
1359
1360 /* Changes the color of the editable object */
1361 static void
1362 _e_editable_color_set(Evas_Object *object, int r, int g, int b, int a)
1363 {
1364    E_Editable_Smart_Data *sd;
1365
1366    if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1367      return;
1368    evas_object_color_set(sd->clip_object, r, g, b, a);
1369 }
1370
1371 /* Clips the editable object against "clip" */
1372 static void
1373 _e_editable_clip_set(Evas_Object *object, Evas_Object *clip)
1374 {
1375    E_Editable_Smart_Data *sd;
1376
1377    if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1378      return;
1379    evas_object_clip_set(sd->clip_object, clip);
1380 }
1381
1382 /* Unclips the editable object */
1383 static void
1384 _e_editable_clip_unset(Evas_Object *object)
1385 {
1386    E_Editable_Smart_Data *sd;
1387
1388    if ((!object) || (!(sd = evas_object_smart_data_get(object))))
1389      return;
1390    evas_object_clip_unset(sd->clip_object);
1391 }
1392