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