diff options
author | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2014-07-24 12:41:33 +0900 |
---|---|---|
committer | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2014-07-24 12:41:33 +0900 |
commit | 8425af77686bace152e93d89d3ed5b872cd0b32e (patch) | |
tree | 18b7e2e701125514c69a50263ccef4785151e5a1 /src/lib | |
parent | 1857e0df0b29a19a6aea330c85ffed0482b58041 (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
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/elm_gen.h | 8 | ||||
-rw-r--r-- | src/lib/elm_gengrid.c | 39 | ||||
-rw-r--r-- | src/lib/elm_gengrid.eo | 26 | ||||
-rw-r--r-- | src/lib/elm_genlist.c | 41 | ||||
-rw-r--r-- | src/lib/elm_genlist.eo | 41 |
5 files changed, 93 insertions, 62 deletions
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 | |||
65 | typedef 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[] = { | |||
105 | EOLIAN static Elm_Object_Item * | 105 | EOLIAN 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 | |||
7547 | EOLIAN static Elm_Object_Item * | 7547 | EOLIAN 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 | } |