1 #include <Elementary.h>
2 #include <Elementary_Cursor.h>
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
14 void (*free)(Elm_Store *store);
16 void (*free)(Elm_Store_Item *item);
19 Ecore_Thread *list_th;
26 Eina_List *always_fetched;
29 Elm_Store_Item_List_Cb func;
33 Elm_Store_Item_Fetch_Cb func;
37 Elm_Store_Item_Unfetch_Cb func;
41 Elm_Store_Item_Select_Cb func;
45 Elm_Store_Item_Sort_Cb func;
49 Elm_Store_Item_Free_Cb func;
54 Eina_Bool fetch_thread : 1;
58 struct _Elm_Store_Item
63 Elm_Genlist_Item *item;
64 Ecore_Thread *fetch_th;
66 const Elm_Store_Item_Mapping *mapping;
68 Elm_Store_Item_Info *item_info;
69 Elm_Genlist_Item *first_item;
70 Elm_Genlist_Item *last_item;
73 Eina_Bool was_live : 1;
74 Eina_Bool realized : 1;
75 Eina_Bool fetched : 1;
78 struct _Elm_Store_Filesystem
85 struct _Elm_Store_Item_Filesystem
91 struct _Elm_Store_DBsystem
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;
107 static Elm_Genlist_Item_Class _store_item_class;
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__);
115 _store_cache_trim(Elm_Store *st)
117 while ((st->realized ) &&
118 (((int)eina_list_count(st->realized) - st->realized_count)
121 Elm_Store_Item *sti = st->realized->data;
124 st->realized = eina_list_remove_list(st->realized, st->realized);
125 sti->realized = EINA_FALSE;
127 eina_lock_take(sti->lock);
130 eina_lock_release(sti->lock);
133 ecore_thread_cancel(sti->fetch_th);
134 sti->fetch_th = NULL;
136 eina_lock_take(sti->lock);
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);
144 eina_lock_release(sti->lock);
149 _store_genlist_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
151 Elm_Store *st = data;
155 ecore_thread_cancel(st->list_th);
158 eina_list_free(st->realized);
161 Elm_Store_Item *sti = (Elm_Store_Item *)st->items;
162 if (sti->eval_job) ecore_job_del(sti->eval_job);
165 ecore_thread_cancel(sti->fetch_th);
166 sti->fetch_th = NULL;
168 if (sti->store->item.free) sti->store->item.free(sti);
171 if (st->cb.unfetch.func)
172 st->cb.unfetch.func(st->cb.unfetch.data, sti, NULL);
175 eina_lock_free(sti->lock);
178 // FIXME: kill threads and more
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 */
186 _store_filesystem_fetch_do(void *data, Ecore_Thread *th __UNUSED__)
188 Elm_Store_Item *sti = data;
189 eina_lock_take(sti->lock);
192 eina_lock_release(sti->lock);
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;
203 eina_lock_release(sti->lock);
205 // ************************************************************************
206 //// * End of separate thread function. *
207 ////// ************************************************************************
208 /* TODO: refactor lock part into core? this does not depend on filesystm part */
210 _store_filesystem_fetch_end(void *data, Ecore_Thread *th)
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;
219 /* TODO: refactor lock part into core? this does not depend on filesystm part */
221 _store_filesystem_fetch_cancel(void *data, Ecore_Thread *th)
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);
231 _store_item_eval(void *data)
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;
239 _store_cache_trim(sti->store);
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,
249 else if ((!sti->store->fetch_thread))
251 _store_filesystem_fetch_do(sti, NULL);
252 _store_filesystem_fetch_end(sti, NULL);
259 ecore_thread_cancel(sti->fetch_th);
260 sti->fetch_th = NULL;
262 _store_cache_trim(sti->store);
267 _store_genlist_item_realized(void *data, Evas_Object *obj __UNUSED__, void *event_info)
269 Elm_Store *st = data;
270 Elm_Genlist_Item *gli = event_info;
271 Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
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);
280 _store_genlist_item_unrealized(void *data, Evas_Object *obj __UNUSED__, void *event_info)
282 Elm_Store *st = data;
283 Elm_Genlist_Item *gli = event_info;
284 Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
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);
292 static const Elm_Store_Item_Mapping *
293 _store_item_mapping_find(Elm_Store_Item *sti, const char *part)
295 const Elm_Store_Item_Mapping *m;
297 for (m = sti->mapping; m; m ++)
299 if (m->type == ELM_STORE_ITEM_MAPPING_NONE) break;
300 if (!strcmp(part, m->part)) return m;
306 _store_item_label_get(void *data, Evas_Object *obj __UNUSED__, const char *part)
308 Elm_Store_Item *sti = data;
310 eina_lock_take(sti->lock);
313 const Elm_Store_Item_Mapping *m = _store_item_mapping_find(sti, part);
318 case ELM_STORE_ITEM_MAPPING_LABEL:
319 s = *(char **)(((unsigned char *)sti->data) + m->offset);
321 case ELM_STORE_ITEM_MAPPING_CUSTOM:
322 if (m->details.custom.func)
323 s = m->details.custom.func(sti->data, sti, part);
330 eina_lock_release(sti->lock);
331 return s ? strdup(s) : NULL;
335 _store_item_icon_get(void *data, Evas_Object *obj, const char *part)
337 Elm_Store_Item *sti = data;
338 eina_lock_take(sti->lock);
341 const Elm_Store_Item_Mapping *m = _store_item_mapping_find(sti, part);
344 Evas_Object *ic = NULL;
345 const char *s = NULL;
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,
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);
364 if (m->details.icon.standard_name)
365 elm_icon_standard_set(ic, s);
367 elm_icon_file_set(ic, s, NULL);
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);
375 elm_photo_file_set(ic, s);
377 case ELM_STORE_ITEM_MAPPING_CUSTOM:
378 if (m->details.custom.func)
379 ic = m->details.custom.func(sti->data, sti, part);
384 eina_lock_release(sti->lock);
388 eina_lock_release(sti->lock);
393 _store_item_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__)
397 ////// **** WARNING ***********************************************************
398 //// * This function runs inside a thread outside efl mainloop. Be careful! *
399 // ************************************************************************
401 _store_filesystem_sort_cb(void *d1, void *d2)
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);
409 _store_filesystem_list_do(void *data, Ecore_Thread *th __UNUSED__)
411 Elm_Store_Filesystem *st = data;
413 const Eina_File_Direct_Info *finf;
414 Eina_List *sorted = NULL;
415 Elm_Store_Item_Info_Filesystem *info;
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);
421 EINA_ITERATOR_FOREACH(it, finf)
424 size_t pathsz = finf->path_length + 1;
426 info = calloc(1, sizeof(Elm_Store_Item_Info_Filesystem) + pathsz);
428 info->path = ((char *)info) + sizeof(Elm_Store_Item_Info_Filesystem);
429 memcpy(info->path, finf->path, pathsz);
431 if (st->base.cb.list.func)
432 ok = st->base.cb.list.func(st->base.cb.list.data, &info->base);
435 if (!st->base.sorted) ecore_thread_feedback(th, info);
436 else sorted = eina_list_append(sorted, info);
440 if (info->base.sort_id) free(info->base.sort_id);
443 if (ecore_thread_check(th)) break;
445 eina_iterator_free(it);
448 sorted = eina_list_sort(sorted, 0,
449 EINA_COMPARE_CB(_store_filesystem_sort_cb));
450 EINA_LIST_FREE(sorted, info)
452 if (!ecore_thread_check(th)) ecore_thread_feedback(th, info);
456 // ************************************************************************
457 //// * End of separate thread function. *
458 ////// ************************************************************************
461 _store_filesystem_list_end(void *data, Ecore_Thread *th)
463 Elm_Store *st = data;
464 if (th == st->list_th) st->list_th = NULL;
468 _store_filesystem_list_cancel(void *data, Ecore_Thread *th)
470 Elm_Store *st = data;
471 if (th == st->list_th) st->list_th = NULL;
475 _store_filesystem_list_update(void *data, Ecore_Thread *th __UNUSED__, void *msg)
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;
482 sti = calloc(1, sizeof(Elm_Store_Item_Filesystem));
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);
491 itc = info->base.item_class;
492 if (!itc) itc = &_store_item_class;
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;
501 // FIXME: handle being a parent (tree)
502 sti->base.item = elm_genlist_item_append(st->genlist, itc,
505 ELM_GENLIST_ITEM_NONE,
507 NULL/* func data */);
508 st->items = eina_inlist_append(st->items, (Eina_Inlist *)sti);
510 if (info->base.sort_id) free(info->base.sort_id);
516 _elm_store_new(size_t size)
518 Elm_Store *st = calloc(1, size);
519 EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
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()
533 EINA_MAGIC_SET(st, ELM_STORE_MAGIC);
535 st->fetch_thread = EINA_TRUE;
539 #define elm_store_new(type) (type*)_elm_store_new(sizeof(type))
542 _elm_store_filesystem_free(Elm_Store *store)
544 Elm_Store_Filesystem *st = (Elm_Store_Filesystem *)store;
545 eina_stringshare_del(st->dir);
549 _elm_store_filesystem_item_free(Elm_Store_Item *item)
551 Elm_Store_Item_Filesystem *sti = (Elm_Store_Item_Filesystem *)item;
552 eina_stringshare_del(sti->path);
556 elm_store_filesystem_new(void)
558 Elm_Store_Filesystem *st = elm_store_new(Elm_Store_Filesystem);
559 EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
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;
569 elm_store_free(Elm_Store *st)
571 void (*item_free)(Elm_Store_Item *);
572 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
575 ecore_thread_cancel(st->list_th);
581 eina_list_free(st->realized);
582 item_free = st->item.free;
585 Elm_Store_Item *sti = (Elm_Store_Item *)st->items;
586 if (sti->eval_job) ecore_job_del(sti->eval_job);
589 ecore_thread_cancel(sti->fetch_th);
590 sti->fetch_th = NULL;
592 if (item_free) item_free(sti);
595 if (st->cb.unfetch.func)
596 st->cb.unfetch.func(st->cb.unfetch.data, sti, NULL);
599 eina_lock_take(sti->lock);
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);
610 if (st->free) st->free(st);
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);
622 while (st->always_fetched)
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);
629 st->always_fetched = eina_list_remove_list(st->always_fetched, find);
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;
642 elm_store_target_genlist_set(Elm_Store *st, Evas_Object *obj)
644 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
645 if (st->genlist == obj) return;
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);
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);
660 elm_genlist_clear(st->genlist);
663 if (!st->genlist) return;
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);
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);
676 elm_genlist_clear(st->genlist);
680 elm_store_filesystem_directory_set(Elm_Store *store, const char *dir)
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;
687 ecore_thread_cancel(store->list_th);
688 store->list_th = NULL;
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,
699 elm_store_filesystem_directory_get(const Elm_Store *store)
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;
708 elm_store_cache_set(Elm_Store *st, int max)
710 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
711 if (max < 0) max = 0;
713 if(!st->type) _store_cache_trim(st);
717 elm_store_cache_get(const Elm_Store *st)
719 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return 0;
720 return st->cache_max;
724 elm_store_list_func_set(Elm_Store *st, Elm_Store_Item_List_Cb func, const void *data)
726 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
727 st->cb.list.func = func;
728 st->cb.list.data = (void *)data;
732 elm_store_fetch_func_set(Elm_Store *st, Elm_Store_Item_Fetch_Cb func, const void *data)
734 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
735 st->cb.fetch.func = func;
736 st->cb.fetch.data = (void *)data;
740 elm_store_fetch_thread_set(Elm_Store *st, Eina_Bool use_thread)
742 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
743 st->fetch_thread = !!use_thread;
747 elm_store_fetch_thread_get(const Elm_Store *st)
749 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return EINA_FALSE;
750 return st->fetch_thread;
754 elm_store_unfetch_func_set(Elm_Store *st, Elm_Store_Item_Unfetch_Cb func, const void *data)
756 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
757 st->cb.unfetch.func = func;
758 st->cb.unfetch.data = (void *)data;
762 elm_store_sorted_set(Elm_Store *st, Eina_Bool sorted)
764 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
769 elm_store_sorted_get(const Elm_Store *st)
771 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return EINA_FALSE;
776 elm_store_item_data_set(Elm_Store_Item *sti, void *data)
778 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
779 eina_lock_take(sti->lock);
781 eina_lock_release(sti->lock);
785 elm_store_item_data_get(Elm_Store_Item *sti)
787 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
789 eina_lock_take(sti->lock);
791 eina_lock_release(sti->lock);
795 EAPI const Elm_Store *
796 elm_store_item_store_get(const Elm_Store_Item *sti)
798 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
803 EAPI const Elm_Genlist_Item *
804 elm_store_item_genlist_item_get(const Elm_Store_Item *sti)
806 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
812 elm_store_item_filesystem_path_get(const Elm_Store_Item *item)
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;
825 // TODO: BEGIN -DBsystem store
827 static const Elm_Store_Item_Mapping *
828 _item_mapping_find(Elm_Store_Item *sti, const char *part)
830 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
831 const Elm_Store_Item_Mapping *m;
833 if (!sti->item_info) return NULL;
835 for (m = sti->item_info->mapping; m; m++)
837 if (m->type == ELM_STORE_ITEM_MAPPING_NONE) break;
838 if (!strcmp(part, m->part)) return m;
844 _item_label_get(void *data, Evas_Object *obj __UNUSED__, const char *part)
846 Elm_Store_Item *sti = data;
847 Elm_Store *st = sti->store;
850 eina_lock_take(sti->lock);
854 const Elm_Store_Item_Mapping *m = _item_mapping_find(sti, part);
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);
865 case ELM_STORE_ITEM_MAPPING_CUSTOM:
866 if (m->details.custom.func)
868 eina_lock_release(sti->lock);
869 s = m->details.custom.func(sti->data, sti, part);
870 eina_lock_take(sti->lock);
879 eina_lock_release(sti->lock);
884 eina_lock_release(sti->lock);
892 const Elm_Store_Item_Mapping *m = _item_mapping_find(sti, part);
893 if (m->type == ELM_STORE_ITEM_MAPPING_CUSTOM)
895 if (m->details.custom.func)
897 eina_lock_release(sti->lock);
898 s = m->details.custom.func(sti->item_info, sti, part);
899 eina_lock_take(sti->lock);
904 eina_lock_release(sti->lock);
909 eina_lock_release(sti->lock);
913 eina_lock_release(sti->lock);
916 if (!strcmp(part, "elm.text.1"))
918 eina_lock_release(sti->lock);
919 // elm_genlist_item_display_only_set(sti->item, EINA_TRUE);
920 return strdup("Loading..");
924 eina_lock_release(sti->lock);
930 _item_icon_get(void *data, Evas_Object *obj, const char *part)
932 Elm_Store_Item *sti = data;
933 Elm_Store *st = sti->store;
935 if (st->live && sti->item)
937 eina_lock_take(sti->lock);
940 const Elm_Store_Item_Mapping *m = _item_mapping_find(sti, part);
943 Evas_Object *ic = NULL;
944 const char *s = NULL;
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,
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);
964 if (m->details.icon.standard_name)
965 elm_icon_standard_set(ic, s);
967 elm_icon_file_set(ic, s, NULL);
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);
976 elm_photo_file_set(ic, s);
979 case ELM_STORE_ITEM_MAPPING_CUSTOM:
980 if (m->details.custom.func)
981 ic = m->details.custom.func(sti->data, sti, part);
987 eina_lock_release(sti->lock);
991 eina_lock_release(sti->lock);
997 _store_init(size_t size)
999 Elm_Store *st = calloc(1, size);
1000 EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
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");
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;
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;
1020 #define _store_new(type) (type *)_store_init(sizeof(type))
1023 _genlist_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1025 Elm_Store *st = data;
1026 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1031 ecore_thread_cancel(st->list_th);
1034 st->realized = eina_list_free(st->realized);
1038 _store_fetch_do(void *data, Ecore_Thread *th __UNUSED__)
1040 Elm_Store_Item *sti = data;
1042 eina_lock_take(sti->lock);
1045 eina_lock_release(sti->lock);
1050 if (sti->item_info != NULL)
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;
1059 eina_lock_release(sti->lock);
1063 _store_fetch_end(void *data, Ecore_Thread *th)
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;
1073 _store_fetch_cancel(void *data, Ecore_Thread *th)
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);
1083 _item_eval(void *data)
1085 Elm_Store_Item *sti = data;
1087 Elm_Store *st = sti->store;
1089 if (sti->fetched == EINA_FALSE)
1091 if (st->fetch_thread && !sti->fetch_th)
1093 sti->fetch_th = ecore_thread_run(_store_fetch_do, _store_fetch_end, _store_fetch_cancel, sti);
1095 else if (!st->fetch_thread)
1097 _store_fetch_do(sti,NULL);
1098 _store_fetch_end(sti,NULL);
1103 eina_lock_take(sti->lock);
1106 eina_lock_release(sti->lock);
1109 ecore_thread_cancel(sti->fetch_th);
1110 sti->fetch_th = NULL;
1112 eina_lock_take(sti->lock);
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);
1120 eina_lock_release(sti->lock);
1125 _item_realize(void *data)
1127 Elm_Store_Item *sti = data;
1128 Elm_Store *st = sti->store;
1129 sti->eval_job = NULL;
1132 Eina_List *find = NULL;
1133 find = eina_list_data_find_list(st->always_fetched, sti);
1136 find = eina_list_data_find_list(st->realized,sti);
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);
1146 if ((int)eina_list_count(st->realized) == st->cache_max)
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);
1155 st->realized = eina_list_prepend(st->realized, sti);
1161 _item_job_add(Elm_Store_Item *sti)
1163 if (sti->eval_job) ecore_job_del(sti->eval_job);
1164 sti->eval_job = ecore_job_add(_item_realize, sti);
1168 _item_fetch(Elm_Store_Item *sti)
1170 Elm_Store *st = sti->store;
1174 eina_lock_take(sti->lock);
1177 eina_lock_release(sti->lock);
1180 ecore_thread_cancel(sti->fetch_th);
1181 sti->fetch_th = NULL;
1183 eina_lock_take(sti->lock);
1185 if (sti->item_info != NULL)
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;
1193 eina_lock_release(sti->lock);
1198 _item_unfetch(Elm_Store_Item *sti)
1200 EINA_SAFETY_ON_NULL_RETURN(sti);
1201 Elm_Store *st = sti->store;
1205 eina_lock_take(sti->lock);
1208 eina_lock_release(sti->lock);
1211 ecore_thread_cancel(sti->fetch_th);
1212 sti->fetch_th = NULL;
1214 eina_lock_take(sti->lock);
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);
1222 eina_lock_release(sti->lock);
1227 _item_realized(void *data , Evas_Object *obj __UNUSED__, void *event_info)
1229 Elm_Store *st = data;
1231 Elm_Genlist_Item *gli = event_info;
1232 Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
1237 if (!sti->data) _item_job_add(sti);
1243 _item_unrealized(void *data , Evas_Object *obj __UNUSED__, void *event_info)
1245 Elm_Store *st = data;
1247 Elm_Genlist_Item *gli = event_info;
1248 Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
1255 ecore_job_del(sti->eval_job);
1256 sti->eval_job = NULL;
1262 _item_free(Elm_Store_Item *sti)
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)
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;
1274 eina_lock_release(sti->lock);
1275 eina_lock_take(sti->lock);
1280 _item_del(void *data, Evas_Object *obj __UNUSED__)
1282 Elm_Store_Item *sti = data;
1283 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1284 Elm_Store *st = sti->store;
1288 ecore_job_del(sti->eval_job);
1289 sti->eval_job = NULL;
1292 Eina_List *find = NULL;
1293 find = eina_list_data_find_list(st->always_fetched, sti);
1296 find = eina_list_data_find_list(st->realized,sti);
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);
1303 if (sti->data) _item_unfetch(sti);
1304 if (st->item.free) st->item.free(sti);
1308 _list_do(void *data, Ecore_Thread *th)
1310 Elm_Store *st = data;
1311 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1313 Elm_Store_Item_Info *item_info;
1314 Eina_Bool ok = EINA_FALSE;
1316 for (loop = 0; loop < st->item_count; loop++)
1318 item_info = calloc(1, sizeof(Elm_Store_Item_Info));
1319 if (!item_info) return;
1320 item_info->index = loop;
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;
1330 _list_update(void *data, Ecore_Thread *th __UNUSED__, void *msg)
1332 Elm_Store *st = data;
1333 Elm_Store_Item_Info *info = msg;
1334 elm_store_item_add(st, info);
1338 _list_end(void *data, Ecore_Thread *th)
1340 Elm_Store *st = data;
1341 if (th == st->list_th) st->list_th = NULL;
1345 _list_cancel(void *data, Ecore_Thread *th)
1347 Elm_Store *st = data;
1348 if (th == st->list_th) st->list_th = NULL;
1352 _group_item_append(Elm_Store_Item *sti, Elm_Genlist_Item_Class *itc)
1354 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1355 Elm_Store *st = sti->store;
1358 if (st->always_fetched)
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)
1365 if (group_sti->item_info->group_index == sti->item_info->group_index)
1367 group_existed = EINA_TRUE;
1372 l = eina_list_next(l);
1373 group_sti = eina_list_data_get(l);
1376 if (group_existed) return; //Already existed the group item
1378 st->always_fetched = eina_list_append(st->always_fetched, sti);
1379 sti->realized = EINA_FALSE;
1380 if (sti->data) _item_unfetch(sti);
1383 if (sti->item_info->group_index == -1)
1385 sti->item = elm_genlist_item_append(st->genlist,
1389 ELM_GENLIST_ITEM_NONE,
1390 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1391 (void *)sti->store->cb.item_select.data);
1398 _normal_item_append(Elm_Store_Item *sti, Elm_Genlist_Item_Class *itc)
1400 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1401 Elm_Store *st = sti->store;
1402 if (st->live && sti->item_info)
1404 Eina_Bool need_update = EINA_FALSE;
1405 Eina_Bool group_existed = EINA_FALSE;
1408 if (st->always_fetched)
1410 if (sti->item_info->rec_item == EINA_TRUE)
1412 if (sti->item_info->group_index != sti->item_info->pre_group_index)
1414 if (sti->item_info->group_index < sti->item_info->pre_group_index)
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)
1421 if (pre_group_sti->item_info->pre_group_index == sti->item_info->pre_group_index)
1423 pre_group_existed = EINA_TRUE;
1428 l = eina_list_next(l);
1429 pre_group_sti = eina_list_data_get(l);
1432 if (pre_group_sti && pre_group_sti->realized) // already added the header item to the genlist
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)
1439 Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
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)
1445 elm_store_item_del(comp_sti);
1446 deleted = EINA_TRUE;
1450 if (last_item) break;
1451 else comp_item = elm_genlist_item_next_get(comp_item);
1453 if (comp_item == pre_group_sti->last_item) last_item = EINA_TRUE;
1455 if (!deleted) printf(" The item does not existed in the pre group of genlist \n");
1457 else //Pre group item does not existed in the always fetched list or the genlist
1459 Eina_Bool deleted = EINA_FALSE;
1460 Elm_Genlist_Item *comp_item = elm_genlist_first_item_get(st->genlist);
1461 while (!deleted && comp_item)
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)
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)
1469 elm_store_item_del(comp_sti);
1470 deleted = EINA_TRUE;
1474 comp_item = elm_genlist_item_next_get(comp_item);
1476 if (!deleted) printf(" The item does not existed in the genlist \n");
1481 sti->item_info->group_index = sti->item_info->pre_group_index;
1482 need_update = EINA_TRUE;
1485 else need_update = EINA_TRUE;
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
1491 if (group_sti->item_info->group_index == sti->item_info->group_index)
1493 group_existed = EINA_TRUE;
1498 l = eina_list_next(l);
1499 group_sti = eina_list_data_get(l);
1504 if (group_sti->realized) // already added the header item to the genlist
1506 Eina_Bool added = EINA_FALSE;
1507 Elm_Genlist_Item *comp_item = group_sti->first_item;
1508 while (!added && comp_item)
1510 Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
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)
1516 if (need_update == EINA_TRUE) elm_store_item_update(comp_sti);
1517 else added = EINA_TRUE;
1520 else if (sort == ELM_STORE_ITEM_SORT_LOW)
1522 sti->item = elm_genlist_item_insert_before(st->genlist,
1527 ELM_GENLIST_ITEM_NONE,
1528 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1529 (void *)sti->store->cb.item_select.data);
1531 if (comp_item == group_sti->first_item) group_sti->first_item = sti->item;
1536 if (comp_item == group_sti->last_item) //To add the item in to the last of its group
1538 need_update = EINA_FALSE;
1542 comp_item = elm_genlist_item_next_get(comp_item);
1544 if (!added && !need_update)
1546 Elm_Genlist_Item *last_item = group_sti->last_item;
1549 sti->item = elm_genlist_item_insert_after(st->genlist,
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;
1559 else printf(" Group item have no last item. so can not add a item to the genlist \n");
1562 else // To add the header item in genlist, and compare with other header items along with callback func
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)
1569 if (comp_group_sti != group_sti && comp_group_sti->realized)
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)
1575 group_sti->item = elm_genlist_item_insert_before(st->genlist,
1576 group_sti->item_info->item_class,
1579 comp_group_sti->item,
1580 ELM_GENLIST_ITEM_GROUP,
1583 group_sti->realized = EINA_TRUE;
1584 sti->item = elm_genlist_item_insert_after(st->genlist,
1589 ELM_GENLIST_ITEM_NONE,
1590 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1591 (void *)sti->store->cb.item_select.data);
1593 group_sti->first_item = sti->item;
1594 group_sti->last_item = sti->item;
1599 l = eina_list_next(l);
1600 comp_group_sti = eina_list_data_get(l);
1602 if (!comp_group_sti) // First item append in the genlist
1604 group_sti->item = elm_genlist_item_append(st->genlist,
1605 group_sti->item_info->item_class,
1608 ELM_GENLIST_ITEM_GROUP,
1611 group_sti->realized = EINA_TRUE;
1612 sti->item = elm_genlist_item_append(st->genlist,
1616 ELM_GENLIST_ITEM_NONE,
1617 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1618 (void *)sti->store->cb.item_select.data);
1620 group_sti->first_item = sti->item;
1621 group_sti->last_item = sti->item;
1626 if (!group_existed) // No exist the group item of normal item, so it added without group.
1628 Eina_Bool added = EINA_FALSE;
1629 Elm_Genlist_Item *comp_item = elm_genlist_first_item_get(st->genlist);
1630 while (!added && comp_item)
1632 Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
1635 if (sti->item_info->item_type == comp_sti->item_info->item_type)
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)
1640 if (sti->item_info->rec_item == EINA_TRUE)
1642 elm_store_item_update(comp_sti);
1643 need_update = EINA_TRUE;
1645 else added = EINA_TRUE;
1648 else if (sort == ELM_STORE_ITEM_SORT_LOW)
1650 sti->item = elm_genlist_item_insert_before(st->genlist,
1655 ELM_GENLIST_ITEM_NONE,
1656 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1657 (void *)sti->store->cb.item_select.data);
1664 comp_item = elm_genlist_item_next_get(comp_item);
1665 if (comp_item == NULL) need_update = EINA_FALSE;
1667 if (!added && !need_update)
1669 sti->item = elm_genlist_item_append(st->genlist,
1673 ELM_GENLIST_ITEM_NONE,
1674 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1675 (void *)sti->store->cb.item_select.data);
1682 _store_free(Elm_Store *st)
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);
1690 * Add a new dbsystem Store object
1692 * @return The new object or NULL if it cannot be created
1697 elm_store_dbsystem_new(void)
1699 Elm_Store_DBsystem *std = _store_new(Elm_Store_DBsystem);
1700 EINA_SAFETY_ON_NULL_RETURN_VAL(std, NULL);
1702 EINA_MAGIC_SET(std, ELM_STORE_DBSYSTEM_MAGIC);
1703 std->base.free = _store_free;
1704 std->base.item.free = _item_free;
1709 * Sets the item count of a store
1711 * @param st The store object
1712 * @param count The item count of an store
1717 elm_store_item_count_set(Elm_Store *st, int count)
1719 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1720 st->item_count = count;
1725 * Set the select func that select the state of a list item whether true or false
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
1734 elm_store_item_select_func_set(Elm_Store *st, Elm_Store_Item_Select_Cb func, const void *data)
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;
1742 * Sets the sort func that sort the item with a next in the list
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
1751 elm_store_item_sort_func_set(Elm_Store *st, Elm_Store_Item_Sort_Cb func, const void *data)
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;
1759 * Set the store item free func
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
1768 elm_store_item_free_func_set(Elm_Store *st, Elm_Store_Item_Free_Cb func, const void *data)
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;
1776 * Get the item index that included header items
1778 * @param sti The store item object
1779 * @return The item index in genlist
1784 elm_store_item_index_get(const Elm_Store_Item *sti)
1786 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return -1;
1787 Elm_Store *st = sti->store;
1794 Elm_Genlist_Item *gen_item = elm_genlist_first_item_get(st->genlist);
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);
1808 * Get the item index of real data that don't included header items
1810 * @param sti The store item object
1811 * @return The real item index
1816 elm_store_item_data_index_get(const Elm_Store_Item *sti)
1818 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return -1;
1819 Elm_Store *st = sti->store;
1824 Elm_Genlist_Item *gen_item = elm_genlist_first_item_get(st->genlist);
1827 Elm_Store_Item *item = elm_genlist_item_data_get(gen_item);
1828 if (item && item->item_info->item_type != ELM_GENLIST_ITEM_GROUP)
1830 if(item == sti) return index;
1833 gen_item = elm_genlist_item_next_get(gen_item);
1840 * Get the DB pointer of an item
1842 * @param sti The store item object
1843 * @return The DB pointer of item
1848 elm_store_dbsystem_db_get(const Elm_Store_Item *sti)
1850 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
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;
1859 * Set the DB pointer of an item
1861 * @param sti The store item object
1862 * @parm p_db The DB pointer of item
1867 elm_store_dbsystem_db_set(Elm_Store *store, void *p_db)
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;
1874 ecore_thread_cancel(store->list_th);
1875 store->list_th = NULL;
1878 store->list_th = ecore_thread_feedback_run(_list_do,
1886 * Append the item to the genlist
1888 * @param st The store object
1889 * @param info The store item info dbsystem object
1890 * @return The item of store
1894 EAPI Elm_Store_Item *
1895 elm_store_item_add(Elm_Store *st, Elm_Store_Item_Info *info)
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;
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);
1907 sti->item_info = info;
1908 sti->fetched = EINA_FALSE;
1910 itc = info->item_class;
1911 if (!itc) itc = &_store_item_class;
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;
1922 if (sti->item_info->item_type == ELM_GENLIST_ITEM_GROUP) _group_item_append(sti, itc);
1923 else _normal_item_append(sti, itc);
1934 * Realize the visible items to the screen
1936 * @param st The store object
1941 elm_store_visible_items_update(Elm_Store *st)
1943 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1945 Eina_List *realized_list = elm_genlist_realized_items_get(st->genlist);
1946 Elm_Genlist_Item *item = eina_list_data_get(realized_list);
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);
1957 * Realize the item to the screen
1959 * @param sti The store item object
1964 elm_store_item_update(Elm_Store_Item *sti)
1966 Elm_Store *st = sti->store;
1968 Eina_List *find = NULL;
1969 find = eina_list_data_find_list(st->always_fetched, sti);
1972 if (sti->data) _item_unfetch(sti);
1974 if (sti->realized) elm_genlist_item_update(sti->item);
1978 find = eina_list_data_find_list(st->realized,sti);
1979 if (find) _item_realize(sti);
1984 * Delete the item of genlist
1986 * @param sti The store item object
1991 elm_store_item_del(Elm_Store_Item *sti)
1993 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1994 Elm_Store *st = sti->store;
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);
2002 Eina_Bool deleted = EINA_FALSE;
2003 Elm_Genlist_Item *comp_item = elm_genlist_first_item_get(st->genlist);
2004 while (!deleted && comp_item)
2006 Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
2007 if (comp_sti && (sti == comp_sti))
2009 Elm_Genlist_Item *group_item = elm_genlist_item_parent_get(comp_item);
2012 Elm_Store_Item *group_sti = elm_genlist_item_data_get(group_item);
2015 if ((group_sti->first_item == comp_item) && (group_sti->last_item == comp_item))
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);
2022 else if ((group_sti->first_item == comp_item) && (group_sti->last_item != comp_item))
2024 Elm_Genlist_Item *next_item = elm_genlist_item_next_get(comp_item);
2025 group_sti->first_item = next_item;
2027 else if ((group_sti->first_item != comp_item) && (group_sti->last_item == comp_item))
2029 Elm_Genlist_Item *prev_item = elm_genlist_item_prev_get(comp_item);
2030 group_sti->last_item = prev_item;
2034 elm_genlist_item_del(comp_sti->item);
2035 deleted = EINA_TRUE;
2038 comp_item = elm_genlist_item_next_get(comp_item);
2041 if(!deleted) printf(" Not deleted because it does not existed in the genlist \n");
2045 // TODO: END -DBsystem store