/* A utility function to delete a range of text from the editable object. * It doesn't update the position of the cursor, nor the selection... */ static int _e_editable_text_delete(Evas_Object *editable, int start, int end) { E_Editable_Smart_Data *sd; int start_id = 0, end_id = 0, i = 0; if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) return 0; start = E_CLAMP(start, 0, sd->unicode_length); end = E_CLAMP(end, 0, sd->unicode_length); if (end <= start) return 0; for (i = 0; i < end; i++) { end_id = evas_string_char_next_get(sd->text, end_id, NULL); if (i < start) start_id = end_id; } if (end_id <= start_id) return 0; memmove(&sd->text[start_id], &sd->text[end_id], sd->char_length - end_id); sd->char_length -= (end_id - start_id); sd->unicode_length -= (end - start); sd->text[sd->char_length] = '\0'; _e_editable_text_update(editable); return (end - start); }
/** * Sets the text of the editable object * * @param editable an editable object * @param text the text to set */ EAPI void e_editable_text_set(Evas_Object *editable, const char *text) { E_Editable_Smart_Data *sd; if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR(); if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) return; if (sd->password_mode) memset(sd->text, 0, sd->char_length); free(sd->text); sd->text = NULL; sd->char_length = 0; sd->unicode_length = 0; sd->allocated_length = -1; if (_e_editable_text_insert(editable, 0, text) <= 0) { sd->text = malloc((E_EDITABLE_BLOCK_SIZE + 1) * sizeof(char)); sd->text[0] = '\0'; sd->char_length = 0; sd->unicode_length = 0; sd->allocated_length = E_EDITABLE_BLOCK_SIZE; _e_editable_text_update(editable); } sd->cursor_pos = sd->unicode_length; sd->selection_pos = sd->unicode_length; _e_editable_cursor_update(editable); }
/** * Sets whether or not the editable object is in password mode. In password * mode, the editable object displays '*' instead of the characters * * @param editable an editable object * @param password_mode 1 to turn on the password mode of the editable object, * 0 to turn it off */ EAPI void e_editable_password_set(Evas_Object *editable, int password_mode) { E_Editable_Smart_Data *sd; if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) return; if (sd->password_mode == password_mode) return; sd->password_mode = password_mode; _e_editable_text_update(editable); _e_editable_cursor_update(editable); }
/** * Sets the theme group to be used by the editable object. * This function has to be called, or the cursor and the selection won't be * visible. * * @param editable an editable object * @param category the theme category to use for the editable object * @param group the theme group to use for the editable object */ EAPI void e_editable_theme_set(Evas_Object *editable, const char *category, const char *group) { E_Editable_Smart_Data *sd; char *obj_group; const char *data; if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR(); if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) return; if ((!category) || (!group)) return; obj_group = alloca(strlen(group) + strlen("/selection") + 1); /* Gets the theme for the text object */ sprintf(obj_group, "%s/text", group); e_theme_edje_object_set(sd->text_object, category, obj_group); sd->average_char_w = -1; sd->average_char_h = -1; /* Gets the theme for the cursor */ sprintf(obj_group, "%s/cursor", group); e_theme_edje_object_set(sd->cursor_object, category, obj_group); edje_object_size_min_get(sd->cursor_object, &sd->cursor_width, NULL); if (sd->cursor_width < 1) sd->cursor_width = 1; /* Gets the theme for the selection */ sprintf(obj_group, "%s/selection", group); e_theme_edje_object_set(sd->selection_object, category, obj_group); data = edje_object_data_get(sd->selection_object, "on_foreground"); if ((data) && (strcmp(data, "1") == 0)) { sd->selection_on_fg = 1; evas_object_stack_above(sd->selection_object, sd->text_object); } else { sd->selection_on_fg = 0; evas_object_stack_below(sd->selection_object, sd->text_object); } _e_editable_text_update(editable); _e_editable_cursor_update(editable); }
/* A utility function to insert some text inside the editable object. * It doesn't update the position of the cursor, nor the selection... */ static int _e_editable_text_insert(Evas_Object *editable, int pos, const char *text) { E_Editable_Smart_Data *sd; int char_length = -1, unicode_length = -1; int prev_char_length, new_char_length, new_unicode_length; int index = 0, i = 0; if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) return 0; if ((!text) || (*text == '\0')) return 0; if (pos < 0) pos = 0; else if (pos > sd->unicode_length) pos = sd->unicode_length; for (i = 0; i != char_length; i = evas_string_char_next_get(text, i, NULL)) { char_length = i; unicode_length++; } for (i = 0; i < pos; i++) index = evas_string_char_next_get(sd->text, index, NULL); if ((unicode_length <= 0) || (char_length <= 0)) return 0; prev_char_length = sd->char_length; new_char_length = sd->char_length + char_length; new_unicode_length = sd->unicode_length + unicode_length; if (new_char_length > sd->allocated_length) { int new_allocated_length = E_EDITABLE_SIZE_TO_ALLOC(new_char_length); char *old = sd->text; if (sd->password_mode) { /* security -- copy contents into new buffer, and overwrite old contents */ sd->text = malloc(new_allocated_length + 1); if (!sd->text) { sd->text = old; return 0; } if (old) { memcpy(sd->text, old, prev_char_length + 1); memset(old, 0, prev_char_length); free(old); } } else { sd->text = realloc(sd->text, new_allocated_length + 1); if (!sd->text) { sd->text = old; return 0; } } sd->allocated_length = new_allocated_length; } sd->unicode_length = new_unicode_length; sd->char_length = new_char_length; if (prev_char_length > index) memmove(&sd->text[index + char_length], &sd->text[index], prev_char_length - index); strncpy(&sd->text[index], text, char_length); sd->text[sd->char_length] = '\0'; _e_editable_text_update(editable); return unicode_length; }