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