[store] add the genlist backing store for the dbsystem
authorYun ilkook <ilkook.yun@samsung.com>
Fri, 8 Apr 2011 12:29:08 +0000 (21:29 +0900)
committerYun ilkook <ilkook.yun@samsung.com>
Fri, 8 Apr 2011 12:29:08 +0000 (21:29 +0900)
Change-Id: I58d20597eabbfdaab9f491396a1ab52c34675a03

configure.ac
debian/control
src/bin/Makefile.am
src/bin/test.c
src/bin/test_db_store.c [new file with mode: 0644]
src/lib/Elementary.h.in
src/lib/elm_store.c

index f8acb1b..77b9b87 100755 (executable)
@@ -439,6 +439,33 @@ if test "x$want_elementary_ethumb" = "xyes" -a "x$have_elementary_ethumb" = "xno
 fi
 AC_SUBST(ELM_ETHUMB_DEF)
 
+ELM_SQLITE3_DEF="#undef"
+have_elementary_sqlite3="no"
+want_elementary_sqlite3="auto"
+AC_ARG_ENABLE([sqlite3],
+   [AC_HELP_STRING([--disable-sqlite3], [disable sqlite3 support. @<:@default=detect@:>@])],
+   [want_elementary_sqlite3=$enableval], [])
+
+if test "x$want_elementary_sqlite3" != "xno"; then
+    PKG_CHECK_MODULES([ELEMENTARY_SQLITE3],
+       [
+        sqlite3
+       ],
+       [
+        AC_DEFINE(HAVE_ELEMENTARY_SQLITE3, 1, [sqlite3 support for Elementary])
+        have_elementary_sqlite3="yes"
+        ELM_SQLITE3_DEF="#define"
+        requirement_elm="sqlite3 ${requirement_elm}"
+       ],
+       [have_elementary_sqlite3="no"]
+    )
+else
+    have_elementary_sqlite3="no"
+fi
+if test "x$want_elementary_sqlite3" = "xyes" -a "x$have_elementary_sqlite3" = "xno"; then
+    AC_MSG_ERROR(sqlite3 support requested, but no sqlite3 found by pkg-config.])
+fi
+
 ELM_DEBUG_DEF="#undef"
 want_elementary_debug="no"
 AC_ARG_ENABLE([debug],
index 0eebee9..27cdedc 100644 (file)
@@ -3,7 +3,7 @@ Section: x11
 Priority: optional
 Maintainer: Jaehwan Kim <jae.hwan.kim@samsung.com>, Chuneon Park <chuneon.park@samsung.com>, Juyung Seo <juyung.seo@samsung.com>, Myungjae Lee <mjae.lee@samsung.com>, Woohyun Jung <wh0705.jung@samsung.com>, Jihoon Kim <jihoon48.kim@samsung.com>, Jeonghyun Yun <jh0506.yun@samsung.com>, Seunggyun Kim <sgyun.kim@samsung.com>, Shinwoo Kim <cinoo.kim@samsung.com>
 Uploaders: Doyoun Kang <doyoun.kang@samsung.com>, Hyoyoung Chang <hyoyoung.chang@samsung.com>, Myoungwoon Kim <myoungwoon.kim@samsung.com>, Shinwoo Kim <cinoo.kim@samsung.com>
-Build-Depends: debhelper (>= 6), cdbs, libecore-dev, libevas-dev, libeet-dev, libeet-bin, libedje-dev, pkg-config, libtool, libeina-dev, libefreet-dev, libethumb-dev
+Build-Depends: debhelper (>= 6), cdbs, libecore-dev, libevas-dev, libeet-dev, libeet-bin, libedje-dev, pkg-config, libtool, libeina-dev, libefreet-dev, libethumb-dev, libsqlite3-dev
 Standards-Version: 3.8.1
 Homepage: http://www.enlightenment.org
 
index 6e0c740..c66e6fc 100644 (file)
@@ -16,7 +16,8 @@ AM_CPPFLAGS = \
 @ELEMENTARY_EDBUS_CFLAGS@ \
 @ELEMENTARY_EFREET_CFLAGS@ \
 @ELEMENTARY_EWEATHER_CFLAGS@ \
-@ELEMENTARY_ETHUMB_CFLAGS@
+@ELEMENTARY_ETHUMB_CFLAGS@ \
+@ELEMENTARY_SQLITE3_CFLAGS@
 
 if ELEMENTARY_WINDOWS_BUILD
 AM_CPPFLAGS += -DELEMENTARY_BUILD
@@ -81,14 +82,16 @@ test_anim.c \
 test_segment_control.c \
 test_calendar.c \
 test_diskselector.c \
-test_ctxpopup.c 
+test_ctxpopup.c \
+test_db_store.c
 
 elementary_test_LDADD = $(top_builddir)/src/lib/libelementary.la \
        @ELEMENTARY_EWEATHER_LIBS@ \
        @ELEMENTARY_EDBUS_LIBS@ \
        @ELEMENTARY_EFREET_LIBS@ \
        @ELEMENTARY_LIBS@ \
-       @my_libs@
+       @my_libs@ \
+       @ELEMENTARY_SQLITE3_LIBS@
 elementary_test_LDFLAGS =
 
 elementary_config_SOURCES = \
index af8fc60..0b78c4e 100644 (file)
@@ -84,6 +84,7 @@ void test_anim(void *data, Evas_Object *obj, void *event_info);
 void test_segment_control(void *data, Evas_Object *obj, void *event_info);
 void test_diskselector(void *data, Evas_Object *obj, void *event_info);
 void test_ctxpopup(void *data, Evas_Object *obj, void *event_info);
+void test_db_store(void *data, Evas_Object * obj, void *event_info);
 
 struct elm_test
 {
@@ -287,6 +288,7 @@ my_win_main(void)
    ADD_TEST("Calendar 2", test_calendar2);
    ADD_TEST("Disk Selector", test_diskselector);
    ADD_TEST("Ctxpopup", test_ctxpopup);
+   ADD_TEST("Db Store", test_db_store);
 #undef ADD_TEST
 
    if (tests)
diff --git a/src/bin/test_db_store.c b/src/bin/test_db_store.c
new file mode 100644 (file)
index 0000000..028c8ce
--- /dev/null
@@ -0,0 +1,305 @@
+#include <Elementary.h>
+
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+#ifndef ELM_LIB_QUICKLAUNCH
+#ifdef HAVE_ELEMENTARY_SQLITE3
+#include "sqlite3.h"
+#endif
+
+#define BUF_SIZE 1024
+#define ITEM_COUNT 1000
+#define BLOCK_COUNT 10
+#define GROUP_MAX (ITEM_COUNT/5)
+
+typedef struct _My_Contact My_Contact;
+typedef struct _Group_Title Group_Title;
+
+struct _My_Contact
+{
+   int n_id;
+   char *psz_name;
+   char *psz_jobtitle;
+   char *psz_mobile;
+};
+
+struct _Group_Title
+{
+   char *group_title;
+};
+
+static int group_index = -1;
+static sqlite3 *p_db = NULL;
+static char *_st_store_group_custom_label_get(void *data, Elm_Store_Item * sti, const char *part);
+
+// callbacks just to see user interacting with genlist
+static void
+_st_selected(void *data __UNUSED__, Evas_Object * obj __UNUSED__, void *event_info)
+{
+   printf("selected: %p\n", event_info);
+}
+
+static void
+_st_clicked(void *data __UNUSED__, Evas_Object * obj __UNUSED__, void *event_info)
+{
+   printf("clicked: %p\n", event_info);
+}
+
+static void
+_st_longpress(void *data __UNUSED__, Evas_Object * obj __UNUSED__, void *event_info)
+{
+   printf("longpress %p\n", event_info);
+}
+
+// store callbacks to handle loading/parsing/freeing of store items from src
+static char *group_title[GROUP_MAX];
+
+static Elm_Genlist_Item_Class itc1 = {
+     "message_db", {NULL, NULL, NULL, NULL}
+};
+
+static Elm_Genlist_Item_Class itc2 = {
+     "group_title", {NULL, NULL, NULL, NULL}
+};
+
+static const Elm_Store_Item_Mapping it1_mapping[] = {
+       {
+          ELM_STORE_ITEM_MAPPING_LABEL,
+          "elm.title.1", ELM_STORE_ITEM_MAPPING_OFFSET (My_Contact, psz_name),
+          {.empty = {
+                       EINA_TRUE}}},
+       {
+          ELM_STORE_ITEM_MAPPING_LABEL,
+          "elm.title.2", ELM_STORE_ITEM_MAPPING_OFFSET (My_Contact, psz_jobtitle),
+          {.empty = {
+                       EINA_TRUE}}},
+       {
+          ELM_STORE_ITEM_MAPPING_LABEL,
+          "elm.text", ELM_STORE_ITEM_MAPPING_OFFSET (My_Contact, psz_mobile),
+          {.empty = {
+                       EINA_TRUE}}},
+       ELM_STORE_ITEM_MAPPING_END
+};
+
+static const Elm_Store_Item_Mapping it2_mapping[] = {
+       {
+          ELM_STORE_ITEM_MAPPING_CUSTOM,
+          "elm.text", 0,
+          {.custom = {
+                        (Elm_Store_Item_Mapping_Cb)_st_store_group_custom_label_get}}},
+       ELM_STORE_ITEM_MAPPING_END
+};
+
+static char *
+_st_store_group_custom_label_get(void *data, Elm_Store_Item * sti, const char *part)
+{
+   if (!strcmp(part, "elm.text"))
+     return strdup("group title");
+
+   return strdup("");
+}
+
+////// **** WARNING ***********************************************************
+////   * This function runs inside a thread outside efl mainloop. Be careful! *
+//     ************************************************************************
+static Eina_Bool
+_st_store_list(void *data __UNUSED__, Elm_Store_Item_Info * item_info)
+{
+   if ((item_info->index % 5) == 0)
+     {
+        char gtext[128];
+        int index_label = item_info->index / 5;
+        sprintf(gtext, "group title (%d)", index_label);
+        group_title[index_label] = strdup(gtext);
+        group_index = index_label;
+
+        item_info->item_type = ELM_GENLIST_ITEM_GROUP;
+        item_info->group_index = group_index;
+        item_info->rec_item = EINA_FALSE;
+        item_info->pre_group_index = -1;
+        item_info->item_class = &itc2;
+        item_info->mapping = it2_mapping;
+     }
+   else
+     {
+        item_info->item_type = ELM_GENLIST_ITEM_NONE;
+        item_info->group_index = group_index;
+        item_info->rec_item = EINA_FALSE;
+        item_info->pre_group_index = -1;
+        item_info->item_class = &itc1;
+        item_info->mapping = it1_mapping;
+     }
+
+   item_info->data = NULL;
+   return EINA_TRUE;
+}
+
+//     ************************************************************************
+////   * End of separate thread function.                                     *
+////// ************************************************************************
+
+////// **** WARNING ***********************************************************
+////   * This function runs inside a thread outside efl mainloop. Be careful! *
+//     ************************************************************************
+
+static void
+_st_store_fetch(void *data __UNUSED__, Elm_Store_Item * sti, Elm_Store_Item_Info * item_info)
+{
+   if (item_info->item_type == ELM_GENLIST_ITEM_GROUP)
+     {
+        Group_Title *pGpTitle;
+        pGpTitle = calloc(1, sizeof(Group_Title));
+        pGpTitle->group_title = strdup(group_title[item_info->group_index]);
+        elm_store_item_data_set(sti, pGpTitle);
+     }
+   else
+     {
+
+        My_Contact *pmyct;
+
+        // alloc my item in memory that holds data to show in the list
+#ifdef HAVE_ELEMENTARY_SQLITE3
+        sqlite3_stmt* stmt = NULL;
+        char szbuf[BUF_SIZE] = {0, };
+        int rc = 0;
+
+        int start_idx = elm_store_item_data_index_get(sti);
+        int fetch_count = 1;
+        sqlite3 *pdb = elm_store_dbsystem_db_get(sti);
+
+        snprintf(szbuf, BUF_SIZE, "SELECT * FROM tblEmpList ORDER BY id ASC LIMIT ?,?;");
+
+        rc = sqlite3_prepare(pdb, szbuf, strlen(szbuf), &stmt, NULL);
+        rc = sqlite3_bind_int(stmt, 1, start_idx);
+        rc = sqlite3_bind_int(stmt, 2, fetch_count);
+        rc = sqlite3_step(stmt);
+
+        pmyct = calloc(1, sizeof(My_Contact));
+        pmyct->n_id = sqlite3_column_int(stmt, 0);
+        pmyct->psz_name = strdup((const char *)sqlite3_column_text(stmt, 1));
+        pmyct->psz_jobtitle= strdup((const char *)sqlite3_column_text(stmt, 2));
+        pmyct->psz_mobile = strdup((const char *)sqlite3_column_text(stmt, 3));
+
+        rc = sqlite3_finalize(stmt);
+#else
+        int start_idx = elm_store_item_data_index_get(sti);
+        pmyct = calloc(1, sizeof(My_Contact));
+        pmyct->n_id = start_idx;
+        pmyct->psz_name = strdup("Name");
+        pmyct->psz_jobtitle = strdup("Title");
+        pmyct->psz_mobile = strdup("Mobile");
+#endif
+        elm_store_item_data_set(sti, pmyct);
+     }
+   return;
+}
+
+//     ************************************************************************
+////   * End of separate thread function.                                     *
+////// ************************************************************************
+static void
+_st_store_unfetch(void *data __UNUSED__, Elm_Store_Item * sti, Elm_Store_Item_Info * item_info)
+{
+   if (item_info->item_type == ELM_GENLIST_ITEM_GROUP)
+     {
+        Group_Title *myit = elm_store_item_data_get(sti);
+
+        if (!myit)
+          return;
+        if (myit->group_title)
+          free(myit->group_title);
+        free(myit);
+
+     }
+   else
+     {
+        My_Contact *myit = elm_store_item_data_get(sti);
+
+        if (!myit)
+          return;
+        if (myit->psz_name)
+          free(myit->psz_name);
+        if (myit->psz_jobtitle)
+          free(myit->psz_jobtitle);
+        if (myit->psz_mobile)
+          free(myit->psz_mobile);
+        free(myit);
+     }
+   elm_store_item_data_set(sti, NULL);
+}
+
+static void
+_st_store_item_select(void *data, Evas_Object * obj, void *event_info)
+{
+   Elm_Genlist_Item *gli = event_info;
+   Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
+
+   if (sti)
+     {
+        int index = elm_store_item_data_index_get(sti);
+        printf("item %d is selected\n", index);
+        elm_genlist_item_selected_set(gli, EINA_FALSE);
+     }
+}
+
+void
+test_db_store(void *data __UNUSED__, Evas_Object * obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Evas_Object *win, *bg, *gl, *bx;
+   Elm_Store *st;
+
+   win = elm_win_add(NULL, "db-store", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Store");
+   elm_win_autodel_set(win, 1);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   bx = elm_box_add(win);
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, bx);
+   evas_object_show(bx);
+
+   gl = elm_genlist_add(win);
+   elm_genlist_homogeneous_set(gl, EINA_TRUE);
+   elm_genlist_compress_mode_set(gl, EINA_TRUE);
+   elm_genlist_block_count_set(gl, BLOCK_COUNT);
+   elm_genlist_height_for_width_mode_set(gl, EINA_TRUE);
+   evas_object_smart_callback_add(gl, "selected", _st_selected, NULL);
+   evas_object_smart_callback_add(gl, "clicked", _st_clicked, NULL);
+   evas_object_smart_callback_add(gl, "longpressed", _st_longpress, NULL);
+   evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bx, gl);
+   evas_object_show(gl);
+
+   // Set the db handler to store. after open it
+   // Then store will add items as you set the item count number
+#ifdef HAVE_ELEMENTARY_SQLITE3
+   if (!p_db)
+     {
+        int rc = sqlite3_open("./genlist.db", &p_db);
+        if(SQLITE_OK != rc)
+          {
+             printf("Fail to open DB ./genlist.db\n");
+          }
+     }
+#endif
+
+   st = elm_store_dbsystem_new();
+   elm_store_fetch_thread_set(st, EINA_TRUE);
+   elm_store_item_count_set(st, ITEM_COUNT);
+   elm_store_list_func_set(st, _st_store_list, NULL);
+   elm_store_fetch_func_set(st, _st_store_fetch, NULL);
+   elm_store_unfetch_func_set(st, _st_store_unfetch, NULL);
+   elm_store_item_select_func_set(st, (Elm_Store_Item_Select_Cb)_st_store_item_select, NULL);
+   elm_store_target_genlist_set(st, gl);
+   elm_store_dbsystem_db_set(st, p_db);
+
+   evas_object_resize(win, 480, 800);
+   evas_object_show(win);
+}
+#endif
index 45b1741..8114cfa 100644 (file)
@@ -3203,116 +3203,136 @@ extern "C" {
    EAPI void                   elm_imageslider_prev(Evas_Object *obj) EINA_ARG_NONNULL(1);
    EAPI void                   elm_imageslider_next(Evas_Object *obj) EINA_ARG_NONNULL(1);
 
-  typedef struct _Elm_Store                      Elm_Store;
-  typedef struct _Elm_Store_Filesystem           Elm_Store_Filesystem;
-  typedef struct _Elm_Store_Item                 Elm_Store_Item;
-  typedef struct _Elm_Store_Item_Filesystem      Elm_Store_Item_Filesystem;
-  typedef struct _Elm_Store_Item_Info            Elm_Store_Item_Info;
-  typedef struct _Elm_Store_Item_Info_Filesystem Elm_Store_Item_Info_Filesystem;
-  typedef struct _Elm_Store_Item_Mapping         Elm_Store_Item_Mapping;
-  typedef struct _Elm_Store_Item_Mapping_Empty   Elm_Store_Item_Mapping_Empty;
-  typedef struct _Elm_Store_Item_Mapping_Icon    Elm_Store_Item_Mapping_Icon;
-  typedef struct _Elm_Store_Item_Mapping_Photo   Elm_Store_Item_Mapping_Photo;
-  typedef struct _Elm_Store_Item_Mapping_Custom  Elm_Store_Item_Mapping_Custom;
-
-  typedef Eina_Bool (*Elm_Store_Item_List_Cb) (void *data, Elm_Store_Item_Info *info);
-  typedef void      (*Elm_Store_Item_Fetch_Cb) (void *data, Elm_Store_Item *sti);
-  typedef void      (*Elm_Store_Item_Unfetch_Cb) (void *data, Elm_Store_Item *sti);
-  typedef void     *(*Elm_Store_Item_Mapping_Cb) (void *data, Elm_Store_Item *sti, const char *part);
-
-  typedef enum
-    {
-      ELM_STORE_ITEM_MAPPING_NONE = 0,
-      ELM_STORE_ITEM_MAPPING_LABEL, // const char * -> label
-      ELM_STORE_ITEM_MAPPING_STATE, // Eina_Bool -> state
-      ELM_STORE_ITEM_MAPPING_ICON, // char * -> icon path
-      ELM_STORE_ITEM_MAPPING_PHOTO, // char * -> photo path
-      ELM_STORE_ITEM_MAPPING_CUSTOM, // item->custom(it->data, it, part) -> void * (-> any)
-      // can add more here as needed by common apps
-      ELM_STORE_ITEM_MAPPING_LAST
-    } Elm_Store_Item_Mapping_Type;
-
-  struct _Elm_Store_Item_Mapping_Icon
-    {
-      // FIXME: allow edje file icons
-      int                   w, h;
-      Elm_Icon_Lookup_Order lookup_order;
-      Eina_Bool             standard_name : 1;
-      Eina_Bool             no_scale : 1;
-      Eina_Bool             smooth : 1;
-      Eina_Bool             scale_up : 1;
-      Eina_Bool             scale_down : 1;
-    };
-
-  struct _Elm_Store_Item_Mapping_Empty
-    {
-      Eina_Bool             dummy;
-    };
+   /* Store */
+   typedef struct _Elm_Store                      Elm_Store;
+   typedef struct _Elm_Store_DBsystem             Elm_Store_DBsystem;
+   typedef struct _Elm_Store_Filesystem           Elm_Store_Filesystem;
+   typedef struct _Elm_Store_Item                 Elm_Store_Item;
+   typedef struct _Elm_Store_Item_DBsystem        Elm_Store_Item_DBsystem;
+   typedef struct _Elm_Store_Item_Filesystem      Elm_Store_Item_Filesystem;
+   typedef struct _Elm_Store_Item_Info            Elm_Store_Item_Info;
+   typedef struct _Elm_Store_Item_Info_Filesystem Elm_Store_Item_Info_Filesystem;
+   typedef struct _Elm_Store_Item_Mapping         Elm_Store_Item_Mapping;
+   typedef struct _Elm_Store_Item_Mapping_Empty   Elm_Store_Item_Mapping_Empty;
+   typedef struct _Elm_Store_Item_Mapping_Icon    Elm_Store_Item_Mapping_Icon;
+   typedef struct _Elm_Store_Item_Mapping_Photo   Elm_Store_Item_Mapping_Photo;
+   typedef struct _Elm_Store_Item_Mapping_Custom  Elm_Store_Item_Mapping_Custom;
+
+   typedef Eina_Bool (*Elm_Store_Item_List_Cb) (void *data, Elm_Store_Item_Info *info);
+   typedef void      (*Elm_Store_Item_Fetch_Cb) (void *data, Elm_Store_Item *sti, Elm_Store_Item_Info *info);
+   typedef void      (*Elm_Store_Item_Unfetch_Cb) (void *data, Elm_Store_Item *sti, Elm_Store_Item_Info *info);
+   typedef void      (*Elm_Store_Item_Select_Cb) (void *data, Elm_Store_Item *sti);
+   typedef void      (*Elm_Store_Item_Sort_Cb) (void *data, Elm_Store_Item *sti, Elm_Store_Item *next);
+   typedef void     *(*Elm_Store_Item_Mapping_Cb) (void *data, Elm_Store_Item *sti, const char *part);
 
-  struct _Elm_Store_Item_Mapping_Photo
-    {
-      int                   size;
-    };
+   typedef enum
+     {
+        ELM_STORE_ITEM_MAPPING_NONE = 0,
+        ELM_STORE_ITEM_MAPPING_LABEL, // const char * -> label
+        ELM_STORE_ITEM_MAPPING_STATE, // Eina_Bool -> state
+        ELM_STORE_ITEM_MAPPING_ICON, // char * -> icon path
+        ELM_STORE_ITEM_MAPPING_PHOTO, // char * -> photo path
+        ELM_STORE_ITEM_MAPPING_CUSTOM, // item->custom(it->data, it, part) -> void * (-> any)
+        // can add more here as needed by common apps
+        ELM_STORE_ITEM_MAPPING_LAST
+     } Elm_Store_Item_Mapping_Type;
+
+   struct _Elm_Store_Item_Mapping_Icon
+     {
+        // FIXME: allow edje file icons
+        int                   w, h;
+        Elm_Icon_Lookup_Order lookup_order;
+        Eina_Bool             standard_name : 1;
+        Eina_Bool             no_scale : 1;
+        Eina_Bool             smooth : 1;
+        Eina_Bool             scale_up : 1;
+        Eina_Bool             scale_down : 1;
+     };
 
-  struct _Elm_Store_Item_Mapping_Custom
-    {
-      Elm_Store_Item_Mapping_Cb func;
-    };
+   struct _Elm_Store_Item_Mapping_Empty
+     {
+        Eina_Bool             dummy;
+     };
 
-  struct _Elm_Store_Item_Mapping
-    {
-      Elm_Store_Item_Mapping_Type     type;
-      const char                     *part;
-      int                             offset;
-      union {
-        Elm_Store_Item_Mapping_Empty  empty;
-        Elm_Store_Item_Mapping_Icon   icon;
-        Elm_Store_Item_Mapping_Photo  photo;
-        Elm_Store_Item_Mapping_Custom custom;
-        // add more types here
-      } details;
-    };
-
-  struct _Elm_Store_Item_Info
-    {
-      Elm_Genlist_Item_Class       *item_class;
-      const Elm_Store_Item_Mapping *mapping;
-      void                         *data;
-      char                         *sort_id;
-    };
+   struct _Elm_Store_Item_Mapping_Photo
+     {
+        int                   size;
+     };
 
-  struct _Elm_Store_Item_Info_Filesystem
-    {
-      Elm_Store_Item_Info  base;
-      char                *path;
-    };
+   struct _Elm_Store_Item_Mapping_Custom
+     {
+        Elm_Store_Item_Mapping_Cb func;
+     };
+
+   struct _Elm_Store_Item_Mapping
+     {
+        Elm_Store_Item_Mapping_Type     type;
+        const char                     *part;
+        int                             offset;
+        union {
+             Elm_Store_Item_Mapping_Empty  empty;
+             Elm_Store_Item_Mapping_Icon   icon;
+             Elm_Store_Item_Mapping_Photo  photo;
+             Elm_Store_Item_Mapping_Custom custom;
+             // add more types here
+        } details;
+     };
+
+   struct _Elm_Store_Item_Info
+     {
+        int                           index;
+        int                           item_type;
+        int                           group_index;
+        Eina_Bool                     rec_item;
+        int                           pre_group_index;
+
+        Elm_Genlist_Item_Class       *item_class;
+        const Elm_Store_Item_Mapping *mapping;
+        void                         *data;
+        char                         *sort_id;
+     };
+
+   struct _Elm_Store_Item_Info_Filesystem
+     {
+        Elm_Store_Item_Info  base;
+        char                *path;
+     };
 
 #define ELM_STORE_ITEM_MAPPING_END { ELM_STORE_ITEM_MAPPING_NONE, NULL, 0, { .empty = { EINA_TRUE } } }
 #define ELM_STORE_ITEM_MAPPING_OFFSET(st, it) offsetof(st, it)
 
-  EAPI void                    elm_store_free(Elm_Store *st);
-
-  EAPI Elm_Store              *elm_store_filesystem_new(void);
-  EAPI void                    elm_store_filesystem_directory_set(Elm_Store *st, const char *dir) EINA_ARG_NONNULL(1);
-  EAPI const char             *elm_store_filesystem_directory_get(const Elm_Store *st) EINA_ARG_NONNULL(1);
-  EAPI const char             *elm_store_item_filesystem_path_get(const Elm_Store_Item *sti) EINA_ARG_NONNULL(1);
-
-  EAPI void                    elm_store_target_genlist_set(Elm_Store *st, Evas_Object *obj) EINA_ARG_NONNULL(1);
-
-  EAPI void                    elm_store_cache_set(Elm_Store *st, int max) EINA_ARG_NONNULL(1);
-  EAPI int                     elm_store_cache_get(const Elm_Store *st) EINA_ARG_NONNULL(1);
-  EAPI void                    elm_store_list_func_set(Elm_Store *st, Elm_Store_Item_List_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
-  EAPI void                    elm_store_fetch_func_set(Elm_Store *st, Elm_Store_Item_Fetch_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
-  EAPI void                    elm_store_fetch_thread_set(Elm_Store *st, Eina_Bool use_thread) EINA_ARG_NONNULL(1);
-  EAPI Eina_Bool               elm_store_fetch_thread_get(const Elm_Store *st) EINA_ARG_NONNULL(1);
-
-  EAPI void                    elm_store_unfetch_func_set(Elm_Store *st, Elm_Store_Item_Unfetch_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
-  EAPI void                    elm_store_sorted_set(Elm_Store *st, Eina_Bool sorted) EINA_ARG_NONNULL(1);
-  EAPI Eina_Bool               elm_store_sorted_get(const Elm_Store *st) EINA_ARG_NONNULL(1);
-  EAPI void                    elm_store_item_data_set(Elm_Store_Item *sti, void *data) EINA_ARG_NONNULL(1);
-  EAPI void                   *elm_store_item_data_get(Elm_Store_Item *sti) EINA_ARG_NONNULL(1);
-  EAPI const Elm_Store        *elm_store_item_store_get(const Elm_Store_Item *sti) EINA_ARG_NONNULL(1);
-  EAPI const Elm_Genlist_Item *elm_store_item_genlist_item_get(const Elm_Store_Item *sti) EINA_ARG_NONNULL(1);
+   EAPI Elm_Store              *elm_store_dbsystem_new(void);
+   EAPI void                    elm_store_item_count_set(Elm_Store *st, int count) EINA_ARG_NONNULL(1);
+   EAPI void                    elm_store_item_select_func_set(Elm_Store *st, Elm_Store_Item_Select_Cb func, const void *data) EINA_ARG_NONNULL(1);
+   EAPI void                    elm_store_item_sort_func_set(Elm_Store *st, Elm_Store_Item_Sort_Cb func, const void *data) EINA_ARG_NONNULL(1);
+   EAPI int                     elm_store_item_data_index_get(const Elm_Store_Item *sti) EINA_ARG_NONNULL(1);
+   EAPI void                   *elm_store_dbsystem_db_get(const Elm_Store_Item *sti) EINA_ARG_NONNULL(1);
+   EAPI void                    elm_store_dbsystem_db_set(Elm_Store *store, void *pDB) EINA_ARG_NONNULL(1);
+   EAPI int                     elm_store_item_index_get(const Elm_Store_Item *sti) EINA_ARG_NONNULL(1);
+   EAPI Elm_Store_Item         *elm_store_item_add(Elm_Store *st, Elm_Store_Item_Info *info) EINA_ARG_NONNULL(1);
+   EAPI void                    elm_store_item_update(Elm_Store *st, Elm_Store_Item *sti) EINA_ARG_NONNULL(1);
+   EAPI void                    elm_store_visible_items_update(Elm_Store *st) EINA_ARG_NONNULL(1);
+   EAPI void                    elm_store_item_del(Elm_Store_Item *sti) EINA_ARG_NONNULL(1);
+   EAPI void                    elm_store_free(Elm_Store *st);
+   EAPI Elm_Store              *elm_store_filesystem_new(void);
+   EAPI void                    elm_store_filesystem_directory_set(Elm_Store *st, const char *dir) EINA_ARG_NONNULL(1);
+   EAPI const char             *elm_store_filesystem_directory_get(const Elm_Store *st) EINA_ARG_NONNULL(1);
+   EAPI const char             *elm_store_item_filesystem_path_get(const Elm_Store_Item *sti) EINA_ARG_NONNULL(1);
+   EAPI void                    elm_store_target_genlist_set(Elm_Store *st, Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void                    elm_store_cache_set(Elm_Store *st, int max) EINA_ARG_NONNULL(1);
+   EAPI int                     elm_store_cache_get(const Elm_Store *st) EINA_ARG_NONNULL(1);
+   EAPI void                    elm_store_list_func_set(Elm_Store *st, Elm_Store_Item_List_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
+   EAPI void                    elm_store_fetch_func_set(Elm_Store *st, Elm_Store_Item_Fetch_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
+   EAPI void                    elm_store_fetch_thread_set(Elm_Store *st, Eina_Bool use_thread) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool               elm_store_fetch_thread_get(const Elm_Store *st) EINA_ARG_NONNULL(1);
+   EAPI void                    elm_store_unfetch_func_set(Elm_Store *st, Elm_Store_Item_Unfetch_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
+   EAPI void                    elm_store_sorted_set(Elm_Store *st, Eina_Bool sorted) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool               elm_store_sorted_get(const Elm_Store *st) EINA_ARG_NONNULL(1);
+   EAPI void                    elm_store_item_data_set(Elm_Store_Item *sti, void *data) EINA_ARG_NONNULL(1);
+   EAPI void                   *elm_store_item_data_get(Elm_Store_Item *sti) EINA_ARG_NONNULL(1);
+   EAPI const Elm_Store        *elm_store_item_store_get(const Elm_Store_Item *sti) EINA_ARG_NONNULL(1);
+   EAPI const Elm_Genlist_Item *elm_store_item_genlist_item_get(const Elm_Store_Item *sti) EINA_ARG_NONNULL(1);
+
 
 #ifdef __cplusplus
 }
index dba552b..cf2d601 100644 (file)
@@ -3,7 +3,7 @@
 #include "elm_priv.h"
 
 #ifndef EFL_HAVE_THREADS
-# error "No thread support. Required." 
+# error "No thread support. Required."
 #endif
 
 #ifdef EFL_HAVE_POSIX_THREADS
 
 #define ELM_STORE_MAGIC            0x3f89ea56
 #define ELM_STORE_FILESYSTEM_MAGIC 0x3f89ea57
+#define ELM_STORE_DBSYSTEM_MAGIC   0x3f89ea58
 #define ELM_STORE_ITEM_MAGIC       0x5afe8c1d
+#define CACHE_COUNT                128
+#define SCREEN_ITEM_COUNT    10
 
 struct _Elm_Store
 {
-  EINA_MAGIC;
-  void         (*free)(Elm_Store *store);
-  struct {
-     void        (*free)(Elm_Store_Item *item);
-  } item;
-  Evas_Object   *genlist;
-  Ecore_Thread  *list_th;
-  Eina_Inlist   *items;
-  Eina_List     *realized;
-  int            realized_count;
-  int            cache_max;
-  struct {
-    struct {
-      Elm_Store_Item_List_Cb     func;
-      void                      *data;
-    } list;
-    struct {
-      Elm_Store_Item_Fetch_Cb    func;
-      void                      *data;
-    } fetch;
-    struct {
-      Elm_Store_Item_Unfetch_Cb  func;
-      void                      *data;
-    } unfetch;
-  } cb;
-  Eina_Bool sorted : 1;
-  Eina_Bool fetch_thread : 1;
+   EINA_MAGIC;
+   void         (*free)(Elm_Store *store);
+   struct {
+        void        (*free)(Elm_Store_Item *item);
+   } item;
+   Evas_Object   *genlist;
+   Ecore_Thread  *list_th;
+   Eina_Inlist   *items;
+   Eina_List     *realized;
+   int            realized_count;
+   int            cache_max;
+   int            current_top_index;
+   int            start_fetch_index;
+   int            end_fetch_index;
+   int            item_count;
+   int            total_count;
+   int            block_count;
+   int            type;
+   Eina_List     *header_items;
+   struct {
+        struct {
+             Elm_Store_Item_List_Cb     func;
+             void                      *data;
+        } list;
+        struct {
+             Elm_Store_Item_Fetch_Cb    func;
+             void                      *data;
+        } fetch;
+        struct {
+             Elm_Store_Item_Unfetch_Cb  func;
+             void                      *data;
+        } unfetch;
+        struct {
+             Elm_Store_Item_Select_Cb func;
+             void                    *data;
+        } item_select;
+        struct {
+             Elm_Store_Item_Sort_Cb func;
+             void                  *data;
+        } item_sort;
+   } cb;
+   Eina_Bool      sorted : 1;
+   Eina_Bool      fetch_thread : 1;
+   Eina_Bool      multi_load : 1;
+   Eina_Bool      live : 1;
 };
 
 struct _Elm_Store_Item
 {
-  EINA_INLIST;
-  EINA_MAGIC;
-  Elm_Store                    *store;
-  Elm_Genlist_Item             *item;
-  Ecore_Thread                 *fetch_th;
-  Ecore_Job                    *eval_job;
-  const Elm_Store_Item_Mapping *mapping;
-  void                         *data;
-  LK(lock);
-  Eina_Bool                     live : 1;
-  Eina_Bool                     was_live : 1;
-  Eina_Bool                     realized : 1;
-  Eina_Bool                     fetched : 1;
+   EINA_INLIST;
+   EINA_MAGIC;
+   Elm_Store                    *store;
+   Elm_Genlist_Item             *item;
+   Ecore_Thread                 *fetch_th;
+   Ecore_Job                    *eval_job;
+   const Elm_Store_Item_Mapping *mapping;
+   void                         *data;
+   Elm_Store_Item_Info          *item_info;
+   LK(lock);
+   Eina_Bool                     live : 1;
+   Eina_Bool                     was_live : 1;
+   Eina_Bool                     realized : 1;
+   Eina_Bool                     fetched : 1;
 };
 
 struct _Elm_Store_Filesystem
 {
-  Elm_Store base;
-  EINA_MAGIC;
-  const char *dir;
+   Elm_Store   base;
+   EINA_MAGIC;
+   const char *dir;
 };
 
 struct _Elm_Store_Item_Filesystem
 {
-  Elm_Store_Item base;
-  const char *path;
+   Elm_Store_Item base;
+   const char    *path;
+};
+
+struct _Elm_Store_DBsystem
+{
+   Elm_Store   base;
+   EINA_MAGIC;
+   void       *p_db;
 };
 
 static Elm_Genlist_Item_Class _store_item_class;
 
+static char *_item_label_get(void *data, Evas_Object *obj __UNUSED__, const char *part);
+static Evas_Object *_item_icon_get(void *data, Evas_Object *obj, const char *part);
+static void _item_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__);
+static void _store_free(Elm_Store *st);
+static void _item_free(Elm_Store_Item *sti);
+static void _item_realized(void *data, Evas_Object *obj __UNUSED__, void *event_info);
+static void _item_unrealized(void *data, Evas_Object *obj __UNUSED__, void *event_info);
+static void _genlist_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__);
+static Elm_Store_Item *_item_unfetch(Elm_Store *st, int index);
+
 static void
 _store_cache_trim(Elm_Store *st)
 {
-  while ((st->realized ) &&
-         (((int)eina_list_count(st->realized) - st->realized_count)
+   while ((st->realized ) &&
+          (((int)eina_list_count(st->realized) - st->realized_count)
            > st->cache_max))
-    {
-      Elm_Store_Item *sti = st->realized->data;
-      if (sti->realized)
-        {
-          st->realized = eina_list_remove_list(st->realized, st->realized);
-          sti->realized = EINA_FALSE;
-        }
-      LKL(sti->lock);
-      if (!sti->fetched)
-        {
-          LKU(sti->lock);
-          if (sti->fetch_th)
-            {
-              ecore_thread_cancel(sti->fetch_th);
-              sti->fetch_th = NULL;
-            }
-          LKL(sti->lock);
-        }
-      sti->fetched = EINA_FALSE;
-      LKU(sti->lock);
-      if (st->cb.unfetch.func)
-        st->cb.unfetch.func(st->cb.unfetch.data, sti);
-      LKL(sti->lock);
-      sti->data = NULL;
-      LKU(sti->lock);
-    }
-}
-
-static void 
+     {
+        Elm_Store_Item *sti = st->realized->data;
+        if (sti->realized)
+          {
+             st->realized = eina_list_remove_list(st->realized, st->realized);
+             sti->realized = EINA_FALSE;
+          }
+        LKL(sti->lock);
+        if (!sti->fetched)
+          {
+             LKU(sti->lock);
+             if (sti->fetch_th)
+               {
+                  ecore_thread_cancel(sti->fetch_th);
+                  sti->fetch_th = NULL;
+               }
+             LKL(sti->lock);
+          }
+        sti->fetched = EINA_FALSE;
+        LKU(sti->lock);
+        if (st->cb.unfetch.func)
+          st->cb.unfetch.func(st->cb.unfetch.data, sti, NULL);
+        LKL(sti->lock);
+        sti->data = NULL;
+        LKU(sti->lock);
+     }
+}
+
+static void
 _store_genlist_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
-  Elm_Store *st = data;
-  st->genlist = NULL;
-  if (st->list_th)
-    {
-      ecore_thread_cancel(st->list_th);
-      st->list_th = NULL;
-    }
-  eina_list_free(st->realized);
-  while (st->items)
-    {
-      Elm_Store_Item *sti = (Elm_Store_Item *)st->items;
-      if (sti->eval_job) ecore_job_del(sti->eval_job);
-      if (sti->fetch_th)
-        {
-          ecore_thread_cancel(sti->fetch_th);
-          sti->fetch_th = NULL;
-        }
-      if (sti->store->item.free) sti->store->item.free(sti);
-      if (sti->data)
-        {
-          if (st->cb.unfetch.func)
-            st->cb.unfetch.func(st->cb.unfetch.data, sti);
-          sti->data = NULL;
-        }
-      LKD(sti->lock);
-      free(sti);
-    }
-  // FIXME: kill threads and more
+   Elm_Store *st = data;
+   st->genlist = NULL;
+   if (st->list_th)
+     {
+        ecore_thread_cancel(st->list_th);
+        st->list_th = NULL;
+     }
+   eina_list_free(st->realized);
+   while (st->items)
+     {
+        Elm_Store_Item *sti = (Elm_Store_Item *)st->items;
+        if (sti->eval_job) ecore_job_del(sti->eval_job);
+        if (sti->fetch_th)
+          {
+             ecore_thread_cancel(sti->fetch_th);
+             sti->fetch_th = NULL;
+          }
+        if (sti->store->item.free) sti->store->item.free(sti);
+        if (sti->data)
+          {
+             if (st->cb.unfetch.func)
+               st->cb.unfetch.func(st->cb.unfetch.data, sti, NULL);
+             sti->data = NULL;
+          }
+        LKD(sti->lock);
+        free(sti);
+     }
+   // FIXME: kill threads and more
 }
 
 ////// **** WARNING ***********************************************************
@@ -165,22 +204,22 @@ _store_genlist_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
 static void
 _store_filesystem_fetch_do(void *data, Ecore_Thread *th __UNUSED__)
 {
-  Elm_Store_Item *sti = data;
-  LKL(sti->lock);
-  if (sti->data)
-    {
-      LKU(sti->lock);
-      return;
-    }
-  if (!sti->fetched)
-    {
-      LKU(sti->lock);
-      if (sti->store->cb.fetch.func)
-        sti->store->cb.fetch.func(sti->store->cb.fetch.data, sti);
-      LKL(sti->lock);
-      sti->fetched = EINA_TRUE;
-    }
-  LKU(sti->lock);
+   Elm_Store_Item *sti = data;
+   LKL(sti->lock);
+   if (sti->data)
+     {
+        LKU(sti->lock);
+        return;
+     }
+   if (!sti->fetched)
+     {
+        LKU(sti->lock);
+        if (sti->store->cb.fetch.func)
+          sti->store->cb.fetch.func(sti->store->cb.fetch.data, sti, NULL);
+        LKL(sti->lock);
+        sti->fetched = EINA_TRUE;
+     }
+   LKU(sti->lock);
 }
 //     ************************************************************************
 ////   * End of separate thread function.                                     *
@@ -189,184 +228,184 @@ _store_filesystem_fetch_do(void *data, Ecore_Thread *th __UNUSED__)
 static void
 _store_filesystem_fetch_end(void *data, Ecore_Thread *th)
 {
-  Elm_Store_Item *sti = data;
-  LKL(sti->lock);
-  if (sti->data) elm_genlist_item_update(sti->item);
-  LKU(sti->lock);
-  if (th == sti->fetch_th) sti->fetch_th = NULL;
+   Elm_Store_Item *sti = data;
+   LKL(sti->lock);
+   if (sti->data) elm_genlist_item_update(sti->item);
+   LKU(sti->lock);
+   if (th == sti->fetch_th) sti->fetch_th = NULL;
 }
 
 /* TODO: refactor lock part into core? this does not depend on filesystm part */
 static void
 _store_filesystem_fetch_cancel(void *data, Ecore_Thread *th)
 {
-  Elm_Store_Item *sti = data;
-  LKL(sti->lock);
-  if (th == sti->fetch_th) sti->fetch_th = NULL;
-  if (sti->data) elm_genlist_item_update(sti->item);
-  LKU(sti->lock);
+   Elm_Store_Item *sti = data;
+   LKL(sti->lock);
+   if (th == sti->fetch_th) sti->fetch_th = NULL;
+   if (sti->data) elm_genlist_item_update(sti->item);
+   LKU(sti->lock);
 }
 
 static void
 _store_item_eval(void *data)
 {
-  Elm_Store_Item *sti = data;
-  sti->eval_job = NULL;
-  if (sti->live == sti->was_live) return;
-  sti->was_live = sti->live;
-  if (sti->live)
-    {
-      _store_cache_trim(sti->store);
-      if (sti->realized)
-        sti->store->realized = eina_list_remove(sti->store->realized, sti);
-      sti->store->realized = eina_list_append(sti->store->realized, sti);
-      sti->realized = EINA_TRUE;
-      if ((sti->store->fetch_thread) && (!sti->fetch_th))
-        sti->fetch_th = ecore_thread_run(_store_filesystem_fetch_do,
-                                         _store_filesystem_fetch_end,
-                                         _store_filesystem_fetch_cancel,
-                                         sti);
-      else if ((!sti->store->fetch_thread))
-        {
-          _store_filesystem_fetch_do(sti, NULL);
-          _store_filesystem_fetch_end(sti, NULL);
-        }
-    }
-  else
-    {
-      if (sti->fetch_th)
-        {
-          ecore_thread_cancel(sti->fetch_th);
-          sti->fetch_th = NULL;
-        }
-      _store_cache_trim(sti->store);
-    }
+   Elm_Store_Item *sti = data;
+   sti->eval_job = NULL;
+   if (sti->live == sti->was_live) return;
+   sti->was_live = sti->live;
+   if (sti->live)
+     {
+        _store_cache_trim(sti->store);
+        if (sti->realized)
+          sti->store->realized = eina_list_remove(sti->store->realized, sti);
+        sti->store->realized = eina_list_append(sti->store->realized, sti);
+        sti->realized = EINA_TRUE;
+        if ((sti->store->fetch_thread) && (!sti->fetch_th))
+          sti->fetch_th = ecore_thread_run(_store_filesystem_fetch_do,
+                                           _store_filesystem_fetch_end,
+                                           _store_filesystem_fetch_cancel,
+                                           sti);
+        else if ((!sti->store->fetch_thread))
+          {
+             _store_filesystem_fetch_do(sti, NULL);
+             _store_filesystem_fetch_end(sti, NULL);
+          }
+     }
+   else
+     {
+        if (sti->fetch_th)
+          {
+             ecore_thread_cancel(sti->fetch_th);
+             sti->fetch_th = NULL;
+          }
+        _store_cache_trim(sti->store);
+     }
 }
 
 static void
 _store_genlist_item_realized(void *data, Evas_Object *obj __UNUSED__, void *event_info)
 {
-  Elm_Store *st = data;
-  Elm_Genlist_Item *gli = event_info;
-  Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
-  if (!sti) return;
-  st->realized_count++;
-  sti->live = EINA_TRUE;
-  if (sti->eval_job) ecore_job_del(sti->eval_job);
-  sti->eval_job = ecore_job_add(_store_item_eval, sti);
+   Elm_Store *st = data;
+   Elm_Genlist_Item *gli = event_info;
+   Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
+   if (!sti) return;
+   st->realized_count++;
+   sti->live = EINA_TRUE;
+   if (sti->eval_job) ecore_job_del(sti->eval_job);
+   sti->eval_job = ecore_job_add(_store_item_eval, sti);
 }
 
 static void
 _store_genlist_item_unrealized(void *data, Evas_Object *obj __UNUSED__, void *event_info)
 {
-  Elm_Store *st = data;
-  Elm_Genlist_Item *gli = event_info;
-  Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
-  if (!sti) return;
-  st->realized_count--;
-  sti->live = EINA_FALSE;
-  if (sti->eval_job) ecore_job_del(sti->eval_job);
-  sti->eval_job = ecore_job_add(_store_item_eval, sti);
+   Elm_Store *st = data;
+   Elm_Genlist_Item *gli = event_info;
+   Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
+   if (!sti) return;
+   st->realized_count--;
+   sti->live = EINA_FALSE;
+   if (sti->eval_job) ecore_job_del(sti->eval_job);
+   sti->eval_job = ecore_job_add(_store_item_eval, sti);
 }
 
 static const Elm_Store_Item_Mapping *
 _store_item_mapping_find(Elm_Store_Item *sti, const char *part)
 {
-  const Elm_Store_Item_Mapping *m;
-  
-  for (m = sti->mapping; m; m ++)
-    {
-      if (m->type == ELM_STORE_ITEM_MAPPING_NONE) break;
-      if (!strcmp(part, m->part)) return m;
-    }
-  return NULL;
+   const Elm_Store_Item_Mapping *m;
+
+   for (m = sti->mapping; m; m ++)
+     {
+        if (m->type == ELM_STORE_ITEM_MAPPING_NONE) break;
+        if (!strcmp(part, m->part)) return m;
+     }
+   return NULL;
 }
 
 static char *
 _store_item_label_get(void *data, Evas_Object *obj __UNUSED__, const char *part)
 {
-  Elm_Store_Item *sti = data;
-  const char *s = "";
-  LKL(sti->lock);
-  if (sti->data)
-    {
-      const Elm_Store_Item_Mapping *m = _store_item_mapping_find(sti, part);
-      if (m)
-        {
-          switch (m->type)
-            {
-            case ELM_STORE_ITEM_MAPPING_LABEL:
-              s = *(char **)(((unsigned char *)sti->data) + m->offset);
-              break;
-            case ELM_STORE_ITEM_MAPPING_CUSTOM:
-              if (m->details.custom.func)
-                s = m->details.custom.func(sti->data, sti, part);
-              break;
-            default:
-              break;
-            }
-        }
-    }
-  LKU(sti->lock);
-  return strdup(s);
+   Elm_Store_Item *sti = data;
+   const char *s = "";
+   LKL(sti->lock);
+   if (sti->data)
+     {
+        const Elm_Store_Item_Mapping *m = _store_item_mapping_find(sti, part);
+        if (m)
+          {
+             switch (m->type)
+               {
+                case ELM_STORE_ITEM_MAPPING_LABEL:
+                   s = *(char **)(((unsigned char *)sti->data) + m->offset);
+                   break;
+                case ELM_STORE_ITEM_MAPPING_CUSTOM:
+                   if (m->details.custom.func)
+                     s = m->details.custom.func(sti->data, sti, part);
+                   break;
+                default:
+                   break;
+               }
+          }
+     }
+   LKU(sti->lock);
+   return strdup(s);
 }
 
 static Evas_Object *
 _store_item_icon_get(void *data, Evas_Object *obj, const char *part)
 {
-  Elm_Store_Item *sti = data;
-  LKL(sti->lock);
-  if (sti->data)
-    {
-      const Elm_Store_Item_Mapping *m = _store_item_mapping_find(sti, part);
-      if (m)
-        {
-          Evas_Object *ic = NULL;
-          const char *s = NULL;
-          
-          switch (m->type)
-            {
-            case ELM_STORE_ITEM_MAPPING_ICON:
-              ic = elm_icon_add(obj);
-              s = *(char **)(((unsigned char *)sti->data) + m->offset);
-              elm_icon_order_lookup_set(ic, m->details.icon.lookup_order);
-              evas_object_size_hint_aspect_set(ic, 
-                                               EVAS_ASPECT_CONTROL_VERTICAL, 
-                                               m->details.icon.w,
-                                               m->details.icon.h);
-              elm_icon_smooth_set(ic, m->details.icon.smooth);
-              elm_icon_no_scale_set(ic, m->details.icon.no_scale);
-              elm_icon_scale_set(ic, 
-                                 m->details.icon.scale_up, 
-                                 m->details.icon.scale_down);
-              if (s)
-                {
-                  if (m->details.icon.standard_name)
-                    elm_icon_standard_set(ic, s);
-                  else
-                    elm_icon_file_set(ic, s, NULL);
-                }
-              break;
-            case ELM_STORE_ITEM_MAPPING_PHOTO:
-              ic = elm_icon_add(obj);
-              s = *(char **)(((unsigned char *)sti->data) + m->offset);
-              elm_photo_size_set(ic, m->details.photo.size);
-              if (s)
-                elm_photo_file_set(ic, s);
-              break;
-            case ELM_STORE_ITEM_MAPPING_CUSTOM:
-              if (m->details.custom.func)
-                ic = m->details.custom.func(sti->data, sti, part);
-              break;
-            default:
-              break;
-            }
-          LKU(sti->lock);
-          return ic;
-        }
-    }
-  LKU(sti->lock);
-  return NULL;
+   Elm_Store_Item *sti = data;
+   LKL(sti->lock);
+   if (sti->data)
+     {
+        const Elm_Store_Item_Mapping *m = _store_item_mapping_find(sti, part);
+        if (m)
+          {
+             Evas_Object *ic = NULL;
+             const char *s = NULL;
+
+             switch (m->type)
+               {
+                case ELM_STORE_ITEM_MAPPING_ICON:
+                   ic = elm_icon_add(obj);
+                   s = *(char **)(((unsigned char *)sti->data) + m->offset);
+                   elm_icon_order_lookup_set(ic, m->details.icon.lookup_order);
+                   evas_object_size_hint_aspect_set(ic,
+                                                    EVAS_ASPECT_CONTROL_VERTICAL,
+                                                    m->details.icon.w,
+                                                    m->details.icon.h);
+                   elm_icon_smooth_set(ic, m->details.icon.smooth);
+                   elm_icon_no_scale_set(ic, m->details.icon.no_scale);
+                   elm_icon_scale_set(ic,
+                                      m->details.icon.scale_up,
+                                      m->details.icon.scale_down);
+                   if (s)
+                     {
+                        if (m->details.icon.standard_name)
+                          elm_icon_standard_set(ic, s);
+                        else
+                          elm_icon_file_set(ic, s, NULL);
+                     }
+                   break;
+                case ELM_STORE_ITEM_MAPPING_PHOTO:
+                   ic = elm_icon_add(obj);
+                   s = *(char **)(((unsigned char *)sti->data) + m->offset);
+                   elm_photo_size_set(ic, m->details.photo.size);
+                   if (s)
+                     elm_photo_file_set(ic, s);
+                   break;
+                case ELM_STORE_ITEM_MAPPING_CUSTOM:
+                   if (m->details.custom.func)
+                     ic = m->details.custom.func(sti->data, sti, part);
+                   break;
+                default:
+                   break;
+               }
+             LKU(sti->lock);
+             return ic;
+          }
+     }
+   LKU(sti->lock);
+   return NULL;
 }
 
 static void
@@ -380,58 +419,58 @@ _store_item_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__)
 static int
 _store_filesystem_sort_cb(void *d1, void *d2)
 {
-  Elm_Store_Item_Info *info1 = d1, *info2 = d2;
-  if ((!info1->sort_id) || (!info2->sort_id)) return 0;
-  return strcoll(info1->sort_id, info2->sort_id);
+   Elm_Store_Item_Info *info1 = d1, *info2 = d2;
+   if ((!info1->sort_id) || (!info2->sort_id)) return 0;
+   return strcoll(info1->sort_id, info2->sort_id);
 }
 
 static void
 _store_filesystem_list_do(void *data, Ecore_Thread *th __UNUSED__)
 {
-  Elm_Store_Filesystem *st = data;
-  Eina_Iterator *it;
-  const Eina_File_Direct_Info *finf;
-  Eina_List *sorted = NULL;
-  Elm_Store_Item_Info_Filesystem *info;
-
-  // FIXME: need a way to abstract the open, list, feed items from list
-  // and maybe get initial sortable key vals etc.
-  it = eina_file_stat_ls(st->dir);
-  if (!it) return;
-  EINA_ITERATOR_FOREACH(it, finf)
-    {
-      Eina_Bool ok;
-      size_t pathsz = finf->path_length + 1;
-
-      info = calloc(1, sizeof(Elm_Store_Item_Info_Filesystem) + pathsz);
-      if (!info) continue;
-      info->path = ((char *)info) + sizeof(Elm_Store_Item_Info_Filesystem);
-      memcpy(info->path, finf->path, pathsz);
-      ok = EINA_TRUE;
-      if (st->base.cb.list.func)
-        ok = st->base.cb.list.func(st->base.cb.list.data, &info->base);
-      if (ok)
-        {
-          if (!st->base.sorted) ecore_thread_feedback(th, info);
-          else sorted = eina_list_append(sorted, info);
-        }
-      else
-        {
-          if (info->base.sort_id) free(info->base.sort_id);
-          free(info);
-        }
-      if (ecore_thread_check(th)) break;
-    }
-  eina_iterator_free(it);
-  if (sorted)
-    {
-      sorted = eina_list_sort(sorted, 0,
-                              EINA_COMPARE_CB(_store_filesystem_sort_cb));
-      EINA_LIST_FREE(sorted, info)
-        {
-          if (!ecore_thread_check(th)) ecore_thread_feedback(th, info);
-        }
-    }
+   Elm_Store_Filesystem *st = data;
+   Eina_Iterator *it;
+   const Eina_File_Direct_Info *finf;
+   Eina_List *sorted = NULL;
+   Elm_Store_Item_Info_Filesystem *info;
+
+   // FIXME: need a way to abstract the open, list, feed items from list
+   // and maybe get initial sortable key vals etc.
+   it = eina_file_stat_ls(st->dir);
+   if (!it) return;
+   EINA_ITERATOR_FOREACH(it, finf)
+     {
+        Eina_Bool ok;
+        size_t pathsz = finf->path_length + 1;
+
+        info = calloc(1, sizeof(Elm_Store_Item_Info_Filesystem) + pathsz);
+        if (!info) continue;
+        info->path = ((char *)info) + sizeof(Elm_Store_Item_Info_Filesystem);
+        memcpy(info->path, finf->path, pathsz);
+        ok = EINA_TRUE;
+        if (st->base.cb.list.func)
+          ok = st->base.cb.list.func(st->base.cb.list.data, &info->base);
+        if (ok)
+          {
+             if (!st->base.sorted) ecore_thread_feedback(th, info);
+             else sorted = eina_list_append(sorted, info);
+          }
+        else
+          {
+             if (info->base.sort_id) free(info->base.sort_id);
+             free(info);
+          }
+        if (ecore_thread_check(th)) break;
+     }
+   eina_iterator_free(it);
+   if (sorted)
+     {
+        sorted = eina_list_sort(sorted, 0,
+                                EINA_COMPARE_CB(_store_filesystem_sort_cb));
+        EINA_LIST_FREE(sorted, info)
+          {
+             if (!ecore_thread_check(th)) ecore_thread_feedback(th, info);
+          }
+     }
 }
 //     ************************************************************************
 ////   * End of separate thread function.                                     *
@@ -440,88 +479,89 @@ _store_filesystem_list_do(void *data, Ecore_Thread *th __UNUSED__)
 static void
 _store_filesystem_list_end(void *data, Ecore_Thread *th)
 {
-  Elm_Store *st = data;
-  if (th == st->list_th) st->list_th = NULL;
+   Elm_Store *st = data;
+   if (th == st->list_th) st->list_th = NULL;
 }
 
 static void
 _store_filesystem_list_cancel(void *data, Ecore_Thread *th)
 {
-  Elm_Store *st = data;
-  if (th == st->list_th) st->list_th = NULL;
+   Elm_Store *st = data;
+   if (th == st->list_th) st->list_th = NULL;
 }
 
 static void
 _store_filesystem_list_update(void *data, Ecore_Thread *th __UNUSED__, void *msg)
 {
-  Elm_Store *st = data;
-  Elm_Store_Item_Filesystem *sti;
-  Elm_Genlist_Item_Class *itc;
-  Elm_Store_Item_Info_Filesystem *info = msg;
-  
-  sti = calloc(1, sizeof(Elm_Store_Item_Filesystem));
-  if (!sti) goto done;
-  LKI(sti->base.lock);
-  EINA_MAGIC_SET(&(sti->base), ELM_STORE_ITEM_MAGIC);
-  sti->base.store = st;
-  sti->base.data = info->base.data;
-  sti->base.mapping = info->base.mapping;
-  sti->path = eina_stringshare_add(info->path);
-  
-  itc = info->base.item_class;
-  if (!itc) itc = &_store_item_class;
-  else
-    {
-      itc->func.label_get = _store_item_label_get;
-      itc->func.icon_get  = _store_item_icon_get;
-      itc->func.state_get = NULL; // FIXME: support state gets later
-      itc->func.del       = _store_item_del;
-    }
-
-  // FIXME: handle being a parent (tree)
-  sti->base.item = elm_genlist_item_append(st->genlist, itc,
-                                           sti/* item data */,
-                                           NULL/* parent */,
-                                           ELM_GENLIST_ITEM_NONE,
-                                           NULL/* func */,
-                                           NULL/* func data */);
-  st->items = eina_inlist_append(st->items, (Eina_Inlist *)sti);
+   Elm_Store *st = data;
+   Elm_Store_Item_Filesystem *sti;
+   Elm_Genlist_Item_Class *itc;
+   Elm_Store_Item_Info_Filesystem *info = msg;
+
+   sti = calloc(1, sizeof(Elm_Store_Item_Filesystem));
+   if (!sti) goto done;
+   LKI(sti->base.lock);
+   EINA_MAGIC_SET(&(sti->base), ELM_STORE_ITEM_MAGIC);
+   sti->base.store = st;
+   sti->base.data = info->base.data;
+   sti->base.mapping = info->base.mapping;
+   sti->path = eina_stringshare_add(info->path);
+
+   itc = info->base.item_class;
+   if (!itc) itc = &_store_item_class;
+   else
+     {
+        itc->func.label_get = (GenlistItemLabelGetFunc)_store_item_label_get;
+        itc->func.icon_get  = (GenlistItemIconGetFunc)_store_item_icon_get;
+        itc->func.state_get = NULL; // FIXME: support state gets later
+        itc->func.del = (GenlistItemDelFunc)_store_item_del;
+     }
+
+   // FIXME: handle being a parent (tree)
+   sti->base.item = elm_genlist_item_append(st->genlist, itc,
+                                            sti/* item data */,
+                                            NULL/* parent */,
+                                            ELM_GENLIST_ITEM_NONE,
+                                            NULL/* func */,
+                                            NULL/* func data */);
+   st->items = eina_inlist_append(st->items, (Eina_Inlist *)sti);
 done:
-  if (info->base.sort_id) free(info->base.sort_id);
-  free(info);
+   if (info->base.sort_id) free(info->base.sort_id);
+   free(info);
 }
 
 // public api calls
 static Elm_Store *
 _elm_store_new(size_t size)
 {
-  Elm_Store *st = calloc(1, size);
-  EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
-
-  // TODO: BEGIN - move to elm_store_init()
-  eina_magic_string_set(ELM_STORE_MAGIC, "Elm_Store");
-  eina_magic_string_set(ELM_STORE_FILESYSTEM_MAGIC, "Elm_Store_Filesystem");
-  eina_magic_string_set(ELM_STORE_ITEM_MAGIC, "Elm_Store_Item");
-  // setup default item class (always the same) if list cb doesnt provide one
-  _store_item_class.item_style = "default";
-  _store_item_class.func.label_get = _store_item_label_get;
-  _store_item_class.func.icon_get  = _store_item_icon_get;
-  _store_item_class.func.state_get = NULL; // FIXME: support state gets later
-  _store_item_class.func.del       = _store_item_del;
-  // TODO: END - move to elm_store_init()
-
-  EINA_MAGIC_SET(st, ELM_STORE_MAGIC);
-  st->cache_max = 128;
-  st->fetch_thread = EINA_TRUE;
-  return st;
+   Elm_Store *st = calloc(1, size);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
+
+   // TODO: BEGIN - move to elm_store_init()
+   eina_magic_string_set(ELM_STORE_MAGIC, "Elm_Store");
+   eina_magic_string_set(ELM_STORE_FILESYSTEM_MAGIC, "Elm_Store_Filesystem");
+   eina_magic_string_set(ELM_STORE_ITEM_MAGIC, "Elm_Store_Item");
+   // setup default item class (always the same) if list cb doesnt provide one
+   _store_item_class.item_style = "default";
+   _store_item_class.func.label_get = (GenlistItemLabelGetFunc)_store_item_label_get;
+   _store_item_class.func.icon_get  = (GenlistItemIconGetFunc)_store_item_icon_get;
+   _store_item_class.func.state_get = NULL; // FIXME: support state gets later
+   _store_item_class.func.del       = (GenlistItemDelFunc)_store_item_del;
+   // TODO: END - move to elm_store_init()
+
+   EINA_MAGIC_SET(st, ELM_STORE_MAGIC);
+   st->cache_max = 128;
+   st->fetch_thread = EINA_TRUE;
+   st->type = 0;
+   return st;
 }
 #define elm_store_new(type) (type*)_elm_store_new(sizeof(type))
 
 static void
 _elm_store_filesystem_free(Elm_Store *store)
 {
-  Elm_Store_Filesystem *st = (Elm_Store_Filesystem *)store;
-  eina_stringshare_del(st->dir);
+   Elm_Store_Filesystem *st = (Elm_Store_Filesystem *)store;
+   eina_stringshare_del(st->dir);
 }
 
 static void
@@ -534,221 +574,1420 @@ _elm_store_filesystem_item_free(Elm_Store_Item *item)
 EAPI Elm_Store *
 elm_store_filesystem_new(void)
 {
-  Elm_Store_Filesystem *st = elm_store_new(Elm_Store_Filesystem);
-  EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
+   Elm_Store_Filesystem *st = elm_store_new(Elm_Store_Filesystem);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
 
-  EINA_MAGIC_SET(st, ELM_STORE_FILESYSTEM_MAGIC);
-  st->base.free = _elm_store_filesystem_free;
-  st->base.item.free = _elm_store_filesystem_item_free;
+   EINA_MAGIC_SET(st, ELM_STORE_FILESYSTEM_MAGIC);
+   st->base.free = _elm_store_filesystem_free;
+   st->base.item.free = _elm_store_filesystem_item_free;
 
-  return &st->base;
+   return &st->base;
 }
 
 EAPI void
 elm_store_free(Elm_Store *st)
 {
-  void (*item_free)(Elm_Store_Item *);
-  if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
-  if (st->list_th)
-    {
-      ecore_thread_cancel(st->list_th);
-      st->list_th = NULL;
-    }
-  eina_list_free(st->realized);
-  item_free = st->item.free;
-  while (st->items)
-    {
-      Elm_Store_Item *sti = (Elm_Store_Item *)st->items;
-      if (sti->eval_job) ecore_job_del(sti->eval_job);
-      if (sti->fetch_th)
-        {
-          ecore_thread_cancel(sti->fetch_th);
-          sti->fetch_th = NULL;
-        }
-      if (item_free) item_free(sti);
-      if (sti->data)
-        {
-          if (st->cb.unfetch.func)
-            st->cb.unfetch.func(st->cb.unfetch.data, sti);
-          sti->data = NULL;
-        }
-      LKD(sti->lock);
-      free(sti);
-    }
-  if (st->genlist)
-    {
-      evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _store_genlist_del, st);
-      evas_object_smart_callback_del(st->genlist, "realized", _store_genlist_item_realized);
-      evas_object_smart_callback_del(st->genlist, "unrealized", _store_genlist_item_unrealized);
-      elm_genlist_clear(st->genlist);
-      st->genlist = NULL;
-    }
-  if (st->free) st->free(st);
-  free(st);
+   void (*item_free)(Elm_Store_Item *);
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
+   if (st->list_th)
+     {
+        ecore_thread_cancel(st->list_th);
+        st->list_th = NULL;
+     }
+
+   if (!st->type)
+     {
+        eina_list_free(st->realized);
+        item_free = st->item.free;
+        while (st->items)
+          {
+             Elm_Store_Item *sti = (Elm_Store_Item *)st->items;
+             if (sti->eval_job) ecore_job_del(sti->eval_job);
+             if (sti->fetch_th)
+               {
+                  ecore_thread_cancel(sti->fetch_th);
+                  sti->fetch_th = NULL;
+               }
+             if (item_free) item_free(sti);
+             if (sti->data)
+               {
+                  if (st->cb.unfetch.func)
+                    st->cb.unfetch.func(st->cb.unfetch.data, sti, NULL);
+                  sti->data = NULL;
+               }
+             LKD(sti->lock);
+             free(sti);
+          }
+        if (st->genlist)
+          {
+             evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _store_genlist_del, st);
+             evas_object_smart_callback_del(st->genlist, "realized", _store_genlist_item_realized);
+             evas_object_smart_callback_del(st->genlist, "unrealized", _store_genlist_item_unrealized);
+             elm_genlist_clear(st->genlist);
+             st->genlist = NULL;
+          }
+        if (st->free) st->free(st);
+     }
+   else
+     {
+        Eina_List *l;
+        Eina_List *header_list;
+
+        EINA_LIST_FOREACH(st->header_items, l, header_list)
+          {
+             if (header_list)
+               {
+                  Eina_List *in_l;
+                  Elm_Store_Item *sti;
+                  EINA_LIST_FOREACH(header_list, in_l, sti)
+                    {
+                       if (sti->data)
+                         {
+                            int index = elm_store_item_index_get(sti);
+                            _item_unfetch(st, index);
+                         }
+                    }
+                  free(sti);
+               }
+          }
+        eina_list_free(st->header_items);
+
+        if (st->genlist)
+          {
+             evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _genlist_del, st);
+             evas_object_smart_callback_del(st->genlist, "realized", _item_realized);
+             evas_object_smart_callback_del(st->genlist, "unrealized", _item_unrealized);
+             elm_genlist_clear(st->genlist);
+             st->genlist = NULL;
+          }
+     }
+   free(st);
 }
 
 EAPI void
 elm_store_target_genlist_set(Elm_Store *st, Evas_Object *obj)
 {
-  if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
-  if (st->genlist == obj) return;
-  if (st->genlist)
-    {
-      evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _store_genlist_del, st);
-      evas_object_smart_callback_del(st->genlist, "realized", _store_genlist_item_realized);
-      evas_object_smart_callback_del(st->genlist, "unrealized", _store_genlist_item_unrealized);
-      elm_genlist_clear(st->genlist);
-    }
-  st->genlist = obj;
-  if (!st->genlist) return;
-  evas_object_smart_callback_add(st->genlist, "realized", _store_genlist_item_realized, st);
-  evas_object_smart_callback_add(st->genlist, "unrealized", _store_genlist_item_unrealized, st);
-  evas_object_event_callback_add(st->genlist, EVAS_CALLBACK_DEL, _store_genlist_del, st);
-  elm_genlist_clear(st->genlist);
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
+   if (st->genlist == obj) return;
+   if (st->genlist)
+     {
+        if (!st->type)
+          {
+             evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _store_genlist_del, st);
+             evas_object_smart_callback_del(st->genlist, "realized", _store_genlist_item_realized);
+             evas_object_smart_callback_del(st->genlist, "unrealized", _store_genlist_item_unrealized);
+          }
+        else
+          {
+             evas_object_event_callback_del_full(st->genlist, EVAS_CALLBACK_DEL, _genlist_del, st);
+             evas_object_smart_callback_del(st->genlist, "realized", _item_realized);
+             evas_object_smart_callback_del(st->genlist, "unrealized", _item_unrealized);
+          }
+        elm_genlist_clear(st->genlist);
+     }
+   st->genlist = obj;
+   if (!st->genlist) return;
+   if (!st->type)
+     {
+        evas_object_smart_callback_add(st->genlist, "realized", _store_genlist_item_realized, st);
+        evas_object_smart_callback_add(st->genlist, "unrealized", _store_genlist_item_unrealized, st);
+        evas_object_event_callback_add(st->genlist, EVAS_CALLBACK_DEL, _store_genlist_del, st);
+     }
+   else
+     {
+        evas_object_smart_callback_add(st->genlist, "realized", _item_realized, st);
+        evas_object_smart_callback_add(st->genlist, "unrealized", _item_unrealized, st);
+        evas_object_event_callback_add(st->genlist, EVAS_CALLBACK_DEL, _genlist_del, st);
+        st->block_count = elm_genlist_block_count_get(st->genlist);
+     }
+   elm_genlist_clear(st->genlist);
 }
 
 EAPI void
 elm_store_filesystem_directory_set(Elm_Store *store, const char *dir)
 {
    Elm_Store_Filesystem *st = (Elm_Store_Filesystem *)store;
-  if (!EINA_MAGIC_CHECK(store, ELM_STORE_MAGIC)) return;
-  if (!EINA_MAGIC_CHECK(st, ELM_STORE_FILESYSTEM_MAGIC)) return;
-  if (store->list_th)
-    {
-      ecore_thread_cancel(store->list_th);
-      store->list_th = NULL;
-    }
-  if (!eina_stringshare_replace(&st->dir, dir)) return;
-  store->list_th = ecore_thread_feedback_run(_store_filesystem_list_do,
-                                             _store_filesystem_list_update,
-                                             _store_filesystem_list_end,
-                                             _store_filesystem_list_cancel,
-                                             st, EINA_TRUE);
+   if (!EINA_MAGIC_CHECK(store, ELM_STORE_MAGIC)) return;
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_FILESYSTEM_MAGIC)) return;
+   if (store->list_th)
+     {
+        ecore_thread_cancel(store->list_th);
+        store->list_th = NULL;
+     }
+   if (!eina_stringshare_replace(&st->dir, dir)) return;
+   store->list_th = ecore_thread_feedback_run(_store_filesystem_list_do,
+                                              _store_filesystem_list_update,
+                                              _store_filesystem_list_end,
+                                              _store_filesystem_list_cancel,
+                                              st, EINA_TRUE);
 }
 
 EAPI const char *
 elm_store_filesystem_directory_get(const Elm_Store *store)
 {
-  const Elm_Store_Filesystem *st = (const Elm_Store_Filesystem *)store;
-  if (!EINA_MAGIC_CHECK(store, ELM_STORE_MAGIC)) return NULL;
-  if (!EINA_MAGIC_CHECK(st, ELM_STORE_FILESYSTEM_MAGIC)) return NULL;
-  return st->dir;
+   const Elm_Store_Filesystem *st = (const Elm_Store_Filesystem *)store;
+   if (!EINA_MAGIC_CHECK(store, ELM_STORE_MAGIC)) return NULL;
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_FILESYSTEM_MAGIC)) return NULL;
+   return st->dir;
 }
 
 EAPI void
 elm_store_cache_set(Elm_Store *st, int max)
 {
-  if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
-  if (max < 0) max = 0;
-  st->cache_max = max;
-  _store_cache_trim(st);
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
+   if (max < 0) max = 0;
+   st->cache_max = max;
+   if(!st->type) _store_cache_trim(st);
 }
 
 EAPI int
 elm_store_cache_get(const Elm_Store *st)
 {
-  if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return 0;
-  return st->cache_max;
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return 0;
+   return st->cache_max;
 }
 
 EAPI void
 elm_store_list_func_set(Elm_Store *st, Elm_Store_Item_List_Cb func, const void *data)
 {
-  if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
-  st->cb.list.func = func;
-  st->cb.list.data = (void *)data;
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
+   st->cb.list.func = func;
+   st->cb.list.data = (void *)data;
 }
 
 EAPI void
 elm_store_fetch_func_set(Elm_Store *st, Elm_Store_Item_Fetch_Cb func, const void *data)
 {
-  if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
-  st->cb.fetch.func = func;
-  st->cb.fetch.data = (void *)data;
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
+   st->cb.fetch.func = func;
+   st->cb.fetch.data = (void *)data;
 }
 
 EAPI void
 elm_store_fetch_thread_set(Elm_Store *st, Eina_Bool use_thread)
 {
-  if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
-  st->fetch_thread = !!use_thread;
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
+   st->fetch_thread = !!use_thread;
 }
 
 EAPI Eina_Bool
 elm_store_fetch_thread_get(const Elm_Store *st)
 {
-  if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return EINA_FALSE;
-  return st->fetch_thread;
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return EINA_FALSE;
+   return st->fetch_thread;
 }
 
 EAPI void
 elm_store_unfetch_func_set(Elm_Store *st, Elm_Store_Item_Unfetch_Cb func, const void *data)
 {
-  if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
-  st->cb.unfetch.func = func;
-  st->cb.unfetch.data = (void *)data;
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
+   st->cb.unfetch.func = func;
+   st->cb.unfetch.data = (void *)data;
 }
 
 EAPI void
 elm_store_sorted_set(Elm_Store *st, Eina_Bool sorted)
 {
-  if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
-  st->sorted = sorted;
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
+   st->sorted = sorted;
 }
 
 EAPI Eina_Bool
 elm_store_sorted_get(const Elm_Store *st)
 {
-  if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return EINA_FALSE;
-  return st->sorted;
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return EINA_FALSE;
+   return st->sorted;
 }
 
 EAPI void
 elm_store_item_data_set(Elm_Store_Item *sti, void *data)
 {
-  if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
-  LKL(sti->lock);
-  sti->data = data;
-  LKU(sti->lock);
+   if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
+   LKL(sti->lock);
+   sti->data = data;
+   LKU(sti->lock);
 }
 
 EAPI void *
 elm_store_item_data_get(Elm_Store_Item *sti)
 {
-  if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
-  void *d;
-  LKL(sti->lock);
-  d = sti->data;
-  LKU(sti->lock);
-  return d;
+   if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
+   void *d;
+   LKL(sti->lock);
+   d = sti->data;
+   LKU(sti->lock);
+   return d;
 }
 
 EAPI const Elm_Store *
 elm_store_item_store_get(const Elm_Store_Item *sti)
 {
-  if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
-  // dont need lock
-  return sti->store;
+   if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
+   // dont need lock
+   return sti->store;
 }
 
 EAPI const Elm_Genlist_Item *
 elm_store_item_genlist_item_get(const Elm_Store_Item *sti)
 {
-  if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
-  // dont need lock
-  return sti->item;
+   if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
+   // dont need lock
+   return sti->item;
 }
 
 EAPI const char *
 elm_store_item_filesystem_path_get(const Elm_Store_Item *item)
 {
-  Elm_Store_Item_Filesystem *sti = (Elm_Store_Item_Filesystem *)item;
-  Elm_Store_Filesystem *st;
-  if (!EINA_MAGIC_CHECK(item, ELM_STORE_ITEM_MAGIC)) return NULL;
-  if (!EINA_MAGIC_CHECK(item->store, ELM_STORE_MAGIC)) return NULL;
-  /* ensure we're dealing with filesystem item */
-  st = (Elm_Store_Filesystem *)item->store;
-  if (!EINA_MAGIC_CHECK(st, ELM_STORE_FILESYSTEM_MAGIC)) return NULL;
-  // dont need lock
-  return sti->path;
+   Elm_Store_Item_Filesystem *sti = (Elm_Store_Item_Filesystem *)item;
+   Elm_Store_Filesystem *st;
+   if (!EINA_MAGIC_CHECK(item, ELM_STORE_ITEM_MAGIC)) return NULL;
+   if (!EINA_MAGIC_CHECK(item->store, ELM_STORE_MAGIC)) return NULL;
+   /* ensure we're dealing with filesystem item */
+   st = (Elm_Store_Filesystem *)item->store;
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_FILESYSTEM_MAGIC)) return NULL;
+   // dont need lock
+   return sti->path;
+}
+
+// TODO: BEGIN -DBsystem store
+
+static Elm_Store *
+_store_init(size_t size)
+{
+   Elm_Store *st = calloc(1, size);
+   if (!st) return NULL;
+
+   eina_magic_string_set(ELM_STORE_MAGIC, "Elm_Store");
+   eina_magic_string_set(ELM_STORE_FILESYSTEM_MAGIC, "Elm_Store_Filesystem");
+   eina_magic_string_set(ELM_STORE_ITEM_MAGIC, "Elm_Store_Item");
+   eina_magic_string_set(ELM_STORE_DBSYSTEM_MAGIC, "Elm_Store_DBsystem");
+
+   _store_item_class.item_style = "default";
+   _store_item_class.func.label_get = (GenlistItemLabelGetFunc)_item_label_get;
+   _store_item_class.func.icon_get = (GenlistItemIconGetFunc)_item_icon_get;
+   _store_item_class.func.state_get = NULL;
+   _store_item_class.func.del = (GenlistItemDelFunc)_item_del;
+
+   EINA_MAGIC_SET(st, ELM_STORE_MAGIC);
+   st->cache_max = CACHE_COUNT;
+   st->current_top_index = 0;
+   st->start_fetch_index = 0;
+   st->end_fetch_index = st->cache_max - 1;
+   st->live = EINA_TRUE;
+   st->multi_load = EINA_FALSE;
+   st->total_count = 0;
+   st->fetch_thread = EINA_FALSE;
+   st->type = 1;
+   return st;
+}
+
+#define _store_new(type) (type *)_store_init(sizeof(type))
+
+static void
+_genlist_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   Elm_Store *st = data;
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
+
+   elm_store_free(st);
+}
+
+static void
+_store_fetch_do(void *data, Ecore_Thread *th __UNUSED__)
+{
+   Elm_Store_Item *sti = data;
+   sti->store->cb.fetch.func(sti->store->cb.fetch.data, sti, sti->item_info);
+   sti->fetched = EINA_TRUE;
+}
+
+static void
+_store_fetch_end(void *data, Ecore_Thread *th)
+{
+   Elm_Store_Item *sti = data;
+   if (sti->data) elm_genlist_item_update(sti->item);
+   if (th == sti->fetch_th) sti->fetch_th = NULL;
+}
+
+static void
+_store_fetch_cancel(void *data, Ecore_Thread *th)
+{
+   Elm_Store_Item *sti = data;
+   if (sti->data) elm_genlist_item_update(sti->item);
+   if (th == sti->fetch_th) sti->fetch_th = NULL;
+}
+
+static Elm_Store_Item *
+_item_fetch(Elm_Store *st, int index)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(st,NULL);
+   Elm_Store_Item *sti;
+
+   int in_index = 0;
+   Eina_List *l;
+   Eina_List *header_list;
+
+   EINA_LIST_FOREACH(st->header_items, l, header_list)
+     {
+        if ((in_index + eina_list_count(header_list)) > index)
+          {
+             sti = eina_list_nth(header_list, index - in_index);
+             if ((!sti->fetched) && st->cb.fetch.func && (!sti->fetch_th))
+               {
+                  if (st->fetch_thread)
+                    {
+                       sti->fetch_th = ecore_thread_run(_store_fetch_do,
+                                                        _store_fetch_end,
+                                                        _store_fetch_cancel,
+                                                        sti);
+                    }
+                  else
+                    {
+                       st->cb.fetch.func(st->cb.fetch.data, sti, sti->item_info);
+                       sti->fetched = EINA_TRUE;
+                    }
+               }
+             return sti;
+          }
+        else
+          {
+             in_index = in_index + eina_list_count(header_list);
+          }
+     }
+   return NULL;
+}
+
+static Elm_Store_Item *
+_item_unfetch(Elm_Store *st, int index)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(st,NULL);
+   Elm_Store_Item *sti;
+
+   int in_index = 0;
+   Eina_List *l;
+   Eina_List *header_list;
+
+   EINA_LIST_FOREACH(st->header_items, l, header_list)
+     {
+        if ((in_index + eina_list_count(header_list)) > index)
+          {
+             sti = eina_list_nth(header_list, index - in_index);
+             if (sti->fetched && st->cb.unfetch.func)
+               {
+                  if (sti->fetch_th)
+                    {
+                       ecore_thread_cancel(sti->fetch_th);
+                       sti->fetch_th = NULL;
+                    }
+
+                  st->cb.unfetch.func(st->cb.unfetch.data, sti, sti->item_info);
+                  sti->data = NULL;
+                  sti->fetched = EINA_FALSE;
+               }
+             return sti;
+          }
+        else
+          {
+             in_index = in_index + eina_list_count(header_list);
+          }
+     }
+   return NULL;
+}
+
+static const Elm_Store_Item_Mapping *
+_item_mapping_find(Elm_Store_Item *sti, const char *part)
+{
+   const Elm_Store_Item_Mapping *m;
+
+   for (m = sti->item_info->mapping; m; m++)
+     {
+        if (m->type == ELM_STORE_ITEM_MAPPING_NONE) break;
+        if (!strcmp(part, m->part)) return m;
+     }
+   return NULL;
+}
+
+static char *
+_item_label_get(void *data, Evas_Object *obj __UNUSED__, const char *part)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(data, strdup(""));
+   Elm_Store_Item *sti = data;
+
+   if (sti->item)
+     {
+        if (sti->fetched == EINA_FALSE)
+          {
+             if (!sti->data)
+               {
+                  int index = elm_store_item_index_get(sti);
+                  if (sti->store->start_fetch_index > index)
+                    {
+                       int diff = sti->store->start_fetch_index - index;
+                       int loop;
+                       for (loop = 1; loop <= diff; loop++)
+                         {
+                            _item_unfetch(sti->store, sti->store->end_fetch_index);
+                            sti->store->end_fetch_index--;
+                            _item_fetch(sti->store, (sti->store->start_fetch_index - loop));
+                         }
+                       sti->store->start_fetch_index = index;
+                    }
+                  else if (index > sti->store->end_fetch_index)
+                    {
+                       int diff = index - sti->store->end_fetch_index;
+                       int loop;
+                       for (loop = 1; loop <= diff; loop++)
+                         {
+                            _item_unfetch(sti->store, sti->store->start_fetch_index);
+                            sti->store->start_fetch_index++;
+                            _item_fetch(sti->store, (sti->store->end_fetch_index + loop));
+                         }
+                       sti->store->end_fetch_index = index;
+                    }
+               }
+          }
+
+        if (sti->data)
+          {
+             const char *s = "";
+             const Elm_Store_Item_Mapping *m = _item_mapping_find(sti, part);
+             if (m)
+               {
+                  switch (m->type)
+                    {
+                     case ELM_STORE_ITEM_MAPPING_LABEL:
+                        s = *(char **)(((unsigned char *)sti->data) + m->offset);
+                        break;
+
+                     case ELM_STORE_ITEM_MAPPING_CUSTOM:
+                        if (m->details.custom.func)
+                          s = m->details.custom.func(sti->data, sti, part);
+                        break;
+
+                     default:
+                        break;
+                    }
+                  if (s)
+                    {
+                       return strdup(s);
+                    }
+                  else
+                    {
+                       return NULL;
+                    }
+               }
+          }
+     }
+   return NULL;
+}
+
+static Evas_Object *
+_item_icon_get(void *data, Evas_Object *obj, const char *part)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(data,NULL);
+   Elm_Store_Item *sti = data;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(sti,NULL);
+
+   if (sti->item)
+     {
+        if (sti->data)
+          {
+             const Elm_Store_Item_Mapping *m = _item_mapping_find(sti, part);
+             if (m)
+               {
+                  Evas_Object *ic = NULL;
+                  const char *s = NULL;
+
+                  switch (m->type)
+                    {
+                     case ELM_STORE_ITEM_MAPPING_ICON:
+                        ic = elm_icon_add(obj);
+                        s = *(char **)(((unsigned char *)sti->data) + m->offset);
+                        elm_icon_order_lookup_set(ic, m->details.icon.lookup_order);
+                        evas_object_size_hint_aspect_set(ic,
+                                                         EVAS_ASPECT_CONTROL_VERTICAL,
+                                                         m->details.icon.w,
+                                                         m->details.icon.h);
+                        elm_icon_smooth_set(ic, m->details.icon.smooth);
+                        elm_icon_no_scale_set(ic, m->details.icon.no_scale);
+                        elm_icon_scale_set(ic,
+                                           m->details.icon.scale_up,
+                                           m->details.icon.scale_down);
+
+                        if (s)
+                          {
+                             if (m->details.icon.standard_name)
+                               elm_icon_standard_set(ic, s);
+                             else
+                               elm_icon_file_set(ic, s, NULL);
+                          }
+                        break;
+
+                     case ELM_STORE_ITEM_MAPPING_PHOTO:
+                        ic = elm_icon_add(obj);
+                        s = *(char **)(((unsigned char *)sti->data) + m->offset);
+                        elm_photo_size_set(ic, m->details.photo.size);
+                        if (s)
+                          elm_photo_file_set(ic, s);
+                        break;
+
+                     case ELM_STORE_ITEM_MAPPING_CUSTOM:
+                        if (m->details.custom.func)
+                          ic = m->details.custom.func(sti->data, sti, part);
+                        break;
+
+                     default:
+                        break;
+                    }
+                  return ic;
+               }
+          }
+     }
+   return NULL;
+}
+
+static void
+_item_realized(void *data, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   EINA_SAFETY_ON_NULL_RETURN(event_info);
+   Elm_Store *st = data;
+   Elm_Genlist_Item *gli = event_info;
+   Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
+
+   EINA_SAFETY_ON_NULL_RETURN(sti);
+
+   int index = elm_store_item_index_get(sti);
+
+   if (st->fetch_thread)
+     {
+        if ((st->start_fetch_index <= index) && (index <= st->end_fetch_index))
+          {
+             int middle_index = sti->store->start_fetch_index + (sti->store->cache_max) / 2;
+
+             if ((middle_index < index) && (sti->store->end_fetch_index < sti->store->total_count))
+               {
+                  int diff = index - middle_index;
+                  int loop;
+                  for (loop = 0; loop < diff; loop++)
+                    {
+                       _item_unfetch(st, sti->store->start_fetch_index);
+                       sti->store->start_fetch_index++;
+                       _item_fetch(st, (sti->store->end_fetch_index + 1));
+                       sti->store->end_fetch_index++;
+                    }
+               }
+             else if ((middle_index > index) && (sti->store->start_fetch_index > 0))
+               {
+                  int diff = st->current_top_index - index;
+                  int loop;
+                  for (loop = 0; loop < diff; loop++)
+                    {
+                       _item_unfetch(st, sti->store->end_fetch_index);
+                       sti->store->end_fetch_index--;
+                       _item_fetch(st, (sti->store->start_fetch_index - 1));
+                       sti->store->start_fetch_index--;
+                    }
+               }
+             else {
+                  if ((!sti->fetched))
+                    {
+                       _item_fetch(st, index);
+                    }
+             }
+          }
+     }
+
+   if ((st->current_top_index > index))
+     {
+        st->current_top_index = index;
+     }
+   else if ((st->current_top_index + SCREEN_ITEM_COUNT) < index)
+     {
+        st->current_top_index = st->current_top_index + (index - (st->current_top_index + SCREEN_ITEM_COUNT));
+     }
+
+   // TODO: fix the item when it disposed quickly before call the label get. as example, get_more_btn in email
+}
+
+static void
+_item_unrealized(void *data, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   EINA_SAFETY_ON_NULL_RETURN(event_info);
+   Elm_Genlist_Item *gli = event_info;
+   Elm_Store_Item *sti = elm_genlist_item_data_get(gli);
+   EINA_SAFETY_ON_NULL_RETURN(sti);
+}
+
+static void
+_item_del(void *data, Evas_Object *obj __UNUSED__)
+{
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   Elm_Store_Item *sti = data;
+   EINA_SAFETY_ON_NULL_RETURN(sti);
+   if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
+   elm_store_item_del(sti);
+}
+
+static void
+_list_do(void *data, Ecore_Thread *th __UNUSED__)
+{
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   Elm_Store *st = data;
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
+
+   if (st->multi_load == EINA_TRUE)
+     {
+        Elm_Store_Item_Info *item_info;
+        Eina_Bool ok = EINA_FALSE;
+        int loop;
+        for (loop = 0; loop < st->item_count; loop++)
+          {
+             item_info = calloc(1, sizeof(Elm_Store_Item_Info));
+             if (!item_info) return;
+             item_info->index = loop;
+
+             if (st->cb.list.func)
+               {
+                  ok = st->cb.list.func(st->cb.list.data, item_info);
+               }
+             if (ok) ecore_thread_feedback(th, item_info);
+             else free(item_info);
+             if (ecore_thread_check(th)) break;
+          }
+     }
+}
+
+static void
+_list_update(void *data, Ecore_Thread *th __UNUSED__, void *msg)
+{
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   EINA_SAFETY_ON_NULL_RETURN(msg);
+   Elm_Store *st = data;
+   Elm_Store_Item_Info *info = msg;
+
+   elm_store_item_add(st, info);
+}
+
+static void
+_list_end(void *data, Ecore_Thread *th)
+{
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   EINA_SAFETY_ON_NULL_RETURN(th);
+   Elm_Store *st = data;
+
+   if (th == st->list_th)
+     {
+        ecore_thread_cancel(st->list_th);
+        st->list_th = NULL;
+     }
+}
+
+static void
+_list_cancel(void *data, Ecore_Thread *th)
+{
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   EINA_SAFETY_ON_NULL_RETURN(th);
+   Elm_Store *st = data;
+
+   if (th == st->list_th)
+     {
+        ecore_thread_cancel(st->list_th);
+        st->list_th = NULL;
+     }
+}
+
+static Elm_Store_Item *
+_item_get(const Elm_Store *st, const int index)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(st,NULL);
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return NULL;
+
+   if (st->live)
+     {
+        int in_index = 0;
+
+        Elm_Store_Item *sti;
+        Eina_List *l;
+        Eina_List *header_list;
+
+        EINA_LIST_FOREACH(st->header_items, l, header_list)
+          {
+             if ((in_index + eina_list_count(header_list)) > index)
+               {
+                  sti = eina_list_nth(header_list, index - in_index);
+                  return sti;
+               }
+             else
+               {
+                  in_index = in_index + eina_list_count(header_list);
+               }
+          }
+     }
+   return NULL;
+}
+
+static void
+_item_select_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   EINA_SAFETY_ON_NULL_RETURN(event_info);
+
+   const Elm_Genlist_Item *it = (Elm_Genlist_Item *)event_info;
+   Elm_Store_Item *sti = elm_genlist_item_data_get(it);
+   if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
+
+   if (sti->store->cb.item_select.func)
+     {
+        sti->store->cb.item_select.func(sti->store->cb.item_select.data, sti);
+     }
+}
+
+static void
+_group_item_append(Elm_Store_Item *sti, Elm_Genlist_Item_Class *itc)
+{
+   EINA_SAFETY_ON_NULL_RETURN(sti);
+   if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
+
+   if (sti->store->header_items)
+     {
+        Eina_Bool header_add = EINA_TRUE;
+        Eina_List *l;
+        Eina_List *header_list;
+
+        EINA_LIST_FOREACH(sti->store->header_items, l, header_list)
+          {
+             Elm_Store_Item *item = eina_list_nth(header_list, 0);
+
+             if (item->item_info->group_index == sti->item_info->group_index)
+               {
+                  header_add = EINA_FALSE;
+                  break;
+               }
+          }
+        if (header_add)
+          {
+             Eina_List *new_header_list = NULL;
+             sti->item_info->index = 0;
+             new_header_list = eina_list_append(new_header_list, sti);
+
+             Eina_Bool last_header = EINA_TRUE;
+             Eina_List *l;
+             Eina_List *header_list;
+
+             EINA_LIST_FOREACH(sti->store->header_items, l, header_list)
+               {
+                  Elm_Store_Item *temp_sti = eina_list_nth(header_list, 0);
+
+                  if (temp_sti->item_info->group_index > sti->item_info->group_index)
+                    {
+                       sti->store->header_items = eina_list_prepend_relative(sti->store->header_items, new_header_list, header_list);
+                       sti->item = elm_genlist_item_insert_before(sti->store->genlist,
+                                                                  itc,
+                                                                  sti,
+                                                                  NULL,
+                                                                  temp_sti->item,
+                                                                  ELM_GENLIST_ITEM_GROUP,
+                                                                  (Evas_Smart_Cb)sti->store->cb.item_select.func,
+                                                                  (void *)sti->store->cb.item_select.data);
+                       elm_store_item_update(sti->store, sti);
+                       last_header = EINA_FALSE;
+                       break;
+                    }
+               }
+             if (last_header)
+               {
+                  sti->store->header_items = eina_list_append(sti->store->header_items, new_header_list);
+                  sti->item = elm_genlist_item_append(sti->store->genlist,
+                                                      itc,
+                                                      sti,
+                                                      NULL,
+                                                      ELM_GENLIST_ITEM_GROUP,
+                                                      _item_select_cb,
+                                                      NULL);
+                  elm_store_item_update(sti->store, sti);
+               }
+          }
+     }
+   else
+     {
+        Eina_List *header_list = NULL;
+        sti->item_info->index = 0;
+        header_list = eina_list_append(header_list, sti);
+        sti->store->header_items = eina_list_append(sti->store->header_items, header_list);
+        sti->item = elm_genlist_item_append(sti->store->genlist,
+                                            itc,
+                                            sti,
+                                            NULL,
+                                            ELM_GENLIST_ITEM_GROUP,
+                                            _item_select_cb,
+                                            NULL);
+        elm_store_item_update(sti->store, sti);
+     }
+}
+
+static void
+_normal_item_append(Elm_Store_Item *sti, Elm_Genlist_Item_Class *itc)
+{
+   EINA_SAFETY_ON_NULL_RETURN(sti);
+   if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
+   Elm_Store *st = sti->store;
+
+   if (sti->item_info->rec_item == EINA_TRUE)
+     {
+        if (sti->item_info->group_index == sti->item_info->pre_group_index)
+          {
+             elm_store_item_update(st, sti);
+          }
+        else
+          {
+             Eina_List *l;
+             Eina_List *header_list;
+
+             EINA_LIST_FOREACH(st->header_items, l, header_list)
+               {
+                  Elm_Store_Item *header_item = eina_list_nth(header_list, 0);
+
+                  if (header_item->item_info->group_index == sti->item_info->pre_group_index)
+                    {
+                       Elm_Store_Item *last_sti = eina_list_nth(header_list, eina_list_count(header_list) - 1);
+
+                       if (last_sti->data)
+                         {
+                            int index = elm_store_item_index_get(last_sti);
+                            _item_unfetch(st, index);
+                         }
+                       header_list = eina_list_remove(header_list, last_sti);
+
+                       if (!header_list)
+                         {
+                            st->header_items = eina_list_remove(st->header_items, header_list);
+                            eina_list_free(header_list);
+                         }
+                       elm_genlist_item_del(last_sti->item);
+
+                       if (eina_list_count(header_list) == 1)
+                         {
+                            Elm_Store_Item *temp_sti = eina_list_nth(header_list, 0);
+                            if (temp_sti->item_info->item_type == ELM_GENLIST_ITEM_GROUP)
+                              {
+                                 if (temp_sti->data)
+                                   {
+                                      int index = elm_store_item_index_get(temp_sti);
+                                      _item_unfetch(st, index);
+                                   }
+                                 header_list = eina_list_remove(header_list, temp_sti);
+                                 st->header_items = eina_list_remove(st->header_items, header_list);
+                                 eina_list_free(header_list);
+                                 elm_genlist_item_del(temp_sti->item);
+                              }
+                         }
+                    }
+                  else if (header_item->item_info->group_index == sti->item_info->group_index)
+                    {
+                       sti->item_info->index = eina_list_count(header_list);
+                       Elm_Store_Item *last_sti = eina_list_nth(header_list, eina_list_count(header_list) - 1);
+                       header_list = eina_list_append(header_list, sti);
+                       sti->item = elm_genlist_item_insert_after(st->genlist,
+                                                                 itc,
+                                                                 sti,
+                                                                 header_item->item,
+                                                                 last_sti->item,
+                                                                 ELM_GENLIST_ITEM_NONE,
+                                                                 (Evas_Smart_Cb)st->cb.item_select.func,
+                                                                 (void *)st->cb.item_select.data);
+                       elm_store_item_update(st, sti);
+                    }
+               }
+          }
+     }
+   else
+     {
+        if (st->header_items)
+          {
+             Eina_Bool normal_add = EINA_TRUE;
+             Eina_List *l;
+             Eina_List *header_list;
+
+             EINA_LIST_FOREACH(st->header_items, l, header_list)
+               {
+                  if (header_list)
+                    {
+                       Elm_Store_Item *header_item = eina_list_nth(header_list, 0);
+
+                       if (header_item->item_info->group_index == sti->item_info->group_index)
+                         {
+                            sti->item_info->index = eina_list_count(header_list);
+                            Elm_Store_Item *last_sti = eina_list_nth(header_list, eina_list_count(header_list) - 1);
+                            header_list = eina_list_append(header_list, sti);
+                            sti->item = elm_genlist_item_insert_after(st->genlist,
+                                                                      itc,
+                                                                      sti,
+                                                                      header_item->item,
+                                                                      last_sti->item,
+                                                                      ELM_GENLIST_ITEM_NONE,
+                                                                      (Evas_Smart_Cb)st->cb.item_select.func,
+                                                                      (void *)st->cb.item_select.data);
+                            elm_store_item_update(st, sti);
+                            normal_add = EINA_FALSE;
+                            break;
+                         }
+                    }
+               }
+             if (normal_add)
+               {
+                  Eina_List *new_header_list = NULL;
+                  sti->item_info->index = 0;
+                  new_header_list = eina_list_append(new_header_list, sti);
+                  st->header_items = eina_list_append(st->header_items, new_header_list);
+                  sti->item = elm_genlist_item_append(st->genlist,
+                                                      itc,
+                                                      sti,
+                                                      NULL,
+                                                      ELM_GENLIST_ITEM_NONE,
+                                                      _item_select_cb,
+                                                      NULL);
+                  elm_store_item_update(st, sti);
+               }
+          }
+        else
+          {
+             if (st->live)
+               {
+                  Eina_List *header_list = NULL;
+                  sti->item_info->index = 0;
+                  header_list = eina_list_append(header_list, sti);
+                  st->header_items = eina_list_append(st->header_items, header_list);
+                  sti->item = elm_genlist_item_append(st->genlist,
+                                                      itc,
+                                                      sti,
+                                                      NULL,
+                                                      ELM_GENLIST_ITEM_NONE,
+                                                      _item_select_cb,
+                                                      NULL);
+                  elm_store_item_update(st, sti);
+               }
+          }
+     }
+}
+
+static void
+_item_free(Elm_Store_Item *sti)
+{
+   if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
+   elm_store_item_del(sti);
+}
+
+static void
+_store_free(Elm_Store *st)
+{
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
+   elm_store_free(st);
+}
+
+/**
+ * Add a new dbsystem Store object
+ *
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Store
+ */
+EAPI Elm_Store *
+elm_store_dbsystem_new(void)
+{
+   Elm_Store_DBsystem *std = _store_new(Elm_Store_DBsystem);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(std, NULL);
+
+   EINA_MAGIC_SET(std, ELM_STORE_DBSYSTEM_MAGIC);
+   std->base.free = _store_free;
+   std->base.item.free = _item_free;
+   return &std->base;
+}
+
+/**
+ * Sets the item count of a store
+ *
+ * @param st The store object
+ * @param count The item count of an store
+ *
+ * @ingroup Store
+ */
+EAPI void
+elm_store_item_count_set(Elm_Store *st, int count)
+{
+   EINA_SAFETY_ON_NULL_RETURN(st);
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
+
+   st->item_count = count;
+   if (count > 0)
+     {
+        st->multi_load = EINA_TRUE;
+     }
+   else
+     {
+        st->multi_load = EINA_FALSE;
+     }
+}
+
+/**
+ * Get the item index that included header items
+ *
+ * @param sti The store item object
+ * @return The item index in genlist
+ *
+ * @ingroup Store
+ */
+EAPI int
+elm_store_item_index_get(const Elm_Store_Item *sti)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(sti, -1);
+   if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return -1;
+
+   if (sti->store->live)
+     {
+        int index = 0;
+        Eina_List *l;
+        Eina_List *header_list;
+
+        EINA_LIST_FOREACH(sti->store->header_items, l, header_list)
+          {
+             if (header_list)
+               {
+                  Elm_Store_Item *temp_sti = eina_list_nth(header_list, 0);
+                  if (sti->item_info->group_index == temp_sti->item_info->group_index)
+                    {
+                       index = index + sti->item_info->index;
+                       break;
+                    }
+                  else
+                    {
+                       index = index + eina_list_count(header_list);
+                    }
+               }
+          }
+        return index;
+     }
+   else
+     {
+        return -1;
+     }
+}
+
+/**
+ * Sets the select func that select the state of a list item whether true or false
+ *
+ * @param st The store object
+ * @param func The select cb function of an store
+ * @param data The new data pointer to set
+ *
+ * @ingroup Store
+ */
+EAPI void
+elm_store_item_select_func_set(Elm_Store *st, Elm_Store_Item_Select_Cb func, const void *data)
+{
+   EINA_SAFETY_ON_NULL_RETURN(st);
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
+
+   st->cb.item_select.func = func;
+   st->cb.item_select.data = (void *)data;
+}
+
+/**
+ * Sets the sort func that sort the item with a next in the list
+ *
+ * @param st The store object
+ * @param func The sort cb function of an store
+ * @param data The new data pointer to set
+ *
+ * @ingroup Store
+ */
+EAPI void
+elm_store_item_sort_func_set(Elm_Store *st, Elm_Store_Item_Sort_Cb func, const void *data)
+{
+   EINA_SAFETY_ON_NULL_RETURN(st);
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
+
+   st->cb.item_sort.func = func;
+   st->cb.item_sort.data = (void *)data;
 }
+
+/**
+ * Get the item index of real data that don't included header items
+ *
+ * @param sti The store item object
+ * @return The real item index
+ *
+ * @ingroup Store
+ */
+EAPI int
+elm_store_item_data_index_get(const Elm_Store_Item *sti)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(sti, -1);
+   if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return -1;
+
+   if (sti->store->live)
+     {
+        if (sti->item_info->item_type == ELM_GENLIST_ITEM_NONE)
+          {
+             int index = 0;
+             int header_count = 0;
+             Eina_List *l;
+             Eina_List *header_list;
+
+             EINA_LIST_FOREACH(sti->store->header_items, l, header_list)
+               {
+
+                  if (header_list)
+                    {
+                       Elm_Store_Item *temp_sti = eina_list_nth(header_list, 0);
+
+                       if (temp_sti->item_info->item_type == ELM_GENLIST_ITEM_GROUP)
+                         {
+                            header_count++;
+                         }
+
+                       if (sti->item_info->group_index == temp_sti->item_info->group_index)
+                         {
+                            index = index + sti->item_info->index - header_count;
+                            break;
+                         }
+                       else
+                         {
+                            index = index + eina_list_count(header_list);
+                         }
+                    }
+               }
+             return index;
+          }
+        else
+          {
+             return -1;
+          }
+     }
+   else
+     {
+        return -1;
+     }
+}
+
+/**
+ * Get the DB pointer of an item
+ *
+ * @param sti The store item object
+ * @return The DB pointer of item
+ *
+ * @ingroup Store
+ */
+EAPI void *
+elm_store_dbsystem_db_get(const Elm_Store_Item *sti)
+{
+   if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return NULL;
+
+   const Elm_Store_DBsystem *std = (const Elm_Store_DBsystem *)sti->store;
+   if (!EINA_MAGIC_CHECK(sti->store, ELM_STORE_MAGIC)) return NULL;
+   if (!EINA_MAGIC_CHECK(std, ELM_STORE_DBSYSTEM_MAGIC)) return NULL;
+   return std->p_db;
+}
+
+/**
+ * Set the DB pointer of an item
+ *
+ * @param sti The store item object
+ * @parm p_db The DB pointer of item
+ *
+ * @ingroup Store
+ */
+EAPI void
+elm_store_dbsystem_db_set(Elm_Store *store, void *p_db)
+{
+   Elm_Store_DBsystem *std = (Elm_Store_DBsystem *)store;
+   if (!EINA_MAGIC_CHECK(store, ELM_STORE_MAGIC)) return;
+   if (!EINA_MAGIC_CHECK(std, ELM_STORE_DBSYSTEM_MAGIC)) return;
+
+   std->p_db = p_db;
+
+   if (store->list_th)
+     {
+        ecore_thread_cancel(store->list_th);
+        store->list_th = NULL;
+     }
+   store->list_th = ecore_thread_feedback_run(_list_do, _list_update, _list_end, _list_cancel, store, EINA_TRUE);
+}
+
+/**
+ * Append the item to the genlist
+ *
+ * @param st The store object
+ * @param info The store item info dbsystem object
+ * @return The item of store
+ *
+ * @ingroup Store
+ */
+EAPI Elm_Store_Item *
+elm_store_item_add(Elm_Store *st, Elm_Store_Item_Info *info)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return NULL;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(info, NULL);
+   Elm_Store_Item *sti;
+   Elm_Genlist_Item_Class *itc;
+
+   sti = calloc(1, sizeof(Elm_Store_Item));
+   if (!sti) return NULL;
+   EINA_MAGIC_SET(sti, ELM_STORE_ITEM_MAGIC);
+
+   sti->store = st;
+   st->total_count++;
+
+   sti->item_info = info;
+
+   itc = info->item_class;
+   if (!itc) itc = &_store_item_class;
+   else
+     {
+        itc->func.label_get = (GenlistItemLabelGetFunc)_item_label_get;
+        itc->func.icon_get = (GenlistItemIconGetFunc)_item_icon_get;
+        itc->func.state_get = NULL;
+        itc->func.del = NULL;
+     }
+
+   if (st->live)
+     {
+        if (sti->item_info->item_type == ELM_GENLIST_ITEM_GROUP)
+          {
+             _group_item_append(sti, itc);
+          }
+        else
+          {
+             _normal_item_append(sti, itc);
+          }
+        return sti;
+     }
+   else
+     {
+        return NULL;
+     }
+}
+
+/**
+ * Realize the visible items to the screen
+ *
+ * @param st The store object
+ *
+ * @ingroup Store
+ */
+EAPI void
+elm_store_visible_items_update(Elm_Store *st)
+{
+   EINA_SAFETY_ON_NULL_RETURN(st);
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
+
+   int loop;
+   for (loop = st->current_top_index; loop < (st->current_top_index + st->block_count); loop++)
+     {
+        Elm_Store_Item *temp_sti = _item_get(st, loop);
+        if (temp_sti)
+          {
+             if (temp_sti->fetched)
+               {
+                  _item_unfetch(st, loop);
+               }
+             _item_fetch(st, loop);
+             if (temp_sti->data) elm_genlist_item_update(temp_sti->item);
+
+             if (!st->fetch_thread)
+               {
+                  if (temp_sti->data) elm_genlist_item_update(temp_sti->item);
+               }
+          }
+        else
+          {
+             break;
+          }
+     }
+}
+
+/**
+ * Realize the item to the screen
+ *
+ * @param st The store object
+ * @param sti The store item object
+ *
+ * @ingroup Store
+ */
+EAPI void
+elm_store_item_update(Elm_Store *st, Elm_Store_Item *sti)
+{
+   EINA_SAFETY_ON_NULL_RETURN(st);
+   EINA_SAFETY_ON_NULL_RETURN(sti);
+   if (!EINA_MAGIC_CHECK(st, ELM_STORE_MAGIC)) return;
+   if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
+
+   int index = elm_store_item_index_get(sti);
+
+   if (sti->fetched)
+     {
+        _item_unfetch(st, index);
+     }
+   _item_fetch(st, index);
+   if (sti->data) elm_genlist_item_update(sti->item);
+
+   if (!st->fetch_thread)
+     {
+        if (sti->data) elm_genlist_item_update(sti->item);
+     }
+}
+
+/**
+ * Delete the item of genlist
+ *
+ * @param sti The store item object
+ *
+ * @ingroup Store
+ */
+EAPI void
+elm_store_item_del(Elm_Store_Item *sti)
+{
+   EINA_SAFETY_ON_NULL_RETURN(sti);
+   if (!EINA_MAGIC_CHECK(sti, ELM_STORE_ITEM_MAGIC)) return;
+
+   sti->store->total_count--;
+
+   Eina_List *l;
+   Eina_List *header_list;
+
+   EINA_LIST_FOREACH(sti->store->header_items, l, header_list)
+     {
+
+        if (header_list)
+          {
+             Elm_Store_Item *item = eina_list_nth(header_list, 0);
+
+             if (item->item_info->group_index == sti->item_info->group_index)
+               {
+                  Eina_List *in_l;
+                  Elm_Store_Item *temp_sti;
+                  EINA_LIST_FOREACH(header_list, in_l, temp_sti)
+                    {
+                       if (temp_sti->item_info->index == sti->item_info->index)
+                         {
+                            if (temp_sti->data)
+                              {
+                                 int index = elm_store_item_index_get(temp_sti);
+                                 _item_unfetch(sti->store, index);
+                              }
+                            header_list = eina_list_remove(header_list, temp_sti);
+                            if (!header_list)
+                              {
+                                 sti->store->header_items = eina_list_remove(sti->store->header_items, header_list);
+                              }
+                            elm_genlist_item_del(temp_sti->item);
+                         }
+                    }
+               }
+          }
+     }
+}
+
+// TODO: END -DBsystem store
+