efl
268 строк · 9.0 Кб
1/* NOTE : Before testing elm_store,
2email data files should exist in your local storage.
3And you can just get example files in enlightenment website.
4Use wget to obtain it. It almost 50 Megabytes.
5http://www.enlightenment.org/~raster/store.tar.gz
6*/
7
8#ifdef HAVE_CONFIG_H
9# include "elementary_config.h"
10#endif
11#include <Elementary.h>
12
13typedef struct _My_Item My_Item;
14
15struct _My_Item
16{
17char *from, *subject, *date, *head_content;
18};
19
20// callbacks just to see user interacting with genlist
21static void
22_st_selected(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
23{
24printf("selected: %p\n", event_info);
25}
26
27static void
28_st_double_clicked(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
29{
30printf("double clicked: %p\n", event_info);
31}
32
33static void
34_st_longpress(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
35{
36printf("longpress %p\n", event_info);
37}
38
39// store callbacks to handle loading/parsing/freeing of store items from src
40static Elm_Genlist_Item_Class *itc1;
41
42static const Elm_Store_Item_Mapping it1_mapping[] =
43{
44{
45ELM_STORE_ITEM_MAPPING_LABEL,
46"elm.title.1", ELM_STORE_ITEM_MAPPING_OFFSET(My_Item, from),
47{ .empty = {
48EINA_TRUE
49} } },
50{
51ELM_STORE_ITEM_MAPPING_LABEL,
52"elm.title.2", ELM_STORE_ITEM_MAPPING_OFFSET(My_Item, subject),
53{ .empty = {
54EINA_TRUE
55} } },
56{
57ELM_STORE_ITEM_MAPPING_LABEL,
58"elm.text", ELM_STORE_ITEM_MAPPING_OFFSET(My_Item, head_content),
59{ .empty = {
60EINA_TRUE
61} } },
62{
63ELM_STORE_ITEM_MAPPING_ICON,
64"elm.swallow.icon", 0,
65{ .icon = {
6648, 48,
67ELM_ICON_LOOKUP_THEME_FDO,
68EINA_TRUE, EINA_FALSE,
69EINA_TRUE,
70EINA_FALSE, EINA_FALSE,
71} } },
72{
73ELM_STORE_ITEM_MAPPING_CUSTOM,
74"elm.swallow.end", 0,
75{ .custom = {
76NULL
77} } },
78ELM_STORE_ITEM_MAPPING_END
79};
80
81////// **** WARNING ***********************************************************
82//// * This function runs inside a thread outside efl mainloop. Be careful! *
83// ************************************************************************
84static Eina_Bool
85_st_store_list(void *data EINA_UNUSED, Elm_Store_Item_Info *item_info)
86{
87Elm_Store_Item_Info_Filesystem *info = (Elm_Store_Item_Info_Filesystem *)item_info;
88int id;
89char sort_id[7];
90
91// create a sort id based on the filename itself assuming it is a numeric
92// value like the id number in mh mail folders which is what this test
93// uses as a data source
94char *file = strrchr(info->path, '/');
95if (file) file++;
96else file = info->path;
97id = atoi(file);
98sort_id[0] = ((id >> 30) & 0x3f) + 32;
99sort_id[1] = ((id >> 24) & 0x3f) + 32;
100sort_id[2] = ((id >> 18) & 0x3f) + 32;
101sort_id[3] = ((id >> 12) & 0x3f) + 32;
102sort_id[4] = ((id >> 6) & 0x3f) + 32;
103sort_id[5] = ((id >> 0) & 0x3f) + 32;
104sort_id[6] = 0;
105info->base.sort_id = strdup(sort_id);
106// choose the item genlist item class to use (only item style should be
107// provided by the app, store will fill everything else in, so it also
108// has to be writable
109info->base.item_class = itc1; // based on item info - return the item class wanted (only style field used - rest reset to internal funcs store sets up to get label/icon etc)
110info->base.mapping = it1_mapping;
111info->base.data = NULL; // if we can already parse and load all of item here and want to - set this
112return EINA_TRUE; // return true to include this, false not to
113}
114// ************************************************************************
115//// * End of separate thread function. *
116////// ************************************************************************
117
118////// **** WARNING ***********************************************************
119//// * This function runs inside a thread outside efl mainloop. Be careful! *
120// ************************************************************************
121static void
122_st_store_fetch(void *data EINA_UNUSED, Elm_Store_Item *sti)
123{
124const char *path = elm_store_item_filesystem_path_get(sti);
125My_Item *myit;
126FILE *f;
127char buf[4096], *p;
128Eina_Bool have_content = EINA_FALSE;
129char *content = NULL, *content_pos = NULL, *content_end = NULL;
130
131// if we already have my item data - skip
132if (elm_store_item_data_get(sti)) return;
133// open the mail file and parse it
134f = fopen(path, "rb");
135if (!f) return;
136
137// alloc my item in memory that holds data to show in the list
138myit = calloc(1, sizeof(My_Item));
139if (!myit)
140{
141fclose(f);
142return;
143}
144while (fgets(buf, sizeof(buf), f))
145{
146if (!have_content)
147{
148if (!isblank(buf[0]))
149{
150// get key: From:, Subject: etc.
151if (!strncmp(buf, "From:", 5))
152{
153p = buf + 5;
154while ((*p) && (isblank(*p))) p++;
155p = strdup(p);
156if (p)
157{
158myit->from = p;
159p = strchr(p, '\n');
160if (p) *p = 0;
161}
162}
163else if (!strncmp(buf, "Subject:", 8))
164{
165p = buf + 8;
166while ((*p) && (isblank(*p))) p++;
167p = strdup(p);
168if (p)
169{
170myit->subject = p;
171p = strchr(p, '\n');
172if (p) *p = 0;
173}
174}
175else if (!strncmp(buf, "Date:", 5))
176{
177p = buf + 5;
178while ((*p) && (isblank(*p))) p++;
179p = strdup(p);
180if (p)
181{
182myit->date = p;
183p = strchr(p, '\n');
184if (p) *p = 0;
185}
186}
187else if (buf[0] == '\n') // begin of content
188have_content = EINA_TRUE;
189}
190}
191else
192{
193// get first 320 bytes of content/body
194if (!content)
195{
196content = calloc(1, 320);
197content_pos = content;
198content_end = content + 319;
199}
200strncat(content_pos, buf, content_end - content_pos - 1);
201content_pos = content + strlen(content);
202}
203}
204fclose(f);
205myit->head_content = elm_entry_utf8_to_markup(content);
206free(content);
207elm_store_item_data_set(sti, myit);
208}
209// ************************************************************************
210//// * End of separate thread function. *
211////// ************************************************************************
212
213static void
214_st_store_unfetch(void *data EINA_UNUSED, Elm_Store_Item *sti)
215{
216My_Item *myit = elm_store_item_data_get(sti);
217if (!myit) return;
218if (myit->from) free(myit->from);
219if (myit->subject) free(myit->subject);
220if (myit->date) free(myit->date);
221if (myit->head_content) free(myit->head_content);
222free(myit);
223}
224
225void
226test_store(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
227{
228Evas_Object *win, *gl, *bx;
229Elm_Store *st;
230
231win = elm_win_util_standard_add("store", "Store");
232elm_win_autodel_set(win, EINA_TRUE);
233
234bx = elm_box_add(win);
235evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
236elm_win_resize_object_add(win, bx);
237evas_object_show(bx);
238
239gl = elm_genlist_add(win);
240elm_genlist_mode_set(gl, ELM_LIST_COMPRESS);
241evas_object_smart_callback_add(gl, "selected", _st_selected, NULL);
242evas_object_smart_callback_add(gl, "clicked,double", _st_double_clicked, NULL);
243evas_object_smart_callback_add(gl, "longpressed", _st_longpress, NULL);
244evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
245evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
246elm_box_pack_end(bx, gl);
247evas_object_show(gl);
248
249itc1 = elm_genlist_item_class_new();
250itc1->item_style = "message";
251
252st = elm_store_filesystem_new();
253elm_store_list_func_set(st, _st_store_list, NULL);
254elm_store_fetch_func_set(st, _st_store_fetch, NULL);
255//elm_store_fetch_thread_set(st, EINA_FALSE);
256elm_store_unfetch_func_set(st, _st_store_unfetch, NULL);
257elm_store_sorted_set(st, EINA_TRUE);
258elm_store_target_genlist_set(st, gl);
259elm_store_filesystem_directory_set(st, "./store");
260
261/* item_class_ref is needed for itc1. some items can be added in callbacks */
262elm_genlist_item_class_ref(itc1);
263elm_genlist_item_class_free(itc1);
264
265evas_object_resize(win, 480 * elm_config_scale_get(),
266800 * elm_config_scale_get());
267evas_object_show(win);
268}
269