summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2014-07-24 12:41:33 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2014-07-24 12:41:33 +0900
commit8425af77686bace152e93d89d3ed5b872cd0b32e (patch)
tree18b7e2e701125514c69a50263ccef4785151e5a1
parent1857e0df0b29a19a6aea330c85ffed0482b58041 (diff)
fix genlist/grid search item patch to be simpler and just better
better - why? 1. no reliance on fnmatrch headers - have special enums for this so fnmatch is an internal detail (casefole may not exist) 2. don't leak strduped strings - free them when done 3. have the same code for genlist and grid (dup for now until an interface makes it the same search interface) 4. improve docs 5. get right @since version 6. use label get func in item class - providing a func won't work when multiple items of multiple classes exist in the list
-rw-r--r--src/bin/test_gengrid.c16
-rw-r--r--src/bin/test_genlist.c29
-rw-r--r--src/lib/elm_gen.h8
-rw-r--r--src/lib/elm_gengrid.c39
-rw-r--r--src/lib/elm_gengrid.eo26
-rw-r--r--src/lib/elm_genlist.c41
-rw-r--r--src/lib/elm_genlist.eo41
7 files changed, 106 insertions, 94 deletions
diff --git a/src/bin/test_gengrid.c b/src/bin/test_gengrid.c
index a2ca6a08b..bfdd85fd0 100644
--- a/src/bin/test_gengrid.c
+++ b/src/bin/test_gengrid.c
@@ -1381,20 +1381,11 @@ static const char *_grid5_items_text[] = {
1381}; 1381};
1382 1382
1383static char * 1383static char *
1384_grid5_search_text_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED)
1385{
1386 char buf[32];
1387 Item_Data *id = data;
1388
1389 snprintf(buf, sizeof(buf), "%s", _grid5_items_text[id->mode]);
1390 return strdup(buf);
1391}
1392
1393static char *
1394_grid5_text_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED) 1384_grid5_text_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED)
1395{ 1385{
1386 Item_Data *id = data;
1396 char buf[64]; 1387 char buf[64];
1397 snprintf(buf, sizeof(buf), "%s", _grid5_search_text_get(data, NULL, NULL)); 1388 snprintf(buf, sizeof(buf), "%s", _grid5_items_text[id->mode]);
1398 return strdup(buf); 1389 return strdup(buf);
1399} 1390}
1400 1391
@@ -1405,7 +1396,8 @@ _grid5_search_item(grid5_Event_Data *event_data, Elm_Object_Item * it)
1405 if (!str || !strlen(str)) return; 1396 if (!str || !strlen(str)) return;
1406 1397
1407 printf("Looking for \"%s\". ", str); 1398 printf("Looking for \"%s\". ", str);
1408 event_data->last_item_found = elm_gengrid_search_by_text_item_get(event_data->grid_obj, it, _grid5_search_text_get, NULL, str, 0); 1399 event_data->last_item_found = elm_gengrid_search_by_text_item_get
1400 (event_data->grid_obj, it, NULL, str, 0);
1409 1401
1410 if (event_data->last_item_found) 1402 if (event_data->last_item_found)
1411 { 1403 {
diff --git a/src/bin/test_genlist.c b/src/bin/test_genlist.c
index d553be566..0d80d1c58 100644
--- a/src/bin/test_genlist.c
+++ b/src/bin/test_genlist.c
@@ -3508,8 +3508,8 @@ static const char *_gl20_items_text[] = {
3508 "Topeka", "Trenton" }; 3508 "Topeka", "Trenton" };
3509 3509
3510static char * 3510static char *
3511_gl20_search_text_get(void *data, Evas_Object *obj EINA_UNUSED, 3511_gl20_text_get(void *data, Evas_Object *obj EINA_UNUSED,
3512 const char *part EINA_UNUSED) 3512 const char *part EINA_UNUSED)
3513{ 3513{
3514 char buf[32]; 3514 char buf[32];
3515 int item_index = (int)(uintptr_t)data; 3515 int item_index = (int)(uintptr_t)data;
@@ -3530,29 +3530,18 @@ _gl20_search_text_get(void *data, Evas_Object *obj EINA_UNUSED,
3530 return NULL; 3530 return NULL;
3531} 3531}
3532 3532
3533static char *
3534_gl20_text_get(void *data, Evas_Object *obj EINA_UNUSED,
3535 const char *part EINA_UNUSED)
3536{
3537 char buf[64];
3538 snprintf(buf, sizeof(buf), "(this text is not uset for search) %s",
3539 _gl20_search_text_get(data, NULL, NULL));
3540 return strdup(buf);
3541}
3542
3543static void 3533static void
3544_gl20_searsh_item(gl20_Event_Data *event_data, Elm_Object_Item * it) 3534_gl20_search_item(gl20_Event_Data *event_data, Elm_Object_Item * it)
3545{ 3535{
3546 const char *str = elm_entry_entry_get(event_data->en_obj); 3536 const char *str = elm_entry_entry_get(event_data->en_obj);
3547 if (!str || !strlen(str)) return; 3537 if (!str || !strlen(str)) return;
3548 3538
3549 int flag = 0; 3539 Elm_Glob_Match_Flags flag = 0;
3550 if (!elm_check_state_get(event_data->tg_obj)) 3540 if (!elm_check_state_get(event_data->tg_obj)) flag = ELM_GLOB_MATCH_NOCASE;
3551 flag = FNM_CASEFOLD;
3552 3541
3553 printf("Looking for \"%s\". ", str); 3542 printf("Looking for \"%s\". ", str);
3554 event_data->last_item_found = elm_genlist_search_by_text_item_get(event_data->gl_obj, 3543 event_data->last_item_found = elm_genlist_search_by_text_item_get
3555 it, _gl20_search_text_get, NULL, str, flag); 3544 (event_data->gl_obj, it, NULL, str, flag);
3556 3545
3557 if (event_data->last_item_found) 3546 if (event_data->last_item_found)
3558 { 3547 {
@@ -3570,7 +3559,7 @@ static void
3570_gl20_search_settings_changed_cb(void *data, Evas_Object *obj EINA_UNUSED, 3559_gl20_search_settings_changed_cb(void *data, Evas_Object *obj EINA_UNUSED,
3571 void *einfo EINA_UNUSED) 3560 void *einfo EINA_UNUSED)
3572{ 3561{
3573 _gl20_searsh_item(data, NULL); 3562 _gl20_search_item(data, NULL);
3574} 3563}
3575 3564
3576static Elm_Genlist_Item_Class * 3565static Elm_Genlist_Item_Class *
@@ -3616,7 +3605,7 @@ static void _gl20_on_keydown(void *data, Evas *evas EINA_UNUSED,
3616 if (!strcmp(ev->key, "Return")) 3605 if (!strcmp(ev->key, "Return"))
3617 { 3606 {
3618 printf("Looking for next item\n"); 3607 printf("Looking for next item\n");
3619 _gl20_searsh_item(data, event_data->last_item_found); 3608 _gl20_search_item(data, event_data->last_item_found);
3620 } 3609 }
3621} 3610}
3622 3611
diff --git a/src/lib/elm_gen.h b/src/lib/elm_gen.h
index 431f7b1bb..8bef0e04b 100644
--- a/src/lib/elm_gen.h
+++ b/src/lib/elm_gen.h
@@ -61,3 +61,11 @@ struct _Elm_Gen_Item_Class
61 61
62#define ELM_GEN_ITEM_CLASS_VERSION 2 62#define ELM_GEN_ITEM_CLASS_VERSION 2
63#define ELM_GEN_ITEM_CLASS_HEADER ELM_GEN_ITEM_CLASS_VERSION, 0, 0 63#define ELM_GEN_ITEM_CLASS_HEADER ELM_GEN_ITEM_CLASS_VERSION, 0, 0
64
65typedef enum
66{
67 ELM_GLOB_MATCH_NO_ESCAPE = (1 << 0), /**< Treat backslash as an ordinary character instead of escape */
68 ELM_GLOB_MATCH_PATH = (1 << 1), /**< Match a slash in string only with a slash in pattern and not by an asterisk (*) or a question mark (?) metacharacter, nor by a bracket expression ([]) containing a slash. */
69 ELM_GLOB_MATCH_PERIOD = (1 << 2), /**< Leading period in string has to be matched exactly by a period in pattern. A period is considered to be leading if it is the first character in string, or if both ELM_GLOB_MATCH_PATH is set and the period immediately follows a slash. */
70 ELM_GLOB_MATCH_NOCASE = (1 << 3) /**< The pattern is matched case-insensitively. */
71} Elm_Glob_Match_Flags; /**< Glob matching bitfiled flags. @since 1.11 */
diff --git a/src/lib/elm_gengrid.c b/src/lib/elm_gengrid.c
index 9d06c64e6..c357e5a1a 100644
--- a/src/lib/elm_gengrid.c
+++ b/src/lib/elm_gengrid.c
@@ -105,24 +105,41 @@ static const Elm_Action key_actions[] = {
105EOLIAN static Elm_Object_Item * 105EOLIAN static Elm_Object_Item *
106_elm_gengrid_search_by_text_item_get(Eo *obj EINA_UNUSED, 106_elm_gengrid_search_by_text_item_get(Eo *obj EINA_UNUSED,
107 Elm_Gengrid_Data *sd, 107 Elm_Gengrid_Data *sd,
108 Elm_Object_Item * item_to_search_from, 108 Elm_Object_Item *item_to_search_from,
109 Elm_Gen_Item_Text_Get_Cb _text_get, 109 const char *part_name,
110 const char * part_name, 110 const char *pattern,
111 const char * pattern, 111 Elm_Glob_Match_Flags flags)
112 int flags)
113{ 112{
114 Elm_Gen_Item *it = NULL; 113 Elm_Gen_Item *it = NULL;
115 const char * str = NULL; 114 char *str = NULL;
116 Eina_Inlist * start = NULL; 115 Eina_Inlist *start = NULL;
116 int fnflags = 0;
117 117
118 if (!_text_get || !pattern) return NULL; 118 if (!pattern) return NULL;
119 if (!sd->items) return NULL; 119 if (!sd->items) return NULL;
120 120
121 start = (item_to_search_from) ? EINA_INLIST_GET((Elm_Gen_Item *)item_to_search_from) : sd->items; 121 if (flags & ELM_GLOB_MATCH_NO_ESCAPE) fnflags |= FNM_NOESCAPE;
122 if (flags & ELM_GLOB_MATCH_PATH) fnflags |= FNM_PATHNAME;
123 if (flags & ELM_GLOB_MATCH_PERIOD) fnflags |= FNM_PERIOD;
124#ifdef FNM_CASEFOLD
125 if (flags & ELM_GLOB_MATCH_NOCASE) fnflags |= FNM_CASEFOLD;
126#endif
127
128 start = (item_to_search_from) ?
129 EINA_INLIST_GET((Elm_Gen_Item *)item_to_search_from) :
130 sd->items;
122 EINA_INLIST_FOREACH(start, it) 131 EINA_INLIST_FOREACH(start, it)
123 { 132 {
124 str = _text_get((void *)it->base.data, VIEW(it), part_name); 133 if (!it->itc->func.text_get) continue;
125 if (!fnmatch(pattern, str, flags)) return (Elm_Object_Item *)it; 134 str = it->itc->func.text_get((void *)it->base.data,
135 VIEW(it), part_name);
136 if (!str) continue;
137 if (!fnmatch(pattern, str, fnflags))
138 {
139 free(str);
140 return (Elm_Object_Item *)it;
141 }
142 free(str);
126 } 143 }
127 return NULL; 144 return NULL;
128} 145}
diff --git a/src/lib/elm_gengrid.eo b/src/lib/elm_gengrid.eo
index 6b125f97a..7e34c97db 100644
--- a/src/lib/elm_gengrid.eo
+++ b/src/lib/elm_gengrid.eo
@@ -656,14 +656,28 @@ class Elm_Gengrid (Elm_Layout, Elm_Interface_Scrollable, Evas.Clickable_Interfac
656 @in const(void)* func_data; /*@ Data to be passed to @p func. */ 656 @in const(void)* func_data; /*@ Data to be passed to @p func. */
657 } 657 }
658 } 658 }
659 search_by_text_item_get { 659 search_by_text_item_get {
660 /*@
661 Get gengrid item by given string.
662
663 @return Pointer to the gengrid item which matches search_string in case of success, otherwise returns NULL.
664
665 It takes pointer to the gengrid item that will be used to start
666 search from it.
667
668 This function uses globs (like "*.jpg") for searching and takes
669 search flags as last parameter That is a bitfield with values
670 to be ored together or 0 for no flags.
671
672 @ingroup Gengrid
673 @since 1.11 */
674
660 return Elm_Object_Item *; 675 return Elm_Object_Item *;
661 params { 676 params {
662 @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. */ 677 @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 gengrid. */
663 @in Elm_Gen_Item_Text_Get_Cb _text_get; /*@ Pointer to Elm_Gen_Item_Text_Get_Cb function to get text for comparison. */ 678 @in const(char) *part_name; /*@ Name of the TEXT part of gengrid item to search string in. */
664 @in const(char)* part_name; /*@ Name of the TEXT part of genlist item to search string in. */ 679 @in const(char) *pattern; /*@ The search pattern. */
665 @in const(char)* pattern; /*@ The search pattern. */ 680 @in Elm_Glob_Match_Flags flags; /*@ Search flags */
666 @in int flags; /*@ fnmatch search flags */
667 } 681 }
668 } 682 }
669 } 683 }
diff --git a/src/lib/elm_genlist.c b/src/lib/elm_genlist.c
index e33a8cfa5..f09f1fe90 100644
--- a/src/lib/elm_genlist.c
+++ b/src/lib/elm_genlist.c
@@ -7547,28 +7547,41 @@ _elm_genlist_elm_widget_focus_highlight_geometry_get(Eo *obj EINA_UNUSED, Elm_Ge
7547EOLIAN static Elm_Object_Item * 7547EOLIAN static Elm_Object_Item *
7548_elm_genlist_search_by_text_item_get(Eo *obj EINA_UNUSED, 7548_elm_genlist_search_by_text_item_get(Eo *obj EINA_UNUSED,
7549 Elm_Genlist_Data *sd, 7549 Elm_Genlist_Data *sd,
7550 Elm_Object_Item * item_to_search_from, 7550 Elm_Object_Item *item_to_search_from,
7551 Elm_Gen_Item_Text_Get_Cb _text_get, 7551 const char *part_name,
7552 const char * part_name, 7552 const char *pattern,
7553 const char * pattern, 7553 Elm_Glob_Match_Flags flags)
7554 int flags)
7555{ 7554{
7556 Elm_Gen_Item *it = NULL; 7555 Elm_Gen_Item *it = NULL;
7557 const char * str = NULL; 7556 char *str = NULL;
7558 Eina_Bool search_flag = (item_to_search_from) ? EINA_FALSE : EINA_TRUE; 7557 Eina_Inlist *start = NULL;
7558 int fnflags = 0;
7559 7559
7560 if (!_text_get || !pattern) return NULL; 7560 if (!pattern) return NULL;
7561 if (!sd->items) return NULL; 7561 if (!sd->items) return NULL;
7562 7562
7563 EINA_INLIST_FOREACH(sd->items, it) 7563 if (flags & ELM_GLOB_MATCH_NO_ESCAPE) fnflags |= FNM_NOESCAPE;
7564 if (flags & ELM_GLOB_MATCH_PATH) fnflags |= FNM_PATHNAME;
7565 if (flags & ELM_GLOB_MATCH_PERIOD) fnflags |= FNM_PERIOD;
7566#ifdef FNM_CASEFOLD
7567 if (flags & ELM_GLOB_MATCH_NOCASE) fnflags |= FNM_CASEFOLD;
7568#endif
7569
7570 start = (item_to_search_from) ?
7571 EINA_INLIST_GET((Elm_Gen_Item *)item_to_search_from) :
7572 sd->items;
7573 EINA_INLIST_FOREACH(start, it)
7564 { 7574 {
7565 if (search_flag) 7575 if (!it->itc->func.text_get) continue;
7576 str = it->itc->func.text_get((void *)it->base.data,
7577 VIEW(it), part_name);
7578 if (!str) continue;
7579 if (!fnmatch(pattern, str, fnflags))
7566 { 7580 {
7567 str = _text_get((void *)it->base.data, VIEW(it), part_name); 7581 free(str);
7568 if (!fnmatch(pattern, str, flags)) return (Elm_Object_Item *)it; 7582 return (Elm_Object_Item *)it;
7569 } 7583 }
7570 else if (item_to_search_from == (Elm_Object_Item *)it) 7584 free(str);
7571 search_flag = EINA_TRUE;
7572 } 7585 }
7573 return NULL; 7586 return NULL;
7574} 7587}
diff --git a/src/lib/elm_genlist.eo b/src/lib/elm_genlist.eo
index 14babba7f..78aed245a 100644
--- a/src/lib/elm_genlist.eo
+++ b/src/lib/elm_genlist.eo
@@ -683,43 +683,22 @@ class Elm_Genlist (Elm_Layout, Elm_Interface_Scrollable, Evas.Clickable_Interfac
683 683
684 @return Pointer to the genlist item which matches search_string in case of success, otherwise returns NULL. 684 @return Pointer to the genlist item which matches search_string in case of success, otherwise returns NULL.
685 685
686 This function takes pointer to the function that returns 686 It takes pointer to the genlist item that will be used to start
687 comparison string for item (it could be the same function as used for setting text for labels). 687 search from it.
688 Also it takes pointer to the genlist item that will be used to start search from it. 688
689 689 This function uses globs (like "*.jpg") for searching and takes
690 This function uses fnmatch() for searching and takes it's seatcing flags as last parameter. 690 search flags as last parameter That is a bitfield with values
691 The list of available flags: 691 to be ored together or 0 for no flags.
692 <dl>
693 <dt>FNM_NOESCAPE</dt>
694 <dd>If this flag is set, treat backslash as an ordinary character, instead of an escape character.</dd>
695 <dt>FNM_PATHNAME</dt>
696 <dd>If this flag is set, match a slash in string only with a slash in pattern and not by an asterisk (*)
697 or a question mark (?) metacharacter, nor by a bracket expression ([]) containing a slash.</dd>
698 <dt>FNM_PERIOD</dt>
699 <dd>If this flag is set, a leading period in string has to be matched exactly by a period in pattern.
700 A period is considered to be leading if it is the first character in string, or if both
701 FNM_PATHNAME is set and the period immediately follows a slash.</dd>
702 <dt>FNM_FILE_NAME</dt>
703 <dd>This is a GNU synonym for FNM_PATHNAME.</dd>
704 <dt>FNM_LEADING_DIR</dt>
705 <dd>If this flag (a GNU extension) is set, the pattern is considered to be matched if it matches an
706 initial segment of string which is followed by a slash. This flag is mainly for the internal
707 use of glibc and is only implemented in certain cases.</dd>
708 <dt>FNM_CASEFOLD</dt>
709 <dd>If this flag (a GNU extension) is set, the pattern is matched case-insensitively.</dd>
710 </dl>
711 For more details see <a href=http://man7.org/linux/man-pages/man3/fnmatch.3.html>Linux Programmer's Manual. FNMATCH()</a>
712 692
713 @ingroup Genlist 693 @ingroup Genlist
714 @since 1.10 */ 694 @since 1.11 */
715 695
716 return Elm_Object_Item *; 696 return Elm_Object_Item *;
717 params { 697 params {
718 @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. */ 698 @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. */
719 @in Elm_Gen_Item_Text_Get_Cb _text_get; /*@ Pointer to Elm_Gen_Item_Text_Get_Cb function to get text for comparison. */ 699 @in const(char)* part_name; /*@ Name of the TEXT part of genlist item to search string in. */
720 @in const(char)* part_name; /*@ Name of the TEXT part of genlist item to search string in. */ 700 @in const(char)* pattern; /*@ The search pattern. */
721 @in const(char)* pattern; /*@ The search pattern. */ 701 @in Elm_Glob_Match_Flags flags; /*@ Search flags */
722 @in int flags; /*@ fnmatch search flags */
723 } 702 }
724 } 703 }
725 } 704 }