1 #include <Elementary.h>
2 #include <Elementary_Cursor.h>
5 #define ELM_STORE_MAGIC 0x3f89ea56
6 #define ELM_STORE_FILESYSTEM_MAGIC 0x3f89ea57
7 #define ELM_STORE_DBSYSTEM_MAGIC 0x3f89ea58
8 #define ELM_STORE_ITEM_MAGIC 0x5afe8c1d
9 #define CACHE_COUNT 1024
14 void (*free)(Elm_Store *store);
16 void (*free)(Elm_Store_Item *item);
19 Ecore_Thread *list_th;
26 Eina_List *always_fetched;
29 Elm_Store_Item_List_Cb func;
33 Elm_Store_Item_Fetch_Cb func;
37 Elm_Store_Item_Unfetch_Cb func;
41 Elm_Store_Item_Select_Cb func;
45 Elm_Store_Item_Sort_Cb func;
49 Elm_Store_Item_Free_Cb func;
54 Eina_Bool fetch_thread : 1;
58 struct _Elm_Store_Item
63 Elm_Object_Item *item;
64 Ecore_Thread *fetch_th;
66 const Elm_Store_Item_Mapping *mapping;
68 Elm_Store_Item_Info *item_info;
69 Elm_Object_Item *first_item;
70 Elm_Object_Item *last_item;
73 Eina_Bool was_live : 1;
74 Eina_Bool realized : 1;
75 Eina_Bool fetched : 1;
78 struct _Elm_Store_Filesystem
85 struct _Elm_Store_Item_Filesystem
91 struct _Elm_Store_DBsystem
100 ELM_STORE_ITEM_SORT_LOW = -1,
101 ELM_STORE_ITEM_SORT_SAME = 0,
102 ELM_STORE_ITEM_SORT_HIGH = 1,
103 ELM_STORE_ITEM_SORT_UNKNOWN = 2,
104 ELM_STORE_ITEM_SORT_LAST
105 } Elm_Store_Item_Sort_Type;
107 static Elm_Genlist_Item_Class _store_item_class;
109 static void _item_del(void *data, Evas_Object *obj __UNUSED__);
110 static void _item_realized(void *data, Evas_Object *obj __UNUSED__, void *event_info);
111 static void _item_unrealized(void *data, Evas_Object *obj __UNUSED__, void *event_info);
112 static void _genlist_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__);
115 _store_cache_trim(Elm_Store *st)
117 while ((st->realized ) &&
118 (((int)eina_list_count(st->realized) - st->realized_count)
121 Elm_Store_Item *sti = st->realized->data;
124 st->realized = eina_list_remove_list(st->realized, st->realized);
125 sti->realized = EINA_FALSE;
127 eina_lock_take(&sti->lock);
130 eina_lock_release(&sti->lock);
133 ecore_thread_cancel(sti->fetch_th);
134 sti->fetch_th = NULL;
136 eina_lock_take(&sti->lock);
138 sti->fetched = EINA_FALSE;
139 eina_lock_release(&sti->lock);
140 if (st->cb.unfetch.func)
141 st->cb.unfetch.func(st->cb.unfetch.data, sti, NULL);
142 eina_lock_take(&sti->lock);
144 eina_lock_release(&sti->lock);
149 _store_genlist_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
151 Elm_Store *st = data;
155 ecore_thread_cancel(st->list_th);
158 eina_list_free(st->realized);
161 Elm_Store_Item *sti = (Elm_Store_Item *)st->items;
162 if (sti->eval_job) ecore_job_del(sti->eval_job);
165 ecore_thread_cancel(sti->fetch_th);
166 sti->fetch_th = NULL;
168 if (sti->store->item.free) sti->store->item.free(sti);
171 if (st->cb.unfetch.func)
172 st->cb.unfetch.func(st->cb.unfetch.data, sti, NULL);
175 eina_lock_free(&sti->lock);
179 // FIXME: kill threads and more
182 ////// **** WARNING ***********************************************************
183 //// * This function runs inside a thread outside efl mainloop. Be careful! *
184 // ************************************************************************
185 /* TODO: refactor lock part into core? this does not depend on filesystm part */
187 _store_filesystem_fetch_do(void *data, Ecore_Thread *th __UNUSED__)
189 Elm_Store_Item *sti = data;
190 eina_lock_take(&sti->lock);
193 eina_lock_release(&sti->lock);
198 eina_lock_release(&sti->lock);
199 if (sti->store->cb.fetch.func)
200 sti->store->cb.fetch.func(sti->store->cb.fetch.data, sti, NULL);
201 eina_lock_take(&sti->lock);
202 sti->fetched = EINA_TRUE;
204 eina_lock_release(&sti->lock);
206 // ************************************************************************
207 //// * End of separate thread function. *
208 ////// ************************************************************************
209 /* TODO: refactor lock part into core? this does not depend on filesystm part */
211 _store_filesystem_fetch_end(void *data, Ecore_Thread *th)
213 Elm_Store_Item *sti = data;
214 eina_lock_take(&sti->lock);
215 if (sti->data) elm_genlist_item_update((Elm_Object_Item *) sti->item);
216 eina_lock_release(&sti->lock);
217 if (th == sti->fetch_th) sti->fetch_th = NULL;
220 /* TODO: refactor lock part into core? this does not depend on filesystm part */
222 _store_filesystem_fetch_cancel(void *data, Ecore_Thread *th)
224 Elm_Store_Item *sti = data;
225 eina_lock_take(&sti->lock);
226 if (th == sti->fetch_th) sti->fetch_th = NULL;
227 if (sti->data) elm_genlist_item_update((Elm_Object_Item *) sti->item);
228 eina_lock_release(&sti->lock);
232 _store_item_eval(void *data)
234 Elm_Store_Item *sti = data;
235 sti->eval_job = NULL;
236 if (sti->live == sti->was_live) return;
237 sti->was_live = sti->live;
240 _store_cache_trim(sti->store);
242 sti->store->realized = eina_list_remove(sti->store->realized, sti);
243 sti->store->realized = eina_list_append(sti->store->realized, sti);
244 sti->realized = EINA_TRUE;
245 if ((sti->store->fetch_thread) && (!sti->fetch_th))
246 sti->fetch_th = ecore_thread_run(_store_filesystem_fetch_do,
247 _store_filesystem_fetch_end,
248 _store_filesystem_fetch_cancel,
250 else if ((!sti->store->fetch_thread))
252 _store_filesystem_fetch_do(sti, NULL);
253 _store_filesystem_fetch_end(sti, NULL);
260 ecore_thread_cancel(sti->fetch_th);
261 sti->fetch_th = NULL;
263 _store_cache_trim(sti->store);
268 _store_genlist_item_realized(void *data, Evas_Object *obj __UNUSED__, void *event_info)
270 Elm_Store *st = data;
271 Elm_Object_Item *gli = event_info;
272 Elm_Store_Item *sti = (Elm_Store_Item *) elm_genlist_item_data_get(gli);
274 st->realized_count++;
275 sti->live = EINA_TRUE;
276 if (sti->eval_job) ecore_job_del(sti->eval_job);
277 sti->eval_job = ecore_job_add(_store_item_eval, sti);
281 _store_genlist_item_unrealized(void *data, Evas_Object *obj __UNUSED__, void *event_info)
283 Elm_Store *st = data;
284 Elm_Object_Item *gli = event_info;
285 Elm_Store_Item *sti = (Elm_Store_Item *) elm_genlist_item_data_get(gli);
287 st->realized_count--;
288 sti->live = EINA_FALSE;
289 if (sti->eval_job) ecore_job_del(sti->eval_job);
290 sti->eval_job = ecore_job_add(_store_item_eval, sti);
293 static const Elm_Store_Item_Mapping *
294 _store_item_mapping_find(Elm_Store_Item *sti, const char *part)
296 const Elm_Store_Item_Mapping *m;
298 for (m = sti->mapping; m; m ++)
300 if (m->type == ELM_STORE_ITEM_MAPPING_NONE) break;
301 if (!strcmp(part, m->part)) return m;
307 _store_item_text_get(void *data, Evas_Object *obj __UNUSED__, const char *part)
309 Elm_Store_Item *sti = data;
311 eina_lock_take(&sti->lock);
314 const Elm_Store_Item_Mapping *m = _store_item_mapping_find(sti, part);
319 case ELM_STORE_ITEM_MAPPING_LABEL:
320 s = *(char **)(((unsigned char *)sti->data) + m->offset);
322 case ELM_STORE_ITEM_MAPPING_CUSTOM:
323 if (m->details.custom.func)
324 s = m->details.custom.func(sti->data, sti, part);
331 eina_lock_release(&sti->lock);
332 return s ? strdup(s) : NULL;
336 _store_item_content_get(void *data, Evas_Object *obj, const char *part)
338 Elm_Store_Item *sti = data;
339 eina_lock_take(&sti->lock);
342 const Elm_Store_Item_Mapping *m = _store_item_mapping_find(sti, part);
345 Evas_Object *ic = NULL;
346 const char *s = NULL;
350 case ELM_STORE_ITEM_MAPPING_ICON:
351 ic = elm_icon_add(obj);
352 s = *(char **)(((unsigned char *)sti->data) + m->offset);
353 elm_icon_order_lookup_set(ic, m->details.icon.lookup_order);
354 evas_object_size_hint_aspect_set(ic,
355 EVAS_ASPECT_CONTROL_VERTICAL,
358 elm_icon_smooth_set(ic, m->details.icon.smooth);
359 elm_icon_no_scale_set(ic, m->details.icon.no_scale);
360 elm_icon_scale_set(ic,
361 m->details.icon.scale_up,
362 m->details.icon.scale_down);
365 if (m->details.icon.standard_name)
366 elm_icon_standard_set(ic, s);
368 elm_icon_file_set(ic, s, NULL);
371 case ELM_STORE_ITEM_MAPPING_PHOTO:
372 ic = elm_icon_add(obj);
373 s = *(char **)(((unsigned char *)sti->data) + m->offset);
374 elm_photo_size_set(ic, m->details.photo.size);
376 elm_photo_file_set(ic, s);
378 case ELM_STORE_ITEM_MAPPING_CUSTOM:
379 if (m->details.custom.func)
380 ic = m->details.custom.func(sti->data, sti, part);
385 eina_lock_release(&sti->lock);
389 eina_lock_release(&sti->lock);
394 _store_item_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__)
398 ////// **** WARNING ***********************************************************
399 //// * This function runs inside a thread outside efl mainloop. Be careful! *
400 // ************************************************************************
402 _store_filesystem_sort_cb(void *d1, void *d2)
404 Elm_Store_Item_Info *info1 = d1, *info2 = d2;
405 if ((!info1->sort_id) || (!info2->sort_id)) return 0;
406 return strcoll(info1->sort_id, info2->sort_id);
410 _store_filesystem_list_do(void *data, Ecore_Thread *th __UNUSED__)
412 Elm_Store_Filesystem *st = data;
414 const Eina_File_Direct_Info *finf;
415 Eina_List *sorted = NULL;
416 Elm_Store_Item_Info_Filesystem *info;
418 // FIXME: need a way to abstract the open, list, feed items from list
419 // and maybe get initial sortable key vals etc.
420 it = eina_file_stat_ls(st->dir);
422 EINA_ITERATOR_FOREACH(it, finf)
425 size_t pathsz = finf->path_length + 1;
427 if (finf->path[finf->name_start] == '.') continue ;
429 info = calloc(1, sizeof(Elm_Store_Item_Info_Filesystem) + pathsz);
431 info->path = ((char *)info) + sizeof(Elm_Store_Item_Info_Filesystem);
432 memcpy(info->path, finf->path, pathsz);
434 if (st->base.cb.list.func)
435 ok = st->base.cb.list.func(st->base.cb.list.data, &info->base);
438 if (!st->base.sorted) ecore_thread_feedback(th, info);
439 else sorted = eina_list_append(sorted, info);
443 if (info->base.sort_id) free(info->base.sort_id);
446 if (ecore_thread_check(th)) break;
448 eina_iterator_free(it);
451 sorted = eina_list_sort(sorted, 0,
452 EINA_COMPARE_CB(_store_filesystem_sort_cb));
453 EINA_LIST_FREE(sorted, info)
455 if (!ecore_thread_check(th)) ecore_thread_feedback(th, info);
459 // ************************************************************************
460 //// * End of separate thread function. *
461 ////// ************************************************************************
464 _store_filesystem_list_end(void *data, Ecore_Thread *th)
466 Elm_Store *st = data;
467 if (th == st->list_th) st->list_th = NULL;
471 _store_filesystem_list_cancel(void *data, Ecore_Thread *th)
473 Elm_Store *st = data;
474 if (th == st->list_th) st->list_th = NULL;
478 _store_filesystem_list_update(void *data, Ecore_Thread *th __UNUSED__, void *msg)
480 Elm_Store *st = data;
481 Elm_Store_Item_Filesystem *sti;
482 Elm_Genlist_Item_Class *itc;
483 Elm_Store_Item_Info_Filesystem *info = msg;
485 sti = calloc(1, sizeof(Elm_Store_Item_Filesystem));
487 eina_lock_new(&sti->base.lock);
488 EINA_MAGIC_SET(&(sti->base), ELM_STORE_ITEM_MAGIC);
489 sti->base.store = st;
490 sti->base.data = info->base.data;
491 sti->base.mapping = info->base.mapping;
492 sti->path = eina_stringshare_add(info->path);
494 itc = info->base.item_class;
495 if (!itc) itc = &_store_item_class;
498 itc->func.text_get = (GenlistItemTextGetFunc)_store_item_text_get;
499 itc->func.content_get = (GenlistItemContentGetFunc)_store_item_content_get;
500 itc->func.state_get = NULL; // FIXME: support state gets later
501 itc->func.del = (GenlistItemDelFunc)_store_item_del;
504 // FIXME: handle being a parent (tree)
505 sti->base.item = elm_genlist_item_append(st->genlist, itc,
508 ELM_GENLIST_ITEM_NONE,
510 NULL/* func data */);
511 st->items = eina_inlist_append(st->items, (Eina_Inlist *)sti);
513 if (info->base.sort_id) free(info->base.sort_id);
519 _elm_store_new(size_t size)
521 Elm_Store *st = calloc(1, size);
522 EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
524 // TODO: BEGIN - move to elm_store_init()
525 eina_magic_string_set(ELM_STORE_MAGIC, "Elm_Store");
526 eina_magic_string_set(ELM_STORE_FILESYSTEM_MAGIC, "Elm_Store_Filesystem");
527 eina_magic_string_set(ELM_STORE_ITEM_MAGIC, "Elm_Store_Item");
528 // setup default item class (always the same) if list cb doesnt provide one
529 _store_item_class.item_style = "default";
530 _store_item_class.func.text_get = (GenlistItemTextGetFunc)_store_item_text_get;
531 _store_item_class.func.content_get = (GenlistItemContentGetFunc)_store_item_content_get;
532 _store_item_class.func.state_get = NULL; // FIXME: support state gets later
533 _store_item_class.func.del = (GenlistItemDelFunc)_store_item_del;
534 // TODO: END - move to elm_store_init()
536 EINA_MAGIC_SET(st, ELM_STORE_MAGIC);
538 st->fetch_thread = EINA_TRUE;
542 #define elm_store_new(type) (type*)_elm_store_new(sizeof(type))
545 _elm_store_filesystem_free(Elm_Store *store)
547 Elm_Store_Filesystem *st = (Elm_Store_Filesystem *)store;
548 eina_stringshare_del(st->dir);
552 _elm_store_filesystem_item_free(Elm_Store_Item *item)
554 Elm_Store_Item_Filesystem *sti = (Elm_Store_Item_Filesystem *)item;
555 eina_stringshare_del(sti->path);
559 elm_store_filesystem_new(void)
561 Elm_Store_Filesystem *st = elm_store_new(Elm_Store_Filesystem);
562 EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
564 EINA_MAGIC_SET(st, ELM_STORE_FILESYSTEM_MAGIC);
565 st->base.free = _elm_store_filesystem_free;
566 st->base.item.free = _elm_store_filesystem_item_free;
572 elm_store_free(Elm_Store *st)
574 void (*item_free)(Elm_Store_Item *);
575 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
578 ecore_thread_cancel(st->list_th);
584 eina_list_free(st->realized);
585 item_free = st->item.free;
588 Elm_Store_Item *sti = (Elm_Store_Item *)st->items;
589 if (sti->eval_job) ecore_job_del(sti->eval_job);
592 ecore_thread_cancel(sti->fetch_th);
593 sti->fetch_th = NULL;
595 if (item_free) item_free(sti);
598 if (st->cb.unfetch.func)
599 st->cb.unfetch.func(st->cb.unfetch.data, sti, NULL);
602 eina_lock_free(&sti->lock);
607 evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _store_genlist_del, st);
608 evas_object_smart_callback_del(st->genlist, "realized", _store_genlist_item_realized);
609 evas_object_smart_callback_del(st->genlist, "unrealized", _store_genlist_item_unrealized);
610 elm_genlist_clear(st->genlist);
613 if (st->free) st->free(st);
619 evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _genlist_del, st);
620 evas_object_smart_callback_del(st->genlist, "realized", _item_realized);
621 evas_object_smart_callback_del(st->genlist, "unrealized", _item_unrealized);
622 elm_genlist_clear(st->genlist);
625 while (st->always_fetched)
627 Elm_Store_Item *sti = eina_list_data_get(st->always_fetched);
628 Eina_List *find = NULL;
629 find = eina_list_data_find_list(st->always_fetched, sti);
632 st->always_fetched = eina_list_remove_list(st->always_fetched, find);
636 st->always_fetched = eina_list_free(st->always_fetched);
637 st->realized = eina_list_free(st->realized);
638 if (st->free) st->free(st);
639 st->live = EINA_FALSE;
645 elm_store_target_genlist_set(Elm_Store *st, Evas_Object *obj)
647 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
648 if (st->genlist == obj) return;
653 evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _store_genlist_del, st);
654 evas_object_smart_callback_del(st->genlist, "realized", _store_genlist_item_realized);
655 evas_object_smart_callback_del(st->genlist, "unrealized", _store_genlist_item_unrealized);
659 evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _genlist_del, st);
660 evas_object_smart_callback_del(st->genlist, "realized", _item_realized);
661 evas_object_smart_callback_del(st->genlist, "unrealized", _item_unrealized);
663 elm_genlist_clear(st->genlist);
666 if (!st->genlist) return;
669 evas_object_smart_callback_add(st->genlist, "realized", _store_genlist_item_realized, st);
670 evas_object_smart_callback_add(st->genlist, "unrealized", _store_genlist_item_unrealized, st);
671 evas_object_event_callback_add(st->genlist, EVAS_CALLBACK_DEL, _store_genlist_del, st);
675 evas_object_smart_callback_add(st->genlist, "realized", _item_realized, st);
676 evas_object_smart_callback_add(st->genlist, "unrealized", _item_unrealized, st);
677 evas_object_event_callback_add(st->genlist, EVAS_CALLBACK_DEL, _genlist_del, st);
679 elm_genlist_clear(st->genlist);
683 elm_store_filesystem_directory_set(Elm_Store *store, const char *dir)
685 Elm_Store_Filesystem *st = (Elm_Store_Filesystem *)store;
686 if (!EINA_MAGIC_CHECK(store, ELM_STORE_MAGIC)) return;
687 if (!EINA_MAGIC_CHECK(st, ELM_STORE_FILESYSTEM_MAGIC)) return;
690 ecore_thread_cancel(store->list_th);
691 store->list_th = NULL;
693 if (!eina_stringshare_replace(&st->dir, dir)) return;
694 store->list_th = ecore_thread_feedback_run(_store_filesystem_list_do,
695 _store_filesystem_list_update,
696 _store_filesystem_list_end,
697 _store_filesystem_list_cancel,
702 elm_store_filesystem_directory_get(const Elm_Store *store)
704 const Elm_Store_Filesystem *st = (const Elm_Store_Filesystem *)store;
705 if (!EINA_MAGIC_CHECK(store, ELM_STORE_MAGIC)) return NULL;
706 if (!EINA_MAGIC_CHECK(st, ELM_STORE_FILESYSTEM_MAGIC)) return NULL;
711 elm_store_cache_set(Elm_Store *st, int max)
713 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
714 if (max < 0) max = 0;
716 if(!st->type) _store_cache_trim(st);
720 elm_store_cache_get(const Elm_Store *st)
722 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return 0;
723 return st->cache_max;
727 elm_store_list_func_set(Elm_Store *st, Elm_Store_Item_List_Cb func, const void *data)
729 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
730 st->cb.list.func = func;
731 st->cb.list.data = (void *)data;
735 elm_store_fetch_func_set(Elm_Store *st, Elm_Store_Item_Fetch_Cb func, const void *data)
737 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
738 st->cb.fetch.func = func;
739 st->cb.fetch.data = (void *)data;
743 elm_store_fetch_thread_set(Elm_Store *st, Eina_Bool use_thread)
745 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
746 st->fetch_thread = !!use_thread;
750 elm_store_fetch_thread_get(const Elm_Store *st)
752 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return EINA_FALSE;
753 return st->fetch_thread;
757 elm_store_unfetch_func_set(Elm_Store *st, Elm_Store_Item_Unfetch_Cb func, const void *data)
759 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
760 st->cb.unfetch.func = func;
761 st->cb.unfetch.data = (void *)data;
765 elm_store_sorted_set(Elm_Store *st, Eina_Bool sorted)
767 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
772 elm_store_sorted_get(const Elm_Store *st)
774 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return EINA_FALSE;
779 elm_store_item_data_set(Elm_Store_Item *sti, void *data)
781 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
782 eina_lock_take(&sti->lock);
784 eina_lock_release(&sti->lock);
788 elm_store_item_data_get(Elm_Store_Item *sti)
790 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
792 eina_lock_take(&sti->lock);
794 eina_lock_release(&sti->lock);
798 EAPI const Elm_Store *
799 elm_store_item_store_get(const Elm_Store_Item *sti)
801 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
806 EAPI const Elm_Object_Item *
807 elm_store_item_genlist_item_get(const Elm_Store_Item *sti)
809 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
815 elm_store_item_filesystem_path_get(const Elm_Store_Item *item)
817 Elm_Store_Item_Filesystem *sti = (Elm_Store_Item_Filesystem *)item;
818 Elm_Store_Filesystem *st;
819 if (!EINA_MAGIC_CHECK(item, ELM_STORE_ITEM_MAGIC)) return NULL;
820 if (!EINA_MAGIC_CHECK(item->store, ELM_STORE_MAGIC)) return NULL;
821 /* ensure we're dealing with filesystem item */
822 st = (Elm_Store_Filesystem *)item->store;
823 if (!EINA_MAGIC_CHECK(st, ELM_STORE_FILESYSTEM_MAGIC)) return NULL;
828 // TODO: BEGIN -DBsystem store
830 static const Elm_Store_Item_Mapping *
831 _item_mapping_find(Elm_Store_Item *sti, const char *part)
833 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
834 const Elm_Store_Item_Mapping *m;
836 if (!sti->item_info) return NULL;
838 for (m = sti->item_info->mapping; m; m++)
840 if (m->type == ELM_STORE_ITEM_MAPPING_NONE) break;
841 if (!strcmp(part, m->part)) return m;
847 _item_text_get(void *data, Evas_Object *obj __UNUSED__, const char *part)
849 Elm_Store_Item *sti = data;
850 Elm_Store *st = sti->store;
853 eina_lock_take(&sti->lock);
857 const Elm_Store_Item_Mapping *m = _item_mapping_find(sti, part);
862 case ELM_STORE_ITEM_MAPPING_LABEL:
863 eina_lock_release(&sti->lock);
864 s = *(char **)(((unsigned char *)sti->data) + m->offset);
865 eina_lock_take(&sti->lock);
868 case ELM_STORE_ITEM_MAPPING_CUSTOM:
869 if (m->details.custom.func)
871 eina_lock_release(&sti->lock);
872 s = m->details.custom.func(sti->data, sti, part);
873 eina_lock_take(&sti->lock);
882 eina_lock_release(&sti->lock);
887 eina_lock_release(&sti->lock);
895 const Elm_Store_Item_Mapping *m = _item_mapping_find(sti, part);
896 if (m->type == ELM_STORE_ITEM_MAPPING_CUSTOM)
898 if (m->details.custom.func)
900 eina_lock_release(&sti->lock);
901 s = m->details.custom.func(sti->item_info, sti, part);
902 eina_lock_take(&sti->lock);
907 eina_lock_release(&sti->lock);
912 eina_lock_release(&sti->lock);
916 eina_lock_release(&sti->lock);
919 if (!strcmp(part, "elm.text.1"))
921 eina_lock_release(&sti->lock);
922 // elm_genlist_item_display_only_set(sti->item, EINA_TRUE);
923 return strdup("Loading..");
927 eina_lock_release(&sti->lock);
933 _item_content_get(void *data, Evas_Object *obj, const char *part)
935 Elm_Store_Item *sti = data;
936 Elm_Store *st = sti->store;
938 if (st->live && sti->item)
940 eina_lock_take(&sti->lock);
943 const Elm_Store_Item_Mapping *m = _item_mapping_find(sti, part);
946 Evas_Object *ic = NULL;
947 const char *s = NULL;
951 case ELM_STORE_ITEM_MAPPING_ICON:
952 ic = elm_icon_add(obj);
953 s = *(char **)(((unsigned char *)sti->data) + m->offset);
954 elm_icon_order_lookup_set(ic, m->details.icon.lookup_order);
955 evas_object_size_hint_aspect_set(ic,
956 EVAS_ASPECT_CONTROL_VERTICAL,
959 elm_icon_smooth_set(ic, m->details.icon.smooth);
960 elm_icon_no_scale_set(ic, m->details.icon.no_scale);
961 elm_icon_scale_set(ic,
962 m->details.icon.scale_up,
963 m->details.icon.scale_down);
967 if (m->details.icon.standard_name)
968 elm_icon_standard_set(ic, s);
970 elm_icon_file_set(ic, s, NULL);
974 case ELM_STORE_ITEM_MAPPING_PHOTO:
975 ic = elm_icon_add(obj);
976 s = *(char **)(((unsigned char *)sti->data) + m->offset);
977 elm_photo_size_set(ic, m->details.photo.size);
979 elm_photo_file_set(ic, s);
982 case ELM_STORE_ITEM_MAPPING_CUSTOM:
983 if (m->details.custom.func)
984 ic = m->details.custom.func(sti->data, sti, part);
990 eina_lock_release(&sti->lock);
994 eina_lock_release(&sti->lock);
1000 _store_init(size_t size)
1002 Elm_Store *st = calloc(1, size);
1003 EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
1005 eina_magic_string_set(ELM_STORE_MAGIC, "Elm_Store");
1006 eina_magic_string_set(ELM_STORE_ITEM_MAGIC, "Elm_Store_Item");
1007 eina_magic_string_set(ELM_STORE_DBSYSTEM_MAGIC, "Elm_Store_DBsystem");
1009 _store_item_class.item_style = "default";
1010 _store_item_class.func.text_get = (GenlistItemTextGetFunc)_item_text_get;
1011 _store_item_class.func.content_get = (GenlistItemContentGetFunc)_item_content_get;
1012 _store_item_class.func.state_get = NULL;
1013 _store_item_class.func.del = NULL;
1015 EINA_MAGIC_SET(st, ELM_STORE_MAGIC);
1016 st->cache_max = CACHE_COUNT;
1017 st->live = EINA_TRUE;
1018 st->fetch_thread = EINA_FALSE;
1023 #define _store_new(type) (type *)_store_init(sizeof(type))
1026 _genlist_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1028 Elm_Store *st = data;
1029 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1034 ecore_thread_cancel(st->list_th);
1037 st->realized = eina_list_free(st->realized);
1041 _store_fetch_do(void *data, Ecore_Thread *th __UNUSED__)
1043 Elm_Store_Item *sti = data;
1045 eina_lock_take(&sti->lock);
1048 eina_lock_release(&sti->lock);
1053 if (sti->item_info != NULL)
1055 eina_lock_release(&sti->lock);
1056 if (sti->store->cb.fetch.func)
1057 sti->store->cb.fetch.func(sti->store->cb.fetch.data, sti, sti->item_info);
1058 eina_lock_take(&sti->lock);
1059 sti->fetched = EINA_TRUE;
1062 eina_lock_release(&sti->lock);
1066 _store_fetch_end(void *data, Ecore_Thread *th)
1068 Elm_Store_Item *sti = data;
1069 eina_lock_take(&sti->lock);
1070 if (sti->data) elm_genlist_item_update((Elm_Object_Item *) sti->item);
1071 eina_lock_release(&sti->lock);
1072 if (th == sti->fetch_th) sti->fetch_th = NULL;
1076 _store_fetch_cancel(void *data, Ecore_Thread *th)
1078 Elm_Store_Item *sti = data;
1079 eina_lock_take(&sti->lock);
1080 if (th == sti->fetch_th) sti->fetch_th = NULL;
1081 // if(sti->data) elm_genlist_item_update(sti->item);
1082 eina_lock_release(&sti->lock);
1086 _item_eval(void *data)
1088 Elm_Store_Item *sti = data;
1090 Elm_Store *st = sti->store;
1092 if (sti->fetched == EINA_FALSE)
1094 if (st->fetch_thread && !sti->fetch_th)
1096 sti->fetch_th = ecore_thread_run(_store_fetch_do, _store_fetch_end, _store_fetch_cancel, sti);
1098 else if (!st->fetch_thread)
1100 _store_fetch_do(sti,NULL);
1101 _store_fetch_end(sti,NULL);
1106 eina_lock_take(&sti->lock);
1109 eina_lock_release(&sti->lock);
1112 ecore_thread_cancel(sti->fetch_th);
1113 sti->fetch_th = NULL;
1115 eina_lock_take(&sti->lock);
1117 sti->fetched = EINA_FALSE;
1118 eina_lock_release(&sti->lock);
1119 if (st->cb.unfetch.func)
1120 st->cb.unfetch.func(st->cb.unfetch.data, sti, sti->item_info);
1121 eina_lock_take(&sti->lock);
1123 eina_lock_release(&sti->lock);
1128 _item_realize(void *data)
1130 Elm_Store_Item *sti = data;
1131 Elm_Store *st = sti->store;
1132 sti->eval_job = NULL;
1135 Eina_List *find = NULL;
1136 find = eina_list_data_find_list(st->always_fetched, sti);
1139 find = eina_list_data_find_list(st->realized,sti);
1142 Elm_Store_Item *realized_sti = NULL;
1143 realized_sti = eina_list_data_get(find);
1144 st->realized = eina_list_remove_list(st->realized, find);
1145 _item_eval(realized_sti);
1149 if ((int)eina_list_count(st->realized) == st->cache_max)
1151 Elm_Store_Item *realized_sti = NULL;
1152 Eina_List *last = eina_list_last(st->realized);
1153 realized_sti = eina_list_data_get(last);
1154 st->realized = eina_list_remove_list(st->realized, last);
1155 _item_eval(realized_sti);
1158 st->realized = eina_list_prepend(st->realized, sti);
1164 _item_job_add(Elm_Store_Item *sti)
1166 if (sti->eval_job) ecore_job_del(sti->eval_job);
1167 sti->eval_job = ecore_job_add(_item_realize, sti);
1171 _item_fetch(Elm_Store_Item *sti)
1173 Elm_Store *st = sti->store;
1177 eina_lock_take(&sti->lock);
1180 eina_lock_release(&sti->lock);
1183 ecore_thread_cancel(sti->fetch_th);
1184 sti->fetch_th = NULL;
1186 eina_lock_take(&sti->lock);
1188 if (sti->item_info != NULL)
1190 eina_lock_release(&sti->lock);
1191 if (sti->store->cb.fetch.func)
1192 sti->store->cb.fetch.func(sti->store->cb.fetch.data, sti, sti->item_info);
1193 eina_lock_take(&sti->lock);
1194 sti->fetched = EINA_TRUE;
1196 eina_lock_release(&sti->lock);
1201 _item_unfetch(Elm_Store_Item *sti)
1203 EINA_SAFETY_ON_NULL_RETURN(sti);
1204 Elm_Store *st = sti->store;
1208 eina_lock_take(&sti->lock);
1211 eina_lock_release(&sti->lock);
1214 ecore_thread_cancel(sti->fetch_th);
1215 sti->fetch_th = NULL;
1217 eina_lock_take(&sti->lock);
1219 sti->fetched = EINA_FALSE;
1220 eina_lock_release(&sti->lock);
1221 if (st->cb.unfetch.func)
1222 st->cb.unfetch.func(st->cb.unfetch.data, sti, sti->item_info);
1223 eina_lock_take(&sti->lock);
1225 eina_lock_release(&sti->lock);
1230 _item_realized(void *data , Evas_Object *obj __UNUSED__, void *event_info)
1232 Elm_Store *st = data;
1234 Elm_Object_Item *gli = event_info;
1235 Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
1240 if (!sti->data) _item_job_add(sti);
1246 _item_unrealized(void *data , Evas_Object *obj __UNUSED__, void *event_info)
1248 Elm_Store *st = data;
1250 Elm_Object_Item *gli = event_info;
1251 Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
1258 ecore_job_del(sti->eval_job);
1259 sti->eval_job = NULL;
1265 _item_free(Elm_Store_Item *sti)
1267 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1268 Elm_Store *st = sti->store;
1269 eina_lock_take(&sti->lock);
1270 if (st->live && st->cb.item_free.func && sti->item_info)
1272 eina_lock_release(&sti->lock);
1273 st->cb.item_free.func(st->cb.item_free.data, sti->item_info);
1274 eina_lock_take(&sti->lock);
1275 sti->item_info = NULL;
1277 eina_lock_release(&sti->lock);
1278 eina_lock_take(&sti->lock);
1283 _item_del(void *data, Evas_Object *obj __UNUSED__)
1285 Elm_Store_Item *sti = data;
1286 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1287 Elm_Store *st = sti->store;
1291 ecore_job_del(sti->eval_job);
1292 sti->eval_job = NULL;
1295 Eina_List *find = NULL;
1296 find = eina_list_data_find_list(st->always_fetched, sti);
1299 find = eina_list_data_find_list(st->realized,sti);
1302 Elm_Store_Item *realized_sti = NULL;
1303 realized_sti = eina_list_data_get(find);
1304 st->realized = eina_list_remove_list(st->realized, find);
1306 if (sti->data) _item_unfetch(sti);
1307 if (st->item.free) st->item.free(sti);
1311 _list_do(void *data, Ecore_Thread *th)
1313 Elm_Store *st = data;
1314 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1316 Elm_Store_Item_Info *item_info;
1317 Eina_Bool ok = EINA_FALSE;
1319 for (loop = 0; loop < st->item_count; loop++)
1321 item_info = calloc(1, sizeof(Elm_Store_Item_Info));
1322 if (!item_info) return;
1323 item_info->index = loop;
1325 if (st->cb.list.func) ok = st->cb.list.func(st->cb.list.data, item_info);
1326 if (ok) ecore_thread_feedback(th, item_info);
1327 else free(item_info);
1328 if (ecore_thread_check(th)) break;
1333 _list_update(void *data, Ecore_Thread *th __UNUSED__, void *msg)
1335 Elm_Store *st = data;
1336 Elm_Store_Item_Info *info = msg;
1337 elm_store_item_add(st, info);
1341 _list_end(void *data, Ecore_Thread *th)
1343 Elm_Store *st = data;
1344 if (th == st->list_th) st->list_th = NULL;
1348 _list_cancel(void *data, Ecore_Thread *th)
1350 Elm_Store *st = data;
1351 if (th == st->list_th) st->list_th = NULL;
1355 _group_item_append(Elm_Store_Item *sti, Elm_Genlist_Item_Class *itc)
1357 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1358 Elm_Store *st = sti->store;
1361 if (st->always_fetched)
1363 Eina_Bool group_existed = EINA_FALSE;
1364 const Eina_List *l = st->always_fetched;
1365 Elm_Store_Item *group_sti = eina_list_data_get(l);
1366 while (!group_existed && group_sti)
1368 if (group_sti->item_info->group_index == sti->item_info->group_index)
1370 group_existed = EINA_TRUE;
1375 l = eina_list_next(l);
1376 group_sti = eina_list_data_get(l);
1379 if (group_existed) return; //Already existed the group item
1381 st->always_fetched = eina_list_append(st->always_fetched, sti);
1382 sti->realized = EINA_FALSE;
1383 if (sti->data) _item_unfetch(sti);
1386 if (sti->item_info->group_index == -1)
1388 sti->item = elm_genlist_item_append(st->genlist,
1392 ELM_GENLIST_ITEM_NONE,
1393 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1394 (void *)sti->store->cb.item_select.data);
1401 _normal_item_append(Elm_Store_Item *sti, Elm_Genlist_Item_Class *itc)
1403 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1404 Elm_Store *st = sti->store;
1405 if (st->live && sti->item_info)
1407 Eina_Bool need_update = EINA_FALSE;
1408 Eina_Bool group_existed = EINA_FALSE;
1411 if (st->always_fetched)
1413 if (sti->item_info->rec_item == EINA_TRUE)
1415 if (sti->item_info->group_index != sti->item_info->pre_group_index)
1417 if (sti->item_info->group_index < sti->item_info->pre_group_index)
1419 Eina_Bool pre_group_existed = EINA_FALSE;
1420 l = st->always_fetched;
1421 Elm_Store_Item *pre_group_sti = eina_list_data_get(l);
1422 while (!pre_group_existed && pre_group_sti)
1424 if (pre_group_sti->item_info->pre_group_index == sti->item_info->pre_group_index)
1426 pre_group_existed = EINA_TRUE;
1431 l = eina_list_next(l);
1432 pre_group_sti = eina_list_data_get(l);
1435 if (pre_group_sti && pre_group_sti->realized) // already added the header item to the genlist
1437 Eina_Bool deleted = EINA_FALSE;
1438 Eina_Bool last_item = EINA_FALSE;
1439 Elm_Object_Item *comp_item = pre_group_sti->first_item;
1440 while (!deleted && comp_item)
1442 Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
1445 int sort = st->cb.item_sort.func(st->cb.item_sort.data, sti->item_info, comp_sti->item_info);
1446 if(sort == ELM_STORE_ITEM_SORT_SAME)
1448 elm_store_item_del(comp_sti);
1449 deleted = EINA_TRUE;
1453 if (last_item) break;
1454 else comp_item = elm_genlist_item_next_get(comp_item);
1456 if (comp_item == pre_group_sti->last_item) last_item = EINA_TRUE;
1458 if (!deleted) printf(" The item does not existed in the pre group of genlist \n");
1460 else //Pre group item does not existed in the always fetched list or the genlist
1462 Eina_Bool deleted = EINA_FALSE;
1463 Elm_Object_Item *comp_item = elm_genlist_first_item_get(st->genlist);
1464 while (!deleted && comp_item)
1466 Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
1467 if (comp_sti && sti->item_info->item_type == comp_sti->item_info->item_type)
1469 int sort = st->cb.item_sort.func(st->cb.item_sort.data, sti->item_info, comp_sti->item_info);
1470 if (sort == ELM_STORE_ITEM_SORT_SAME)
1472 elm_store_item_del(comp_sti);
1473 deleted = EINA_TRUE;
1477 comp_item = elm_genlist_item_next_get(comp_item);
1479 if (!deleted) printf(" The item does not existed in the genlist \n");
1484 sti->item_info->group_index = sti->item_info->pre_group_index;
1485 need_update = EINA_TRUE;
1488 else need_update = EINA_TRUE;
1490 l = st->always_fetched;
1491 Elm_Store_Item *group_sti = eina_list_data_get(l);
1492 while (!group_existed && group_sti) // Search the group item of a normal item in the always_fetched list
1494 if (group_sti->item_info->group_index == sti->item_info->group_index)
1496 group_existed = EINA_TRUE;
1501 l = eina_list_next(l);
1502 group_sti = eina_list_data_get(l);
1507 if (group_sti->realized) // already added the header item to the genlist
1509 Eina_Bool added = EINA_FALSE;
1510 Elm_Object_Item *comp_item = group_sti->first_item;
1511 while (!added && comp_item)
1513 Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
1516 int sort = st->cb.item_sort.func(st->cb.item_sort.data, sti->item_info, comp_sti->item_info);
1517 if (sort == ELM_STORE_ITEM_SORT_SAME)
1519 if (need_update == EINA_TRUE) elm_store_item_update(comp_sti);
1520 else added = EINA_TRUE;
1523 else if (sort == ELM_STORE_ITEM_SORT_LOW)
1525 sti->item = elm_genlist_item_insert_before(st->genlist,
1530 ELM_GENLIST_ITEM_NONE,
1531 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1532 (void *)sti->store->cb.item_select.data);
1534 if (comp_item == group_sti->first_item) group_sti->first_item = sti->item;
1539 if (comp_item == group_sti->last_item) //To add the item in to the last of its group
1541 need_update = EINA_FALSE;
1545 comp_item = elm_genlist_item_next_get(comp_item);
1547 if (!added && !need_update)
1549 Elm_Object_Item *last_item = group_sti->last_item;
1552 sti->item = elm_genlist_item_insert_after(st->genlist,
1557 ELM_GENLIST_ITEM_NONE,
1558 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1559 (void *)sti->store->cb.item_select.data);
1560 group_sti->last_item = sti->item;
1562 else printf(" Group item have no last item. so can not add a item to the genlist \n");
1565 else // To add the header item in genlist, and compare with other header items along with callback func
1567 Eina_Bool added = EINA_FALSE;
1568 l = st->always_fetched;
1569 Elm_Store_Item *comp_group_sti = eina_list_data_get(l);
1570 while (!added && comp_group_sti)
1572 if (comp_group_sti != group_sti && comp_group_sti->realized)
1574 // Compare with group items
1575 int sort = st->cb.item_sort.func(st->cb.item_sort.data, group_sti->item_info, comp_group_sti->item_info);
1576 if(sort == ELM_STORE_ITEM_SORT_LOW)
1578 group_sti->item = elm_genlist_item_insert_before(st->genlist,
1579 group_sti->item_info->item_class,
1582 comp_group_sti->item,
1583 ELM_GENLIST_ITEM_GROUP,
1586 group_sti->realized = EINA_TRUE;
1587 sti->item = elm_genlist_item_insert_after(st->genlist,
1592 ELM_GENLIST_ITEM_NONE,
1593 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1594 (void *)sti->store->cb.item_select.data);
1596 group_sti->first_item = sti->item;
1597 group_sti->last_item = sti->item;
1602 l = eina_list_next(l);
1603 comp_group_sti = eina_list_data_get(l);
1605 if (!comp_group_sti) // First item append in the genlist
1607 group_sti->item = elm_genlist_item_append(st->genlist,
1608 group_sti->item_info->item_class,
1611 ELM_GENLIST_ITEM_GROUP,
1614 group_sti->realized = EINA_TRUE;
1615 sti->item = elm_genlist_item_append(st->genlist,
1619 ELM_GENLIST_ITEM_NONE,
1620 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1621 (void *)sti->store->cb.item_select.data);
1623 group_sti->first_item = sti->item;
1624 group_sti->last_item = sti->item;
1629 if (!group_existed) // No exist the group item of normal item, so it added without group.
1631 Eina_Bool added = EINA_FALSE;
1632 Elm_Object_Item *comp_item = elm_genlist_first_item_get(st->genlist);
1633 while (!added && comp_item)
1635 Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
1638 if (sti->item_info->item_type == comp_sti->item_info->item_type)
1640 int sort = st->cb.item_sort.func(st->cb.item_sort.data, sti->item_info, comp_sti->item_info);
1641 if (sort == ELM_STORE_ITEM_SORT_SAME)
1643 if (sti->item_info->rec_item == EINA_TRUE)
1645 elm_store_item_update(comp_sti);
1646 need_update = EINA_TRUE;
1648 else added = EINA_TRUE;
1651 else if (sort == ELM_STORE_ITEM_SORT_LOW)
1653 sti->item = elm_genlist_item_insert_before(st->genlist,
1658 ELM_GENLIST_ITEM_NONE,
1659 (Evas_Smart_Cb)sti->store->cb.item_select.func,
1660 (void *)sti->store->cb.item_select.data);
1667 comp_item = elm_genlist_item_next_get(comp_item);
1668 if (comp_item == NULL) need_update = EINA_FALSE;
1670 if (!added && !need_update)
1672 sti->item = elm_genlist_item_append(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 _store_free(Elm_Store *st)
1687 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1688 Elm_Store_DBsystem *std = (Elm_Store_DBsystem *)st;
1689 if(std->p_db) eina_stringshare_del(std->p_db);
1693 * Add a new dbsystem Store object
1695 * @return The new object or NULL if it cannot be created
1700 elm_store_dbsystem_new(void)
1702 Elm_Store_DBsystem *std = _store_new(Elm_Store_DBsystem);
1703 EINA_SAFETY_ON_NULL_RETURN_VAL(std, NULL);
1705 EINA_MAGIC_SET(std, ELM_STORE_DBSYSTEM_MAGIC);
1706 std->base.free = _store_free;
1707 std->base.item.free = _item_free;
1712 * Sets the item count of a store
1714 * @param st The store object
1715 * @param count The item count of an store
1720 elm_store_item_count_set(Elm_Store *st, int count)
1722 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1723 st->item_count = count;
1728 * Set the select func that select the state of a list item whether true or false
1730 * @param st The store object
1731 * @param func The select cb function of an store
1732 * @param data The new data pointer to set
1737 elm_store_item_select_func_set(Elm_Store *st, Elm_Store_Item_Select_Cb func, const void *data)
1739 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1740 st->cb.item_select.func = func;
1741 st->cb.item_select.data = (void *)data;
1745 * Sets the sort func that sort the item with a next in the list
1747 * @param st The store object
1748 * @param func The sort cb function of an store
1749 * @param data The new data pointer to set
1754 elm_store_item_sort_func_set(Elm_Store *st, Elm_Store_Item_Sort_Cb func, const void *data)
1756 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1757 st->cb.item_sort.func = func;
1758 st->cb.item_sort.data = (void *)data;
1762 * Set the store item free func
1764 * @param st The store object
1765 * @param func The free cb function of an store
1766 * @param data The new data pointer to set
1771 elm_store_item_free_func_set(Elm_Store *st, Elm_Store_Item_Free_Cb func, const void *data)
1773 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1774 st->cb.item_free.func = func;
1775 st->cb.item_free.data = (void *)data;
1779 * Get the item index that included header items
1781 * @param sti The store item object
1782 * @return The item index in genlist
1787 elm_store_item_index_get(const Elm_Store_Item *sti)
1789 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return -1;
1790 Elm_Store *st = sti->store;
1797 Elm_Object_Item *gen_item = elm_genlist_first_item_get(st->genlist);
1800 Elm_Store_Item *item = elm_genlist_item_data_get(gen_item);
1801 if (item == sti) return index;
1802 gen_item = elm_genlist_item_next_get(gen_item);
1811 * Get the item index of real data that don't included header items
1813 * @param sti The store item object
1814 * @return The real item index
1819 elm_store_item_data_index_get(const Elm_Store_Item *sti)
1821 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return -1;
1822 Elm_Store *st = sti->store;
1827 Elm_Object_Item *gen_item = elm_genlist_first_item_get(st->genlist);
1830 Elm_Store_Item *item = elm_genlist_item_data_get(gen_item);
1831 if (item && item->item_info->item_type != ELM_GENLIST_ITEM_GROUP)
1833 if(item == sti) return index;
1836 gen_item = elm_genlist_item_next_get(gen_item);
1843 * Get the DB pointer of an item
1845 * @param sti The store item object
1846 * @return The DB pointer of item
1851 elm_store_dbsystem_db_get(const Elm_Store_Item *sti)
1853 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
1855 const Elm_Store_DBsystem *std = (const Elm_Store_DBsystem *)sti->store;
1856 if (!EINA_MAGIC_CHECK(sti->store, ELM_STORE_MAGIC)) return NULL;
1857 if (!EINA_MAGIC_CHECK(std, ELM_STORE_DBSYSTEM_MAGIC)) return NULL;
1862 * Set the DB pointer of an item
1864 * @param sti The store item object
1865 * @parm p_db The DB pointer of item
1870 elm_store_dbsystem_db_set(Elm_Store *store, void *p_db)
1872 Elm_Store_DBsystem *std = (Elm_Store_DBsystem *)store;
1873 if (!EINA_MAGIC_CHECK(store, ELM_STORE_MAGIC)) return;
1874 if (!EINA_MAGIC_CHECK(std, ELM_STORE_DBSYSTEM_MAGIC)) return;
1877 ecore_thread_cancel(store->list_th);
1878 store->list_th = NULL;
1881 store->list_th = ecore_thread_feedback_run(_list_do,
1889 * Append the item to the genlist
1891 * @param st The store object
1892 * @param info The store item info dbsystem object
1893 * @return The item of store
1897 EAPI Elm_Store_Item *
1898 elm_store_item_add(Elm_Store *st, Elm_Store_Item_Info *info)
1900 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return NULL;
1901 EINA_SAFETY_ON_NULL_RETURN_VAL(info, NULL);
1902 Elm_Store_Item *sti;
1903 Elm_Genlist_Item_Class *itc;
1905 sti = calloc(1, sizeof(Elm_Store_Item));
1906 if (!sti) return NULL;
1907 eina_lock_new(&sti->lock);
1908 EINA_MAGIC_SET(sti, ELM_STORE_ITEM_MAGIC);
1910 sti->item_info = info;
1911 sti->fetched = EINA_FALSE;
1913 itc = info->item_class;
1914 if (!itc) itc = &_store_item_class;
1917 itc->func.text_get = (GenlistItemTextGetFunc)_item_text_get;
1918 itc->func.content_get = (GenlistItemContentGetFunc)_item_content_get;
1919 itc->func.state_get = NULL;
1920 itc->func.del = (GenlistItemDelFunc)_item_del;
1925 if (sti->item_info->item_type == ELM_GENLIST_ITEM_GROUP) _group_item_append(sti, itc);
1926 else _normal_item_append(sti, itc);
1937 * Realize the visible items to the screen
1939 * @param st The store object
1944 elm_store_visible_items_update(Elm_Store *st)
1946 if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
1948 Eina_List *realized_list = elm_genlist_realized_items_get(st->genlist);
1949 Elm_Object_Item *item = eina_list_data_get(realized_list);
1952 Elm_Store_Item *realized_sti = elm_genlist_item_data_get(item);
1953 elm_store_item_update(realized_sti);
1954 realized_list = eina_list_next(realized_list);
1955 item = eina_list_data_get(realized_list);
1960 * Realize the item to the screen
1962 * @param sti The store item object
1967 elm_store_item_update(Elm_Store_Item *sti)
1969 Elm_Store *st = sti->store;
1971 Eina_List *find = NULL;
1972 find = eina_list_data_find_list(st->always_fetched, sti);
1975 if (sti->data) _item_unfetch(sti);
1977 if (sti->realized) elm_genlist_item_update(sti->item);
1981 find = eina_list_data_find_list(st->realized,sti);
1982 if (find) _item_realize(sti);
1987 * Delete the item of genlist
1989 * @param sti The store item object
1994 elm_store_item_del(Elm_Store_Item *sti)
1996 if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
1997 Elm_Store *st = sti->store;
2001 Eina_List *find = NULL;
2002 find = eina_list_data_find_list(st->always_fetched, sti);
2003 if (find) st->always_fetched = eina_list_remove_list(st->always_fetched, find);
2005 Eina_Bool deleted = EINA_FALSE;
2006 Elm_Object_Item *comp_item = elm_genlist_first_item_get(st->genlist);
2007 while (!deleted && comp_item)
2009 Elm_Store_Item *comp_sti = elm_genlist_item_data_get(comp_item);
2010 if (comp_sti && (sti == comp_sti))
2012 Elm_Object_Item *group_item = elm_genlist_item_parent_get(comp_item);
2015 Elm_Store_Item *group_sti = elm_genlist_item_data_get(group_item);
2018 if ((group_sti->first_item == comp_item) && (group_sti->last_item == comp_item))
2020 group_sti->realized = EINA_FALSE;
2021 group_sti->first_item = NULL;
2022 group_sti->last_item = NULL;
2023 elm_genlist_item_del(group_item);
2025 else if ((group_sti->first_item == comp_item) && (group_sti->last_item != comp_item))
2027 Elm_Object_Item *next_item = elm_genlist_item_next_get(comp_item);
2028 group_sti->first_item = next_item;
2030 else if ((group_sti->first_item != comp_item) && (group_sti->last_item == comp_item))
2032 Elm_Object_Item *prev_item = elm_genlist_item_prev_get(comp_item);
2033 group_sti->last_item = prev_item;
2037 elm_genlist_item_del(comp_sti->item);
2038 deleted = EINA_TRUE;
2041 comp_item = elm_genlist_item_next_get(comp_item);
2044 if(!deleted) printf(" Not deleted because it does not existed in the genlist \n");
2048 // TODO: END -DBsystem store