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 128
32 #define SCREEN_ITEM_COUNT 10
37 void (*free)(Elm_Store *store);
39 void (*free)(Elm_Store_Item *item);
42 Ecore_Thread *list_th;
47 int current_top_index;
48 int start_fetch_index;
54 Eina_List *header_items;
57 Elm_Store_Item_List_Cb func;
61 Elm_Store_Item_Fetch_Cb func;
65 Elm_Store_Item_Unfetch_Cb func;
69 Elm_Store_Item_Select_Cb func;
73 Elm_Store_Item_Sort_Cb func;
78 Eina_Bool fetch_thread : 1;
79 Eina_Bool multi_load : 1;
83 struct _Elm_Store_Item
88 Elm_Genlist_Item *item;
89 Ecore_Thread *fetch_th;
91 const Elm_Store_Item_Mapping *mapping;
93 Elm_Store_Item_Info *item_info;
96 Eina_Bool was_live : 1;
97 Eina_Bool realized : 1;
98 Eina_Bool fetched : 1;
101 struct _Elm_Store_Filesystem
108 struct _Elm_Store_Item_Filesystem
114 struct _Elm_Store_DBsystem
121 static Elm_Genlist_Item_Class _store_item_class;
123 static char *_item_label_get(void *data, Evas_Object *obj __UNUSED__, const char *part);
124 static Evas_Object *_item_icon_get(void *data, Evas_Object *obj, const char *part);
125 static void _item_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__);
126 static void _store_free(Elm_Store *st);
127 static void _item_free(Elm_Store_Item *sti);
128 static void _item_realized(void *data, Evas_Object *obj __UNUSED__, void *event_info);
129 static void _item_unrealized(void *data, Evas_Object *obj __UNUSED__, void *event_info);
130 static void _genlist_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__);
131 static Elm_Store_Item *_item_unfetch(Elm_Store *st, int index);
134 _store_cache_trim(Elm_Store *st)
136 while ((st->realized ) &&
137 (((int)eina_list_count(st->realized) - st->realized_count)
140 Elm_Store_Item *sti = st->realized->data;
143 st->realized = eina_list_remove_list(st->realized, st->realized);
144 sti->realized = EINA_FALSE;
152 ecore_thread_cancel(sti->fetch_th);
153 sti->fetch_th = NULL;
157 sti->fetched = EINA_FALSE;
159 if (st->cb.unfetch.func)
160 st->cb.unfetch.func(st->cb.unfetch.data, sti, NULL);
168 _store_genlist_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
170 Elm_Store *st = data;
174 ecore_thread_cancel(st->list_th);
177 eina_list_free(st->realized);
180 Elm_Store_Item *sti = (Elm_Store_Item *)st->items;
181 if (sti->eval_job) ecore_job_del(sti->eval_job);
184 ecore_thread_cancel(sti->fetch_th);
185 sti->fetch_th = NULL;
187 if (sti->store->item.free) sti->store->item.free(sti);
190 if (st->cb.unfetch.func)
191 st->cb.unfetch.func(st->cb.unfetch.data, sti, NULL);
197 // FIXME: kill threads and more
200 ////// **** WARNING ***********************************************************
201 //// * This function runs inside a thread outside efl mainloop. Be careful! *
202 // ************************************************************************
203 /* TODO: refactor lock part into core? this does not depend on filesystm part */
205 _store_filesystem_fetch_do(void *data, Ecore_Thread *th __UNUSED__)
207 Elm_Store_Item *sti = data;
217 if (sti->store->cb.fetch.func)
218 sti->store->cb.fetch.func(sti->store->cb.fetch.data, sti, NULL);
220 sti->fetched = EINA_TRUE;
224 // ************************************************************************
225 //// * End of separate thread function. *
226 ////// ************************************************************************
227 /* TODO: refactor lock part into core? this does not depend on filesystm part */
229 _store_filesystem_fetch_end(void *data, Ecore_Thread *th)
231 Elm_Store_Item *sti = data;
233 if (sti->data) elm_genlist_item_update(sti->item);
235 if (th == sti->fetch_th) sti->fetch_th = NULL;
238 /* TODO: refactor lock part into core? this does not depend on filesystm part */
240 _store_filesystem_fetch_cancel(void *data, Ecore_Thread *th)
242 Elm_Store_Item *sti = data;
244 if (th == sti->fetch_th) sti->fetch_th = NULL;
245 if (sti->data) elm_genlist_item_update(sti->item);
250 _store_item_eval(void *data)
252 Elm_Store_Item *sti = data;
253 sti->eval_job = NULL;
254 if (sti->live == sti->was_live) return;
255 sti->was_live = sti->live;
258 _store_cache_trim(sti->store);
260 sti->store->realized = eina_list_remove(sti->store->realized, sti);
261 sti->store->realized = eina_list_append(sti->store->realized, sti);
262 sti->realized = EINA_TRUE;
263 if ((sti->store->fetch_thread) && (!sti->fetch_th))
264 sti->fetch_th = ecore_thread_run(_store_filesystem_fetch_do,
265 _store_filesystem_fetch_end,
266 _store_filesystem_fetch_cancel,
268 else if ((!sti->store->fetch_thread))
270 _store_filesystem_fetch_do(sti, NULL);
271 _store_filesystem_fetch_end(sti, NULL);
278 ecore_thread_cancel(sti->fetch_th);
279 sti->fetch_th = NULL;
281 _store_cache_trim(sti->store);
286 _store_genlist_item_realized(void *data, Evas_Object *obj __UNUSED__, void *event_info)
288 Elm_Store *st = data;
289 Elm_Genlist_Item *gli = event_info;
290 Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
292 st->realized_count++;
293 sti->live = EINA_TRUE;
294 if (sti->eval_job) ecore_job_del(sti->eval_job);
295 sti->eval_job = ecore_job_add(_store_item_eval, sti);
299 _store_genlist_item_unrealized(void *data, Evas_Object *obj __UNUSED__, void *event_info)
301 Elm_Store *st = data;
302 Elm_Genlist_Item *gli = event_info;
303 Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
305 st->realized_count--;
306 sti->live = EINA_FALSE;
307 if (sti->eval_job) ecore_job_del(sti->eval_job);
308 sti->eval_job = ecore_job_add(_store_item_eval, sti);
311 static const Elm_Store_Item_Mapping *
312 _store_item_mapping_find(Elm_Store_Item *sti, const char *part)
314 const Elm_Store_Item_Mapping *m;
316 for (m = sti->mapping; m; m ++)
318 if (m->type == ELM_STORE_ITEM_MAPPING_NONE) break;
319 if (!strcmp(part, m->part)) return m;
325 _store_item_label_get(void *data, Evas_Object *obj __UNUSED__, const char *part)
327 Elm_Store_Item *sti = data;
332 const Elm_Store_Item_Mapping *m = _store_item_mapping_find(sti, part);
337 case ELM_STORE_ITEM_MAPPING_LABEL:
338 s = *(char **)(((unsigned char *)sti->data) + m->offset);
340 case ELM_STORE_ITEM_MAPPING_CUSTOM:
341 if (m->details.custom.func)
342 s = m->details.custom.func(sti->data, sti, part);
354 _store_item_icon_get(void *data, Evas_Object *obj, const char *part)
356 Elm_Store_Item *sti = data;
360 const Elm_Store_Item_Mapping *m = _store_item_mapping_find(sti, part);
363 Evas_Object *ic = NULL;
364 const char *s = NULL;
368 case ELM_STORE_ITEM_MAPPING_ICON:
369 ic = elm_icon_add(obj);
370 s = *(char **)(((unsigned char *)sti->data) + m->offset);
371 elm_icon_order_lookup_set(ic, m->details.icon.lookup_order);
372 evas_object_size_hint_aspect_set(ic,
373 EVAS_ASPECT_CONTROL_VERTICAL,
376 elm_icon_smooth_set(ic, m->details.icon.smooth);
377 elm_icon_no_scale_set(ic, m->details.icon.no_scale);
378 elm_icon_scale_set(ic,
379 m->details.icon.scale_up,
380 m->details.icon.scale_down);
383 if (m->details.icon.standard_name)
384 elm_icon_standard_set(ic, s);
386 elm_icon_file_set(ic, s, NULL);
389 case ELM_STORE_ITEM_MAPPING_PHOTO:
390 ic = elm_icon_add(obj);
391 s = *(char **)(((unsigned char *)sti->data) + m->offset);
392 elm_photo_size_set(ic, m->details.photo.size);
394 elm_photo_file_set(ic, s);
396 case ELM_STORE_ITEM_MAPPING_CUSTOM:
397 if (m->details.custom.func)
398 ic = m->details.custom.func(sti->data, sti, part);
412 _store_item_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__)
416 ////// **** WARNING ***********************************************************
417 //// * This function runs inside a thread outside efl mainloop. Be careful! *
418 // ************************************************************************
420 _store_filesystem_sort_cb(void *d1, void *d2)
422 Elm_Store_Item_Info *info1 = d1, *info2 = d2;
423 if ((!info1->sort_id) || (!info2->sort_id)) return 0;
424 return strcoll(info1->sort_id, info2->sort_id);
428 _store_filesystem_list_do(void *data, Ecore_Thread *th __UNUSED__)
430 Elm_Store_Filesystem *st = data;
432 const Eina_File_Direct_Info *finf;
433 Eina_List *sorted = NULL;
434 Elm_Store_Item_Info_Filesystem *info;
436 // FIXME: need a way to abstract the open, list, feed items from list
437 // and maybe get initial sortable key vals etc.
438 it = eina_file_stat_ls(st->dir);
440 EINA_ITERATOR_FOREACH(it, finf)
443 size_t pathsz = finf->path_length + 1;
445 info = calloc(1, sizeof(Elm_Store_Item_Info_Filesystem) + pathsz);
447 info->path = ((char *)info) + sizeof(Elm_Store_Item_Info_Filesystem);
448 memcpy(info->path, finf->path, pathsz);
450 if (st->base.cb.list.func)
451 ok = st->base.cb.list.func(st->base.cb.list.data, &info->base);
454 if (!st->base.sorted) ecore_thread_feedback(th, info);
455 else sorted = eina_list_append(sorted, info);
459 if (info->base.sort_id) free(info->base.sort_id);
462 if (ecore_thread_check(th)) break;
464 eina_iterator_free(it);
467 sorted = eina_list_sort(sorted, 0,
468 EINA_COMPARE_CB(_store_filesystem_sort_cb));
469 EINA_LIST_FREE(sorted, info)
471 if (!ecore_thread_check(th)) ecore_thread_feedback(th, info);
475 // ************************************************************************
476 //// * End of separate thread function. *
477 ////// ************************************************************************
480 _store_filesystem_list_end(void *data, Ecore_Thread *th)
482 Elm_Store *st = data;
483 if (th == st->list_th) st->list_th = NULL;
487 _store_filesystem_list_cancel(void *data, Ecore_Thread *th)
489 Elm_Store *st = data;
490 if (th == st->list_th) st->list_th = NULL;
494 _store_filesystem_list_update(void *data, Ecore_Thread *th __UNUSED__, void *msg)
496 Elm_Store *st = data;
497 Elm_Store_Item_Filesystem *sti;
498 Elm_Genlist_Item_Class *itc;
499 Elm_Store_Item_Info_Filesystem *info = msg;
501 sti = calloc(1, sizeof(Elm_Store_Item_Filesystem));
504 EINA_MAGIC_SET(&(sti->base), ELM_STORE_ITEM_MAGIC);
505 sti->base.store = st;
506 sti->base.data = info->base.data;
507 sti->base.mapping = info->base.mapping;
508 sti->path = eina_stringshare_add(info->path);
510 itc = info->base.item_class;
511 if (!itc) itc = &_store_item_class;
514 itc->func.label_get = (GenlistItemLabelGetFunc)_store_item_label_get;
515 itc->func.icon_get = (GenlistItemIconGetFunc)_store_item_icon_get;
516 itc->func.state_get = NULL; // FIXME: support state gets later
517 itc->func.del = (GenlistItemDelFunc)_store_item_del;
520 // FIXME: handle being a parent (tree)
521 sti->base.item = elm_genlist_item_append(st->genlist, itc,
524 ELM_GENLIST_ITEM_NONE,
526 NULL/* func data */);
527 st->items = eina_inlist_append(st->items, (Eina_Inlist *)sti);
529 if (info->base.sort_id) free(info->base.sort_id);
535 _elm_store_new(size_t size)
537 Elm_Store *st = calloc(1, size);
538 EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
540 // TODO: BEGIN - move to elm_store_init()
541 eina_magic_string_set(ELM_STORE_MAGIC, "Elm_Store");
542 eina_magic_string_set(ELM_STORE_FILESYSTEM_MAGIC, "Elm_Store_Filesystem");
543 eina_magic_string_set(ELM_STORE_ITEM_MAGIC, "Elm_Store_Item");
544 // setup default item class (always the same) if list cb doesnt provide one
545 _store_item_class.item_style = "default";
546 _store_item_class.func.label_get = (GenlistItemLabelGetFunc)_store_item_label_get;
547 _store_item_class.func.icon_get = (GenlistItemIconGetFunc)_store_item_icon_get;
548 _store_item_class.func.state_get = NULL; // FIXME: support state gets later
549 _store_item_class.func.del = (GenlistItemDelFunc)_store_item_del;
550 // TODO: END - move to elm_store_init()
552 EINA_MAGIC_SET(st, ELM_STORE_MAGIC);
554 st->fetch_thread = EINA_TRUE;
558 #define elm_store_new(type) (type*)_elm_store_new(sizeof(type))
561 _elm_store_filesystem_free(Elm_Store *store)
563 Elm_Store_Filesystem *st = (Elm_Store_Filesystem *)store;
564 eina_stringshare_del(st->dir);
568 _elm_store_filesystem_item_free(Elm_Store_Item *item)
570 Elm_Store_Item_Filesystem *sti = (Elm_Store_Item_Filesystem *)item;
571 eina_stringshare_del(sti->path);
575 elm_store_filesystem_new(void)
577 Elm_Store_Filesystem *st = elm_store_new(Elm_Store_Filesystem);
578 EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
580 EINA_MAGIC_SET(st, ELM_STORE_FILESYSTEM_MAGIC);
581 st->base.free = _elm_store_filesystem_free;
582 st->base.item.free = _elm_store_filesystem_item_free;
588 elm_store_free(Elm_Store *st)
590 void (*item_free)(Elm_Store_Item *);
591 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
594 ecore_thread_cancel(st->list_th);
600 eina_list_free(st->realized);
601 item_free = st->item.free;
604 Elm_Store_Item *sti = (Elm_Store_Item *)st->items;
605 if (sti->eval_job) ecore_job_del(sti->eval_job);
608 ecore_thread_cancel(sti->fetch_th);
609 sti->fetch_th = NULL;
611 if (item_free) item_free(sti);
614 if (st->cb.unfetch.func)
615 st->cb.unfetch.func(st->cb.unfetch.data, sti, NULL);
623 evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _store_genlist_del, st);
624 evas_object_smart_callback_del(st->genlist, "realized", _store_genlist_item_realized);
625 evas_object_smart_callback_del(st->genlist, "unrealized", _store_genlist_item_unrealized);
626 elm_genlist_clear(st->genlist);
629 if (st->free) st->free(st);
634 Eina_List *header_list;
636 EINA_LIST_FOREACH(st->header_items, l, header_list)
642 EINA_LIST_FOREACH(header_list, in_l, sti)
646 ecore_thread_cancel(sti->fetch_th);
647 sti->fetch_th = NULL;
651 int index = elm_store_item_index_get(sti);
652 _item_unfetch(st, index);
659 eina_list_free(st->header_items);
663 evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _genlist_del, st);
664 evas_object_smart_callback_del(st->genlist, "realized", _item_realized);
665 evas_object_smart_callback_del(st->genlist, "unrealized", _item_unrealized);
666 elm_genlist_clear(st->genlist);
674 elm_store_target_genlist_set(Elm_Store *st, Evas_Object *obj)
676 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
677 if (st->genlist == obj) return;
682 evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _store_genlist_del, st);
683 evas_object_smart_callback_del(st->genlist, "realized", _store_genlist_item_realized);
684 evas_object_smart_callback_del(st->genlist, "unrealized", _store_genlist_item_unrealized);
688 evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _genlist_del, st);
689 evas_object_smart_callback_del(st->genlist, "realized", _item_realized);
690 evas_object_smart_callback_del(st->genlist, "unrealized", _item_unrealized);
692 elm_genlist_clear(st->genlist);
695 if (!st->genlist) return;
698 evas_object_smart_callback_add(st->genlist, "realized", _store_genlist_item_realized, st);
699 evas_object_smart_callback_add(st->genlist, "unrealized", _store_genlist_item_unrealized, st);
700 evas_object_event_callback_add(st->genlist, EVAS_CALLBACK_DEL, _store_genlist_del, st);
704 evas_object_smart_callback_add(st->genlist, "realized", _item_realized, st);
705 evas_object_smart_callback_add(st->genlist, "unrealized", _item_unrealized, st);
706 evas_object_event_callback_add(st->genlist, EVAS_CALLBACK_DEL, _genlist_del, st);
707 st->block_count = elm_genlist_block_count_get(st->genlist);
709 elm_genlist_clear(st->genlist);
713 elm_store_filesystem_directory_set(Elm_Store *store, const char *dir)
715 Elm_Store_Filesystem *st = (Elm_Store_Filesystem *)store;
716 if (!EINA_MAGIC_CHECK(store, ELM_STORE_MAGIC)) return;
717 if (!EINA_MAGIC_CHECK(st, ELM_STORE_FILESYSTEM_MAGIC)) return;
720 ecore_thread_cancel(store->list_th);
721 store->list_th = NULL;
723 if (!eina_stringshare_replace(&st->dir, dir)) return;
724 store->list_th = ecore_thread_feedback_run(_store_filesystem_list_do,
725 _store_filesystem_list_update,
726 _store_filesystem_list_end,
727 _store_filesystem_list_cancel,
732 elm_store_filesystem_directory_get(const Elm_Store *store)
734 const Elm_Store_Filesystem *st = (const Elm_Store_Filesystem *)store;
735 if (!EINA_MAGIC_CHECK(store, ELM_STORE_MAGIC)) return NULL;
736 if (!EINA_MAGIC_CHECK(st, ELM_STORE_FILESYSTEM_MAGIC)) return NULL;
741 elm_store_cache_set(Elm_Store *st, int max)
743 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
744 if (max < 0) max = 0;
746 if(!st->type) _store_cache_trim(st);
750 elm_store_cache_get(const Elm_Store *st)
752 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return 0;
753 return st->cache_max;
757 elm_store_list_func_set(Elm_Store *st, Elm_Store_Item_List_Cb func, const void *data)
759 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
760 st->cb.list.func = func;
761 st->cb.list.data = (void *)data;
765 elm_store_fetch_func_set(Elm_Store *st, Elm_Store_Item_Fetch_Cb func, const void *data)
767 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
768 st->cb.fetch.func = func;
769 st->cb.fetch.data = (void *)data;
773 elm_store_fetch_thread_set(Elm_Store *st, Eina_Bool use_thread)
775 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
776 st->fetch_thread = !!use_thread;
780 elm_store_fetch_thread_get(const Elm_Store *st)
782 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return EINA_FALSE;
783 return st->fetch_thread;
787 elm_store_unfetch_func_set(Elm_Store *st, Elm_Store_Item_Unfetch_Cb func, const void *data)
789 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
790 st->cb.unfetch.func = func;
791 st->cb.unfetch.data = (void *)data;
795 elm_store_sorted_set(Elm_Store *st, Eina_Bool sorted)
797 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
802 elm_store_sorted_get(const Elm_Store *st)
804 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return EINA_FALSE;
809 elm_store_item_data_set(Elm_Store_Item *sti, void *data)
811 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
818 elm_store_item_data_get(Elm_Store_Item *sti)
820 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
828 EAPI const Elm_Store *
829 elm_store_item_store_get(const Elm_Store_Item *sti)
831 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
836 EAPI const Elm_Genlist_Item *
837 elm_store_item_genlist_item_get(const Elm_Store_Item *sti)
839 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
845 elm_store_item_filesystem_path_get(const Elm_Store_Item *item)
847 Elm_Store_Item_Filesystem *sti = (Elm_Store_Item_Filesystem *)item;
848 Elm_Store_Filesystem *st;
849 if (!EINA_MAGIC_CHECK(item, ELM_STORE_ITEM_MAGIC)) return NULL;
850 if (!EINA_MAGIC_CHECK(item->store, ELM_STORE_MAGIC)) return NULL;
851 /* ensure we're dealing with filesystem item */
852 st = (Elm_Store_Filesystem *)item->store;
853 if (!EINA_MAGIC_CHECK(st, ELM_STORE_FILESYSTEM_MAGIC)) return NULL;
858 // TODO: BEGIN -DBsystem store
861 _store_init(size_t size)
863 Elm_Store *st = calloc(1, size);
864 if (!st) return NULL;
866 eina_magic_string_set(ELM_STORE_MAGIC, "Elm_Store");
867 eina_magic_string_set(ELM_STORE_FILESYSTEM_MAGIC, "Elm_Store_Filesystem");
868 eina_magic_string_set(ELM_STORE_ITEM_MAGIC, "Elm_Store_Item");
869 eina_magic_string_set(ELM_STORE_DBSYSTEM_MAGIC, "Elm_Store_DBsystem");
871 _store_item_class.item_style = "default";
872 _store_item_class.func.label_get = (GenlistItemLabelGetFunc)_item_label_get;
873 _store_item_class.func.icon_get = (GenlistItemIconGetFunc)_item_icon_get;
874 _store_item_class.func.state_get = NULL;
875 _store_item_class.func.del = (GenlistItemDelFunc)_item_del;
877 EINA_MAGIC_SET(st, ELM_STORE_MAGIC);
878 st->cache_max = CACHE_COUNT;
879 st->current_top_index = 0;
880 st->start_fetch_index = 0;
881 st->end_fetch_index = st->cache_max - 1;
882 st->live = EINA_TRUE;
883 st->multi_load = EINA_FALSE;
885 st->fetch_thread = EINA_FALSE;
890 #define _store_new(type) (type *)_store_init(sizeof(type))
893 _genlist_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
895 EINA_SAFETY_ON_NULL_RETURN(data);
896 Elm_Store *st = data;
897 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
903 _store_fetch_do(void *data, Ecore_Thread *th __UNUSED__)
905 Elm_Store_Item *sti = data;
917 if (sti->store->cb.fetch.func)
919 sti->store->cb.fetch.func(sti->store->cb.fetch.data, sti, sti->item_info);
922 sti->fetched = EINA_TRUE;
928 _store_fetch_end(void *data, Ecore_Thread *th)
930 Elm_Store_Item *sti = data;
932 if (sti->data) elm_genlist_item_update(sti->item);
934 if (th == sti->fetch_th) sti->fetch_th = NULL;
938 _store_fetch_cancel(void *data, Ecore_Thread *th)
940 Elm_Store_Item *sti = data;
942 if (th == sti->fetch_th) sti->fetch_th = NULL;
943 if (sti->data) elm_genlist_item_update(sti->item);
947 static Elm_Store_Item *
948 _item_fetch(Elm_Store *st, int index)
950 EINA_SAFETY_ON_NULL_RETURN_VAL(st,NULL);
955 Eina_List *header_list;
957 EINA_LIST_FOREACH(st->header_items, l, header_list)
959 if ((in_index + (signed)eina_list_count(header_list)) > index)
961 sti = eina_list_nth(header_list, index - in_index);
963 if ((!sti->fetched) && st->cb.fetch.func && (!sti->fetch_th))
965 if (st->fetch_thread)
968 sti->fetch_th = ecore_thread_run(_store_fetch_do,
977 st->cb.fetch.func(st->cb.fetch.data, sti, sti->item_info);
979 sti->fetched = EINA_TRUE;
987 in_index = in_index + eina_list_count(header_list);
993 static Elm_Store_Item *
994 _item_unfetch(Elm_Store *st, int index)
996 EINA_SAFETY_ON_NULL_RETURN_VAL(st,NULL);
1001 Eina_List *header_list;
1003 EINA_LIST_FOREACH(st->header_items, l, header_list)
1005 if ((in_index + (signed)eina_list_count(header_list)) > index)
1007 sti = eina_list_nth(header_list, index - in_index);
1009 if (sti->fetched && st->cb.unfetch.func)
1014 ecore_thread_cancel(sti->fetch_th);
1015 sti->fetch_th = NULL;
1019 st->cb.unfetch.func(st->cb.unfetch.data, sti, sti->item_info);
1022 sti->fetched = EINA_FALSE;
1029 in_index = in_index + eina_list_count(header_list);
1035 static const Elm_Store_Item_Mapping *
1036 _item_mapping_find(Elm_Store_Item *sti, const char *part)
1038 const Elm_Store_Item_Mapping *m;
1040 for (m = sti->item_info->mapping; m; m++)
1042 if (m->type == ELM_STORE_ITEM_MAPPING_NONE) break;
1043 if (!strcmp(part, m->part)) return m;
1049 _item_label_get(void *data, Evas_Object *obj __UNUSED__, const char *part)
1051 EINA_SAFETY_ON_NULL_RETURN_VAL(data, strdup(""));
1052 Elm_Store_Item *sti = data;
1058 int index = elm_store_item_index_get(sti);
1059 if (sti->store->start_fetch_index > index)
1061 int diff = sti->store->start_fetch_index - index;
1063 for (loop = 1; loop <= diff; loop++)
1065 _item_unfetch(sti->store, sti->store->end_fetch_index);
1066 sti->store->end_fetch_index--;
1067 _item_fetch(sti->store, (sti->store->start_fetch_index - loop));
1069 sti->store->start_fetch_index = index;
1071 else if (index > sti->store->end_fetch_index)
1073 int diff = index - sti->store->end_fetch_index;
1075 for (loop = 1; loop <= diff; loop++)
1077 _item_unfetch(sti->store, sti->store->start_fetch_index);
1078 sti->store->start_fetch_index++;
1079 _item_fetch(sti->store, (sti->store->end_fetch_index + loop));
1081 sti->store->end_fetch_index = index;
1085 _item_fetch(sti->store, index);
1093 const Elm_Store_Item_Mapping *m = _item_mapping_find(sti, part);
1098 case ELM_STORE_ITEM_MAPPING_LABEL:
1099 s = *(char **)(((unsigned char *)sti->data) + m->offset);
1102 case ELM_STORE_ITEM_MAPPING_CUSTOM:
1103 if (m->details.custom.func)
1104 s = m->details.custom.func(sti->data, sti, part);
1127 static Evas_Object *
1128 _item_icon_get(void *data, Evas_Object *obj, const char *part)
1130 EINA_SAFETY_ON_NULL_RETURN_VAL(data,NULL);
1131 Elm_Store_Item *sti = data;
1132 EINA_SAFETY_ON_NULL_RETURN_VAL(sti,NULL);
1139 const Elm_Store_Item_Mapping *m = _item_mapping_find(sti, part);
1142 Evas_Object *ic = NULL;
1143 const char *s = NULL;
1147 case ELM_STORE_ITEM_MAPPING_ICON:
1148 ic = elm_icon_add(obj);
1149 s = *(char **)(((unsigned char *)sti->data) + m->offset);
1150 elm_icon_order_lookup_set(ic, m->details.icon.lookup_order);
1151 evas_object_size_hint_aspect_set(ic,
1152 EVAS_ASPECT_CONTROL_VERTICAL,
1155 elm_icon_smooth_set(ic, m->details.icon.smooth);
1156 elm_icon_no_scale_set(ic, m->details.icon.no_scale);
1157 elm_icon_scale_set(ic,
1158 m->details.icon.scale_up,
1159 m->details.icon.scale_down);
1163 if (m->details.icon.standard_name)
1164 elm_icon_standard_set(ic, s);
1166 elm_icon_file_set(ic, s, NULL);
1170 case ELM_STORE_ITEM_MAPPING_PHOTO:
1171 ic = elm_icon_add(obj);
1172 s = *(char **)(((unsigned char *)sti->data) + m->offset);
1173 elm_photo_size_set(ic, m->details.photo.size);
1175 elm_photo_file_set(ic, s);
1178 case ELM_STORE_ITEM_MAPPING_CUSTOM:
1179 if (m->details.custom.func)
1180 ic = m->details.custom.func(sti->data, sti, part);
1196 _item_realized(void *data, Evas_Object *obj __UNUSED__, void *event_info)
1198 EINA_SAFETY_ON_NULL_RETURN(data);
1199 EINA_SAFETY_ON_NULL_RETURN(event_info);
1200 Elm_Store *st = data;
1201 Elm_Genlist_Item *gli = event_info;
1202 Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
1204 EINA_SAFETY_ON_NULL_RETURN(sti);
1206 int index = elm_store_item_index_get(sti);
1208 if (st->fetch_thread)
1210 if ((st->start_fetch_index <= index) && (index <= st->end_fetch_index))
1212 int middle_index = sti->store->start_fetch_index + (sti->store->cache_max) / 2;
1214 if ((middle_index < index) && (sti->store->end_fetch_index < sti->store->total_count))
1216 int diff = index - middle_index;
1218 for (loop = 0; loop < diff; loop++)
1220 _item_unfetch(st, sti->store->start_fetch_index);
1221 sti->store->start_fetch_index++;
1222 _item_fetch(st, (sti->store->end_fetch_index + 1));
1223 sti->store->end_fetch_index++;
1226 else if ((middle_index > index) && (sti->store->start_fetch_index > 0))
1228 int diff = st->current_top_index - index;
1230 for (loop = 0; loop < diff; loop++)
1232 _item_unfetch(st, sti->store->end_fetch_index);
1233 sti->store->end_fetch_index--;
1234 _item_fetch(st, (sti->store->start_fetch_index - 1));
1235 sti->store->start_fetch_index--;
1239 if ((!sti->fetched))
1241 _item_fetch(st, index);
1247 if ((st->current_top_index > index))
1249 st->current_top_index = index;
1251 else if ((st->current_top_index + SCREEN_ITEM_COUNT) < index)
1253 st->current_top_index = st->current_top_index + (index - (st->current_top_index + SCREEN_ITEM_COUNT));
1256 // TODO: fix the item when it disposed quickly before call the label get. as example, get_more_btn in email
1260 _item_unrealized(void *data, Evas_Object *obj __UNUSED__, void *event_info)
1262 EINA_SAFETY_ON_NULL_RETURN(data);
1263 EINA_SAFETY_ON_NULL_RETURN(event_info);
1264 Elm_Genlist_Item *gli = event_info;
1265 Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
1266 EINA_SAFETY_ON_NULL_RETURN(sti);
1270 _item_del(void *data, Evas_Object *obj __UNUSED__)
1272 EINA_SAFETY_ON_NULL_RETURN(data);
1273 Elm_Store_Item *sti = data;
1274 EINA_SAFETY_ON_NULL_RETURN(sti);
1275 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1276 elm_store_item_del(sti);
1280 _list_do(void *data, Ecore_Thread *th __UNUSED__)
1282 EINA_SAFETY_ON_NULL_RETURN(data);
1283 Elm_Store *st = data;
1284 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1286 if (st->multi_load == EINA_TRUE)
1288 Elm_Store_Item_Info *item_info;
1289 Eina_Bool ok = EINA_FALSE;
1291 for (loop = 0; loop < st->item_count; loop++)
1293 item_info = calloc(1, sizeof(Elm_Store_Item_Info));
1294 if (!item_info) return;
1295 item_info->index = loop;
1297 if (st->cb.list.func)
1299 ok = st->cb.list.func(st->cb.list.data, item_info);
1301 if (ok) ecore_thread_feedback(th, item_info);
1302 else free(item_info);
1303 if (ecore_thread_check(th)) break;
1309 _list_update(void *data, Ecore_Thread *th __UNUSED__, void *msg)
1311 EINA_SAFETY_ON_NULL_RETURN(data);
1312 EINA_SAFETY_ON_NULL_RETURN(msg);
1313 Elm_Store *st = data;
1314 Elm_Store_Item_Info *info = msg;
1316 elm_store_item_add(st, info);
1320 _list_end(void *data, Ecore_Thread *th)
1322 EINA_SAFETY_ON_NULL_RETURN(data);
1323 EINA_SAFETY_ON_NULL_RETURN(th);
1324 Elm_Store *st = data;
1326 if (th == st->list_th)
1328 ecore_thread_cancel(st->list_th);
1334 _list_cancel(void *data, Ecore_Thread *th)
1336 EINA_SAFETY_ON_NULL_RETURN(data);
1337 EINA_SAFETY_ON_NULL_RETURN(th);
1338 Elm_Store *st = data;
1340 if (th == st->list_th)
1342 ecore_thread_cancel(st->list_th);
1347 static Elm_Store_Item *
1348 _item_get(const Elm_Store *st, const int index)
1350 EINA_SAFETY_ON_NULL_RETURN_VAL(st,NULL);
1351 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return NULL;
1357 Elm_Store_Item *sti;
1359 Eina_List *header_list;
1361 EINA_LIST_FOREACH(st->header_items, l, header_list)
1363 if ((in_index + (signed)eina_list_count(header_list)) > index)
1365 sti = eina_list_nth(header_list, index - in_index);
1370 in_index = in_index + eina_list_count(header_list);
1378 _item_select_cb(void *data, Evas_Object *obj, void *event_info)
1380 EINA_SAFETY_ON_NULL_RETURN(event_info);
1382 const Elm_Genlist_Item *it = (Elm_Genlist_Item *)event_info;
1383 Elm_Store_Item *sti = elm_genlist_item_data_get(it);
1384 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1386 if (sti->store->cb.item_select.func)
1388 sti->store->cb.item_select.func(sti->store->cb.item_select.data, sti);
1393 _group_item_append(Elm_Store_Item *sti, Elm_Genlist_Item_Class *itc)
1395 EINA_SAFETY_ON_NULL_RETURN(sti);
1396 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1398 if (sti->store->header_items)
1400 Eina_Bool header_add = EINA_TRUE;
1402 Eina_List *header_list;
1404 EINA_LIST_FOREACH(sti->store->header_items, l, header_list)
1406 Elm_Store_Item *item = eina_list_nth(header_list, 0);
1408 if (item->item_info->group_index == sti->item_info->group_index)
1410 header_add = EINA_FALSE;
1416 Eina_List *new_header_list = NULL;
1417 sti->item_info->index = 0;
1418 new_header_list = eina_list_append(new_header_list, sti);
1420 Eina_Bool last_header = EINA_TRUE;
1422 Eina_List *header_list;
1424 EINA_LIST_FOREACH(sti->store->header_items, l, header_list)
1426 Elm_Store_Item *temp_sti = eina_list_nth(header_list, 0);
1428 if (temp_sti->item_info->group_index > sti->item_info->group_index)
1430 sti->store->header_items = eina_list_prepend_relative(sti->store->header_items, new_header_list, header_list);
1431 sti->item = elm_genlist_item_insert_before(sti->store->genlist,
1436 ELM_GENLIST_ITEM_GROUP,
1437 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1438 (void *)sti->store->cb.item_select.data);
1439 elm_store_item_update(sti->store, sti);
1440 last_header = EINA_FALSE;
1446 sti->store->header_items = eina_list_append(sti->store->header_items, new_header_list);
1447 sti->item = elm_genlist_item_append(sti->store->genlist,
1451 ELM_GENLIST_ITEM_GROUP,
1452 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1453 (void *)sti->store->cb.item_select.data);
1454 elm_store_item_update(sti->store, sti);
1460 Eina_List *header_list = NULL;
1461 sti->item_info->index = 0;
1462 header_list = eina_list_append(header_list, sti);
1463 sti->store->header_items = eina_list_append(sti->store->header_items, header_list);
1464 sti->item = elm_genlist_item_append(sti->store->genlist,
1468 ELM_GENLIST_ITEM_GROUP,
1469 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1470 (void *)sti->store->cb.item_select.data);
1471 elm_store_item_update(sti->store, sti);
1476 _normal_item_append(Elm_Store_Item *sti, Elm_Genlist_Item_Class *itc)
1478 EINA_SAFETY_ON_NULL_RETURN(sti);
1479 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1480 Elm_Store *st = sti->store;
1482 if (sti->item_info->rec_item == EINA_TRUE)
1484 if (sti->item_info->group_index == sti->item_info->pre_group_index)
1486 elm_store_item_update(st, sti);
1491 Eina_List *header_list;
1493 EINA_LIST_FOREACH(st->header_items, l, header_list)
1495 Elm_Store_Item *header_item = eina_list_nth(header_list, 0);
1497 if (header_item->item_info->group_index == sti->item_info->pre_group_index)
1499 Elm_Store_Item *last_sti = eina_list_nth(header_list, eina_list_count(header_list) - 1);
1503 int index = elm_store_item_index_get(last_sti);
1504 _item_unfetch(st, index);
1506 Eina_List *temp_header_list = header_list;
1507 header_list = eina_list_remove(header_list, last_sti);
1508 if (eina_list_count(header_list) == 0)
1510 st->header_items = eina_list_remove(st->header_items, temp_header_list);
1511 eina_list_free(header_list);
1513 elm_genlist_item_del(last_sti->item);
1515 if (eina_list_count(header_list) == 1)
1517 Elm_Store_Item *temp_sti = eina_list_nth(header_list, 0);
1518 if (temp_sti->item_info->item_type == ELM_GENLIST_ITEM_GROUP)
1522 int index = elm_store_item_index_get(temp_sti);
1523 _item_unfetch(st, index);
1525 header_list = eina_list_remove(header_list, temp_sti);
1526 st->header_items = eina_list_remove(st->header_items, temp_header_list);
1527 eina_list_free(header_list);
1528 elm_genlist_item_del(temp_sti->item);
1532 else if (header_item->item_info->group_index == sti->item_info->group_index)
1534 sti->item_info->index = eina_list_count(header_list);
1535 Elm_Store_Item *last_sti = eina_list_nth(header_list, eina_list_count(header_list) - 1);
1536 header_list = eina_list_append(header_list, sti);
1537 sti->item = elm_genlist_item_insert_after(st->genlist,
1542 ELM_GENLIST_ITEM_NONE,
1543 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1544 (void *)sti->store->cb.item_select.data);
1545 elm_store_item_update(st, sti);
1552 if (st->header_items)
1554 Eina_Bool normal_add = EINA_TRUE;
1556 Eina_List *header_list;
1558 EINA_LIST_FOREACH(st->header_items, l, header_list)
1562 Elm_Store_Item *header_item = eina_list_nth(header_list, 0);
1564 if (header_item->item_info->group_index == sti->item_info->group_index)
1566 sti->item_info->index = eina_list_count(header_list);
1567 Elm_Store_Item *last_sti = eina_list_nth(header_list, eina_list_count(header_list) - 1);
1568 header_list = eina_list_append(header_list, sti);
1569 sti->item = elm_genlist_item_insert_after(st->genlist,
1574 ELM_GENLIST_ITEM_NONE,
1575 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1576 (void *)sti->store->cb.item_select.data);
1577 elm_store_item_update(st, sti);
1578 normal_add = EINA_FALSE;
1585 Eina_List *new_header_list = NULL;
1586 sti->item_info->index = 0;
1587 new_header_list = eina_list_append(new_header_list, sti);
1588 st->header_items = eina_list_append(st->header_items, new_header_list);
1589 sti->item = elm_genlist_item_append(st->genlist,
1593 ELM_GENLIST_ITEM_NONE,
1594 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1595 (void *)sti->store->cb.item_select.data);
1596 elm_store_item_update(st, sti);
1603 Eina_List *header_list = NULL;
1604 sti->item_info->index = 0;
1605 header_list = eina_list_append(header_list, sti);
1606 st->header_items = eina_list_append(st->header_items, header_list);
1607 sti->item = elm_genlist_item_append(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);
1614 elm_store_item_update(st, sti);
1621 _item_free(Elm_Store_Item *sti)
1623 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1624 elm_store_item_del(sti);
1628 _store_free(Elm_Store *st)
1630 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1635 * Add a new dbsystem Store object
1637 * @return The new object or NULL if it cannot be created
1642 elm_store_dbsystem_new(void)
1644 Elm_Store_DBsystem *std = _store_new(Elm_Store_DBsystem);
1645 EINA_SAFETY_ON_NULL_RETURN_VAL(std, NULL);
1647 EINA_MAGIC_SET(std, ELM_STORE_DBSYSTEM_MAGIC);
1648 std->base.free = _store_free;
1649 std->base.item.free = _item_free;
1654 * Sets the item count of a store
1656 * @param st The store object
1657 * @param count The item count of an store
1662 elm_store_item_count_set(Elm_Store *st, int count)
1664 EINA_SAFETY_ON_NULL_RETURN(st);
1665 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1667 st->item_count = count;
1670 st->multi_load = EINA_TRUE;
1674 st->multi_load = EINA_FALSE;
1679 * Get the item index that included header items
1681 * @param sti The store item object
1682 * @return The item index in genlist
1687 elm_store_item_index_get(const Elm_Store_Item *sti)
1689 EINA_SAFETY_ON_NULL_RETURN_VAL(sti, -1);
1690 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return -1;
1692 if (sti->store->live)
1696 Eina_List *header_list;
1698 EINA_LIST_FOREACH(sti->store->header_items, l, header_list)
1702 Elm_Store_Item *temp_sti = eina_list_nth(header_list, 0);
1703 if (sti->item_info->group_index == temp_sti->item_info->group_index)
1705 index = index + sti->item_info->index;
1710 index = index + eina_list_count(header_list);
1723 * Sets the select func that select the state of a list item whether true or false
1725 * @param st The store object
1726 * @param func The select cb function of an store
1727 * @param data The new data pointer to set
1732 elm_store_item_select_func_set(Elm_Store *st, Elm_Store_Item_Select_Cb func, const void *data)
1734 EINA_SAFETY_ON_NULL_RETURN(st);
1735 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 EINA_SAFETY_ON_NULL_RETURN(st);
1754 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1756 st->cb.item_sort.func = func;
1757 st->cb.item_sort.data = (void *)data;
1761 * Get the item index of real data that don't included header items
1763 * @param sti The store item object
1764 * @return The real item index
1769 elm_store_item_data_index_get(const Elm_Store_Item *sti)
1771 EINA_SAFETY_ON_NULL_RETURN_VAL(sti, -1);
1772 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return -1;
1774 if (sti->store->live)
1776 if (sti->item_info->item_type == ELM_GENLIST_ITEM_NONE)
1779 int header_count = 0;
1781 Eina_List *header_list;
1783 EINA_LIST_FOREACH(sti->store->header_items, l, header_list)
1788 Elm_Store_Item *temp_sti = eina_list_nth(header_list, 0);
1790 if (temp_sti->item_info->item_type == ELM_GENLIST_ITEM_GROUP)
1795 if (sti->item_info->group_index == temp_sti->item_info->group_index)
1797 index = index + sti->item_info->index - header_count;
1802 index = index + eina_list_count(header_list);
1820 * Get the DB pointer of an item
1822 * @param sti The store item object
1823 * @return The DB pointer of item
1828 elm_store_dbsystem_db_get(const Elm_Store_Item *sti)
1830 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
1832 const Elm_Store_DBsystem *std = (const Elm_Store_DBsystem *)sti->store;
1833 if (!EINA_MAGIC_CHECK(sti->store, ELM_STORE_MAGIC)) return NULL;
1834 if (!EINA_MAGIC_CHECK(std, ELM_STORE_DBSYSTEM_MAGIC)) return NULL;
1839 * Set the DB pointer of an item
1841 * @param sti The store item object
1842 * @parm p_db The DB pointer of item
1847 elm_store_dbsystem_db_set(Elm_Store *store, void *p_db)
1849 Elm_Store_DBsystem *std = (Elm_Store_DBsystem *)store;
1850 if (!EINA_MAGIC_CHECK(store, ELM_STORE_MAGIC)) return;
1851 if (!EINA_MAGIC_CHECK(std, ELM_STORE_DBSYSTEM_MAGIC)) return;
1857 ecore_thread_cancel(store->list_th);
1858 store->list_th = NULL;
1860 store->list_th = ecore_thread_feedback_run(_list_do, _list_update, _list_end, _list_cancel, store, EINA_TRUE);
1864 * Append the item to the genlist
1866 * @param st The store object
1867 * @param info The store item info dbsystem object
1868 * @return The item of store
1872 EAPI Elm_Store_Item *
1873 elm_store_item_add(Elm_Store *st, Elm_Store_Item_Info *info)
1875 EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
1876 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return NULL;
1877 EINA_SAFETY_ON_NULL_RETURN_VAL(info, NULL);
1878 Elm_Store_Item *sti;
1879 Elm_Genlist_Item_Class *itc;
1881 sti = calloc(1, sizeof(Elm_Store_Item));
1882 if (!sti) return NULL;
1883 if (st->fetch_thread)
1887 EINA_MAGIC_SET(sti, ELM_STORE_ITEM_MAGIC);
1892 sti->item_info = info;
1894 itc = info->item_class;
1895 if (!itc) itc = &_store_item_class;
1898 itc->func.label_get = (GenlistItemLabelGetFunc)_item_label_get;
1899 itc->func.icon_get = (GenlistItemIconGetFunc)_item_icon_get;
1900 itc->func.state_get = NULL;
1901 itc->func.del = NULL;
1906 if (sti->item_info->item_type == ELM_GENLIST_ITEM_GROUP)
1908 _group_item_append(sti, itc);
1912 _normal_item_append(sti, itc);
1923 * Realize the visible items to the screen
1925 * @param st The store object
1930 elm_store_visible_items_update(Elm_Store *st)
1932 EINA_SAFETY_ON_NULL_RETURN(st);
1933 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1936 for (loop = st->current_top_index; loop < (st->current_top_index + st->block_count); loop++)
1938 Elm_Store_Item *temp_sti = _item_get(st, loop);
1941 if (temp_sti->fetched)
1943 _item_unfetch(st, loop);
1945 _item_fetch(st, loop);
1946 if (temp_sti->data) elm_genlist_item_update(temp_sti->item);
1948 if (!st->fetch_thread)
1950 if (temp_sti->data) elm_genlist_item_update(temp_sti->item);
1961 * Realize the item to the screen
1963 * @param st The store object
1964 * @param sti The store item object
1969 elm_store_item_update(Elm_Store *st, Elm_Store_Item *sti)
1971 EINA_SAFETY_ON_NULL_RETURN(st);
1972 EINA_SAFETY_ON_NULL_RETURN(sti);
1973 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1974 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1976 int index = elm_store_item_index_get(sti);
1978 if ((st->start_fetch_index <= index) && (index <= st->end_fetch_index))
1982 _item_unfetch(st, index);
1984 _item_fetch(st, index);
1985 if (sti->data) elm_genlist_item_update(sti->item);
1990 * Delete the item of genlist
1992 * @param sti The store item object
1997 elm_store_item_del(Elm_Store_Item *sti)
1999 EINA_SAFETY_ON_NULL_RETURN(sti);
2000 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
2002 sti->store->total_count--;
2005 Eina_List *header_list;
2007 EINA_LIST_FOREACH(sti->store->header_items, l, header_list)
2011 Elm_Store_Item *item = eina_list_nth(header_list, 0);
2013 if (item->item_info->group_index == sti->item_info->group_index)
2016 Elm_Store_Item *temp_sti;
2017 EINA_LIST_FOREACH(header_list, in_l, temp_sti)
2019 if (temp_sti->item_info->index == sti->item_info->index)
2023 int index = elm_store_item_index_get(temp_sti);
2024 _item_unfetch(sti->store, index);
2026 Eina_List *temp_header_list = header_list;
2027 header_list = eina_list_remove(header_list, temp_sti);
2028 if (eina_list_count(header_list) == 0)
2030 sti->store->header_items = eina_list_remove(sti->store->header_items, temp_header_list);
2031 eina_list_free(header_list);
2034 elm_genlist_item_del(temp_sti->item);
2043 // TODO: END -DBsystem store