Merge "[elm_label]Changed *.c file mode & Fix build fail & remove warning in TC"
[framework/uifw/elementary.git] / src / lib / elm_store.c
1 #include <Elementary.h>
2 #include <Elementary_Cursor.h>
3 #include "elm_priv.h"
4
5 #ifndef EFL_HAVE_THREADS
6 # error "No thread support. Required."
7 #endif
8
9 #ifdef EFL_HAVE_POSIX_THREADS
10 # include <pthread.h>
11 # define LK(x)  pthread_mutex_t x
12 # define LKI(x) pthread_mutex_init(&(x), NULL);
13 # define LKD(x) pthread_mutex_destroy(&(x));
14 # define LKL(x) pthread_mutex_lock(&(x));
15 # define LKU(x) pthread_mutex_unlock(&(x));
16 #else /* EFL_HAVE_WIN32_THREADS */
17 # define WIN32_LEAN_AND_MEAN
18 # include <windows.h>
19 # undef WIN32_LEAN_AND_MEAN
20 # define LK(x)  HANDLE x
21 # define LKI(x) x = CreateMutex(NULL, FALSE, NULL)
22 # define LKD(x) CloseHandle(x)
23 # define LKL(x) WaitForSingleObject(x, INFINITE)
24 # define LKU(x) ReleaseMutex(x)
25 #endif
26
27 #define ELM_STORE_MAGIC            0x3f89ea56
28 #define ELM_STORE_FILESYSTEM_MAGIC 0x3f89ea57
29 #define ELM_STORE_DBSYSTEM_MAGIC   0x3f89ea58
30 #define ELM_STORE_ITEM_MAGIC       0x5afe8c1d
31 #define CACHE_COUNT                1024
32
33 struct _Elm_Store
34 {
35    EINA_MAGIC;
36    void         (*free)(Elm_Store *store);
37    struct {
38         void        (*free)(Elm_Store_Item *item);
39    } item;
40    Evas_Object   *genlist;
41    Ecore_Thread  *list_th;
42    Eina_Inlist   *items;
43    Eina_List     *realized;
44    int            realized_count;
45    int            cache_max;
46    int            item_count;
47    int            type;
48    Eina_List     *always_fetched;
49    struct {
50         struct {
51              Elm_Store_Item_List_Cb     func;
52              void                      *data;
53         } list;
54         struct {
55              Elm_Store_Item_Fetch_Cb    func;
56              void                      *data;
57         } fetch;
58         struct {
59              Elm_Store_Item_Unfetch_Cb  func;
60              void                      *data;
61         } unfetch;
62         struct {
63              Elm_Store_Item_Select_Cb func;
64              void                    *data;
65         } item_select;
66         struct {
67              Elm_Store_Item_Sort_Cb func;
68              void                  *data;
69         } item_sort;
70         struct {
71              Elm_Store_Item_Free_Cb func;
72              void                  *data;
73         } item_free;
74    } cb;
75    Eina_Bool      sorted : 1;
76    Eina_Bool      fetch_thread : 1;
77    Eina_Bool      live : 1;
78 };
79
80 struct _Elm_Store_Item
81 {
82    EINA_INLIST;
83    EINA_MAGIC;
84    Elm_Store                    *store;
85    Elm_Genlist_Item             *item;
86    Ecore_Thread                 *fetch_th;
87    Ecore_Job                    *eval_job;
88    const Elm_Store_Item_Mapping *mapping;
89    void                         *data;
90    Elm_Store_Item_Info          *item_info;
91    Elm_Genlist_Item             *first_item;
92    Elm_Genlist_Item             *last_item;
93    LK(lock);
94    Eina_Bool                     live : 1;
95    Eina_Bool                     was_live : 1;
96    Eina_Bool                     realized : 1;
97    Eina_Bool                     fetched : 1;
98 };
99
100 struct _Elm_Store_Filesystem
101 {
102    Elm_Store   base;
103    EINA_MAGIC;
104    const char *dir;
105 };
106
107 struct _Elm_Store_Item_Filesystem
108 {
109    Elm_Store_Item base;
110    const char    *path;
111 };
112
113 struct _Elm_Store_DBsystem
114 {
115    Elm_Store   base;
116    EINA_MAGIC;
117    void       *p_db;
118 };
119
120 typedef enum
121 {
122    ELM_STORE_ITEM_SORT_LOW = -1,
123    ELM_STORE_ITEM_SORT_SAME = 0,
124    ELM_STORE_ITEM_SORT_HIGH = 1,
125    ELM_STORE_ITEM_SORT_UNKNOWN = 2,
126    ELM_STORE_ITEM_SORT_LAST
127 } Elm_Store_Item_Sort_Type;
128
129 static Elm_Genlist_Item_Class _store_item_class;
130
131 static void _item_del(void *data, Evas_Object *obj __UNUSED__);
132 static void _item_realized(void *data, Evas_Object *obj __UNUSED__, void *event_info);
133 static void _item_unrealized(void *data, Evas_Object *obj __UNUSED__, void *event_info);
134 static void _genlist_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__);
135
136 static void
137 _store_cache_trim(Elm_Store *st)
138 {
139    while ((st->realized ) &&
140           (((int)eina_list_count(st->realized) - st->realized_count)
141            > st->cache_max))
142      {
143         Elm_Store_Item *sti = st->realized->data;
144         if (sti->realized)
145           {
146              st->realized = eina_list_remove_list(st->realized, st->realized);
147              sti->realized = EINA_FALSE;
148           }
149         LKL(sti->lock);
150         if (!sti->fetched)
151           {
152              LKU(sti->lock);
153              if (sti->fetch_th)
154                {
155                   ecore_thread_cancel(sti->fetch_th);
156                   sti->fetch_th = NULL;
157                }
158              LKL(sti->lock);
159           }
160         sti->fetched = EINA_FALSE;
161         LKU(sti->lock);
162         if (st->cb.unfetch.func)
163           st->cb.unfetch.func(st->cb.unfetch.data, sti, NULL);
164         LKL(sti->lock);
165         sti->data = NULL;
166         LKU(sti->lock);
167      }
168 }
169
170 static void
171 _store_genlist_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
172 {
173    Elm_Store *st = data;
174    st->genlist = NULL;
175    if (st->list_th)
176      {
177         ecore_thread_cancel(st->list_th);
178         st->list_th = NULL;
179      }
180    eina_list_free(st->realized);
181    while (st->items)
182      {
183         Elm_Store_Item *sti = (Elm_Store_Item *)st->items;
184         if (sti->eval_job) ecore_job_del(sti->eval_job);
185         if (sti->fetch_th)
186           {
187              ecore_thread_cancel(sti->fetch_th);
188              sti->fetch_th = NULL;
189           }
190         if (sti->store->item.free) sti->store->item.free(sti);
191         if (sti->data)
192           {
193              if (st->cb.unfetch.func)
194                st->cb.unfetch.func(st->cb.unfetch.data, sti, NULL);
195              sti->data = NULL;
196           }
197         LKD(sti->lock);
198         free(sti);
199      }
200    // FIXME: kill threads and more
201 }
202
203 ////// **** WARNING ***********************************************************
204 ////   * This function runs inside a thread outside efl mainloop. Be careful! *
205 //     ************************************************************************
206 /* TODO: refactor lock part into core? this does not depend on filesystm part */
207 static void
208 _store_filesystem_fetch_do(void *data, Ecore_Thread *th __UNUSED__)
209 {
210    Elm_Store_Item *sti = data;
211    LKL(sti->lock);
212    if (sti->data)
213      {
214         LKU(sti->lock);
215         return;
216      }
217    if (!sti->fetched)
218      {
219         LKU(sti->lock);
220         if (sti->store->cb.fetch.func)
221           sti->store->cb.fetch.func(sti->store->cb.fetch.data, sti, NULL);
222         LKL(sti->lock);
223         sti->fetched = EINA_TRUE;
224      }
225    LKU(sti->lock);
226 }
227 //     ************************************************************************
228 ////   * End of separate thread function.                                     *
229 ////// ************************************************************************
230 /* TODO: refactor lock part into core? this does not depend on filesystm part */
231 static void
232 _store_filesystem_fetch_end(void *data, Ecore_Thread *th)
233 {
234    Elm_Store_Item *sti = data;
235    LKL(sti->lock);
236    if (sti->data) elm_genlist_item_update(sti->item);
237    LKU(sti->lock);
238    if (th == sti->fetch_th) sti->fetch_th = NULL;
239 }
240
241 /* TODO: refactor lock part into core? this does not depend on filesystm part */
242 static void
243 _store_filesystem_fetch_cancel(void *data, Ecore_Thread *th)
244 {
245    Elm_Store_Item *sti = data;
246    LKL(sti->lock);
247    if (th == sti->fetch_th) sti->fetch_th = NULL;
248    if (sti->data) elm_genlist_item_update(sti->item);
249    LKU(sti->lock);
250 }
251
252 static void
253 _store_item_eval(void *data)
254 {
255    Elm_Store_Item *sti = data;
256    sti->eval_job = NULL;
257    if (sti->live == sti->was_live) return;
258    sti->was_live = sti->live;
259    if (sti->live)
260      {
261         _store_cache_trim(sti->store);
262         if (sti->realized)
263           sti->store->realized = eina_list_remove(sti->store->realized, sti);
264         sti->store->realized = eina_list_append(sti->store->realized, sti);
265         sti->realized = EINA_TRUE;
266         if ((sti->store->fetch_thread) && (!sti->fetch_th))
267           sti->fetch_th = ecore_thread_run(_store_filesystem_fetch_do,
268                                            _store_filesystem_fetch_end,
269                                            _store_filesystem_fetch_cancel,
270                                            sti);
271         else if ((!sti->store->fetch_thread))
272           {
273              _store_filesystem_fetch_do(sti, NULL);
274              _store_filesystem_fetch_end(sti, NULL);
275           }
276      }
277    else
278      {
279         if (sti->fetch_th)
280           {
281              ecore_thread_cancel(sti->fetch_th);
282              sti->fetch_th = NULL;
283           }
284         _store_cache_trim(sti->store);
285      }
286 }
287
288 static void
289 _store_genlist_item_realized(void *data, Evas_Object *obj __UNUSED__, void *event_info)
290 {
291    Elm_Store *st = data;
292    Elm_Genlist_Item *gli = event_info;
293    Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
294    if (!sti) return;
295    st->realized_count++;
296    sti->live = EINA_TRUE;
297    if (sti->eval_job) ecore_job_del(sti->eval_job);
298    sti->eval_job = ecore_job_add(_store_item_eval, sti);
299 }
300
301 static void
302 _store_genlist_item_unrealized(void *data, Evas_Object *obj __UNUSED__, void *event_info)
303 {
304    Elm_Store *st = data;
305    Elm_Genlist_Item *gli = event_info;
306    Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
307    if (!sti) return;
308    st->realized_count--;
309    sti->live = EINA_FALSE;
310    if (sti->eval_job) ecore_job_del(sti->eval_job);
311    sti->eval_job = ecore_job_add(_store_item_eval, sti);
312 }
313
314 static const Elm_Store_Item_Mapping *
315 _store_item_mapping_find(Elm_Store_Item *sti, const char *part)
316 {
317    const Elm_Store_Item_Mapping *m;
318
319    for (m = sti->mapping; m; m ++)
320      {
321         if (m->type == ELM_STORE_ITEM_MAPPING_NONE) break;
322         if (!strcmp(part, m->part)) return m;
323      }
324    return NULL;
325 }
326
327 static char *
328 _store_item_label_get(void *data, Evas_Object *obj __UNUSED__, const char *part)
329 {
330    Elm_Store_Item *sti = data;
331    const char *s = "";
332    LKL(sti->lock);
333    if (sti->data)
334      {
335         const Elm_Store_Item_Mapping *m = _store_item_mapping_find(sti, part);
336         if (m)
337           {
338              switch (m->type)
339                {
340                 case ELM_STORE_ITEM_MAPPING_LABEL:
341                    s = *(char **)(((unsigned char *)sti->data) + m->offset);
342                    break;
343                 case ELM_STORE_ITEM_MAPPING_CUSTOM:
344                    if (m->details.custom.func)
345                      s = m->details.custom.func(sti->data, sti, part);
346                    break;
347                 default:
348                    break;
349                }
350           }
351      }
352    LKU(sti->lock);
353    return strdup(s);
354 }
355
356 static Evas_Object *
357 _store_item_icon_get(void *data, Evas_Object *obj, const char *part)
358 {
359    Elm_Store_Item *sti = data;
360    LKL(sti->lock);
361    if (sti->data)
362      {
363         const Elm_Store_Item_Mapping *m = _store_item_mapping_find(sti, part);
364         if (m)
365           {
366              Evas_Object *ic = NULL;
367              const char *s = NULL;
368
369              switch (m->type)
370                {
371                 case ELM_STORE_ITEM_MAPPING_ICON:
372                    ic = elm_icon_add(obj);
373                    s = *(char **)(((unsigned char *)sti->data) + m->offset);
374                    elm_icon_order_lookup_set(ic, m->details.icon.lookup_order);
375                    evas_object_size_hint_aspect_set(ic,
376                                                     EVAS_ASPECT_CONTROL_VERTICAL,
377                                                     m->details.icon.w,
378                                                     m->details.icon.h);
379                    elm_icon_smooth_set(ic, m->details.icon.smooth);
380                    elm_icon_no_scale_set(ic, m->details.icon.no_scale);
381                    elm_icon_scale_set(ic,
382                                       m->details.icon.scale_up,
383                                       m->details.icon.scale_down);
384                    if (s)
385                      {
386                         if (m->details.icon.standard_name)
387                           elm_icon_standard_set(ic, s);
388                         else
389                           elm_icon_file_set(ic, s, NULL);
390                      }
391                    break;
392                 case ELM_STORE_ITEM_MAPPING_PHOTO:
393                    ic = elm_icon_add(obj);
394                    s = *(char **)(((unsigned char *)sti->data) + m->offset);
395                    elm_photo_size_set(ic, m->details.photo.size);
396                    if (s)
397                      elm_photo_file_set(ic, s);
398                    break;
399                 case ELM_STORE_ITEM_MAPPING_CUSTOM:
400                    if (m->details.custom.func)
401                      ic = m->details.custom.func(sti->data, sti, part);
402                    break;
403                 default:
404                    break;
405                }
406              LKU(sti->lock);
407              return ic;
408           }
409      }
410    LKU(sti->lock);
411    return NULL;
412 }
413
414 static void
415 _store_item_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__)
416 {
417 }
418
419 ////// **** WARNING ***********************************************************
420 ////   * This function runs inside a thread outside efl mainloop. Be careful! *
421 //     ************************************************************************
422 static int
423 _store_filesystem_sort_cb(void *d1, void *d2)
424 {
425    Elm_Store_Item_Info *info1 = d1, *info2 = d2;
426    if ((!info1->sort_id) || (!info2->sort_id)) return 0;
427    return strcoll(info1->sort_id, info2->sort_id);
428 }
429
430 static void
431 _store_filesystem_list_do(void *data, Ecore_Thread *th __UNUSED__)
432 {
433    Elm_Store_Filesystem *st = data;
434    Eina_Iterator *it;
435    const Eina_File_Direct_Info *finf;
436    Eina_List *sorted = NULL;
437    Elm_Store_Item_Info_Filesystem *info;
438
439    // FIXME: need a way to abstract the open, list, feed items from list
440    // and maybe get initial sortable key vals etc.
441    it = eina_file_stat_ls(st->dir);
442    if (!it) return;
443    EINA_ITERATOR_FOREACH(it, finf)
444      {
445         Eina_Bool ok;
446         size_t pathsz = finf->path_length + 1;
447
448         info = calloc(1, sizeof(Elm_Store_Item_Info_Filesystem) + pathsz);
449         if (!info) continue;
450         info->path = ((char *)info) + sizeof(Elm_Store_Item_Info_Filesystem);
451         memcpy(info->path, finf->path, pathsz);
452         ok = EINA_TRUE;
453         if (st->base.cb.list.func)
454           ok = st->base.cb.list.func(st->base.cb.list.data, &info->base);
455         if (ok)
456           {
457              if (!st->base.sorted) ecore_thread_feedback(th, info);
458              else sorted = eina_list_append(sorted, info);
459           }
460         else
461           {
462              if (info->base.sort_id) free(info->base.sort_id);
463              free(info);
464           }
465         if (ecore_thread_check(th)) break;
466      }
467    eina_iterator_free(it);
468    if (sorted)
469      {
470         sorted = eina_list_sort(sorted, 0,
471                                 EINA_COMPARE_CB(_store_filesystem_sort_cb));
472         EINA_LIST_FREE(sorted, info)
473           {
474              if (!ecore_thread_check(th)) ecore_thread_feedback(th, info);
475           }
476      }
477 }
478 //     ************************************************************************
479 ////   * End of separate thread function.                                     *
480 ////// ************************************************************************
481
482 static void
483 _store_filesystem_list_end(void *data, Ecore_Thread *th)
484 {
485    Elm_Store *st = data;
486    if (th == st->list_th) st->list_th = NULL;
487 }
488
489 static void
490 _store_filesystem_list_cancel(void *data, Ecore_Thread *th)
491 {
492    Elm_Store *st = data;
493    if (th == st->list_th) st->list_th = NULL;
494 }
495
496 static void
497 _store_filesystem_list_update(void *data, Ecore_Thread *th __UNUSED__, void *msg)
498 {
499    Elm_Store *st = data;
500    Elm_Store_Item_Filesystem *sti;
501    Elm_Genlist_Item_Class *itc;
502    Elm_Store_Item_Info_Filesystem *info = msg;
503
504    sti = calloc(1, sizeof(Elm_Store_Item_Filesystem));
505    if (!sti) goto done;
506    LKI(sti->base.lock);
507    EINA_MAGIC_SET(&(sti->base), ELM_STORE_ITEM_MAGIC);
508    sti->base.store = st;
509    sti->base.data = info->base.data;
510    sti->base.mapping = info->base.mapping;
511    sti->path = eina_stringshare_add(info->path);
512
513    itc = info->base.item_class;
514    if (!itc) itc = &_store_item_class;
515    else
516      {
517         itc->func.label_get = (GenlistItemLabelGetFunc)_store_item_label_get;
518         itc->func.icon_get  = (GenlistItemIconGetFunc)_store_item_icon_get;
519         itc->func.state_get = NULL; // FIXME: support state gets later
520         itc->func.del = (GenlistItemDelFunc)_store_item_del;
521      }
522
523    // FIXME: handle being a parent (tree)
524    sti->base.item = elm_genlist_item_append(st->genlist, itc,
525                                             sti/* item data */,
526                                             NULL/* parent */,
527                                             ELM_GENLIST_ITEM_NONE,
528                                             NULL/* func */,
529                                             NULL/* func data */);
530    st->items = eina_inlist_append(st->items, (Eina_Inlist *)sti);
531 done:
532    if (info->base.sort_id) free(info->base.sort_id);
533    free(info);
534 }
535
536 // public api calls
537 static Elm_Store *
538 _elm_store_new(size_t size)
539 {
540    Elm_Store *st = calloc(1, size);
541    EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
542
543    // TODO: BEGIN - move to elm_store_init()
544    eina_magic_string_set(ELM_STORE_MAGIC, "Elm_Store");
545    eina_magic_string_set(ELM_STORE_FILESYSTEM_MAGIC, "Elm_Store_Filesystem");
546    eina_magic_string_set(ELM_STORE_ITEM_MAGIC, "Elm_Store_Item");
547    // setup default item class (always the same) if list cb doesnt provide one
548    _store_item_class.item_style = "default";
549    _store_item_class.func.label_get = (GenlistItemLabelGetFunc)_store_item_label_get;
550    _store_item_class.func.icon_get  = (GenlistItemIconGetFunc)_store_item_icon_get;
551    _store_item_class.func.state_get = NULL; // FIXME: support state gets later
552    _store_item_class.func.del       = (GenlistItemDelFunc)_store_item_del;
553    // TODO: END - move to elm_store_init()
554
555    EINA_MAGIC_SET(st, ELM_STORE_MAGIC);
556    st->cache_max = 128;
557    st->fetch_thread = EINA_TRUE;
558    st->type = 0;
559    return st;
560 }
561 #define elm_store_new(type) (type*)_elm_store_new(sizeof(type))
562
563 static void
564 _elm_store_filesystem_free(Elm_Store *store)
565 {
566    Elm_Store_Filesystem *st = (Elm_Store_Filesystem *)store;
567    eina_stringshare_del(st->dir);
568 }
569
570 static void
571 _elm_store_filesystem_item_free(Elm_Store_Item *item)
572 {
573    Elm_Store_Item_Filesystem *sti = (Elm_Store_Item_Filesystem *)item;
574    eina_stringshare_del(sti->path);
575 }
576
577 EAPI Elm_Store *
578 elm_store_filesystem_new(void)
579 {
580    Elm_Store_Filesystem *st = elm_store_new(Elm_Store_Filesystem);
581    EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
582
583    EINA_MAGIC_SET(st, ELM_STORE_FILESYSTEM_MAGIC);
584    st->base.free = _elm_store_filesystem_free;
585    st->base.item.free = _elm_store_filesystem_item_free;
586
587    return &st->base;
588 }
589
590 EAPI void
591 elm_store_free(Elm_Store *st)
592 {
593    void (*item_free)(Elm_Store_Item *);
594    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
595    if (st->list_th)
596      {
597         ecore_thread_cancel(st->list_th);
598         st->list_th = NULL;
599      }
600
601    if (!st->type)
602      {
603         eina_list_free(st->realized);
604         item_free = st->item.free;
605         while (st->items)
606           {
607              Elm_Store_Item *sti = (Elm_Store_Item *)st->items;
608              if (sti->eval_job) ecore_job_del(sti->eval_job);
609              if (sti->fetch_th)
610                {
611                   ecore_thread_cancel(sti->fetch_th);
612                   sti->fetch_th = NULL;
613                }
614              if (item_free) item_free(sti);
615              if (sti->data)
616                {
617                   if (st->cb.unfetch.func)
618                     st->cb.unfetch.func(st->cb.unfetch.data, sti, NULL);
619                   sti->data = NULL;
620                }
621              LKD(sti->lock);
622              free(sti);
623           }
624         if (st->genlist)
625           {
626              evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _store_genlist_del, st);
627              evas_object_smart_callback_del(st->genlist, "realized", _store_genlist_item_realized);
628              evas_object_smart_callback_del(st->genlist, "unrealized", _store_genlist_item_unrealized);
629              elm_genlist_clear(st->genlist);
630              st->genlist = NULL;
631           }
632         if (st->free) st->free(st);
633      }
634    else
635      {
636         if (st->genlist)
637           {
638              evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _genlist_del, st);
639              evas_object_smart_callback_del(st->genlist, "realized", _item_realized);
640              evas_object_smart_callback_del(st->genlist, "unrealized", _item_unrealized);
641              elm_genlist_clear(st->genlist);
642              st->genlist = NULL;
643           }
644         while (st->always_fetched)
645           {
646              Elm_Store_Item *sti = eina_list_data_get(st->always_fetched);
647              Eina_List *find = NULL;
648              find = eina_list_data_find_list(st->always_fetched, sti);
649              if (find)
650                {
651                   st->always_fetched = eina_list_remove_list(st->always_fetched, find);
652                   _item_del(sti,NULL);
653                }
654           }
655         st->always_fetched = eina_list_free(st->always_fetched);
656         st->realized = eina_list_free(st->realized);
657         if (st->free) st->free(st);
658         st->live = EINA_FALSE;
659      }
660    free(st);
661 }
662
663 EAPI void
664 elm_store_target_genlist_set(Elm_Store *st, Evas_Object *obj)
665 {
666    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
667    if (st->genlist == obj) return;
668    if (st->genlist)
669      {
670         if (!st->type)
671           {
672              evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _store_genlist_del, st);
673              evas_object_smart_callback_del(st->genlist, "realized", _store_genlist_item_realized);
674              evas_object_smart_callback_del(st->genlist, "unrealized", _store_genlist_item_unrealized);
675           }
676         else
677           {
678              evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _genlist_del, st);
679              evas_object_smart_callback_del(st->genlist, "realized", _item_realized);
680              evas_object_smart_callback_del(st->genlist, "unrealized", _item_unrealized);
681           }
682         elm_genlist_clear(st->genlist);
683      }
684    st->genlist = obj;
685    if (!st->genlist) return;
686    if (!st->type)
687      {
688         evas_object_smart_callback_add(st->genlist, "realized", _store_genlist_item_realized, st);
689         evas_object_smart_callback_add(st->genlist, "unrealized", _store_genlist_item_unrealized, st);
690         evas_object_event_callback_add(st->genlist, EVAS_CALLBACK_DEL, _store_genlist_del, st);
691      }
692    else
693      {
694         evas_object_smart_callback_add(st->genlist, "realized", _item_realized, st);
695         evas_object_smart_callback_add(st->genlist, "unrealized", _item_unrealized, st);
696         evas_object_event_callback_add(st->genlist, EVAS_CALLBACK_DEL, _genlist_del, st);
697      }
698    elm_genlist_clear(st->genlist);
699 }
700
701 EAPI void
702 elm_store_filesystem_directory_set(Elm_Store *store, const char *dir)
703 {
704    Elm_Store_Filesystem *st = (Elm_Store_Filesystem *)store;
705    if (!EINA_MAGIC_CHECK(store, ELM_STORE_MAGIC)) return;
706    if (!EINA_MAGIC_CHECK(st, ELM_STORE_FILESYSTEM_MAGIC)) return;
707    if (store->list_th)
708      {
709         ecore_thread_cancel(store->list_th);
710         store->list_th = NULL;
711      }
712    if (!eina_stringshare_replace(&st->dir, dir)) return;
713    store->list_th = ecore_thread_feedback_run(_store_filesystem_list_do,
714                                               _store_filesystem_list_update,
715                                               _store_filesystem_list_end,
716                                               _store_filesystem_list_cancel,
717                                               st, EINA_TRUE);
718 }
719
720 EAPI const char *
721 elm_store_filesystem_directory_get(const Elm_Store *store)
722 {
723    const Elm_Store_Filesystem *st = (const Elm_Store_Filesystem *)store;
724    if (!EINA_MAGIC_CHECK(store, ELM_STORE_MAGIC)) return NULL;
725    if (!EINA_MAGIC_CHECK(st, ELM_STORE_FILESYSTEM_MAGIC)) return NULL;
726    return st->dir;
727 }
728
729 EAPI void
730 elm_store_cache_set(Elm_Store *st, int max)
731 {
732    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
733    if (max < 0) max = 0;
734    st->cache_max = max;
735    if(!st->type) _store_cache_trim(st);
736 }
737
738 EAPI int
739 elm_store_cache_get(const Elm_Store *st)
740 {
741    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return 0;
742    return st->cache_max;
743 }
744
745 EAPI void
746 elm_store_list_func_set(Elm_Store *st, Elm_Store_Item_List_Cb func, const void *data)
747 {
748    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
749    st->cb.list.func = func;
750    st->cb.list.data = (void *)data;
751 }
752
753 EAPI void
754 elm_store_fetch_func_set(Elm_Store *st, Elm_Store_Item_Fetch_Cb func, const void *data)
755 {
756    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
757    st->cb.fetch.func = func;
758    st->cb.fetch.data = (void *)data;
759 }
760
761 EAPI void
762 elm_store_fetch_thread_set(Elm_Store *st, Eina_Bool use_thread)
763 {
764    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
765    st->fetch_thread = !!use_thread;
766 }
767
768 EAPI Eina_Bool
769 elm_store_fetch_thread_get(const Elm_Store *st)
770 {
771    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return EINA_FALSE;
772    return st->fetch_thread;
773 }
774
775 EAPI void
776 elm_store_unfetch_func_set(Elm_Store *st, Elm_Store_Item_Unfetch_Cb func, const void *data)
777 {
778    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
779    st->cb.unfetch.func = func;
780    st->cb.unfetch.data = (void *)data;
781 }
782
783 EAPI void
784 elm_store_sorted_set(Elm_Store *st, Eina_Bool sorted)
785 {
786    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
787    st->sorted = sorted;
788 }
789
790 EAPI Eina_Bool
791 elm_store_sorted_get(const Elm_Store *st)
792 {
793    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return EINA_FALSE;
794    return st->sorted;
795 }
796
797 EAPI void
798 elm_store_item_data_set(Elm_Store_Item *sti, void *data)
799 {
800    if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
801    LKL(sti->lock);
802    sti->data = data;
803    LKU(sti->lock);
804 }
805
806 EAPI void *
807 elm_store_item_data_get(Elm_Store_Item *sti)
808 {
809    if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
810    void *d;
811    LKL(sti->lock);
812    d = sti->data;
813    LKU(sti->lock);
814    return d;
815 }
816
817 EAPI const Elm_Store *
818 elm_store_item_store_get(const Elm_Store_Item *sti)
819 {
820    if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
821    // dont need lock
822    return sti->store;
823 }
824
825 EAPI const Elm_Genlist_Item *
826 elm_store_item_genlist_item_get(const Elm_Store_Item *sti)
827 {
828    if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
829    // dont need lock
830    return sti->item;
831 }
832
833 EAPI const char *
834 elm_store_item_filesystem_path_get(const Elm_Store_Item *item)
835 {
836    Elm_Store_Item_Filesystem *sti = (Elm_Store_Item_Filesystem *)item;
837    Elm_Store_Filesystem *st;
838    if (!EINA_MAGIC_CHECK(item, ELM_STORE_ITEM_MAGIC)) return NULL;
839    if (!EINA_MAGIC_CHECK(item->store, ELM_STORE_MAGIC)) return NULL;
840    /* ensure we're dealing with filesystem item */
841    st = (Elm_Store_Filesystem *)item->store;
842    if (!EINA_MAGIC_CHECK(st, ELM_STORE_FILESYSTEM_MAGIC)) return NULL;
843    // dont need lock
844    return sti->path;
845 }
846
847 // TODO: BEGIN -DBsystem store
848
849 static const Elm_Store_Item_Mapping *
850 _item_mapping_find(Elm_Store_Item *sti, const char *part)
851 {
852    if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
853    const Elm_Store_Item_Mapping *m;
854
855    if (!sti->item_info) return NULL;
856
857    for (m = sti->item_info->mapping; m; m++)
858      {
859         if (m->type == ELM_STORE_ITEM_MAPPING_NONE) break;
860         if (!strcmp(part, m->part)) return m;
861      }
862    return NULL;
863 }
864
865 static char *
866 _item_label_get(void *data, Evas_Object *obj __UNUSED__, const char *part)
867 {
868    Elm_Store_Item *sti = data;
869    Elm_Store *st = sti->store;
870    if (st->live)
871      {
872         LKL(sti->lock);
873         if (sti->data)
874           {
875              const char *s = "";
876              const Elm_Store_Item_Mapping *m = _item_mapping_find(sti, part);
877              if (m)
878                {
879                   switch (m->type)
880                     {
881                      case ELM_STORE_ITEM_MAPPING_LABEL:
882                         LKU(sti->lock);
883                         s = *(char **)(((unsigned char *)sti->data) + m->offset);
884                         LKL(sti->lock);
885                         break;
886
887                      case ELM_STORE_ITEM_MAPPING_CUSTOM:
888                         if (m->details.custom.func)
889                           {
890                              LKU(sti->lock);
891                              s = m->details.custom.func(sti->data, sti, part);
892                              LKL(sti->lock);
893                           }
894                         break;
895
896                      default:
897                         break;
898                     }
899                   if (s)
900                     {
901                        LKU(sti->lock);
902                        return strdup(s);
903                     }
904                   else
905                     {
906                        LKU(sti->lock);
907                        return NULL;
908                     }
909                }
910           }
911         else
912           {
913              const char *s = "";
914              const Elm_Store_Item_Mapping *m = _item_mapping_find(sti, part);
915              if (m->type == ELM_STORE_ITEM_MAPPING_CUSTOM)
916                {
917                   if (m->details.custom.func)
918                     {
919                        LKU(sti->lock);
920                        s = m->details.custom.func(sti->item_info, sti, part);
921                        LKL(sti->lock);
922                     }
923
924                   if (s)
925                     {
926                        LKU(sti->lock);
927                        return strdup(s);
928                     }
929                   else
930                     {
931                        LKU(sti->lock);
932                        return NULL;
933                     }
934                }
935              LKU(sti->lock);
936              return NULL;
937              /*
938                 if (!strcmp(part, "elm.text.1"))
939                 {
940                 LKU(sti->lock);
941              //                            elm_genlist_item_display_only_set(sti->item, EINA_TRUE);
942              return strdup("Loading..");
943              }
944               */
945           }
946         LKU(sti->lock);
947      }
948    return NULL;
949 }
950
951 static Evas_Object *
952 _item_icon_get(void *data, Evas_Object *obj, const char *part)
953 {
954    Elm_Store_Item *sti = data;
955    Elm_Store *st = sti->store;
956
957    if (st->live && sti->item)
958      {
959         LKL(sti->lock);
960         if (sti->data)
961           {
962              const Elm_Store_Item_Mapping *m = _item_mapping_find(sti, part);
963              if (m)
964                {
965                   Evas_Object *ic = NULL;
966                   const char *s = NULL;
967
968                   switch (m->type)
969                     {
970                      case ELM_STORE_ITEM_MAPPING_ICON:
971                         ic = elm_icon_add(obj);
972                         s = *(char **)(((unsigned char *)sti->data) + m->offset);
973                         elm_icon_order_lookup_set(ic, m->details.icon.lookup_order);
974                         evas_object_size_hint_aspect_set(ic,
975                                                          EVAS_ASPECT_CONTROL_VERTICAL,
976                                                          m->details.icon.w,
977                                                          m->details.icon.h);
978                         elm_icon_smooth_set(ic, m->details.icon.smooth);
979                         elm_icon_no_scale_set(ic, m->details.icon.no_scale);
980                         elm_icon_scale_set(ic,
981                                            m->details.icon.scale_up,
982                                            m->details.icon.scale_down);
983
984                         if (s)
985                           {
986                              if (m->details.icon.standard_name)
987                                elm_icon_standard_set(ic, s);
988                              else
989                                elm_icon_file_set(ic, s, NULL);
990                           }
991                         break;
992
993                      case ELM_STORE_ITEM_MAPPING_PHOTO:
994                         ic = elm_icon_add(obj);
995                         s = *(char **)(((unsigned char *)sti->data) + m->offset);
996                         elm_photo_size_set(ic, m->details.photo.size);
997                         if (s)
998                           elm_photo_file_set(ic, s);
999                         break;
1000
1001                      case ELM_STORE_ITEM_MAPPING_CUSTOM:
1002                         if (m->details.custom.func)
1003                           ic = m->details.custom.func(sti->data, sti, part);
1004                         break;
1005
1006                      default:
1007                         break;
1008                     }
1009                   LKU(sti->lock);
1010                   return ic;
1011                }
1012           }
1013         LKU(sti->lock);
1014      }
1015    return NULL;
1016 }
1017
1018 static Elm_Store *
1019 _store_init(size_t size)
1020 {
1021    Elm_Store *st = calloc(1, size);
1022    EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
1023
1024    eina_magic_string_set(ELM_STORE_MAGIC, "Elm_Store");
1025    eina_magic_string_set(ELM_STORE_ITEM_MAGIC, "Elm_Store_Item");
1026    eina_magic_string_set(ELM_STORE_DBSYSTEM_MAGIC, "Elm_Store_DBsystem");
1027
1028    _store_item_class.item_style = "default";
1029    _store_item_class.func.label_get = (GenlistItemLabelGetFunc)_item_label_get;
1030    _store_item_class.func.icon_get = (GenlistItemIconGetFunc)_item_icon_get;
1031    _store_item_class.func.state_get = NULL;
1032    _store_item_class.func.del = NULL;
1033
1034    EINA_MAGIC_SET(st, ELM_STORE_MAGIC);
1035    st->cache_max = CACHE_COUNT;
1036    st->live = EINA_TRUE;
1037    st->fetch_thread = EINA_FALSE;
1038    st->type = 1;
1039    return st;
1040 }
1041
1042 #define _store_new(type) (type *)_store_init(sizeof(type))
1043
1044 static void
1045 _genlist_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1046 {
1047    Elm_Store *st = data;
1048    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1049
1050    st->genlist = NULL;
1051    if (st->list_th)
1052      {
1053         ecore_thread_cancel(st->list_th);
1054         st->list_th = NULL;
1055      }
1056    st->realized = eina_list_free(st->realized);
1057 }
1058
1059 static void
1060 _store_fetch_do(void *data, Ecore_Thread *th __UNUSED__)
1061 {
1062    Elm_Store_Item *sti = data;
1063
1064    LKL(sti->lock);
1065    if (sti->data)
1066      {
1067         LKU(sti->lock);
1068         return;
1069      }
1070    if (!sti->fetched)
1071      {
1072         if (sti->item_info != NULL)
1073           {
1074              LKU(sti->lock);
1075              if (sti->store->cb.fetch.func)
1076                sti->store->cb.fetch.func(sti->store->cb.fetch.data, sti, sti->item_info);
1077              LKL(sti->lock);
1078              sti->fetched = EINA_TRUE;
1079           }
1080      }
1081    LKU(sti->lock);
1082 }
1083
1084 static void
1085 _store_fetch_end(void *data, Ecore_Thread *th)
1086 {
1087    Elm_Store_Item *sti = data;
1088    LKL(sti->lock);
1089    if (sti->data) elm_genlist_item_update(sti->item);
1090    LKU(sti->lock);
1091    if (th == sti->fetch_th) sti->fetch_th = NULL;
1092 }
1093
1094 static void
1095 _store_fetch_cancel(void *data, Ecore_Thread *th)
1096 {
1097    Elm_Store_Item *sti = data;
1098    LKL(sti->lock);
1099    if (th == sti->fetch_th) sti->fetch_th = NULL;
1100    //   if(sti->data) elm_genlist_item_update(sti->item);
1101    LKU(sti->lock);
1102 }
1103
1104 static void
1105 _item_eval(void *data)
1106 {
1107    Elm_Store_Item *sti = data;
1108    if (!sti) return;
1109    Elm_Store *st = sti->store;
1110
1111    if (sti->fetched == EINA_FALSE)
1112      {
1113         if (st->fetch_thread && !sti->fetch_th)
1114           {
1115              sti->fetch_th = ecore_thread_run(_store_fetch_do, _store_fetch_end, _store_fetch_cancel, sti);
1116           }
1117         else if (!st->fetch_thread)
1118           {
1119              _store_fetch_do(sti,NULL);
1120              _store_fetch_end(sti,NULL);
1121           }
1122      }
1123    else
1124      {
1125         LKL(sti->lock);
1126         if (!sti->fetched)
1127           {
1128              LKU(sti->lock);
1129              if (sti->fetch_th)
1130                {
1131                   ecore_thread_cancel(sti->fetch_th);
1132                   sti->fetch_th = NULL;
1133                }
1134              LKL(sti->lock);
1135           }
1136         sti->fetched = EINA_FALSE;
1137         LKU(sti->lock);
1138         if (st->cb.unfetch.func)
1139           st->cb.unfetch.func(st->cb.unfetch.data, sti, sti->item_info);
1140         LKL(sti->lock);
1141         sti->data = NULL;
1142         LKU(sti->lock);
1143      }
1144 }
1145
1146 static void
1147 _item_realize(Elm_Store_Item *sti)
1148 {
1149    Elm_Store *st = sti->store;
1150    sti->eval_job = NULL;
1151    if (st->live)
1152      {
1153         Eina_List *find = NULL;
1154         find = eina_list_data_find_list(st->always_fetched, sti);
1155         if (find) return;
1156
1157         find = eina_list_data_find_list(st->realized,sti);
1158         if (find)
1159           {
1160              Elm_Store_Item *realized_sti = NULL;
1161              realized_sti = eina_list_data_get(find);
1162              st->realized = eina_list_remove_list(st->realized, find);
1163              _item_eval(realized_sti);
1164           }
1165         if (st->realized)
1166           {
1167              if ((int)eina_list_count(st->realized) == st->cache_max)
1168                {
1169                   Elm_Store_Item *realized_sti = NULL;
1170                   Eina_List *last = eina_list_last(st->realized);
1171                   realized_sti = eina_list_data_get(last);
1172                   st->realized = eina_list_remove_list(st->realized, last);
1173                   _item_eval(realized_sti);
1174                }
1175           }
1176         st->realized = eina_list_prepend(st->realized, sti);
1177         _item_eval(sti);
1178      }
1179 }
1180
1181 static void
1182 _item_job_add(Elm_Store_Item *sti)
1183 {
1184    if (sti->eval_job) ecore_job_del(sti->eval_job);
1185    sti->eval_job = ecore_job_add(_item_realize, sti);
1186 }
1187
1188 static void
1189 _item_fetch(Elm_Store_Item *sti)
1190 {
1191    Elm_Store *st = sti->store;
1192
1193    if (st->live)
1194      {
1195         LKL(sti->lock);
1196         if (!sti->fetched)
1197           {
1198              LKU(sti->lock);
1199              if (sti->fetch_th)
1200                {
1201                   ecore_thread_cancel(sti->fetch_th);
1202                   sti->fetch_th = NULL;
1203                }
1204              LKL(sti->lock);
1205           }
1206         if (sti->item_info != NULL)
1207           {
1208              LKU(sti->lock);
1209              if (sti->store->cb.fetch.func)
1210                sti->store->cb.fetch.func(sti->store->cb.fetch.data, sti, sti->item_info);
1211              LKL(sti->lock);
1212              sti->fetched = EINA_TRUE;
1213           }
1214         LKU(sti->lock);
1215      }
1216 }
1217
1218 static void
1219 _item_unfetch(Elm_Store_Item *sti)
1220 {
1221    EINA_SAFETY_ON_NULL_RETURN(sti);
1222    Elm_Store *st = sti->store;
1223
1224    if (st->live)
1225      {
1226         LKL(sti->lock);
1227         if (!sti->fetched)
1228           {
1229              LKU(sti->lock);
1230              if (sti->fetch_th)
1231                {
1232                   ecore_thread_cancel(sti->fetch_th);
1233                   sti->fetch_th = NULL;
1234                }
1235              LKL(sti->lock);
1236           }
1237         sti->fetched = EINA_FALSE;
1238         LKU(sti->lock);
1239         if (st->cb.unfetch.func)
1240           st->cb.unfetch.func(st->cb.unfetch.data, sti, sti->item_info);
1241         LKL(sti->lock);
1242         sti->data = NULL;
1243         LKU(sti->lock);
1244      }
1245 }
1246
1247 static void
1248 _item_realized(void *data , Evas_Object *obj __UNUSED__, void *event_info)
1249 {
1250    Elm_Store *st = data;
1251    if (!st) return;
1252    Elm_Genlist_Item *gli = event_info;
1253    Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
1254    if (!sti) return;
1255
1256    if (st->live)
1257      {
1258         if (!sti->data) _item_job_add(sti);
1259      }
1260    // TODO:
1261 }
1262
1263 static void
1264 _item_unrealized(void *data , Evas_Object *obj __UNUSED__, void *event_info)
1265 {
1266    Elm_Store *st = data;
1267    if (!st) return;
1268    Elm_Genlist_Item *gli = event_info;
1269    Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
1270    if (!sti) return;
1271
1272    if (st->live)
1273      {
1274         if (sti->eval_job)
1275           {
1276              ecore_job_del(sti->eval_job);
1277              sti->eval_job = NULL;
1278           }
1279      }
1280 }
1281
1282 static void
1283 _item_free(Elm_Store_Item *sti)
1284 {
1285    if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1286    Elm_Store *st = sti->store;
1287    LKL(sti->lock);
1288    if (st->live && st->cb.item_free.func && sti->item_info)
1289      {
1290         LKU(sti->lock);
1291         st->cb.item_free.func(st->cb.item_free.data, sti->item_info);
1292         LKL(sti->lock);
1293         sti->item_info = NULL;
1294      }
1295    LKU(sti->lock);
1296    LKD(sti->lock);
1297    free(sti);
1298 }
1299
1300 static void
1301 _item_del(void *data, Evas_Object *obj __UNUSED__)
1302 {
1303    Elm_Store_Item *sti = data;
1304    if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1305    Elm_Store *st = sti->store;
1306
1307    if (sti->eval_job)
1308      {
1309         ecore_job_del(sti->eval_job);
1310         sti->eval_job = NULL;
1311      }
1312
1313    Eina_List *find = NULL;
1314    find = eina_list_data_find_list(st->always_fetched, sti);
1315    if (find) return;
1316
1317    find = eina_list_data_find_list(st->realized,sti);
1318    if (find)
1319      {
1320         Elm_Store_Item *realized_sti = NULL;
1321         realized_sti = eina_list_data_get(find);
1322         st->realized = eina_list_remove_list(st->realized, find);
1323      }
1324    if (sti->data) _item_unfetch(sti);
1325    if (st->item.free) st->item.free(sti);
1326 }
1327
1328 static void
1329 _list_do(void *data, Ecore_Thread *th)
1330 {
1331    Elm_Store *st = data;
1332    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1333
1334    Elm_Store_Item_Info *item_info;
1335    Eina_Bool ok = EINA_FALSE;
1336    int loop;
1337    for (loop = 0; loop < st->item_count; loop++)
1338      {
1339         item_info = calloc(1, sizeof(Elm_Store_Item_Info));
1340         if (!item_info) return;
1341         item_info->index = loop;
1342
1343         if (st->cb.list.func) ok = st->cb.list.func(st->cb.list.data, item_info);
1344         if (ok) ecore_thread_feedback(th, item_info);
1345         else free(item_info);
1346         if (ecore_thread_check(th)) break;
1347      }
1348 }
1349
1350 static void
1351 _list_update(void *data, Ecore_Thread *th __UNUSED__, void *msg)
1352 {
1353    Elm_Store *st = data;
1354    Elm_Store_Item_Info *info = msg;
1355    elm_store_item_add(st, info);
1356 }
1357
1358 static void
1359 _list_end(void *data, Ecore_Thread *th)
1360 {
1361    Elm_Store *st = data;
1362    if (th == st->list_th) st->list_th = NULL;
1363 }
1364
1365 static void
1366 _list_cancel(void *data, Ecore_Thread *th)
1367 {
1368    Elm_Store *st = data;
1369    if (th == st->list_th) st->list_th = NULL;
1370 }
1371
1372 static void
1373 _group_item_append(Elm_Store_Item *sti, Elm_Genlist_Item_Class *itc)
1374 {
1375    if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1376    Elm_Store *st = sti->store;
1377    if (st->live)
1378      {
1379         if (st->always_fetched)
1380           {
1381              Eina_Bool group_existed = EINA_FALSE;
1382              const Eina_List *l = st->always_fetched;
1383              Elm_Store_Item *group_sti = eina_list_data_get(l);
1384              while (!group_existed && group_sti)
1385                {
1386                   if (group_sti->item_info->group_index == sti->item_info->group_index)
1387                     {
1388                        group_existed = EINA_TRUE;
1389                        break;
1390                     }
1391                   else
1392                     {
1393                        l = eina_list_next(l);
1394                        group_sti = eina_list_data_get(l);
1395                     }
1396                }
1397              if (group_existed) return; //Already existed the group item
1398           }
1399         st->always_fetched = eina_list_append(st->always_fetched, sti);
1400         sti->realized = EINA_FALSE;
1401         if (sti->data) _item_unfetch(sti);
1402         _item_fetch(sti);
1403
1404         if (sti->item_info->group_index == -1)
1405           {
1406              sti->item = elm_genlist_item_append(st->genlist,
1407                                                  itc,
1408                                                  sti,
1409                                                  NULL,
1410                                                  ELM_GENLIST_ITEM_NONE,
1411                                                  (Evas_Smart_Cb)sti->store->cb.item_select.func,
1412                                                  (void *)sti->store->cb.item_select.data);
1413              return;
1414           }
1415      }
1416 }
1417
1418 static void
1419 _normal_item_append(Elm_Store_Item *sti, Elm_Genlist_Item_Class *itc)
1420 {
1421    if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1422    Elm_Store *st = sti->store;
1423    if (st->live && sti->item_info)
1424      {
1425         Eina_Bool need_update = EINA_FALSE;
1426         Eina_Bool group_existed = EINA_FALSE;
1427         const Eina_List *l;
1428
1429         if (st->always_fetched)
1430           {
1431              if (sti->item_info->rec_item == EINA_TRUE)
1432                {
1433                   if (sti->item_info->group_index != sti->item_info->pre_group_index)
1434                     {
1435                        if (sti->item_info->group_index < sti->item_info->pre_group_index)
1436                          {
1437                             Eina_Bool pre_group_existed = EINA_FALSE;
1438                             l = st->always_fetched;
1439                             Elm_Store_Item *pre_group_sti = eina_list_data_get(l);
1440                             while (!pre_group_existed && pre_group_sti)
1441                               {
1442                                  if (pre_group_sti->item_info->pre_group_index == sti->item_info->pre_group_index)
1443                                    {
1444                                       pre_group_existed = EINA_TRUE;
1445                                       break;
1446                                    }
1447                                  else
1448                                    {
1449                                       l = eina_list_next(l);
1450                                       pre_group_sti = eina_list_data_get(l);
1451                                    }
1452                               }
1453                             if (pre_group_sti && pre_group_sti->realized) // already added the header item to the genlist
1454                               {
1455                                  Eina_Bool deleted = EINA_FALSE;
1456                                  Eina_Bool last_item = EINA_FALSE;
1457                                  Elm_Genlist_Item *comp_item = pre_group_sti->first_item;
1458                                  while (!deleted && comp_item)
1459                                    {
1460                                       Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
1461                                       if (comp_sti)
1462                                         {
1463                                            int sort = st->cb.item_sort.func(st->cb.item_sort.data, sti->item_info, comp_sti->item_info);
1464                                            if(sort == ELM_STORE_ITEM_SORT_SAME)
1465                                              {
1466                                                 elm_store_item_del(comp_sti);
1467                                                 deleted = EINA_TRUE;
1468                                                 break;
1469                                              }
1470                                         }
1471                                       if (last_item) break;
1472                                       else comp_item = elm_genlist_item_next_get(comp_item);
1473
1474                                       if (comp_item == pre_group_sti->last_item) last_item = EINA_TRUE;
1475                                    }
1476                                  if (!deleted) printf(" The item does not existed in the pre group of genlist \n");
1477                               }
1478                             else //Pre group item does not existed in the always fetched list or the genlist
1479                               {
1480                                  Eina_Bool deleted = EINA_FALSE;
1481                                  Elm_Genlist_Item *comp_item = elm_genlist_first_item_get(st->genlist);
1482                                  while (!deleted && comp_item)
1483                                    {
1484                                       Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
1485                                       if (comp_sti && sti->item_info->item_type == comp_sti->item_info->item_type)
1486                                         {
1487                                            int sort = st->cb.item_sort.func(st->cb.item_sort.data, sti->item_info, comp_sti->item_info);
1488                                            if (sort == ELM_STORE_ITEM_SORT_SAME)
1489                                              {
1490                                                 elm_store_item_del(comp_sti);
1491                                                 deleted = EINA_TRUE;
1492                                                 break;
1493                                              }
1494                                         }
1495                                       comp_item = elm_genlist_item_next_get(comp_item);
1496                                    }
1497                                  if (!deleted) printf(" The item does not existed in the genlist \n");
1498                               }
1499                          }
1500                        else
1501                          {
1502                             sti->item_info->group_index = sti->item_info->pre_group_index;
1503                             need_update = EINA_TRUE;
1504                          }
1505                     }
1506                   else  need_update = EINA_TRUE;
1507                }
1508              l = st->always_fetched;
1509              Elm_Store_Item *group_sti = eina_list_data_get(l);
1510              while (!group_existed && group_sti) // Search the group item of a normal item in the always_fetched list
1511                {
1512                   if (group_sti->item_info->group_index == sti->item_info->group_index)
1513                     {
1514                        group_existed = EINA_TRUE;
1515                        break;
1516                     }
1517                   else
1518                     {
1519                        l = eina_list_next(l);
1520                        group_sti = eina_list_data_get(l);
1521                     }
1522                }
1523              if (group_sti)
1524                {
1525                   if (group_sti->realized) // already added the header item to the genlist
1526                     {
1527                        Eina_Bool added = EINA_FALSE;
1528                        Elm_Genlist_Item *comp_item = group_sti->first_item;
1529                        while (!added && comp_item)
1530                          {
1531                             Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
1532                             if (comp_sti)
1533                               {
1534                                  int sort = st->cb.item_sort.func(st->cb.item_sort.data, sti->item_info, comp_sti->item_info);
1535                                  if (sort == ELM_STORE_ITEM_SORT_SAME)
1536                                    {
1537                                       if (need_update == EINA_TRUE) elm_store_item_update(comp_sti);
1538                                       else added = EINA_TRUE;
1539                                       break;
1540                                    }
1541                                  else if (sort == ELM_STORE_ITEM_SORT_LOW)
1542                                    {
1543                                       sti->item = elm_genlist_item_insert_before(st->genlist,
1544                                                                                  itc,
1545                                                                                  sti,
1546                                                                                  group_sti->item,
1547                                                                                  comp_item,
1548                                                                                  ELM_GENLIST_ITEM_NONE,
1549                                                                                  (Evas_Smart_Cb)sti->store->cb.item_select.func,
1550                                                                                  (void *)sti->store->cb.item_select.data);
1551
1552                                       if (comp_item == group_sti->first_item) group_sti->first_item = sti->item;
1553                                       added = EINA_TRUE;
1554                                       break;
1555                                    }
1556
1557                                  if (comp_item == group_sti->last_item) //To add the item in to the last of its group
1558                                    {
1559                                       need_update = EINA_FALSE;
1560                                       break;
1561                                    }
1562                               }
1563                             comp_item = elm_genlist_item_next_get(comp_item);
1564                          }
1565                        if (!added && !need_update)
1566                          {
1567                             Elm_Genlist_Item *last_item = group_sti->last_item;
1568                             if (last_item)
1569                               {
1570                                  sti->item = elm_genlist_item_insert_after(st->genlist,
1571                                                                            itc,
1572                                                                            sti,
1573                                                                            group_sti->item,
1574                                                                            last_item,
1575                                                                            ELM_GENLIST_ITEM_NONE,
1576                                                                            (Evas_Smart_Cb)sti->store->cb.item_select.func,
1577                                                                            (void *)sti->store->cb.item_select.data);
1578                                  group_sti->last_item = sti->item;
1579                               }
1580                             else printf(" Group item have no last item. so can not add a item to the genlist \n");
1581                          }
1582                     }
1583                   else // To add the header item in genlist, and compare with other header items along with callback func
1584                     {
1585                        Eina_Bool added = EINA_FALSE;
1586                        l = st->always_fetched;
1587                        Elm_Store_Item *comp_group_sti = eina_list_data_get(l);
1588                        while (!added && comp_group_sti)
1589                          {
1590                             if (comp_group_sti != group_sti && comp_group_sti->realized)
1591                               {
1592                                  // Compare with group items
1593                                  int sort = st->cb.item_sort.func(st->cb.item_sort.data, group_sti->item_info, comp_group_sti->item_info);
1594                                  if(sort == ELM_STORE_ITEM_SORT_LOW)
1595                                    {
1596                                       group_sti->item = elm_genlist_item_insert_before(st->genlist,
1597                                                                                        group_sti->item_info->item_class,
1598                                                                                        group_sti,
1599                                                                                        NULL,
1600                                                                                        comp_group_sti->item,
1601                                                                                        ELM_GENLIST_ITEM_GROUP,
1602                                                                                        NULL, NULL);
1603
1604                                       group_sti->realized = EINA_TRUE;
1605                                       sti->item = elm_genlist_item_insert_after(st->genlist,
1606                                                                                 itc,
1607                                                                                 sti,
1608                                                                                 group_sti->item,
1609                                                                                 group_sti->item,
1610                                                                                 ELM_GENLIST_ITEM_NONE,
1611                                                                                 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1612                                                                                 (void *)sti->store->cb.item_select.data);
1613
1614                                       group_sti->first_item = sti->item;
1615                                       group_sti->last_item = sti->item;
1616                                       added = EINA_TRUE;
1617                                       break;
1618                                    }
1619                               }
1620                             l = eina_list_next(l);
1621                             comp_group_sti = eina_list_data_get(l);
1622                          }
1623                        if (!comp_group_sti) // First item append in the genlist
1624                          {
1625                             group_sti->item = elm_genlist_item_append(st->genlist,
1626                                                                       group_sti->item_info->item_class,
1627                                                                       group_sti,
1628                                                                       NULL,
1629                                                                       ELM_GENLIST_ITEM_GROUP,
1630                                                                       NULL, NULL);
1631
1632                             group_sti->realized = EINA_TRUE;
1633                             sti->item = elm_genlist_item_append(st->genlist,
1634                                                                 itc,
1635                                                                 sti,
1636                                                                 group_sti->item,
1637                                                                 ELM_GENLIST_ITEM_NONE,
1638                                                                 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1639                                                                 (void *)sti->store->cb.item_select.data);
1640
1641                             group_sti->first_item = sti->item;
1642                             group_sti->last_item = sti->item;
1643                          }
1644                     }
1645                }
1646           }
1647         if (!group_existed) // No exist the group item of normal item, so it added without group.
1648           {
1649              Eina_Bool added = EINA_FALSE;
1650              Elm_Genlist_Item *comp_item = elm_genlist_first_item_get(st->genlist);
1651              while (!added && comp_item)
1652                {
1653                   Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
1654                   if (comp_sti)
1655                     {
1656                        if (sti->item_info->item_type == comp_sti->item_info->item_type)
1657                          {
1658                             int sort = st->cb.item_sort.func(st->cb.item_sort.data, sti->item_info, comp_sti->item_info);
1659                             if (sort == ELM_STORE_ITEM_SORT_SAME)
1660                               {
1661                                  if (sti->item_info->rec_item == EINA_TRUE)
1662                                    {
1663                                       elm_store_item_update(comp_sti);
1664                                       need_update = EINA_TRUE;
1665                                    }
1666                                  else added = EINA_TRUE;
1667                                  break;
1668                               }
1669                             else if (sort == ELM_STORE_ITEM_SORT_LOW)
1670                               {
1671                                  sti->item = elm_genlist_item_insert_before(st->genlist,
1672                                                                             itc,
1673                                                                             sti,
1674                                                                             NULL,
1675                                                                             comp_item,
1676                                                                             ELM_GENLIST_ITEM_NONE,
1677                                                                             (Evas_Smart_Cb)sti->store->cb.item_select.func,
1678                                                                             (void *)sti->store->cb.item_select.data);
1679
1680                                  added = EINA_TRUE;
1681                                  break;
1682                               }
1683                          }
1684                     }
1685                   comp_item = elm_genlist_item_next_get(comp_item);
1686                   if (comp_item == NULL) need_update = EINA_FALSE;
1687                }
1688              if (!added && !need_update)
1689                {
1690                   sti->item = elm_genlist_item_append(st->genlist,
1691                                                       itc,
1692                                                       sti,
1693                                                       NULL,
1694                                                       ELM_GENLIST_ITEM_NONE,
1695                                                       (Evas_Smart_Cb)sti->store->cb.item_select.func,
1696                                                       (void *)sti->store->cb.item_select.data);
1697                }
1698           }
1699      }
1700 }
1701
1702 static void
1703 _store_free(Elm_Store *st)
1704 {
1705    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1706    Elm_Store_DBsystem *std = (Elm_Store_DBsystem *)st;
1707    if(std->p_db) eina_stringshare_del(std->p_db);
1708 }
1709
1710 /**
1711  * Add a new dbsystem Store object
1712  *
1713  * @return The new object or NULL if it cannot be created
1714  *
1715  * @ingroup Store
1716  */
1717 EAPI Elm_Store *
1718 elm_store_dbsystem_new(void)
1719 {
1720    Elm_Store_DBsystem *std = _store_new(Elm_Store_DBsystem);
1721    EINA_SAFETY_ON_NULL_RETURN_VAL(std, NULL);
1722
1723    EINA_MAGIC_SET(std, ELM_STORE_DBSYSTEM_MAGIC);
1724    std->base.free = _store_free;
1725    std->base.item.free = _item_free;
1726    return &std->base;
1727 }
1728
1729 /**
1730  * Sets the item count of a store
1731  *
1732  * @param st The store object
1733  * @param count The item count of an store
1734  *
1735  * @ingroup Store
1736  */
1737 EAPI void
1738 elm_store_item_count_set(Elm_Store *st, int count)
1739 {
1740    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1741    st->item_count = count;
1742 }
1743
1744
1745 /**
1746  * Set the select func that select the state of a list item whether true or false
1747  *
1748  * @param st The store object
1749  * @param func The select cb function of an store
1750  * @param data The new data pointer to set
1751  *
1752  * @ingroup Store
1753  */
1754 EAPI void
1755 elm_store_item_select_func_set(Elm_Store *st, Elm_Store_Item_Select_Cb func, const void *data)
1756 {
1757    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1758    st->cb.item_select.func = func;
1759    st->cb.item_select.data = (void *)data;
1760 }
1761
1762 /**
1763  * Sets the sort func that sort the item with a next in the list
1764  *
1765  * @param st The store object
1766  * @param func The sort cb function of an store
1767  * @param data The new data pointer to set
1768  *
1769  * @ingroup Store
1770  */
1771 EAPI void
1772 elm_store_item_sort_func_set(Elm_Store *st, Elm_Store_Item_Sort_Cb func, const void *data)
1773 {
1774    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1775    st->cb.item_sort.func = func;
1776    st->cb.item_sort.data = (void *)data;
1777 }
1778
1779 /**
1780  * Set the store item free func
1781  *
1782  * @param st The store object
1783  * @param func The free cb function of an store
1784  * @param data The new data pointer to set
1785  *
1786  * @ingroup Store
1787  */
1788 EAPI void
1789 elm_store_item_free_func_set(Elm_Store *st, Elm_Store_Item_Free_Cb func, const void *data)
1790 {
1791    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1792    st->cb.item_free.func = func;
1793    st->cb.item_free.data = (void *)data;
1794 }
1795
1796 /**
1797  * Get the item index that included header items
1798  *
1799  * @param sti The store item object
1800  * @return The item index in genlist
1801  *
1802  * @ingroup Store
1803  */
1804 EAPI int
1805 elm_store_item_index_get(const Elm_Store_Item *sti)
1806 {
1807    if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return -1;
1808    Elm_Store *st = sti->store;
1809
1810    if (st->live)
1811      {
1812         int index = 0;
1813         if (st->genlist)
1814           {
1815              Elm_Genlist_Item *gen_item = elm_genlist_first_item_get(st->genlist);
1816              while (gen_item)
1817                {
1818                   Elm_Store_Item *item = elm_genlist_item_data_get(gen_item);
1819                   if (item == sti) return index;
1820                   gen_item = elm_genlist_item_next_get(gen_item);
1821                   index++;
1822                }
1823           }
1824         else return -1;
1825      }
1826    else return -1;
1827 }
1828
1829 /**
1830  * Get the item index of real data that don't included header items
1831  *
1832  * @param sti The store item object
1833  * @return The real item index
1834  *
1835  * @ingroup Store
1836  */
1837 EAPI int
1838 elm_store_item_data_index_get(const Elm_Store_Item *sti)
1839 {
1840    if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return -1;
1841    Elm_Store *st = sti->store;
1842
1843    if (st->live)
1844      {
1845         int index = 0;
1846         Elm_Genlist_Item *gen_item = elm_genlist_first_item_get(st->genlist);
1847         while (gen_item)
1848           {
1849              Elm_Store_Item *item = elm_genlist_item_data_get(gen_item);
1850              if (item && item->item_info->item_type != ELM_GENLIST_ITEM_GROUP)
1851                {
1852                   if(item == sti) return index;
1853                   index++;
1854                }
1855              gen_item = elm_genlist_item_next_get(gen_item);
1856           }
1857         return -1;
1858      }
1859    else return -1;
1860 }
1861
1862 /**
1863  * Get the DB pointer of an item
1864  *
1865  * @param sti The store item object
1866  * @return The DB pointer of item
1867  *
1868  * @ingroup Store
1869  */
1870 EAPI void *
1871 elm_store_dbsystem_db_get(const Elm_Store_Item *sti)
1872 {
1873    if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
1874
1875    const Elm_Store_DBsystem *std = (const Elm_Store_DBsystem *)sti->store;
1876    if (!EINA_MAGIC_CHECK(sti->store, ELM_STORE_MAGIC)) return NULL;
1877    if (!EINA_MAGIC_CHECK(std, ELM_STORE_DBSYSTEM_MAGIC)) return NULL;
1878    return std->p_db;
1879 }
1880
1881 /**
1882  * Set the DB pointer of an item
1883  *
1884  * @param sti The store item object
1885  * @parm p_db The DB pointer of item
1886  *
1887  * @ingroup Store
1888  */
1889 EAPI void
1890 elm_store_dbsystem_db_set(Elm_Store *store, void *p_db)
1891 {
1892    Elm_Store_DBsystem *std = (Elm_Store_DBsystem *)store;
1893    if (!EINA_MAGIC_CHECK(store, ELM_STORE_MAGIC)) return;
1894    if (!EINA_MAGIC_CHECK(std, ELM_STORE_DBSYSTEM_MAGIC)) return;
1895    if (store->list_th)
1896      {
1897         ecore_thread_cancel(store->list_th);
1898         store->list_th = NULL;
1899      }
1900    std->p_db = p_db;
1901    store->list_th = ecore_thread_feedback_run(_list_do,
1902                                               _list_update,
1903                                               _list_end,
1904                                               _list_cancel,
1905                                               store, EINA_TRUE);
1906 }
1907
1908 /**
1909  * Append the item to the genlist
1910  *
1911  * @param st The store object
1912  * @param info The store item info dbsystem object
1913  * @return The item of store
1914  *
1915  * @ingroup Store
1916  */
1917 EAPI Elm_Store_Item *
1918 elm_store_item_add(Elm_Store *st, Elm_Store_Item_Info *info)
1919 {
1920    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return NULL;
1921    EINA_SAFETY_ON_NULL_RETURN_VAL(info, NULL);
1922    Elm_Store_Item *sti;
1923    Elm_Genlist_Item_Class *itc;
1924
1925    sti = calloc(1, sizeof(Elm_Store_Item));
1926    if (!sti) return NULL;
1927    LKI(sti->lock);
1928    EINA_MAGIC_SET(sti, ELM_STORE_ITEM_MAGIC);
1929    sti->store = st;
1930    sti->item_info = info;
1931    sti->fetched = EINA_FALSE;
1932
1933    itc = info->item_class;
1934    if (!itc) itc = &_store_item_class;
1935    else
1936      {
1937         itc->func.label_get = (GenlistItemLabelGetFunc)_item_label_get;
1938         itc->func.icon_get = (GenlistItemIconGetFunc)_item_icon_get;
1939         itc->func.state_get = NULL;
1940         itc->func.del = (GenlistItemDelFunc)_item_del;
1941      }
1942
1943    if (st->live)
1944      {
1945         if (sti->item_info->item_type == ELM_GENLIST_ITEM_GROUP) _group_item_append(sti, itc);
1946         else _normal_item_append(sti, itc);
1947         return sti;
1948      }
1949    else return NULL;
1950 }
1951
1952 /**
1953  * Realize the visible items to the screen
1954  *
1955  * @param st The store object
1956  *
1957  * @ingroup Store
1958  */
1959 EAPI void
1960 elm_store_visible_items_update(Elm_Store *st)
1961 {
1962    if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1963
1964    Eina_List *realized_list = elm_genlist_realized_items_get(st->genlist);
1965    Elm_Genlist_Item *item = eina_list_data_get(realized_list);
1966    while (item)
1967      {
1968         Elm_Store_Item *realized_sti = elm_genlist_item_data_get(item);
1969         elm_store_item_update(realized_sti);
1970         realized_list = eina_list_next(realized_list);
1971         item = eina_list_data_get(realized_list);
1972      }
1973 }
1974
1975 /**
1976  * Realize the item to the screen
1977  *
1978  * @param sti The store item object
1979  *
1980  * @ingroup Store
1981  */
1982 EAPI void
1983 elm_store_item_update(Elm_Store_Item *sti)
1984 {
1985    Elm_Store *st = sti->store;
1986
1987    Eina_List *find = NULL;
1988    find = eina_list_data_find_list(st->always_fetched, sti);
1989    if (find)
1990      {
1991         if (sti->data) _item_unfetch(sti);
1992         _item_fetch(sti);
1993         if (sti->realized) elm_genlist_item_update(sti->item);
1994      }
1995    else
1996      {
1997         find = eina_list_data_find_list(st->realized,sti);
1998         if (find)       _item_realize(sti);
1999      }
2000 }
2001
2002 /**
2003  * Delete the item of genlist
2004  *
2005  * @param sti The store item object
2006  *
2007  * @ingroup Store
2008  */
2009 EAPI void
2010 elm_store_item_del(Elm_Store_Item *sti)
2011 {
2012    if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
2013    Elm_Store *st = sti->store;
2014
2015    if (st->live)
2016      {
2017         Eina_List *find = NULL;
2018         find = eina_list_data_find_list(st->always_fetched, sti);
2019         if (find) st->always_fetched = eina_list_remove_list(st->always_fetched, find);
2020
2021         Eina_Bool deleted = EINA_FALSE;
2022         Elm_Genlist_Item *comp_item = elm_genlist_first_item_get(st->genlist);
2023         while (!deleted && comp_item)
2024           {
2025              Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
2026              if (comp_sti && (sti == comp_sti))
2027                {
2028                   Elm_Genlist_Item *group_item = elm_genlist_item_parent_get(comp_item);
2029                   if (group_item)
2030                     {
2031                        Elm_Store_Item *group_sti = elm_genlist_item_data_get(group_item);
2032                        if (group_sti)
2033                          {
2034                             if ((group_sti->first_item == comp_item) && (group_sti->last_item == comp_item))
2035                               {
2036                                  group_sti->realized = EINA_FALSE;
2037                                  group_sti->first_item = NULL;
2038                                  group_sti->last_item = NULL;
2039                                  elm_genlist_item_del(group_item);
2040                               }
2041                             else if ((group_sti->first_item == comp_item) && (group_sti->last_item != comp_item))
2042                               {
2043                                  Elm_Genlist_Item *next_item = elm_genlist_item_next_get(comp_item);
2044                                  group_sti->first_item = next_item;
2045                               }
2046                             else if ((group_sti->first_item != comp_item) && (group_sti->last_item == comp_item))
2047                               {
2048                                  Elm_Genlist_Item *prev_item = elm_genlist_item_prev_get(comp_item);
2049                                  group_sti->last_item = prev_item;
2050                               }
2051                          }
2052                     }
2053                   elm_genlist_item_del(comp_sti->item);
2054                   deleted = EINA_TRUE;
2055                   break;
2056                }
2057              comp_item = elm_genlist_item_next_get(comp_item);
2058           }
2059
2060         if(!deleted) printf(" Not deleted because it does not existed in the genlist \n");
2061      }
2062 }
2063
2064 // TODO: END -DBsystem store
2065