summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKateryna Fesyna <k.fesyna@samsung.com>2014-05-27 15:53:11 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2014-05-27 15:55:05 +0900
commite4e57dc1949e7e2f5a08e54ceda039c6ab3c47f4 (patch)
treecdc0ee1a093517023e2f1ff3de127cf873dfec98
parent71fc5afd638dc0e59403bd774a4bcc72e9db84e0 (diff)
Genlist: Add function to search item by string.
Summary: This function allows user to search for item in Genlist. It takes four search parameters: 1. pointer to function to get text of the item. It could be the same with item's get_text function. This parameter is added to let user use the specific search key and to avoid problems with setting item's text, that is not constant. 2. pointer to the item from which search should start. 3. search pattern. 4. fnmatch() flags. To check it's usage the new test is added to the elementary_test (Genlist Item Search By Text) Reviewers: cedric, seoz, raster CC: reutskiy.v.v Differential Revision: https://phab.enlightenment.org/D566
-rw-r--r--src/bin/test.c2
-rw-r--r--src/bin/test_genlist.c272
-rw-r--r--src/lib/elm_genlist.c29
-rw-r--r--src/lib/elm_genlist.eo45
-rw-r--r--src/lib/elm_genlist_legacy.h2
5 files changed, 349 insertions, 1 deletions
diff --git a/src/bin/test.c b/src/bin/test.c
index 9ff36fd8d..ada5c2516 100644
--- a/src/bin/test.c
+++ b/src/bin/test.c
@@ -112,6 +112,7 @@ void test_genlist16(void *data, Evas_Object *obj, void *event_info);
112void test_genlist17(void *data, Evas_Object *obj, void *event_info); 112void test_genlist17(void *data, Evas_Object *obj, void *event_info);
113void test_genlist18(void *data, Evas_Object *obj, void *event_info); 113void test_genlist18(void *data, Evas_Object *obj, void *event_info);
114void test_genlist19(void *data, Evas_Object *obj, void *event_info); 114void test_genlist19(void *data, Evas_Object *obj, void *event_info);
115void test_genlist20(void *data, Evas_Object *obj, void *event_info);
115void test_genlist_focus(void *data, Evas_Object *obj, void *event_info); 116void test_genlist_focus(void *data, Evas_Object *obj, void *event_info);
116void test_genlist_item_styles(void *data, Evas_Object *obj, void *event_info); 117void test_genlist_item_styles(void *data, Evas_Object *obj, void *event_info);
117void test_genlist_multi_select(void *data, Evas_Object *obj, void *event_info); 118void test_genlist_multi_select(void *data, Evas_Object *obj, void *event_info);
@@ -652,6 +653,7 @@ add_tests:
652 ADD_TEST(NULL, "Lists - Genlist", "Genlist Decorate Modes", test_genlist17); 653 ADD_TEST(NULL, "Lists - Genlist", "Genlist Decorate Modes", test_genlist17);
653 ADD_TEST(NULL, "Lists - Genlist", "Genlist Tree and Decorate All Mode", test_genlist18); 654 ADD_TEST(NULL, "Lists - Genlist", "Genlist Tree and Decorate All Mode", test_genlist18);
654 ADD_TEST(NULL, "Lists - Genlist", "Genlist Full Widget", test_genlist19); 655 ADD_TEST(NULL, "Lists - Genlist", "Genlist Full Widget", test_genlist19);
656 ADD_TEST(NULL, "Lists - Genlist", "Genlist Item Search By Text", test_genlist20);
655 ADD_TEST(NULL, "Lists - Genlist", "Genlist Focus", test_genlist_focus); 657 ADD_TEST(NULL, "Lists - Genlist", "Genlist Focus", test_genlist_focus);
656 ADD_TEST(NULL, "Lists - Genlist", "Genlist Item Styles", test_genlist_item_styles); 658 ADD_TEST(NULL, "Lists - Genlist", "Genlist Item Styles", test_genlist_item_styles);
657 ADD_TEST(NULL, "Lists - Genlist", "Genlist Multi Select", test_genlist_multi_select); 659 ADD_TEST(NULL, "Lists - Genlist", "Genlist Multi Select", test_genlist_multi_select);
diff --git a/src/bin/test_genlist.c b/src/bin/test_genlist.c
index ea9a4c6d1..d78f6455b 100644
--- a/src/bin/test_genlist.c
+++ b/src/bin/test_genlist.c
@@ -3468,6 +3468,278 @@ test_genlist_multi_select(void *data EINA_UNUSED,
3468 evas_object_show(win); 3468 evas_object_show(win);
3469} 3469}
3470 3470
3471/* test genlist item search by text */
3472
3473typedef struct _gl20_Event_Data gl20_Event_Data;
3474struct _gl20_Event_Data
3475{
3476 Evas_Object *gl_obj;
3477 Evas_Object *tg_obj;
3478 Evas_Object *en_obj;
3479 Elm_Object_Item *last_item_found;
3480};
3481
3482static const char *_gl20_items_text[] = {
3483 "Albany", "Annapolis",
3484 "Atlanta", "Augusta",
3485 "Austin", "Baton Rouge",
3486 "Bismarck", "Boise",
3487 "Boston", "Carson City",
3488 "Charleston", "Cheyenne",
3489 "Columbia", "Columbus",
3490 "Concord", "Denver",
3491 "Des Moines", "Dover",
3492 "Frankfort", "Harrisburg",
3493 "Hartford", "Helena",
3494 "Honolulu", "Indianapolis",
3495 "Jackson", "Jefferson City",
3496 "Juneau", "Lansing",
3497 "Lincoln", "Little Rock",
3498 "Madison", "Montgomery",
3499 "Montpelier", "Nashville",
3500 "Oklahoma City", "Olympia",
3501 "Phoenix", "Pierre",
3502 "Providence", "Raleigh",
3503 "Richmond", "Sacramento",
3504 "Saint Paul", "Salem",
3505 "Salt Lake City", "Santa Fe",
3506 "Springfield", "Tallahassee",
3507 "Topeka", "Trenton" };
3508
3509static char *
3510_gl20_search_text_get(void *data, Evas_Object *obj EINA_UNUSED,
3511 const char *part EINA_UNUSED)
3512{
3513 char buf[32];
3514 int item_index = (int)(uintptr_t)data;
3515
3516 if (item_index < 50)
3517 {
3518 snprintf(buf, sizeof(buf), "%s", _gl20_items_text[item_index]);
3519 return strdup(buf);
3520 }
3521 else if (item_index < 100)
3522 {
3523 snprintf(buf, sizeof(buf), "%X", (item_index - 50));
3524 return strdup(buf);
3525 }
3526 else if (item_index == 100)
3527 return strdup("Tree Item");
3528
3529 return NULL;
3530}
3531
3532static char *
3533_gl20_text_get(void *data, Evas_Object *obj EINA_UNUSED,
3534 const char *part EINA_UNUSED)
3535{
3536 char buf[64];
3537 snprintf(buf, sizeof(buf), "(this text is not uset for search) %s",
3538 _gl20_search_text_get(data, NULL, NULL));
3539 return strdup(buf);
3540}
3541
3542static void
3543_gl20_searsh_item(gl20_Event_Data *event_data, Elm_Object_Item * it)
3544{
3545 const char *str = elm_entry_entry_get(event_data->en_obj);
3546 if (!str || !strlen(str)) return;
3547
3548 int flag = 0;
3549 if (!elm_check_state_get(event_data->tg_obj))
3550 flag = FNM_CASEFOLD;
3551
3552 printf("Looking for \"%s\". ", str);
3553 event_data->last_item_found = elm_genlist_search_by_text_item_get(event_data->gl_obj,
3554 it, _gl20_search_text_get, NULL, str, flag);
3555
3556 if (event_data->last_item_found)
3557 {
3558 printf("Found.\n");
3559 elm_genlist_item_selected_set(event_data->last_item_found, EINA_TRUE);
3560 elm_genlist_item_bring_in(event_data->last_item_found,
3561 ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
3562 elm_object_focus_set(event_data->en_obj, EINA_TRUE);
3563 }
3564 else
3565 printf("Not Found.\n");
3566}
3567
3568static void
3569_gl20_search_settings_changed_cb(void *data, Evas_Object *obj EINA_UNUSED,
3570 void *einfo EINA_UNUSED)
3571{
3572 _gl20_searsh_item(data, NULL);
3573}
3574
3575static Elm_Genlist_Item_Class *
3576_gl20_item_class_create(const char *item_style)
3577{
3578 Elm_Genlist_Item_Class * itc = elm_genlist_item_class_new();
3579 itc->item_style = item_style;
3580 itc->func.text_get = _gl20_text_get;
3581 itc->func.content_get = gl_content_get;
3582 itc->func.state_get = gl_state_get;
3583 itc->func.del = NULL;
3584 return itc;
3585}
3586
3587static void
3588_gl20_expand_cb(void *data EINA_UNUSED, Evas_Object *o EINA_UNUSED,
3589 void *event_info)
3590{
3591 Elm_Object_Item *glit = event_info;
3592 Evas_Object *gl = elm_object_item_widget_get(glit);
3593 Elm_Genlist_Item_Class *itc = NULL;
3594 int i = 0;
3595
3596 itc = _gl20_item_class_create("default");
3597
3598 for (i = 50; i < 100; i++)
3599 {
3600 elm_genlist_item_append(gl, itc,
3601 (void *)(uintptr_t) i/* item data */,
3602 glit/* parent */,
3603 ELM_GENLIST_ITEM_NONE, NULL/* func */,
3604 NULL/* func data */);
3605 }
3606 elm_genlist_item_class_free(itc);
3607}
3608
3609static void _gl20_on_keydown(void *data, Evas *evas EINA_UNUSED,
3610 Evas_Object *o EINA_UNUSED, void *einfo)
3611{
3612 Evas_Event_Key_Down *ev = einfo;
3613 gl20_Event_Data * event_data = (gl20_Event_Data *)data;
3614
3615 if (!strcmp(ev->key, "Return"))
3616 {
3617 printf("Looking for next item\n");
3618 _gl20_searsh_item(data, event_data->last_item_found);
3619 }
3620}
3621
3622void
3623test_genlist20(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
3624 void *event_info EINA_UNUSED)
3625{
3626 Evas_Object *win, *bx, *gl;
3627 Evas_Object *fr, *lb_frame; // info frame
3628 Evas_Object *bx_entry, *lb_entry, *en; // search line
3629 Evas_Object *tg; // "case sensitive" toggle
3630 Elm_Genlist_Item_Class *itc = NULL;
3631 gl20_Event_Data* event_data = NULL;
3632 int i = 0;
3633
3634 win = elm_win_util_standard_add("genlist-item-search-by-text",
3635 "Genlist Item Search By Text");
3636 elm_win_autodel_set(win, EINA_TRUE);
3637
3638 bx = elm_box_add(win);
3639 evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
3640 elm_win_resize_object_add(win, bx);
3641 evas_object_show(bx);
3642
3643 fr = elm_frame_add(bx);
3644 evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, 0.0);
3645 evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, EVAS_HINT_FILL);
3646 elm_object_text_set(fr, "Information");
3647 elm_box_pack_end(bx, fr);
3648 evas_object_show(fr);
3649
3650 lb_frame = elm_label_add(fr);
3651 elm_object_text_set(lb_frame,
3652 "<align=left>This is an example of "
3653 "elm_genlist_search_by_text_item_get() usage.<br>"
3654 "Enter search string to the entry and press Enter to "
3655 "show next search result.<br>");
3656 elm_object_content_set(fr, lb_frame);
3657 evas_object_show(lb_frame);
3658
3659 tg = elm_check_add(win);
3660 elm_object_style_set(tg, "toggle");
3661 elm_object_text_set(tg, " Case Sensitive Search");
3662 elm_check_state_set(tg, EINA_TRUE);
3663 elm_box_pack_end(bx, tg);
3664 evas_object_show(tg);
3665
3666 bx_entry = elm_box_add(win);
3667 elm_box_horizontal_set(bx_entry, EINA_TRUE);
3668 evas_object_size_hint_weight_set(bx_entry, EVAS_HINT_EXPAND, 0.0);
3669 evas_object_size_hint_align_set(bx_entry, EVAS_HINT_FILL, 0.0);
3670 elm_box_pack_end(bx, bx_entry);
3671 evas_object_show(bx_entry);
3672
3673 lb_entry = elm_label_add(win);
3674 elm_object_text_set(lb_entry, " Search:");
3675 evas_object_size_hint_weight_set(lb_entry, 0.0, EVAS_HINT_EXPAND);
3676 evas_object_size_hint_align_set(lb_entry, 0.0, EVAS_HINT_FILL);
3677 elm_box_pack_end(bx_entry, lb_entry);
3678 evas_object_show(lb_entry);
3679
3680 en = elm_entry_add(win);
3681 elm_entry_single_line_set(en, EINA_TRUE);
3682 elm_entry_scrollable_set(en, EINA_TRUE);
3683 elm_object_part_text_set(en, "guide", "Type item's name here to search.");
3684 evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
3685 evas_object_size_hint_align_set(en, EVAS_HINT_FILL, EVAS_HINT_FILL);
3686 elm_box_pack_end(bx_entry, en);
3687 evas_object_show(en);
3688 elm_object_focus_set(en, EINA_TRUE);
3689
3690 gl = elm_genlist_add(bx);
3691
3692 evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
3693 evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
3694 elm_box_pack_end(bx, gl);
3695 evas_object_show(gl);
3696
3697 event_data = calloc(1, sizeof(gl20_Event_Data));
3698 event_data->tg_obj = tg;
3699 event_data->en_obj = en;
3700 event_data->gl_obj = gl;
3701 event_data->last_item_found = NULL;
3702
3703 evas_object_event_callback_add(en, EVAS_CALLBACK_KEY_DOWN,
3704 _gl20_on_keydown, (void*)event_data);
3705 evas_object_event_callback_add(gl, EVAS_CALLBACK_FREE,
3706 _cleanup_cb, (void*)event_data);
3707 evas_object_smart_callback_add(en, "changed,user",
3708 _gl20_search_settings_changed_cb, (void*)event_data);
3709 evas_object_smart_callback_add(tg, "changed",
3710 _gl20_search_settings_changed_cb, (void*)event_data);
3711 evas_object_smart_callback_add(gl, "expand,request", gl4_exp_req, gl);
3712 evas_object_smart_callback_add(gl, "contract,request", gl4_con_req, gl);
3713 evas_object_smart_callback_add(gl, "contracted", gl4_con, gl);
3714 evas_object_smart_callback_add(gl, "expanded", _gl20_expand_cb, gl);
3715
3716 itc = _gl20_item_class_create("tree_effect");
3717
3718 elm_genlist_item_append(gl, itc,
3719 (void *)100/* item data */,
3720 NULL/* parent */,
3721 ELM_GENLIST_ITEM_TREE,
3722 NULL/* func */,
3723 NULL/* func data */);
3724
3725 itc->item_style = "default";
3726
3727 for (i = 0; i < 50; i++)
3728 {
3729 elm_genlist_item_append(gl, itc,
3730 (void *)(uintptr_t)i/* item data */,
3731 NULL/* parent */,
3732 ELM_GENLIST_ITEM_NONE,
3733 NULL/* func */,
3734 NULL/* func data */);
3735 }
3736
3737 elm_genlist_item_class_free(itc);
3738
3739 evas_object_resize(win, 320, 500);
3740 evas_object_show(win);
3741}
3742
3471/* test genlist deletion */ 3743/* test genlist deletion */
3472 3744
3473static void _gl_del_sel(void *data, Evas_Object *obj, void *event_info); 3745static void _gl_del_sel(void *data, Evas_Object *obj, void *event_info);
diff --git a/src/lib/elm_genlist.c b/src/lib/elm_genlist.c
index 5f73def7e..0e26793f8 100644
--- a/src/lib/elm_genlist.c
+++ b/src/lib/elm_genlist.c
@@ -7496,6 +7496,35 @@ _elm_genlist_elm_widget_focus_highlight_geometry_get(Eo *obj EINA_UNUSED, Elm_Ge
7496 } 7496 }
7497} 7497}
7498 7498
7499EOLIAN static Elm_Object_Item *
7500_elm_genlist_search_by_text_item_get(Eo *obj EINA_UNUSED,
7501 Elm_Genlist_Data *sd,
7502 Elm_Object_Item * item_to_search_from,
7503 Elm_Gen_Item_Text_Get_Cb _text_get,
7504 const char * part_name,
7505 const char * pattern,
7506 int flags)
7507{
7508 Elm_Gen_Item *it = NULL;
7509 const char * str = NULL;
7510 Eina_Bool search_flag = (item_to_search_from) ? EINA_FALSE : EINA_TRUE;
7511
7512 if (!_text_get || !pattern) return NULL;
7513 if (!sd->items) return NULL;
7514
7515 EINA_INLIST_FOREACH(sd->items, it)
7516 {
7517 if (search_flag)
7518 {
7519 str = _text_get((void *)it->base.data, VIEW(it), part_name);
7520 if (!fnmatch(pattern, str, flags)) return (Elm_Object_Item *)it;
7521 }
7522 else if (item_to_search_from == (Elm_Object_Item *)it)
7523 search_flag = EINA_TRUE;
7524 }
7525 return NULL;
7526}
7527
7499EOLIAN static Elm_Object_Item* 7528EOLIAN static Elm_Object_Item*
7500_elm_genlist_elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd) 7529_elm_genlist_elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
7501{ 7530{
diff --git a/src/lib/elm_genlist.eo b/src/lib/elm_genlist.eo
index 0a2d74af3..5f04a22f4 100644
--- a/src/lib/elm_genlist.eo
+++ b/src/lib/elm_genlist.eo
@@ -681,6 +681,51 @@ class Elm_Genlist (Elm_Layout, Elm_Interface_Scrollable, Evas_Clickable_Interfac
681 @in const void *func_data; /*@ Data passed to @p func above. */ 681 @in const void *func_data; /*@ Data passed to @p func above. */
682 } 682 }
683 } 683 }
684 search_by_text_item_get {
685 /*@
686 Get genlist item by given string.
687
688 @return Pointer to the genlist item which matches search_string in case of success, otherwise returns NULL.
689
690 This function takes pointer to the function that returns
691 comparison string for item (it could be the same function as used for setting text for labels).
692 Also it takes pointer to the genlist item that will be used to start search from it.
693
694 This function uses fnmatch() for searching and takes it's seatcing flags as last parameter.
695 The list of available flags:
696 <dl>
697 <dt>FNM_NOESCAPE</dt>
698 <dd>If this flag is set, treat backslash as an ordinary character, instead of an escape character.</dd>
699 <dt>FNM_PATHNAME</dt>
700 <dd>If this flag is set, match a slash in string only with a slash in pattern and not by an asterisk (*)
701 or a question mark (?) metacharacter, nor by a bracket expression ([]) containing a slash.</dd>
702 <dt>FNM_PERIOD</dt>
703 <dd>If this flag is set, a leading period in string has to be matched exactly by a period in pattern.
704 A period is considered to be leading if it is the first character in string, or if both
705 FNM_PATHNAME is set and the period immediately follows a slash.</dd>
706 <dt>FNM_FILE_NAME</dt>
707 <dd>This is a GNU synonym for FNM_PATHNAME.</dd>
708 <dt>FNM_LEADING_DIR</dt>
709 <dd>If this flag (a GNU extension) is set, the pattern is considered to be matched if it matches an
710 initial segment of string which is followed by a slash. This flag is mainly for the internal
711 use of glibc and is only implemented in certain cases.</dd>
712 <dt>FNM_CASEFOLD</dt>
713 <dd>If this flag (a GNU extension) is set, the pattern is matched case-insensitively.</dd>
714 </dl>
715 For more details see <a href=http://man7.org/linux/man-pages/man3/fnmatch.3.html>Linux Programmer's Manual. FNMATCH()</a>
716
717 @ingroup Genlist
718 @since 1.10 */
719
720 return Elm_Object_Item *;
721 params {
722 @in Elm_Object_Item * item_to_search_from; /*@ Pointer to item to start search from. If NULL search will be started from the first item of the genlist. */
723 @in Elm_Gen_Item_Text_Get_Cb _text_get; /*@ Pointer to Elm_Gen_Item_Text_Get_Cb function to get text for comparison. */
724 @in const char * part_name; /*@ Name of the TEXT part of genlist item to search string in. */
725 @in const char * pattern; /*@ The search pattern. */
726 @in int flags; /*@ fnmatch search flags */
727 }
728 }
684 } 729 }
685 implements { 730 implements {
686 class::constructor; 731 class::constructor;
diff --git a/src/lib/elm_genlist_legacy.h b/src/lib/elm_genlist_legacy.h
index 61be1f963..c83667e0e 100644
--- a/src/lib/elm_genlist_legacy.h
+++ b/src/lib/elm_genlist_legacy.h
@@ -31,4 +31,4 @@ EAPI Evas_Object *elm_genlist_add(Evas_Object *parent);
31EAPI Elm_Object_Item * 31EAPI Elm_Object_Item *
32elm_genlist_nth_item_get(const Evas_Object *obj, unsigned int nth); 32elm_genlist_nth_item_get(const Evas_Object *obj, unsigned int nth);
33 33
34#include "elm_genlist.eo.legacy.h" \ No newline at end of file 34#include "elm_genlist.eo.legacy.h"