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(Elm_Store_Item *sti)
1149 Elm_Store *st = sti->store;
1150 sti->eval_job = NULL;
1153 Eina_List *find = NULL;
1154 find = eina_list_data_find_list(st->always_fetched, sti);
1157 find = eina_list_data_find_list(st->realized,sti);
1160 Elm_Store_Item *realized_sti = NULL;
1161 realized_sti = eina_list_data_get(find);
1162 st->realized = eina_list_remove_list(st->realized, find);
1163 _item_eval(realized_sti);
1167 if ((int)eina_list_count(st->realized) == st->cache_max)
1169 Elm_Store_Item *realized_sti = NULL;
1170 Eina_List *last = eina_list_last(st->realized);
1171 realized_sti = eina_list_data_get(last);
1172 st->realized = eina_list_remove_list(st->realized, last);
1173 _item_eval(realized_sti);
1176 st->realized = eina_list_prepend(st->realized, sti);
1182 _item_job_add(Elm_Store_Item *sti)
1184 if (sti->eval_job) ecore_job_del(sti->eval_job);
1185 sti->eval_job = ecore_job_add(_item_realize, sti);
1189 _item_fetch(Elm_Store_Item *sti)
1191 Elm_Store *st = sti->store;
1201 ecore_thread_cancel(sti->fetch_th);
1202 sti->fetch_th = NULL;
1206 if (sti->item_info != NULL)
1209 if (sti->store->cb.fetch.func)
1210 sti->store->cb.fetch.func(sti->store->cb.fetch.data, sti, sti->item_info);
1212 sti->fetched = EINA_TRUE;
1219 _item_unfetch(Elm_Store_Item *sti)
1221 EINA_SAFETY_ON_NULL_RETURN(sti);
1222 Elm_Store *st = sti->store;
1232 ecore_thread_cancel(sti->fetch_th);
1233 sti->fetch_th = NULL;
1237 sti->fetched = EINA_FALSE;
1239 if (st->cb.unfetch.func)
1240 st->cb.unfetch.func(st->cb.unfetch.data, sti, sti->item_info);
1248 _item_realized(void *data , Evas_Object *obj __UNUSED__, void *event_info)
1250 Elm_Store *st = data;
1252 Elm_Genlist_Item *gli = event_info;
1253 Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
1258 if (!sti->data) _item_job_add(sti);
1264 _item_unrealized(void *data , Evas_Object *obj __UNUSED__, void *event_info)
1266 Elm_Store *st = data;
1268 Elm_Genlist_Item *gli = event_info;
1269 Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
1276 ecore_job_del(sti->eval_job);
1277 sti->eval_job = NULL;
1283 _item_free(Elm_Store_Item *sti)
1285 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1286 Elm_Store *st = sti->store;
1288 if (st->live && st->cb.item_free.func && sti->item_info)
1291 st->cb.item_free.func(st->cb.item_free.data, sti->item_info);
1293 sti->item_info = NULL;
1301 _item_del(void *data, Evas_Object *obj __UNUSED__)
1303 Elm_Store_Item *sti = data;
1304 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1305 Elm_Store *st = sti->store;
1309 ecore_job_del(sti->eval_job);
1310 sti->eval_job = NULL;
1313 Eina_List *find = NULL;
1314 find = eina_list_data_find_list(st->always_fetched, sti);
1317 find = eina_list_data_find_list(st->realized,sti);
1320 Elm_Store_Item *realized_sti = NULL;
1321 realized_sti = eina_list_data_get(find);
1322 st->realized = eina_list_remove_list(st->realized, find);
1324 if (sti->data) _item_unfetch(sti);
1325 if (st->item.free) st->item.free(sti);
1329 _list_do(void *data, Ecore_Thread *th)
1331 Elm_Store *st = data;
1332 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1334 Elm_Store_Item_Info *item_info;
1335 Eina_Bool ok = EINA_FALSE;
1337 for (loop = 0; loop < st->item_count; loop++)
1339 item_info = calloc(1, sizeof(Elm_Store_Item_Info));
1340 if (!item_info) return;
1341 item_info->index = loop;
1343 if (st->cb.list.func) ok = st->cb.list.func(st->cb.list.data, item_info);
1344 if (ok) ecore_thread_feedback(th, item_info);
1345 else free(item_info);
1346 if (ecore_thread_check(th)) break;
1351 _list_update(void *data, Ecore_Thread *th __UNUSED__, void *msg)
1353 Elm_Store *st = data;
1354 Elm_Store_Item_Info *info = msg;
1355 elm_store_item_add(st, info);
1359 _list_end(void *data, Ecore_Thread *th)
1361 Elm_Store *st = data;
1362 if (th == st->list_th) st->list_th = NULL;
1366 _list_cancel(void *data, Ecore_Thread *th)
1368 Elm_Store *st = data;
1369 if (th == st->list_th) st->list_th = NULL;
1373 _group_item_append(Elm_Store_Item *sti, Elm_Genlist_Item_Class *itc)
1375 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1376 Elm_Store *st = sti->store;
1379 if (st->always_fetched)
1381 Eina_Bool group_existed = EINA_FALSE;
1382 const Eina_List *l = st->always_fetched;
1383 Elm_Store_Item *group_sti = eina_list_data_get(l);
1384 while (!group_existed && group_sti)
1386 if (group_sti->item_info->group_index == sti->item_info->group_index)
1388 group_existed = EINA_TRUE;
1393 l = eina_list_next(l);
1394 group_sti = eina_list_data_get(l);
1397 if (group_existed) return; //Already existed the group item
1399 st->always_fetched = eina_list_append(st->always_fetched, sti);
1400 sti->realized = EINA_FALSE;
1401 if (sti->data) _item_unfetch(sti);
1404 if (sti->item_info->group_index == -1)
1406 sti->item = elm_genlist_item_append(st->genlist,
1410 ELM_GENLIST_ITEM_NONE,
1411 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1412 (void *)sti->store->cb.item_select.data);
1419 _normal_item_append(Elm_Store_Item *sti, Elm_Genlist_Item_Class *itc)
1421 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1422 Elm_Store *st = sti->store;
1423 if (st->live && sti->item_info)
1425 Eina_Bool need_update = EINA_FALSE;
1426 Eina_Bool group_existed = EINA_FALSE;
1429 if (st->always_fetched)
1431 if (sti->item_info->rec_item == EINA_TRUE)
1433 if (sti->item_info->group_index != sti->item_info->pre_group_index)
1435 if (sti->item_info->group_index < sti->item_info->pre_group_index)
1437 Eina_Bool pre_group_existed = EINA_FALSE;
1438 l = st->always_fetched;
1439 Elm_Store_Item *pre_group_sti = eina_list_data_get(l);
1440 while (!pre_group_existed && pre_group_sti)
1442 if (pre_group_sti->item_info->pre_group_index == sti->item_info->pre_group_index)
1444 pre_group_existed = EINA_TRUE;
1449 l = eina_list_next(l);
1450 pre_group_sti = eina_list_data_get(l);
1453 if (pre_group_sti && pre_group_sti->realized) // already added the header item to the genlist
1455 Eina_Bool deleted = EINA_FALSE;
1456 Eina_Bool last_item = EINA_FALSE;
1457 Elm_Genlist_Item *comp_item = pre_group_sti->first_item;
1458 while (!deleted && comp_item)
1460 Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
1463 int sort = st->cb.item_sort.func(st->cb.item_sort.data, sti->item_info, comp_sti->item_info);
1464 if(sort == ELM_STORE_ITEM_SORT_SAME)
1466 elm_store_item_del(comp_sti);
1467 deleted = EINA_TRUE;
1471 if (last_item) break;
1472 else comp_item = elm_genlist_item_next_get(comp_item);
1474 if (comp_item == pre_group_sti->last_item) last_item = EINA_TRUE;
1476 if (!deleted) printf(" The item does not existed in the pre group of genlist \n");
1478 else //Pre group item does not existed in the always fetched list or the genlist
1480 Eina_Bool deleted = EINA_FALSE;
1481 Elm_Genlist_Item *comp_item = elm_genlist_first_item_get(st->genlist);
1482 while (!deleted && comp_item)
1484 Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
1485 if (comp_sti && sti->item_info->item_type == comp_sti->item_info->item_type)
1487 int sort = st->cb.item_sort.func(st->cb.item_sort.data, sti->item_info, comp_sti->item_info);
1488 if (sort == ELM_STORE_ITEM_SORT_SAME)
1490 elm_store_item_del(comp_sti);
1491 deleted = EINA_TRUE;
1495 comp_item = elm_genlist_item_next_get(comp_item);
1497 if (!deleted) printf(" The item does not existed in the genlist \n");
1502 sti->item_info->group_index = sti->item_info->pre_group_index;
1503 need_update = EINA_TRUE;
1506 else need_update = EINA_TRUE;
1508 l = st->always_fetched;
1509 Elm_Store_Item *group_sti = eina_list_data_get(l);
1510 while (!group_existed && group_sti) // Search the group item of a normal item in the always_fetched list
1512 if (group_sti->item_info->group_index == sti->item_info->group_index)
1514 group_existed = EINA_TRUE;
1519 l = eina_list_next(l);
1520 group_sti = eina_list_data_get(l);
1525 if (group_sti->realized) // already added the header item to the genlist
1527 Eina_Bool added = EINA_FALSE;
1528 Elm_Genlist_Item *comp_item = group_sti->first_item;
1529 while (!added && comp_item)
1531 Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
1534 int sort = st->cb.item_sort.func(st->cb.item_sort.data, sti->item_info, comp_sti->item_info);
1535 if (sort == ELM_STORE_ITEM_SORT_SAME)
1537 if (need_update == EINA_TRUE) elm_store_item_update(comp_sti);
1538 else added = EINA_TRUE;
1541 else if (sort == ELM_STORE_ITEM_SORT_LOW)
1543 sti->item = elm_genlist_item_insert_before(st->genlist,
1548 ELM_GENLIST_ITEM_NONE,
1549 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1550 (void *)sti->store->cb.item_select.data);
1552 if (comp_item == group_sti->first_item) group_sti->first_item = sti->item;
1557 if (comp_item == group_sti->last_item) //To add the item in to the last of its group
1559 need_update = EINA_FALSE;
1563 comp_item = elm_genlist_item_next_get(comp_item);
1565 if (!added && !need_update)
1567 Elm_Genlist_Item *last_item = group_sti->last_item;
1570 sti->item = elm_genlist_item_insert_after(st->genlist,
1575 ELM_GENLIST_ITEM_NONE,
1576 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1577 (void *)sti->store->cb.item_select.data);
1578 group_sti->last_item = sti->item;
1580 else printf(" Group item have no last item. so can not add a item to the genlist \n");
1583 else // To add the header item in genlist, and compare with other header items along with callback func
1585 Eina_Bool added = EINA_FALSE;
1586 l = st->always_fetched;
1587 Elm_Store_Item *comp_group_sti = eina_list_data_get(l);
1588 while (!added && comp_group_sti)
1590 if (comp_group_sti != group_sti && comp_group_sti->realized)
1592 // Compare with group items
1593 int sort = st->cb.item_sort.func(st->cb.item_sort.data, group_sti->item_info, comp_group_sti->item_info);
1594 if(sort == ELM_STORE_ITEM_SORT_LOW)
1596 group_sti->item = elm_genlist_item_insert_before(st->genlist,
1597 group_sti->item_info->item_class,
1600 comp_group_sti->item,
1601 ELM_GENLIST_ITEM_GROUP,
1604 group_sti->realized = EINA_TRUE;
1605 sti->item = elm_genlist_item_insert_after(st->genlist,
1610 ELM_GENLIST_ITEM_NONE,
1611 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1612 (void *)sti->store->cb.item_select.data);
1614 group_sti->first_item = sti->item;
1615 group_sti->last_item = sti->item;
1620 l = eina_list_next(l);
1621 comp_group_sti = eina_list_data_get(l);
1623 if (!comp_group_sti) // First item append in the genlist
1625 group_sti->item = elm_genlist_item_append(st->genlist,
1626 group_sti->item_info->item_class,
1629 ELM_GENLIST_ITEM_GROUP,
1632 group_sti->realized = EINA_TRUE;
1633 sti->item = elm_genlist_item_append(st->genlist,
1637 ELM_GENLIST_ITEM_NONE,
1638 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1639 (void *)sti->store->cb.item_select.data);
1641 group_sti->first_item = sti->item;
1642 group_sti->last_item = sti->item;
1647 if (!group_existed) // No exist the group item of normal item, so it added without group.
1649 Eina_Bool added = EINA_FALSE;
1650 Elm_Genlist_Item *comp_item = elm_genlist_first_item_get(st->genlist);
1651 while (!added && comp_item)
1653 Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
1656 if (sti->item_info->item_type == comp_sti->item_info->item_type)
1658 int sort = st->cb.item_sort.func(st->cb.item_sort.data, sti->item_info, comp_sti->item_info);
1659 if (sort == ELM_STORE_ITEM_SORT_SAME)
1661 if (sti->item_info->rec_item == EINA_TRUE)
1663 elm_store_item_update(comp_sti);
1664 need_update = EINA_TRUE;
1666 else added = EINA_TRUE;
1669 else if (sort == ELM_STORE_ITEM_SORT_LOW)
1671 sti->item = elm_genlist_item_insert_before(st->genlist,
1676 ELM_GENLIST_ITEM_NONE,
1677 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1678 (void *)sti->store->cb.item_select.data);
1685 comp_item = elm_genlist_item_next_get(comp_item);
1686 if (comp_item == NULL) need_update = EINA_FALSE;
1688 if (!added && !need_update)
1690 sti->item = elm_genlist_item_append(st->genlist,
1694 ELM_GENLIST_ITEM_NONE,
1695 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1696 (void *)sti->store->cb.item_select.data);
1703 _store_free(Elm_Store *st)
1705 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1706 Elm_Store_DBsystem *std = (Elm_Store_DBsystem *)st;
1707 if(std->p_db) eina_stringshare_del(std->p_db);
1711 * Add a new dbsystem Store object
1713 * @return The new object or NULL if it cannot be created
1718 elm_store_dbsystem_new(void)
1720 Elm_Store_DBsystem *std = _store_new(Elm_Store_DBsystem);
1721 EINA_SAFETY_ON_NULL_RETURN_VAL(std, NULL);
1723 EINA_MAGIC_SET(std, ELM_STORE_DBSYSTEM_MAGIC);
1724 std->base.free = _store_free;
1725 std->base.item.free = _item_free;
1730 * Sets the item count of a store
1732 * @param st The store object
1733 * @param count The item count of an store
1738 elm_store_item_count_set(Elm_Store *st, int count)
1740 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1741 st->item_count = count;
1746 * Set the select func that select the state of a list item whether true or false
1748 * @param st The store object
1749 * @param func The select cb function of an store
1750 * @param data The new data pointer to set
1755 elm_store_item_select_func_set(Elm_Store *st, Elm_Store_Item_Select_Cb func, const void *data)
1757 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1758 st->cb.item_select.func = func;
1759 st->cb.item_select.data = (void *)data;
1763 * Sets the sort func that sort the item with a next in the list
1765 * @param st The store object
1766 * @param func The sort cb function of an store
1767 * @param data The new data pointer to set
1772 elm_store_item_sort_func_set(Elm_Store *st, Elm_Store_Item_Sort_Cb func, const void *data)
1774 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1775 st->cb.item_sort.func = func;
1776 st->cb.item_sort.data = (void *)data;
1780 * Set the store item free func
1782 * @param st The store object
1783 * @param func The free cb function of an store
1784 * @param data The new data pointer to set
1789 elm_store_item_free_func_set(Elm_Store *st, Elm_Store_Item_Free_Cb func, const void *data)
1791 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1792 st->cb.item_free.func = func;
1793 st->cb.item_free.data = (void *)data;
1797 * Get the item index that included header items
1799 * @param sti The store item object
1800 * @return The item index in genlist
1805 elm_store_item_index_get(const Elm_Store_Item *sti)
1807 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return -1;
1808 Elm_Store *st = sti->store;
1815 Elm_Genlist_Item *gen_item = elm_genlist_first_item_get(st->genlist);
1818 Elm_Store_Item *item = elm_genlist_item_data_get(gen_item);
1819 if (item == sti) return index;
1820 gen_item = elm_genlist_item_next_get(gen_item);
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);
1863 * Get the DB pointer of an item
1865 * @param sti The store item object
1866 * @return The DB pointer of item
1871 elm_store_dbsystem_db_get(const Elm_Store_Item *sti)
1873 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
1875 const Elm_Store_DBsystem *std = (const Elm_Store_DBsystem *)sti->store;
1876 if (!EINA_MAGIC_CHECK(sti->store, ELM_STORE_MAGIC)) return NULL;
1877 if (!EINA_MAGIC_CHECK(std, ELM_STORE_DBSYSTEM_MAGIC)) return NULL;
1882 * Set the DB pointer of an item
1884 * @param sti The store item object
1885 * @parm p_db The DB pointer of item
1890 elm_store_dbsystem_db_set(Elm_Store *store, void *p_db)
1892 Elm_Store_DBsystem *std = (Elm_Store_DBsystem *)store;
1893 if (!EINA_MAGIC_CHECK(store, ELM_STORE_MAGIC)) return;
1894 if (!EINA_MAGIC_CHECK(std, ELM_STORE_DBSYSTEM_MAGIC)) return;
1897 ecore_thread_cancel(store->list_th);
1898 store->list_th = NULL;
1901 store->list_th = ecore_thread_feedback_run(_list_do,
1909 * Append the item to the genlist
1911 * @param st The store object
1912 * @param info The store item info dbsystem object
1913 * @return The item of store
1917 EAPI Elm_Store_Item *
1918 elm_store_item_add(Elm_Store *st, Elm_Store_Item_Info *info)
1920 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return NULL;
1921 EINA_SAFETY_ON_NULL_RETURN_VAL(info, NULL);
1922 Elm_Store_Item *sti;
1923 Elm_Genlist_Item_Class *itc;
1925 sti = calloc(1, sizeof(Elm_Store_Item));
1926 if (!sti) return NULL;
1928 EINA_MAGIC_SET(sti, ELM_STORE_ITEM_MAGIC);
1930 sti->item_info = info;
1931 sti->fetched = EINA_FALSE;
1933 itc = info->item_class;
1934 if (!itc) itc = &_store_item_class;
1937 itc->func.label_get = (GenlistItemLabelGetFunc)_item_label_get;
1938 itc->func.icon_get = (GenlistItemIconGetFunc)_item_icon_get;
1939 itc->func.state_get = NULL;
1940 itc->func.del = (GenlistItemDelFunc)_item_del;
1945 if (sti->item_info->item_type == ELM_GENLIST_ITEM_GROUP) _group_item_append(sti, itc);
1946 else _normal_item_append(sti, itc);
1953 * Realize the visible items to the screen
1955 * @param st The store object
1960 elm_store_visible_items_update(Elm_Store *st)
1962 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1964 Eina_List *realized_list = elm_genlist_realized_items_get(st->genlist);
1965 Elm_Genlist_Item *item = eina_list_data_get(realized_list);
1968 Elm_Store_Item *realized_sti = elm_genlist_item_data_get(item);
1969 elm_store_item_update(realized_sti);
1970 realized_list = eina_list_next(realized_list);
1971 item = eina_list_data_get(realized_list);
1976 * Realize the item to the screen
1978 * @param sti The store item object
1983 elm_store_item_update(Elm_Store_Item *sti)
1985 Elm_Store *st = sti->store;
1987 Eina_List *find = NULL;
1988 find = eina_list_data_find_list(st->always_fetched, sti);
1991 if (sti->data) _item_unfetch(sti);
1993 if (sti->realized) elm_genlist_item_update(sti->item);
1997 find = eina_list_data_find_list(st->realized,sti);
1998 if (find) _item_realize(sti);
2003 * Delete the item of genlist
2005 * @param sti The store item object
2010 elm_store_item_del(Elm_Store_Item *sti)
2012 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
2013 Elm_Store *st = sti->store;
2017 Eina_List *find = NULL;
2018 find = eina_list_data_find_list(st->always_fetched, sti);
2019 if (find) st->always_fetched = eina_list_remove_list(st->always_fetched, find);
2021 Eina_Bool deleted = EINA_FALSE;
2022 Elm_Genlist_Item *comp_item = elm_genlist_first_item_get(st->genlist);
2023 while (!deleted && comp_item)
2025 Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
2026 if (comp_sti && (sti == comp_sti))
2028 Elm_Genlist_Item *group_item = elm_genlist_item_parent_get(comp_item);
2031 Elm_Store_Item *group_sti = elm_genlist_item_data_get(group_item);
2034 if ((group_sti->first_item == comp_item) && (group_sti->last_item == comp_item))
2036 group_sti->realized = EINA_FALSE;
2037 group_sti->first_item = NULL;
2038 group_sti->last_item = NULL;
2039 elm_genlist_item_del(group_item);
2041 else if ((group_sti->first_item == comp_item) && (group_sti->last_item != comp_item))
2043 Elm_Genlist_Item *next_item = elm_genlist_item_next_get(comp_item);
2044 group_sti->first_item = next_item;
2046 else if ((group_sti->first_item != comp_item) && (group_sti->last_item == comp_item))
2048 Elm_Genlist_Item *prev_item = elm_genlist_item_prev_get(comp_item);
2049 group_sti->last_item = prev_item;
2053 elm_genlist_item_del(comp_sti->item);
2054 deleted = EINA_TRUE;
2057 comp_item = elm_genlist_item_next_get(comp_item);
2060 if(!deleted) printf(" Not deleted because it does not existed in the genlist \n");
2064 // TODO: END -DBsystem store