1 #include <Elementary.h>
2 #include <Elementary_Cursor.h>
5 #ifndef EFL_HAVE_THREADS
6 # error "No thread support. Required."
9 #ifdef EFL_HAVE_POSIX_THREADS
11 # define LK(x) pthread_mutex_t x
12 # define LKI(x) pthread_mutex_init(&(x), NULL);
13 # define LKD(x) pthread_mutex_destroy(&(x));
14 # define LKL(x) pthread_mutex_lock(&(x));
15 # define LKU(x) pthread_mutex_unlock(&(x));
16 #else /* EFL_HAVE_WIN32_THREADS */
17 # define WIN32_LEAN_AND_MEAN
19 # undef WIN32_LEAN_AND_MEAN
20 # define LK(x) HANDLE x
21 # define LKI(x) x = CreateMutex(NULL, FALSE, NULL)
22 # define LKD(x) CloseHandle(x)
23 # define LKL(x) WaitForSingleObject(x, INFINITE)
24 # define LKU(x) ReleaseMutex(x)
27 #define ELM_STORE_MAGIC 0x3f89ea56
28 #define ELM_STORE_FILESYSTEM_MAGIC 0x3f89ea57
29 #define ELM_STORE_DBSYSTEM_MAGIC 0x3f89ea58
30 #define ELM_STORE_ITEM_MAGIC 0x5afe8c1d
31 #define CACHE_COUNT 1024
36 void (*free)(Elm_Store *store);
38 void (*free)(Elm_Store_Item *item);
41 Ecore_Thread *list_th;
48 Eina_List *always_fetched;
51 Elm_Store_Item_List_Cb func;
55 Elm_Store_Item_Fetch_Cb func;
59 Elm_Store_Item_Unfetch_Cb func;
63 Elm_Store_Item_Select_Cb func;
67 Elm_Store_Item_Sort_Cb func;
71 Elm_Store_Item_Free_Cb func;
76 Eina_Bool fetch_thread : 1;
80 struct _Elm_Store_Item
85 Elm_Genlist_Item *item;
86 Ecore_Thread *fetch_th;
88 const Elm_Store_Item_Mapping *mapping;
90 Elm_Store_Item_Info *item_info;
91 Elm_Genlist_Item *first_item;
92 Elm_Genlist_Item *last_item;
95 Eina_Bool was_live : 1;
96 Eina_Bool realized : 1;
97 Eina_Bool fetched : 1;
100 struct _Elm_Store_Filesystem
107 struct _Elm_Store_Item_Filesystem
113 struct _Elm_Store_DBsystem
122 ELM_STORE_ITEM_SORT_LOW = -1,
123 ELM_STORE_ITEM_SORT_SAME = 0,
124 ELM_STORE_ITEM_SORT_HIGH = 1,
125 ELM_STORE_ITEM_SORT_UNKNOWN = 2,
126 ELM_STORE_ITEM_SORT_LAST
127 } Elm_Store_Item_Sort_Type;
129 static Elm_Genlist_Item_Class _store_item_class;
131 static void _item_del(void *data, Evas_Object *obj __UNUSED__);
132 static void _item_realized(void *data, Evas_Object *obj __UNUSED__, void *event_info);
133 static void _item_unrealized(void *data, Evas_Object *obj __UNUSED__, void *event_info);
134 static void _genlist_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__);
137 _store_cache_trim(Elm_Store *st)
139 while ((st->realized ) &&
140 (((int)eina_list_count(st->realized) - st->realized_count)
143 Elm_Store_Item *sti = st->realized->data;
146 st->realized = eina_list_remove_list(st->realized, st->realized);
147 sti->realized = EINA_FALSE;
155 ecore_thread_cancel(sti->fetch_th);
156 sti->fetch_th = NULL;
160 sti->fetched = EINA_FALSE;
162 if (st->cb.unfetch.func)
163 st->cb.unfetch.func(st->cb.unfetch.data, sti, NULL);
171 _store_genlist_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
173 Elm_Store *st = data;
177 ecore_thread_cancel(st->list_th);
180 eina_list_free(st->realized);
183 Elm_Store_Item *sti = (Elm_Store_Item *)st->items;
184 if (sti->eval_job) ecore_job_del(sti->eval_job);
187 ecore_thread_cancel(sti->fetch_th);
188 sti->fetch_th = NULL;
190 if (sti->store->item.free) sti->store->item.free(sti);
193 if (st->cb.unfetch.func)
194 st->cb.unfetch.func(st->cb.unfetch.data, sti, NULL);
200 // FIXME: kill threads and more
203 ////// **** WARNING ***********************************************************
204 //// * This function runs inside a thread outside efl mainloop. Be careful! *
205 // ************************************************************************
206 /* TODO: refactor lock part into core? this does not depend on filesystm part */
208 _store_filesystem_fetch_do(void *data, Ecore_Thread *th __UNUSED__)
210 Elm_Store_Item *sti = data;
220 if (sti->store->cb.fetch.func)
221 sti->store->cb.fetch.func(sti->store->cb.fetch.data, sti, NULL);
223 sti->fetched = EINA_TRUE;
227 // ************************************************************************
228 //// * End of separate thread function. *
229 ////// ************************************************************************
230 /* TODO: refactor lock part into core? this does not depend on filesystm part */
232 _store_filesystem_fetch_end(void *data, Ecore_Thread *th)
234 Elm_Store_Item *sti = data;
236 if (sti->data) elm_genlist_item_update(sti->item);
238 if (th == sti->fetch_th) sti->fetch_th = NULL;
241 /* TODO: refactor lock part into core? this does not depend on filesystm part */
243 _store_filesystem_fetch_cancel(void *data, Ecore_Thread *th)
245 Elm_Store_Item *sti = data;
247 if (th == sti->fetch_th) sti->fetch_th = NULL;
248 if (sti->data) elm_genlist_item_update(sti->item);
253 _store_item_eval(void *data)
255 Elm_Store_Item *sti = data;
256 sti->eval_job = NULL;
257 if (sti->live == sti->was_live) return;
258 sti->was_live = sti->live;
261 _store_cache_trim(sti->store);
263 sti->store->realized = eina_list_remove(sti->store->realized, sti);
264 sti->store->realized = eina_list_append(sti->store->realized, sti);
265 sti->realized = EINA_TRUE;
266 if ((sti->store->fetch_thread) && (!sti->fetch_th))
267 sti->fetch_th = ecore_thread_run(_store_filesystem_fetch_do,
268 _store_filesystem_fetch_end,
269 _store_filesystem_fetch_cancel,
271 else if ((!sti->store->fetch_thread))
273 _store_filesystem_fetch_do(sti, NULL);
274 _store_filesystem_fetch_end(sti, NULL);
281 ecore_thread_cancel(sti->fetch_th);
282 sti->fetch_th = NULL;
284 _store_cache_trim(sti->store);
289 _store_genlist_item_realized(void *data, Evas_Object *obj __UNUSED__, void *event_info)
291 Elm_Store *st = data;
292 Elm_Genlist_Item *gli = event_info;
293 Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
295 st->realized_count++;
296 sti->live = EINA_TRUE;
297 if (sti->eval_job) ecore_job_del(sti->eval_job);
298 sti->eval_job = ecore_job_add(_store_item_eval, sti);
302 _store_genlist_item_unrealized(void *data, Evas_Object *obj __UNUSED__, void *event_info)
304 Elm_Store *st = data;
305 Elm_Genlist_Item *gli = event_info;
306 Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
308 st->realized_count--;
309 sti->live = EINA_FALSE;
310 if (sti->eval_job) ecore_job_del(sti->eval_job);
311 sti->eval_job = ecore_job_add(_store_item_eval, sti);
314 static const Elm_Store_Item_Mapping *
315 _store_item_mapping_find(Elm_Store_Item *sti, const char *part)
317 const Elm_Store_Item_Mapping *m;
319 for (m = sti->mapping; m; m ++)
321 if (m->type == ELM_STORE_ITEM_MAPPING_NONE) break;
322 if (!strcmp(part, m->part)) return m;
328 _store_item_label_get(void *data, Evas_Object *obj __UNUSED__, const char *part)
330 Elm_Store_Item *sti = data;
335 const Elm_Store_Item_Mapping *m = _store_item_mapping_find(sti, part);
340 case ELM_STORE_ITEM_MAPPING_LABEL:
341 s = *(char **)(((unsigned char *)sti->data) + m->offset);
343 case ELM_STORE_ITEM_MAPPING_CUSTOM:
344 if (m->details.custom.func)
345 s = m->details.custom.func(sti->data, sti, part);
357 _store_item_icon_get(void *data, Evas_Object *obj, const char *part)
359 Elm_Store_Item *sti = data;
363 const Elm_Store_Item_Mapping *m = _store_item_mapping_find(sti, part);
366 Evas_Object *ic = NULL;
367 const char *s = NULL;
371 case ELM_STORE_ITEM_MAPPING_ICON:
372 ic = elm_icon_add(obj);
373 s = *(char **)(((unsigned char *)sti->data) + m->offset);
374 elm_icon_order_lookup_set(ic, m->details.icon.lookup_order);
375 evas_object_size_hint_aspect_set(ic,
376 EVAS_ASPECT_CONTROL_VERTICAL,
379 elm_icon_smooth_set(ic, m->details.icon.smooth);
380 elm_icon_no_scale_set(ic, m->details.icon.no_scale);
381 elm_icon_scale_set(ic,
382 m->details.icon.scale_up,
383 m->details.icon.scale_down);
386 if (m->details.icon.standard_name)
387 elm_icon_standard_set(ic, s);
389 elm_icon_file_set(ic, s, NULL);
392 case ELM_STORE_ITEM_MAPPING_PHOTO:
393 ic = elm_icon_add(obj);
394 s = *(char **)(((unsigned char *)sti->data) + m->offset);
395 elm_photo_size_set(ic, m->details.photo.size);
397 elm_photo_file_set(ic, s);
399 case ELM_STORE_ITEM_MAPPING_CUSTOM:
400 if (m->details.custom.func)
401 ic = m->details.custom.func(sti->data, sti, part);
415 _store_item_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__)
419 ////// **** WARNING ***********************************************************
420 //// * This function runs inside a thread outside efl mainloop. Be careful! *
421 // ************************************************************************
423 _store_filesystem_sort_cb(void *d1, void *d2)
425 Elm_Store_Item_Info *info1 = d1, *info2 = d2;
426 if ((!info1->sort_id) || (!info2->sort_id)) return 0;
427 return strcoll(info1->sort_id, info2->sort_id);
431 _store_filesystem_list_do(void *data, Ecore_Thread *th __UNUSED__)
433 Elm_Store_Filesystem *st = data;
435 const Eina_File_Direct_Info *finf;
436 Eina_List *sorted = NULL;
437 Elm_Store_Item_Info_Filesystem *info;
439 // FIXME: need a way to abstract the open, list, feed items from list
440 // and maybe get initial sortable key vals etc.
441 it = eina_file_stat_ls(st->dir);
443 EINA_ITERATOR_FOREACH(it, finf)
446 size_t pathsz = finf->path_length + 1;
448 info = calloc(1, sizeof(Elm_Store_Item_Info_Filesystem) + pathsz);
450 info->path = ((char *)info) + sizeof(Elm_Store_Item_Info_Filesystem);
451 memcpy(info->path, finf->path, pathsz);
453 if (st->base.cb.list.func)
454 ok = st->base.cb.list.func(st->base.cb.list.data, &info->base);
457 if (!st->base.sorted) ecore_thread_feedback(th, info);
458 else sorted = eina_list_append(sorted, info);
462 if (info->base.sort_id) free(info->base.sort_id);
465 if (ecore_thread_check(th)) break;
467 eina_iterator_free(it);
470 sorted = eina_list_sort(sorted, 0,
471 EINA_COMPARE_CB(_store_filesystem_sort_cb));
472 EINA_LIST_FREE(sorted, info)
474 if (!ecore_thread_check(th)) ecore_thread_feedback(th, info);
478 // ************************************************************************
479 //// * End of separate thread function. *
480 ////// ************************************************************************
483 _store_filesystem_list_end(void *data, Ecore_Thread *th)
485 Elm_Store *st = data;
486 if (th == st->list_th) st->list_th = NULL;
490 _store_filesystem_list_cancel(void *data, Ecore_Thread *th)
492 Elm_Store *st = data;
493 if (th == st->list_th) st->list_th = NULL;
497 _store_filesystem_list_update(void *data, Ecore_Thread *th __UNUSED__, void *msg)
499 Elm_Store *st = data;
500 Elm_Store_Item_Filesystem *sti;
501 Elm_Genlist_Item_Class *itc;
502 Elm_Store_Item_Info_Filesystem *info = msg;
504 sti = calloc(1, sizeof(Elm_Store_Item_Filesystem));
507 EINA_MAGIC_SET(&(sti->base), ELM_STORE_ITEM_MAGIC);
508 sti->base.store = st;
509 sti->base.data = info->base.data;
510 sti->base.mapping = info->base.mapping;
511 sti->path = eina_stringshare_add(info->path);
513 itc = info->base.item_class;
514 if (!itc) itc = &_store_item_class;
517 itc->func.label_get = (GenlistItemLabelGetFunc)_store_item_label_get;
518 itc->func.icon_get = (GenlistItemIconGetFunc)_store_item_icon_get;
519 itc->func.state_get = NULL; // FIXME: support state gets later
520 itc->func.del = (GenlistItemDelFunc)_store_item_del;
523 // FIXME: handle being a parent (tree)
524 sti->base.item = elm_genlist_item_append(st->genlist, itc,
527 ELM_GENLIST_ITEM_NONE,
529 NULL/* func data */);
530 st->items = eina_inlist_append(st->items, (Eina_Inlist *)sti);
532 if (info->base.sort_id) free(info->base.sort_id);
538 _elm_store_new(size_t size)
540 Elm_Store *st = calloc(1, size);
541 EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
543 // TODO: BEGIN - move to elm_store_init()
544 eina_magic_string_set(ELM_STORE_MAGIC, "Elm_Store");
545 eina_magic_string_set(ELM_STORE_FILESYSTEM_MAGIC, "Elm_Store_Filesystem");
546 eina_magic_string_set(ELM_STORE_ITEM_MAGIC, "Elm_Store_Item");
547 // setup default item class (always the same) if list cb doesnt provide one
548 _store_item_class.item_style = "default";
549 _store_item_class.func.label_get = (GenlistItemLabelGetFunc)_store_item_label_get;
550 _store_item_class.func.icon_get = (GenlistItemIconGetFunc)_store_item_icon_get;
551 _store_item_class.func.state_get = NULL; // FIXME: support state gets later
552 _store_item_class.func.del = (GenlistItemDelFunc)_store_item_del;
553 // TODO: END - move to elm_store_init()
555 EINA_MAGIC_SET(st, ELM_STORE_MAGIC);
557 st->fetch_thread = EINA_TRUE;
561 #define elm_store_new(type) (type*)_elm_store_new(sizeof(type))
564 _elm_store_filesystem_free(Elm_Store *store)
566 Elm_Store_Filesystem *st = (Elm_Store_Filesystem *)store;
567 eina_stringshare_del(st->dir);
571 _elm_store_filesystem_item_free(Elm_Store_Item *item)
573 Elm_Store_Item_Filesystem *sti = (Elm_Store_Item_Filesystem *)item;
574 eina_stringshare_del(sti->path);
578 elm_store_filesystem_new(void)
580 Elm_Store_Filesystem *st = elm_store_new(Elm_Store_Filesystem);
581 EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
583 EINA_MAGIC_SET(st, ELM_STORE_FILESYSTEM_MAGIC);
584 st->base.free = _elm_store_filesystem_free;
585 st->base.item.free = _elm_store_filesystem_item_free;
591 elm_store_free(Elm_Store *st)
593 void (*item_free)(Elm_Store_Item *);
594 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
597 ecore_thread_cancel(st->list_th);
603 eina_list_free(st->realized);
604 item_free = st->item.free;
607 Elm_Store_Item *sti = (Elm_Store_Item *)st->items;
608 if (sti->eval_job) ecore_job_del(sti->eval_job);
611 ecore_thread_cancel(sti->fetch_th);
612 sti->fetch_th = NULL;
614 if (item_free) item_free(sti);
617 if (st->cb.unfetch.func)
618 st->cb.unfetch.func(st->cb.unfetch.data, sti, NULL);
626 evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _store_genlist_del, st);
627 evas_object_smart_callback_del(st->genlist, "realized", _store_genlist_item_realized);
628 evas_object_smart_callback_del(st->genlist, "unrealized", _store_genlist_item_unrealized);
629 elm_genlist_clear(st->genlist);
632 if (st->free) st->free(st);
638 evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _genlist_del, st);
639 evas_object_smart_callback_del(st->genlist, "realized", _item_realized);
640 evas_object_smart_callback_del(st->genlist, "unrealized", _item_unrealized);
641 elm_genlist_clear(st->genlist);
644 while (st->always_fetched)
646 Elm_Store_Item *sti = eina_list_data_get(st->always_fetched);
647 Eina_List *find = NULL;
648 find = eina_list_data_find_list(st->always_fetched, sti);
651 st->always_fetched = eina_list_remove_list(st->always_fetched, find);
655 st->always_fetched = eina_list_free(st->always_fetched);
656 st->realized = eina_list_free(st->realized);
657 if (st->free) st->free(st);
658 st->live = EINA_FALSE;
664 elm_store_target_genlist_set(Elm_Store *st, Evas_Object *obj)
666 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
667 if (st->genlist == obj) return;
672 evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _store_genlist_del, st);
673 evas_object_smart_callback_del(st->genlist, "realized", _store_genlist_item_realized);
674 evas_object_smart_callback_del(st->genlist, "unrealized", _store_genlist_item_unrealized);
678 evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _genlist_del, st);
679 evas_object_smart_callback_del(st->genlist, "realized", _item_realized);
680 evas_object_smart_callback_del(st->genlist, "unrealized", _item_unrealized);
682 elm_genlist_clear(st->genlist);
685 if (!st->genlist) return;
688 evas_object_smart_callback_add(st->genlist, "realized", _store_genlist_item_realized, st);
689 evas_object_smart_callback_add(st->genlist, "unrealized", _store_genlist_item_unrealized, st);
690 evas_object_event_callback_add(st->genlist, EVAS_CALLBACK_DEL, _store_genlist_del, st);
694 evas_object_smart_callback_add(st->genlist, "realized", _item_realized, st);
695 evas_object_smart_callback_add(st->genlist, "unrealized", _item_unrealized, st);
696 evas_object_event_callback_add(st->genlist, EVAS_CALLBACK_DEL, _genlist_del, st);
698 elm_genlist_clear(st->genlist);
702 elm_store_filesystem_directory_set(Elm_Store *store, const char *dir)
704 Elm_Store_Filesystem *st = (Elm_Store_Filesystem *)store;
705 if (!EINA_MAGIC_CHECK(store, ELM_STORE_MAGIC)) return;
706 if (!EINA_MAGIC_CHECK(st, ELM_STORE_FILESYSTEM_MAGIC)) return;
709 ecore_thread_cancel(store->list_th);
710 store->list_th = NULL;
712 if (!eina_stringshare_replace(&st->dir, dir)) return;
713 store->list_th = ecore_thread_feedback_run(_store_filesystem_list_do,
714 _store_filesystem_list_update,
715 _store_filesystem_list_end,
716 _store_filesystem_list_cancel,
721 elm_store_filesystem_directory_get(const Elm_Store *store)
723 const Elm_Store_Filesystem *st = (const Elm_Store_Filesystem *)store;
724 if (!EINA_MAGIC_CHECK(store, ELM_STORE_MAGIC)) return NULL;
725 if (!EINA_MAGIC_CHECK(st, ELM_STORE_FILESYSTEM_MAGIC)) return NULL;
730 elm_store_cache_set(Elm_Store *st, int max)
732 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
733 if (max < 0) max = 0;
735 if(!st->type) _store_cache_trim(st);
739 elm_store_cache_get(const Elm_Store *st)
741 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return 0;
742 return st->cache_max;
746 elm_store_list_func_set(Elm_Store *st, Elm_Store_Item_List_Cb func, const void *data)
748 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
749 st->cb.list.func = func;
750 st->cb.list.data = (void *)data;
754 elm_store_fetch_func_set(Elm_Store *st, Elm_Store_Item_Fetch_Cb func, const void *data)
756 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
757 st->cb.fetch.func = func;
758 st->cb.fetch.data = (void *)data;
762 elm_store_fetch_thread_set(Elm_Store *st, Eina_Bool use_thread)
764 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
765 st->fetch_thread = !!use_thread;
769 elm_store_fetch_thread_get(const Elm_Store *st)
771 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return EINA_FALSE;
772 return st->fetch_thread;
776 elm_store_unfetch_func_set(Elm_Store *st, Elm_Store_Item_Unfetch_Cb func, const void *data)
778 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
779 st->cb.unfetch.func = func;
780 st->cb.unfetch.data = (void *)data;
784 elm_store_sorted_set(Elm_Store *st, Eina_Bool sorted)
786 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
791 elm_store_sorted_get(const Elm_Store *st)
793 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return EINA_FALSE;
798 elm_store_item_data_set(Elm_Store_Item *sti, void *data)
800 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
807 elm_store_item_data_get(Elm_Store_Item *sti)
809 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
817 EAPI const Elm_Store *
818 elm_store_item_store_get(const Elm_Store_Item *sti)
820 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
825 EAPI const Elm_Genlist_Item *
826 elm_store_item_genlist_item_get(const Elm_Store_Item *sti)
828 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
834 elm_store_item_filesystem_path_get(const Elm_Store_Item *item)
836 Elm_Store_Item_Filesystem *sti = (Elm_Store_Item_Filesystem *)item;
837 Elm_Store_Filesystem *st;
838 if (!EINA_MAGIC_CHECK(item, ELM_STORE_ITEM_MAGIC)) return NULL;
839 if (!EINA_MAGIC_CHECK(item->store, ELM_STORE_MAGIC)) return NULL;
840 /* ensure we're dealing with filesystem item */
841 st = (Elm_Store_Filesystem *)item->store;
842 if (!EINA_MAGIC_CHECK(st, ELM_STORE_FILESYSTEM_MAGIC)) return NULL;
847 // TODO: BEGIN -DBsystem store
849 static const Elm_Store_Item_Mapping *
850 _item_mapping_find(Elm_Store_Item *sti, const char *part)
852 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
853 const Elm_Store_Item_Mapping *m;
855 if (!sti->item_info) return NULL;
857 for (m = sti->item_info->mapping; m; m++)
859 if (m->type == ELM_STORE_ITEM_MAPPING_NONE) break;
860 if (!strcmp(part, m->part)) return m;
866 _item_label_get(void *data, Evas_Object *obj __UNUSED__, const char *part)
868 Elm_Store_Item *sti = data;
869 Elm_Store *st = sti->store;
876 const Elm_Store_Item_Mapping *m = _item_mapping_find(sti, part);
881 case ELM_STORE_ITEM_MAPPING_LABEL:
883 s = *(char **)(((unsigned char *)sti->data) + m->offset);
887 case ELM_STORE_ITEM_MAPPING_CUSTOM:
888 if (m->details.custom.func)
891 s = m->details.custom.func(sti->data, sti, part);
914 const Elm_Store_Item_Mapping *m = _item_mapping_find(sti, part);
915 if (m->type == ELM_STORE_ITEM_MAPPING_CUSTOM)
917 if (m->details.custom.func)
920 s = m->details.custom.func(sti->item_info, sti, part);
938 if (!strcmp(part, "elm.text.1"))
941 // elm_genlist_item_display_only_set(sti->item, EINA_TRUE);
942 return strdup("Loading..");
952 _item_icon_get(void *data, Evas_Object *obj, const char *part)
954 Elm_Store_Item *sti = data;
955 Elm_Store *st = sti->store;
957 if (st->live && sti->item)
962 const Elm_Store_Item_Mapping *m = _item_mapping_find(sti, part);
965 Evas_Object *ic = NULL;
966 const char *s = NULL;
970 case ELM_STORE_ITEM_MAPPING_ICON:
971 ic = elm_icon_add(obj);
972 s = *(char **)(((unsigned char *)sti->data) + m->offset);
973 elm_icon_order_lookup_set(ic, m->details.icon.lookup_order);
974 evas_object_size_hint_aspect_set(ic,
975 EVAS_ASPECT_CONTROL_VERTICAL,
978 elm_icon_smooth_set(ic, m->details.icon.smooth);
979 elm_icon_no_scale_set(ic, m->details.icon.no_scale);
980 elm_icon_scale_set(ic,
981 m->details.icon.scale_up,
982 m->details.icon.scale_down);
986 if (m->details.icon.standard_name)
987 elm_icon_standard_set(ic, s);
989 elm_icon_file_set(ic, s, NULL);
993 case ELM_STORE_ITEM_MAPPING_PHOTO:
994 ic = elm_icon_add(obj);
995 s = *(char **)(((unsigned char *)sti->data) + m->offset);
996 elm_photo_size_set(ic, m->details.photo.size);
998 elm_photo_file_set(ic, s);
1001 case ELM_STORE_ITEM_MAPPING_CUSTOM:
1002 if (m->details.custom.func)
1003 ic = m->details.custom.func(sti->data, sti, part);
1019 _store_init(size_t size)
1021 Elm_Store *st = calloc(1, size);
1022 EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
1024 eina_magic_string_set(ELM_STORE_MAGIC, "Elm_Store");
1025 eina_magic_string_set(ELM_STORE_ITEM_MAGIC, "Elm_Store_Item");
1026 eina_magic_string_set(ELM_STORE_DBSYSTEM_MAGIC, "Elm_Store_DBsystem");
1028 _store_item_class.item_style = "default";
1029 _store_item_class.func.label_get = (GenlistItemLabelGetFunc)_item_label_get;
1030 _store_item_class.func.icon_get = (GenlistItemIconGetFunc)_item_icon_get;
1031 _store_item_class.func.state_get = NULL;
1032 _store_item_class.func.del = NULL;
1034 EINA_MAGIC_SET(st, ELM_STORE_MAGIC);
1035 st->cache_max = CACHE_COUNT;
1036 st->live = EINA_TRUE;
1037 st->fetch_thread = EINA_FALSE;
1042 #define _store_new(type) (type *)_store_init(sizeof(type))
1045 _genlist_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1047 Elm_Store *st = data;
1048 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1053 ecore_thread_cancel(st->list_th);
1056 st->realized = eina_list_free(st->realized);
1060 _store_fetch_do(void *data, Ecore_Thread *th __UNUSED__)
1062 Elm_Store_Item *sti = data;
1072 if (sti->item_info != NULL)
1075 if (sti->store->cb.fetch.func)
1076 sti->store->cb.fetch.func(sti->store->cb.fetch.data, sti, sti->item_info);
1078 sti->fetched = EINA_TRUE;
1085 _store_fetch_end(void *data, Ecore_Thread *th)
1087 Elm_Store_Item *sti = data;
1089 if (sti->data) elm_genlist_item_update(sti->item);
1091 if (th == sti->fetch_th) sti->fetch_th = NULL;
1095 _store_fetch_cancel(void *data, Ecore_Thread *th)
1097 Elm_Store_Item *sti = data;
1099 if (th == sti->fetch_th) sti->fetch_th = NULL;
1100 // if(sti->data) elm_genlist_item_update(sti->item);
1105 _item_eval(void *data)
1107 Elm_Store_Item *sti = data;
1109 Elm_Store *st = sti->store;
1111 if (sti->fetched == EINA_FALSE)
1113 if (st->fetch_thread && !sti->fetch_th)
1115 sti->fetch_th = ecore_thread_run(_store_fetch_do, _store_fetch_end, _store_fetch_cancel, sti);
1117 else if (!st->fetch_thread)
1119 _store_fetch_do(sti,NULL);
1120 _store_fetch_end(sti,NULL);
1131 ecore_thread_cancel(sti->fetch_th);
1132 sti->fetch_th = NULL;
1136 sti->fetched = EINA_FALSE;
1138 if (st->cb.unfetch.func)
1139 st->cb.unfetch.func(st->cb.unfetch.data, sti, sti->item_info);
1147 _item_realize(void *data)
1149 Elm_Store_Item *sti = data;
1150 Elm_Store *st = sti->store;
1151 sti->eval_job = NULL;
1154 Eina_List *find = NULL;
1155 find = eina_list_data_find_list(st->always_fetched, sti);
1158 find = eina_list_data_find_list(st->realized,sti);
1161 Elm_Store_Item *realized_sti = NULL;
1162 realized_sti = eina_list_data_get(find);
1163 st->realized = eina_list_remove_list(st->realized, find);
1164 _item_eval(realized_sti);
1168 if ((int)eina_list_count(st->realized) == st->cache_max)
1170 Elm_Store_Item *realized_sti = NULL;
1171 Eina_List *last = eina_list_last(st->realized);
1172 realized_sti = eina_list_data_get(last);
1173 st->realized = eina_list_remove_list(st->realized, last);
1174 _item_eval(realized_sti);
1177 st->realized = eina_list_prepend(st->realized, sti);
1183 _item_job_add(Elm_Store_Item *sti)
1185 if (sti->eval_job) ecore_job_del(sti->eval_job);
1186 sti->eval_job = ecore_job_add(_item_realize, sti);
1190 _item_fetch(Elm_Store_Item *sti)
1192 Elm_Store *st = sti->store;
1202 ecore_thread_cancel(sti->fetch_th);
1203 sti->fetch_th = NULL;
1207 if (sti->item_info != NULL)
1210 if (sti->store->cb.fetch.func)
1211 sti->store->cb.fetch.func(sti->store->cb.fetch.data, sti, sti->item_info);
1213 sti->fetched = EINA_TRUE;
1220 _item_unfetch(Elm_Store_Item *sti)
1222 EINA_SAFETY_ON_NULL_RETURN(sti);
1223 Elm_Store *st = sti->store;
1233 ecore_thread_cancel(sti->fetch_th);
1234 sti->fetch_th = NULL;
1238 sti->fetched = EINA_FALSE;
1240 if (st->cb.unfetch.func)
1241 st->cb.unfetch.func(st->cb.unfetch.data, sti, sti->item_info);
1249 _item_realized(void *data , Evas_Object *obj __UNUSED__, void *event_info)
1251 Elm_Store *st = data;
1253 Elm_Genlist_Item *gli = event_info;
1254 Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
1259 if (!sti->data) _item_job_add(sti);
1265 _item_unrealized(void *data , Evas_Object *obj __UNUSED__, void *event_info)
1267 Elm_Store *st = data;
1269 Elm_Genlist_Item *gli = event_info;
1270 Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
1277 ecore_job_del(sti->eval_job);
1278 sti->eval_job = NULL;
1284 _item_free(Elm_Store_Item *sti)
1286 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1287 Elm_Store *st = sti->store;
1289 if (st->live && st->cb.item_free.func && sti->item_info)
1292 st->cb.item_free.func(st->cb.item_free.data, sti->item_info);
1294 sti->item_info = NULL;
1302 _item_del(void *data, Evas_Object *obj __UNUSED__)
1304 Elm_Store_Item *sti = data;
1305 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1306 Elm_Store *st = sti->store;
1310 ecore_job_del(sti->eval_job);
1311 sti->eval_job = NULL;
1314 Eina_List *find = NULL;
1315 find = eina_list_data_find_list(st->always_fetched, sti);
1318 find = eina_list_data_find_list(st->realized,sti);
1321 Elm_Store_Item *realized_sti = NULL;
1322 realized_sti = eina_list_data_get(find);
1323 st->realized = eina_list_remove_list(st->realized, find);
1325 if (sti->data) _item_unfetch(sti);
1326 if (st->item.free) st->item.free(sti);
1330 _list_do(void *data, Ecore_Thread *th)
1332 Elm_Store *st = data;
1333 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1335 Elm_Store_Item_Info *item_info;
1336 Eina_Bool ok = EINA_FALSE;
1338 for (loop = 0; loop < st->item_count; loop++)
1340 item_info = calloc(1, sizeof(Elm_Store_Item_Info));
1341 if (!item_info) return;
1342 item_info->index = loop;
1344 if (st->cb.list.func) ok = st->cb.list.func(st->cb.list.data, item_info);
1345 if (ok) ecore_thread_feedback(th, item_info);
1346 else free(item_info);
1347 if (ecore_thread_check(th)) break;
1352 _list_update(void *data, Ecore_Thread *th __UNUSED__, void *msg)
1354 Elm_Store *st = data;
1355 Elm_Store_Item_Info *info = msg;
1356 elm_store_item_add(st, info);
1360 _list_end(void *data, Ecore_Thread *th)
1362 Elm_Store *st = data;
1363 if (th == st->list_th) st->list_th = NULL;
1367 _list_cancel(void *data, Ecore_Thread *th)
1369 Elm_Store *st = data;
1370 if (th == st->list_th) st->list_th = NULL;
1374 _group_item_append(Elm_Store_Item *sti, Elm_Genlist_Item_Class *itc)
1376 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1377 Elm_Store *st = sti->store;
1380 if (st->always_fetched)
1382 Eina_Bool group_existed = EINA_FALSE;
1383 const Eina_List *l = st->always_fetched;
1384 Elm_Store_Item *group_sti = eina_list_data_get(l);
1385 while (!group_existed && group_sti)
1387 if (group_sti->item_info->group_index == sti->item_info->group_index)
1389 group_existed = EINA_TRUE;
1394 l = eina_list_next(l);
1395 group_sti = eina_list_data_get(l);
1398 if (group_existed) return; //Already existed the group item
1400 st->always_fetched = eina_list_append(st->always_fetched, sti);
1401 sti->realized = EINA_FALSE;
1402 if (sti->data) _item_unfetch(sti);
1405 if (sti->item_info->group_index == -1)
1407 sti->item = elm_genlist_item_append(st->genlist,
1411 ELM_GENLIST_ITEM_NONE,
1412 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1413 (void *)sti->store->cb.item_select.data);
1420 _normal_item_append(Elm_Store_Item *sti, Elm_Genlist_Item_Class *itc)
1422 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1423 Elm_Store *st = sti->store;
1424 if (st->live && sti->item_info)
1426 Eina_Bool need_update = EINA_FALSE;
1427 Eina_Bool group_existed = EINA_FALSE;
1430 if (st->always_fetched)
1432 if (sti->item_info->rec_item == EINA_TRUE)
1434 if (sti->item_info->group_index != sti->item_info->pre_group_index)
1436 if (sti->item_info->group_index < sti->item_info->pre_group_index)
1438 Eina_Bool pre_group_existed = EINA_FALSE;
1439 l = st->always_fetched;
1440 Elm_Store_Item *pre_group_sti = eina_list_data_get(l);
1441 while (!pre_group_existed && pre_group_sti)
1443 if (pre_group_sti->item_info->pre_group_index == sti->item_info->pre_group_index)
1445 pre_group_existed = EINA_TRUE;
1450 l = eina_list_next(l);
1451 pre_group_sti = eina_list_data_get(l);
1454 if (pre_group_sti && pre_group_sti->realized) // already added the header item to the genlist
1456 Eina_Bool deleted = EINA_FALSE;
1457 Eina_Bool last_item = EINA_FALSE;
1458 Elm_Genlist_Item *comp_item = pre_group_sti->first_item;
1459 while (!deleted && comp_item)
1461 Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
1464 int sort = st->cb.item_sort.func(st->cb.item_sort.data, sti->item_info, comp_sti->item_info);
1465 if(sort == ELM_STORE_ITEM_SORT_SAME)
1467 elm_store_item_del(comp_sti);
1468 deleted = EINA_TRUE;
1472 if (last_item) break;
1473 else comp_item = elm_genlist_item_next_get(comp_item);
1475 if (comp_item == pre_group_sti->last_item) last_item = EINA_TRUE;
1477 if (!deleted) printf(" The item does not existed in the pre group of genlist \n");
1479 else //Pre group item does not existed in the always fetched list or the genlist
1481 Eina_Bool deleted = EINA_FALSE;
1482 Elm_Genlist_Item *comp_item = elm_genlist_first_item_get(st->genlist);
1483 while (!deleted && comp_item)
1485 Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
1486 if (comp_sti && sti->item_info->item_type == comp_sti->item_info->item_type)
1488 int sort = st->cb.item_sort.func(st->cb.item_sort.data, sti->item_info, comp_sti->item_info);
1489 if (sort == ELM_STORE_ITEM_SORT_SAME)
1491 elm_store_item_del(comp_sti);
1492 deleted = EINA_TRUE;
1496 comp_item = elm_genlist_item_next_get(comp_item);
1498 if (!deleted) printf(" The item does not existed in the genlist \n");
1503 sti->item_info->group_index = sti->item_info->pre_group_index;
1504 need_update = EINA_TRUE;
1507 else need_update = EINA_TRUE;
1509 l = st->always_fetched;
1510 Elm_Store_Item *group_sti = eina_list_data_get(l);
1511 while (!group_existed && group_sti) // Search the group item of a normal item in the always_fetched list
1513 if (group_sti->item_info->group_index == sti->item_info->group_index)
1515 group_existed = EINA_TRUE;
1520 l = eina_list_next(l);
1521 group_sti = eina_list_data_get(l);
1526 if (group_sti->realized) // already added the header item to the genlist
1528 Eina_Bool added = EINA_FALSE;
1529 Elm_Genlist_Item *comp_item = group_sti->first_item;
1530 while (!added && comp_item)
1532 Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
1535 int sort = st->cb.item_sort.func(st->cb.item_sort.data, sti->item_info, comp_sti->item_info);
1536 if (sort == ELM_STORE_ITEM_SORT_SAME)
1538 if (need_update == EINA_TRUE) elm_store_item_update(comp_sti);
1539 else added = EINA_TRUE;
1542 else if (sort == ELM_STORE_ITEM_SORT_LOW)
1544 sti->item = elm_genlist_item_insert_before(st->genlist,
1549 ELM_GENLIST_ITEM_NONE,
1550 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1551 (void *)sti->store->cb.item_select.data);
1553 if (comp_item == group_sti->first_item) group_sti->first_item = sti->item;
1558 if (comp_item == group_sti->last_item) //To add the item in to the last of its group
1560 need_update = EINA_FALSE;
1564 comp_item = elm_genlist_item_next_get(comp_item);
1566 if (!added && !need_update)
1568 Elm_Genlist_Item *last_item = group_sti->last_item;
1571 sti->item = elm_genlist_item_insert_after(st->genlist,
1576 ELM_GENLIST_ITEM_NONE,
1577 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1578 (void *)sti->store->cb.item_select.data);
1579 group_sti->last_item = sti->item;
1581 else printf(" Group item have no last item. so can not add a item to the genlist \n");
1584 else // To add the header item in genlist, and compare with other header items along with callback func
1586 Eina_Bool added = EINA_FALSE;
1587 l = st->always_fetched;
1588 Elm_Store_Item *comp_group_sti = eina_list_data_get(l);
1589 while (!added && comp_group_sti)
1591 if (comp_group_sti != group_sti && comp_group_sti->realized)
1593 // Compare with group items
1594 int sort = st->cb.item_sort.func(st->cb.item_sort.data, group_sti->item_info, comp_group_sti->item_info);
1595 if(sort == ELM_STORE_ITEM_SORT_LOW)
1597 group_sti->item = elm_genlist_item_insert_before(st->genlist,
1598 group_sti->item_info->item_class,
1601 comp_group_sti->item,
1602 ELM_GENLIST_ITEM_GROUP,
1605 group_sti->realized = EINA_TRUE;
1606 sti->item = elm_genlist_item_insert_after(st->genlist,
1611 ELM_GENLIST_ITEM_NONE,
1612 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1613 (void *)sti->store->cb.item_select.data);
1615 group_sti->first_item = sti->item;
1616 group_sti->last_item = sti->item;
1621 l = eina_list_next(l);
1622 comp_group_sti = eina_list_data_get(l);
1624 if (!comp_group_sti) // First item append in the genlist
1626 group_sti->item = elm_genlist_item_append(st->genlist,
1627 group_sti->item_info->item_class,
1630 ELM_GENLIST_ITEM_GROUP,
1633 group_sti->realized = EINA_TRUE;
1634 sti->item = elm_genlist_item_append(st->genlist,
1638 ELM_GENLIST_ITEM_NONE,
1639 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1640 (void *)sti->store->cb.item_select.data);
1642 group_sti->first_item = sti->item;
1643 group_sti->last_item = sti->item;
1648 if (!group_existed) // No exist the group item of normal item, so it added without group.
1650 Eina_Bool added = EINA_FALSE;
1651 Elm_Genlist_Item *comp_item = elm_genlist_first_item_get(st->genlist);
1652 while (!added && comp_item)
1654 Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
1657 if (sti->item_info->item_type == comp_sti->item_info->item_type)
1659 int sort = st->cb.item_sort.func(st->cb.item_sort.data, sti->item_info, comp_sti->item_info);
1660 if (sort == ELM_STORE_ITEM_SORT_SAME)
1662 if (sti->item_info->rec_item == EINA_TRUE)
1664 elm_store_item_update(comp_sti);
1665 need_update = EINA_TRUE;
1667 else added = EINA_TRUE;
1670 else if (sort == ELM_STORE_ITEM_SORT_LOW)
1672 sti->item = elm_genlist_item_insert_before(st->genlist,
1677 ELM_GENLIST_ITEM_NONE,
1678 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1679 (void *)sti->store->cb.item_select.data);
1686 comp_item = elm_genlist_item_next_get(comp_item);
1687 if (comp_item == NULL) need_update = EINA_FALSE;
1689 if (!added && !need_update)
1691 sti->item = elm_genlist_item_append(st->genlist,
1695 ELM_GENLIST_ITEM_NONE,
1696 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1697 (void *)sti->store->cb.item_select.data);
1704 _store_free(Elm_Store *st)
1706 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1707 Elm_Store_DBsystem *std = (Elm_Store_DBsystem *)st;
1708 if(std->p_db) eina_stringshare_del(std->p_db);
1712 * Add a new dbsystem Store object
1714 * @return The new object or NULL if it cannot be created
1719 elm_store_dbsystem_new(void)
1721 Elm_Store_DBsystem *std = _store_new(Elm_Store_DBsystem);
1722 EINA_SAFETY_ON_NULL_RETURN_VAL(std, NULL);
1724 EINA_MAGIC_SET(std, ELM_STORE_DBSYSTEM_MAGIC);
1725 std->base.free = _store_free;
1726 std->base.item.free = _item_free;
1731 * Sets the item count of a store
1733 * @param st The store object
1734 * @param count The item count of an store
1739 elm_store_item_count_set(Elm_Store *st, int count)
1741 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1742 st->item_count = count;
1747 * Set the select func that select the state of a list item whether true or false
1749 * @param st The store object
1750 * @param func The select cb function of an store
1751 * @param data The new data pointer to set
1756 elm_store_item_select_func_set(Elm_Store *st, Elm_Store_Item_Select_Cb func, const void *data)
1758 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1759 st->cb.item_select.func = func;
1760 st->cb.item_select.data = (void *)data;
1764 * Sets the sort func that sort the item with a next in the list
1766 * @param st The store object
1767 * @param func The sort cb function of an store
1768 * @param data The new data pointer to set
1773 elm_store_item_sort_func_set(Elm_Store *st, Elm_Store_Item_Sort_Cb func, const void *data)
1775 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1776 st->cb.item_sort.func = func;
1777 st->cb.item_sort.data = (void *)data;
1781 * Set the store item free func
1783 * @param st The store object
1784 * @param func The free cb function of an store
1785 * @param data The new data pointer to set
1790 elm_store_item_free_func_set(Elm_Store *st, Elm_Store_Item_Free_Cb func, const void *data)
1792 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1793 st->cb.item_free.func = func;
1794 st->cb.item_free.data = (void *)data;
1798 * Get the item index that included header items
1800 * @param sti The store item object
1801 * @return The item index in genlist
1806 elm_store_item_index_get(const Elm_Store_Item *sti)
1808 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return -1;
1809 Elm_Store *st = sti->store;
1816 Elm_Genlist_Item *gen_item = elm_genlist_first_item_get(st->genlist);
1819 Elm_Store_Item *item = elm_genlist_item_data_get(gen_item);
1820 if (item == sti) return index;
1821 gen_item = elm_genlist_item_next_get(gen_item);
1830 * Get the item index of real data that don't included header items
1832 * @param sti The store item object
1833 * @return The real item index
1838 elm_store_item_data_index_get(const Elm_Store_Item *sti)
1840 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return -1;
1841 Elm_Store *st = sti->store;
1846 Elm_Genlist_Item *gen_item = elm_genlist_first_item_get(st->genlist);
1849 Elm_Store_Item *item = elm_genlist_item_data_get(gen_item);
1850 if (item && item->item_info->item_type != ELM_GENLIST_ITEM_GROUP)
1852 if(item == sti) return index;
1855 gen_item = elm_genlist_item_next_get(gen_item);
1862 * Get the DB pointer of an item
1864 * @param sti The store item object
1865 * @return The DB pointer of item
1870 elm_store_dbsystem_db_get(const Elm_Store_Item *sti)
1872 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
1874 const Elm_Store_DBsystem *std = (const Elm_Store_DBsystem *)sti->store;
1875 if (!EINA_MAGIC_CHECK(sti->store, ELM_STORE_MAGIC)) return NULL;
1876 if (!EINA_MAGIC_CHECK(std, ELM_STORE_DBSYSTEM_MAGIC)) return NULL;
1881 * Set the DB pointer of an item
1883 * @param sti The store item object
1884 * @parm p_db The DB pointer of item
1889 elm_store_dbsystem_db_set(Elm_Store *store, void *p_db)
1891 Elm_Store_DBsystem *std = (Elm_Store_DBsystem *)store;
1892 if (!EINA_MAGIC_CHECK(store, ELM_STORE_MAGIC)) return;
1893 if (!EINA_MAGIC_CHECK(std, ELM_STORE_DBSYSTEM_MAGIC)) return;
1896 ecore_thread_cancel(store->list_th);
1897 store->list_th = NULL;
1900 store->list_th = ecore_thread_feedback_run(_list_do,
1908 * Append the item to the genlist
1910 * @param st The store object
1911 * @param info The store item info dbsystem object
1912 * @return The item of store
1916 EAPI Elm_Store_Item *
1917 elm_store_item_add(Elm_Store *st, Elm_Store_Item_Info *info)
1919 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return NULL;
1920 EINA_SAFETY_ON_NULL_RETURN_VAL(info, NULL);
1921 Elm_Store_Item *sti;
1922 Elm_Genlist_Item_Class *itc;
1924 sti = calloc(1, sizeof(Elm_Store_Item));
1925 if (!sti) return NULL;
1927 EINA_MAGIC_SET(sti, ELM_STORE_ITEM_MAGIC);
1929 sti->item_info = info;
1930 sti->fetched = EINA_FALSE;
1932 itc = info->item_class;
1933 if (!itc) itc = &_store_item_class;
1936 itc->func.label_get = (GenlistItemLabelGetFunc)_item_label_get;
1937 itc->func.icon_get = (GenlistItemIconGetFunc)_item_icon_get;
1938 itc->func.state_get = NULL;
1939 itc->func.del = (GenlistItemDelFunc)_item_del;
1944 if (sti->item_info->item_type == ELM_GENLIST_ITEM_GROUP) _group_item_append(sti, itc);
1945 else _normal_item_append(sti, itc);
1956 * Realize the visible items to the screen
1958 * @param st The store object
1963 elm_store_visible_items_update(Elm_Store *st)
1965 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1967 Eina_List *realized_list = elm_genlist_realized_items_get(st->genlist);
1968 Elm_Genlist_Item *item = eina_list_data_get(realized_list);
1971 Elm_Store_Item *realized_sti = elm_genlist_item_data_get(item);
1972 elm_store_item_update(realized_sti);
1973 realized_list = eina_list_next(realized_list);
1974 item = eina_list_data_get(realized_list);
1979 * Realize the item to the screen
1981 * @param sti The store item object
1986 elm_store_item_update(Elm_Store_Item *sti)
1988 Elm_Store *st = sti->store;
1990 Eina_List *find = NULL;
1991 find = eina_list_data_find_list(st->always_fetched, sti);
1994 if (sti->data) _item_unfetch(sti);
1996 if (sti->realized) elm_genlist_item_update(sti->item);
2000 find = eina_list_data_find_list(st->realized,sti);
2001 if (find) _item_realize(sti);
2006 * Delete the item of genlist
2008 * @param sti The store item object
2013 elm_store_item_del(Elm_Store_Item *sti)
2015 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
2016 Elm_Store *st = sti->store;
2020 Eina_List *find = NULL;
2021 find = eina_list_data_find_list(st->always_fetched, sti);
2022 if (find) st->always_fetched = eina_list_remove_list(st->always_fetched, find);
2024 Eina_Bool deleted = EINA_FALSE;
2025 Elm_Genlist_Item *comp_item = elm_genlist_first_item_get(st->genlist);
2026 while (!deleted && comp_item)
2028 Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
2029 if (comp_sti && (sti == comp_sti))
2031 Elm_Genlist_Item *group_item = elm_genlist_item_parent_get(comp_item);
2034 Elm_Store_Item *group_sti = elm_genlist_item_data_get(group_item);
2037 if ((group_sti->first_item == comp_item) && (group_sti->last_item == comp_item))
2039 group_sti->realized = EINA_FALSE;
2040 group_sti->first_item = NULL;
2041 group_sti->last_item = NULL;
2042 elm_genlist_item_del(group_item);
2044 else if ((group_sti->first_item == comp_item) && (group_sti->last_item != comp_item))
2046 Elm_Genlist_Item *next_item = elm_genlist_item_next_get(comp_item);
2047 group_sti->first_item = next_item;
2049 else if ((group_sti->first_item != comp_item) && (group_sti->last_item == comp_item))
2051 Elm_Genlist_Item *prev_item = elm_genlist_item_prev_get(comp_item);
2052 group_sti->last_item = prev_item;
2056 elm_genlist_item_del(comp_sti->item);
2057 deleted = EINA_TRUE;
2060 comp_item = elm_genlist_item_next_get(comp_item);
2063 if(!deleted) printf(" Not deleted because it does not existed in the genlist \n");
2067 // TODO: END -DBsystem store