/* 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);
}
/**
 * Gets a range of the text of the editable object, from position @a start to
 * position @a end
 *
 * @param editable an editable object
 * @param start the start position of the text range to get
 * @param end the end position of the text range to get
 * @return Returns the range of text. The returned string will have to be freed
 */
EAPI char *
e_editable_text_range_get(Evas_Object *editable, int start, int end)
{
   E_Editable_Smart_Data *sd;
   char *range;
   int start_id = 0, end_id = 0, i;

   if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(NULL);
   if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
     return NULL;

   start = E_CLAMP(start, 0, sd->unicode_length);
   end = E_CLAMP(end, 0, sd->unicode_length);
   if (end <= start) return NULL;

   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 NULL;

   range = malloc((end_id - start_id + 1) * sizeof(char));
   strncpy(range, &sd->text[start_id], end_id - start_id);
   range[end_id - start_id] = '\0';

   return range;
}
/**
 * Selects the word at the provided character index
 */
EAPI void
e_editable_select_word(Evas_Object *editable, int index)
{
   E_Editable_Smart_Data *sd;
   int spos = 0, epos = -1, i = 0, pos = 0;

   if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERRNR();
   if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
     return;
   if ((index < 0) || (index >= sd->unicode_length)) return;

   while (i < sd->char_length)
     {
	if (sd->text[i] == ' ')
	  {
	     if (pos < index) spos = pos + 1;
	     else if (pos > index)
	       {
		  epos = pos;
		  break;
	       }
	  }
	i = evas_string_char_next_get(sd->text, i, NULL);
	pos++;
     }
   if (epos == -1) epos = pos;
   e_editable_selection_pos_set(editable, spos);
   e_editable_cursor_pos_set(editable, epos);
}
Exemple #4
0
static void
_ekbd_send_x_string_press(const char *str, Ekbd_Mod mod)
{
   char *string = (char*)str;
   char *key;
   int glyph = 0;

   /* First keysym is 'quotedbl' */
   string += evas_string_char_next_get(string, 0, &glyph);
   key = (char*) _glyph_to_keysym(glyph);

   while(key)
     {
        if(strcmp(key,"quotedbl"))
          _ekbd_send_x_keysym_press(key, mod);
        glyph = 0;
        /* utf8 -> glyph id (unicode - ucs4) */
        string += evas_string_char_next_get(string, 0, &glyph);
        key = (char*) _glyph_to_keysym(glyph);
     }
}
/**
 * Gets the cursor position at the coords ( @a x, @a y ). It's used to know
 * where to place the cursor or the selection bound on mouse evevents.
 *
 * @param editable an editable object
 * @param x the x coord, relative to the editable object
 * @param y the y coord, relative to the editable object
 * @return Returns the position where to place the cursor according to the
 * given coords
 */
EAPI int
e_editable_pos_get_from_coords(Evas_Object *editable, Evas_Coord x, Evas_Coord y)
{
   E_Editable_Smart_Data *sd;
   const Evas_Object *text_obj;
   Evas_Coord ox, oy;
   Evas_Coord tx, ty, tw, th;
   Evas_Coord cx, cw;
   Evas_Coord canvas_x, canvas_y;
   int index, pos, i, j;
   const char *text;

   if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(0);
   if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
     return 0;
   if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
     return 0;

   evas_object_geometry_get(editable, &ox, &oy, NULL, NULL);
   evas_object_geometry_get(text_obj, &tx, &ty, &tw, &th);
   canvas_x = ox + x;
   canvas_y = oy + y;

   if ((canvas_y < ty) || (canvas_x < tx))
     pos = 0;
   else if ((canvas_y > (ty + th)) || (canvas_x > (tx + tw)))
     pos = sd->unicode_length;
   else
     {
        index = evas_object_text_char_coords_get(text_obj,
                                                 canvas_x - tx, canvas_y - ty,
                                                 &cx, NULL, &cw, NULL);
        text = evas_object_text_text_get(text_obj);
        if ((index >= 0) && (text))
          {
             if ((canvas_x - tx) > (cx + (cw / 2))) index++;

             i = 0;
             j = -1;
             pos = 0;
             while ((i < index) && (j != i))
               {
                  pos++;
                  j = i;
                  i = evas_string_char_next_get(text, i, NULL);
               }
             if (pos > sd->unicode_length) pos = sd->unicode_length;
          }
        else pos = 0;
     }
   return pos;
}
/* Gets the geometry of the char according to its utf-8 pos */
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)
{
   E_Editable_Smart_Data *sd;
   const Evas_Object *text_obj;
   const char *text;
   Evas_Coord x, w;
   int index = 0, i, last_pos, ret;

   if (cx) *cx = 0;
   if (cy) *cy = 0;
   if (cw) *cw = 0;
   if (ch) *ch = 0;

   if ((!editable) || (!(sd = evas_object_smart_data_get(editable))))
     return 0;
   if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text")))
     return 0;

   text = evas_object_text_text_get(text_obj);
   if ((!text) || (sd->unicode_length <= 0) || (utf_pos <= 0))
     {
        e_editable_char_size_get(editable, cw, ch);
        return 1;
     }
   else
     {
        if (utf_pos >= sd->unicode_length)
          {
            utf_pos = sd->unicode_length - 1;
            last_pos = 1;
          }
        else
          last_pos = 0;

        for (i = 0; i < utf_pos; i++)
          index = evas_string_char_next_get(text, index, NULL);

        ret = evas_object_text_char_pos_get(text_obj, index, &x, cy, &w, ch);
        if (cx) *cx = x - 1 + (last_pos ? w : 0);
        if (cw) *cw = last_pos ? 1 : w;
        return ret;
     }
}
/* callbacks */
static void
_enscribi_input_frame_cb_matches(void *data, Evas_Object *obj, const char *emission, const char *source)
{
    Match *match;
    Eina_List *matches, *l;
    int i;
    Edje_Message_String_Set *msg;
    Edje_Message_Int_Set *msg2;
    Smart_Data *sd;
    
    sd = data;
    matches = enscribi_canvas_matches_get(sd->canvas);
    if (!matches) return;
        
    msg = calloc(1, sizeof(Edje_Message_String_Set) + ((9-1) * sizeof(char *)));
    msg->count = 9;
    msg2 = calloc(1, sizeof(Edje_Message_String_Set) + ((9-1) * sizeof(int)));
    msg2->count = 9;
    for (i = 0; i < 8; i++) {
        l = eina_list_nth_list(matches, i);
        match = l->data;
        msg->str[i] = match->str;

        // Get and send the unicode value of the glyph as well
        int glyph;
        evas_string_char_next_get(match->str, 0, &(glyph));
        msg2->val[i] = glyph;

        printf("%s\t(%d)\n", msg->str[i], msg2->val[i]);
    }
    msg->str[8] = ""; // Why do we have to set a 9th element to not get scrap in 8th?
    msg2->val[8] = 0;

    edje_object_message_send(obj, EDJE_MESSAGE_STRING_SET, 1, msg);
    edje_object_message_send(obj, EDJE_MESSAGE_INT_SET, 1, msg2);
    free(msg);
    free(msg2);
}
Exemple #8
0
END_TEST

/* Tests for functions that are in evas_object_text.c but
 * don't really have anything to do with it. */
START_TEST(evas_text_unrelated)
{
   START_TEXT_TEST();
   const char *buf = "נסיון";
   int pos;
   int value;
   /* Actually, they are tested in eina, just doing it for completeness. */
   fail_if(evas_string_char_len_get(buf) != 5);

   pos = 0;
   fail_if(2 != evas_string_char_next_get(buf, pos, &value));
   fail_if(value != 1504);

   pos = 2;
   fail_if(0 != evas_string_char_prev_get(buf, pos, &value));
   fail_if(value != 1505);

   END_TEXT_TEST();
}
/* 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;
}
Exemple #10
0
static void
_e_kbd_normalise_init(void)
{
   int i;
   const char *table[][2] =
     {
	  {"À", "a"},
	  {"Á", "a"},
	  {"Â", "a"},
	  {"Ã", "a"},
	  {"Ä", "a"},
	  {"Å", "a"},
	  {"Æ", "a"},
	  {"Ç", "c"},
	  {"È", "e"},
	  {"É", "e"},
	  {"Ê", "e"},
	  {"Ë", "e"},
	  {"Ì", "i"},
	  {"Í", "i"},
	  {"Î", "i"},
	  {"Ï", "i"},
	  {"Ð", "d"},
	  {"Ñ", "n"},
	  {"Ò", "o"},
	  {"Ó", "o"},
	  {"Ô", "o"},
	  {"Õ", "o"},
	  {"Ö", "o"},
	  {"×", "x"},
	  {"Ø", "o"},
	  {"Ù", "u"},
	  {"Ú", "u"},
	  {"Û", "u"},
	  {"Ü", "u"},
	  {"Ý", "y"},
	  {"Þ", "p"},
	  {"ß", "s"},
	  {"à", "a"},
	  {"á", "a"},
	  {"â", "a"},
	  {"ã", "a"},
	  {"ä", "a"},
	  {"å", "a"},
	  {"æ", "a"},
	  {"ç", "c"},
	  {"è", "e"},
	  {"é", "e"},
	  {"ê", "e"},
	  {"ë", "e"},
	  {"ì", "i"},
	  {"í", "i"},
	  {"î", "i"},
	  {"ï", "i"},
	  {"ð", "o"},
	  {"ñ", "n"},
	  {"ò", "o"},
	  {"ó", "o"},
	  {"ô", "o"},
	  {"õ", "o"},
	  {"ö", "o"},
	  {"ø", "o"},
	  {"ù", "u"},
	  {"ú", "u"},
	  {"û", "u"},
	  {"ü", "u"},
	  {"ý", "y"},
	  {"þ", "p"},
	  {"ÿ", "y"}
     }; // 63 items

   if (_e_kbd_normalise_ready) return;
   _e_kbd_normalise_ready = 1;
   for (i = 0; i < 128; i++)
     _e_kbd_normalise_base[i] = tolower(i);
   for (;i < MAXLATIN; i++)
     {
	int glyph, j;

	for (j = 0; j < 63; j++)
	  {
	     evas_string_char_next_get(table[j][0], 0, &glyph);
	     if (glyph == i)
	       {
		  _e_kbd_normalise_base[i] = *table[j][1];
		  break;
	       }
	  }
     }
}
Exemple #11
0
static const char *
_edje_text_fit_x(Edje *ed, Edje_Real_Part *ep,
                 Edje_Calc_Params *params,
                 const char *text, const char *font, int size,
                 Evas_Coord sw, int *free_text)
{
    Evas_Coord tw = 0, th = 0, p;
    int l, r;
    int i;
    char *buf;
    int uc1 = -1, uc2 = -1, c1 = -1, c2 = -1;
    int loop = 0, extra;
    size_t orig_len;
    FLOAT_T sc;

    sc = ed->scale;
    if (sc == ZERO) sc = _edje_scale;

    *free_text = 0;
    if (sw <= 1) return "";

    if (ep->part->scale) evas_object_scale_set(ep->object, TO_DOUBLE(sc));
    evas_object_text_font_set(ep->object, font, size);
    evas_object_text_text_set(ep->object, text);

    part_get_geometry(ep, &tw, &th);
    evas_object_text_style_pad_get(ep->object, &l, &r, NULL, NULL);

    p = ((sw - tw) * params->type.text.elipsis);

    /* chop chop */
    if (tw > sw)
    {
        if (params->type.text.elipsis != 0.0)
            /* should be the last in text! not the rightmost */
            uc1 = evas_object_text_last_up_to_pos(ep->object,
                                                  -p + l, th / 2);
        if (params->type.text.elipsis != 1.0)
        {
            /* should be the last in text! not the rightmost */
            if ((-p + sw -r) < 0)
                uc2 = evas_object_text_last_up_to_pos(ep->object, 0, th / 2);
            else
                uc2 = evas_object_text_last_up_to_pos(ep->object,
                                                      -p + sw - r, th / 2);
        }
        if ((uc1 < 0) && (uc2 < 0))
        {
            uc1 = 0;
            uc2 = 0;
        }
    }

    if (!(((uc1 >= 0) || (uc2 >= 0)) && (tw > sw)))
        return text;

    if ((uc1 == 0) && (uc2 == 0))
        return text;

    orig_len = strlen(text);

    /* don't overflow orig_len by adding extra
     * FIXME: we might want to set a max string length somewhere...
     */
    extra = 1 + 3 + 3; /* terminator, leading and trailing ellipsis */
    orig_len = MIN(orig_len, ((size_t) 8192 - extra));

    if (!(buf = malloc(orig_len + extra)))
        return text;

    /* Convert uc1, uc2 -> c1, c2 */
    i = 0;
    if (uc1 >= 0)
    {
        c1 = 0;
        for ( ; i < uc1 ; i++)
        {
            c1 = evas_string_char_next_get(text, c1, NULL);
        }
    }
    if (uc2 >= 0)
    {
        if (c1 >= 0)
        {
            c2 = c1;
        }
        else
        {
            c2 = 0;
        }
        for ( ; i < uc2 ; i++)
        {
            c2 = evas_string_char_next_get(text, c2, NULL);
        }
    }

    buf[0] = '\0';

    while (((c1 >= 0) || (c2 >= 0)) && (tw > sw))
    {
        loop++;
        if (sw <= 0.0)
        {
            buf[0] = 0;
            break;
        }
        if ((c1 >= 0) && (c2 >= 0))
        {
            if ((loop & 0x1))
            {
                if (c1 >= 0)
                    c1 = evas_string_char_next_get(text, c1, NULL);
            }
            else
            {
                if (c2 >= 0)
                {
                    c2 = evas_string_char_prev_get(text, c2, NULL);
                    if (c2 < 0)
                    {
                        buf[0] = 0;
                        break;
                    }
                }
            }
        }
        else
        {
            if (c1 >= 0)
                c1 = evas_string_char_next_get(text, c1, NULL);
            else if (c2 >= 0)
            {
                c2 = evas_string_char_prev_get(text, c2, NULL);
                if (c2 < 0)
                {
                    buf[0] = 0;
                    break;
                }
            }
        }
        if ((c1 >= 0) && (c2 >= 0))
        {
            if (c1 >= c2)
            {
                buf[0] = 0;
                break;
            }
        }
        else if ((c1 > 0 && (size_t) c1 >= orig_len) || c2 == 0)
        {
            buf[0] = 0;
            break;
        }

        buf[0] = 0;

        _edje_text_fit_set(buf, text, c1, c2);

        evas_object_text_text_set(ep->object, buf);
        part_get_geometry(ep, &tw, &th);
    }

    *free_text = 1;

    return buf;
}