add delete mode
[framework/uifw/cbhm.git] / src / clipdrawer.c
1 #include "common.h"
2 #include "cbhm_main.h"
3 #include "storage.h"
4 #include "xcnphandler.h"
5 #include "clipdrawer.h"
6
7 #define IM      "/opt/media/Images and videos/My photo clips/"
8 static const char *g_images_path[] = {
9         IM"1_photo.jpg",
10 /*
11         IM"2_photo.jpg",
12         IM"3_photo.jpg",
13         IM"4_photo.jpg",
14         IM"5_photo.jpg",
15         IM"6_photo.jpg",
16 */
17 };
18 #define N_IMAGES (1)
19
20 #define GRID_ITEM_SIZE 100
21
22 static int g_clipdrawer_mode = 0;
23 // gic should live at gengrid callback functions
24 Elm_Gengrid_Item_Class gic;
25
26 typedef struct tag_gridimgitem
27 {
28         Elm_Gengrid_Item *item;
29         const char *path;
30         Evas_Object *delbtn;
31 } gridimgitem_t;
32
33 static int toggle_clipdrawer_mode()
34 {
35         g_clipdrawer_mode = !g_clipdrawer_mode;
36         return g_clipdrawer_mode;
37 }
38
39 static int get_clipdrawer_mode()
40 {
41         return g_clipdrawer_mode;
42 }
43
44 static void _list_longpress(void *data, Evas_Object *obj, void *event_info)
45 {
46         struct appdata *ad = data;
47
48         clipdrawer_change_mode(ad);
49 }
50
51 static void _list_click_paste(void *data, Evas_Object *obj, void *event_info)
52 {
53         struct appdata *ad = data;
54     Elm_List_Item *it = (Elm_List_Item *) elm_list_selected_item_get(obj);
55         if (it == NULL)
56                 return;
57
58     elm_list_item_selected_set(it, 0);
59
60         char *p = NULL;
61         int cplen;
62
63         char *cpdata = NULL;
64         cpdata = elm_list_item_label_get(it);
65         if (cpdata == NULL)
66                 return;
67         cplen = strlen(cpdata);
68         p = malloc(cplen + 1);
69         snprintf(p, cplen+1, "%s", cpdata);
70         elm_selection_set(1, obj, /*ELM_SEL_FORMAT_TEXT*/1, p);
71 //      elm_selection_set(1, obj, /*ELM_SEL_FORMAT_MARKUP*/2, p);
72
73 //      clipdrawer_lower_view(ad);
74 }
75
76 static void _list_del_response_cb(void *data, Evas_Object *obj, void *event_info)
77 {
78         Elm_List_Item *it = (Elm_List_Item *)data;
79         evas_object_del(obj);
80
81         if((int)event_info == ELM_POPUP_RESPONSE_OK)
82                 elm_list_item_del(it);
83 }
84
85 static void _list_click_delete(void *data, Evas_Object *obj, void *event_info)
86 {
87         struct appdata *ad = data;
88     Elm_List_Item *it = (Elm_List_Item *) elm_list_selected_item_get(obj);
89         if (it == NULL)
90                 return;
91
92     elm_list_item_selected_set(it, 0);
93
94         Evas_Object *popup = elm_popup_add(ad->win_main);
95         elm_popup_timeout_set(popup, 3);
96         evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
97         elm_popup_desc_set(popup, "Are you sure delete this?");
98         elm_popup_buttons_add(popup, 2,
99                                                   "Yes", ELM_POPUP_RESPONSE_OK,
100                                                   "No", ELM_POPUP_RESPONSE_CANCEL,
101                                                   NULL);
102         evas_object_smart_callback_add(popup, "response", _list_del_response_cb, it);
103         evas_object_show(popup);
104
105 //      char *slabel = NULL;
106 //      slabel = elm_list_item_label_get(it);
107 }
108
109 int clipdrawer_update_contents(void *data)
110 {
111         struct appdata *ad = data;
112         int i, pos;
113
114         elm_list_clear(ad->txtlist);
115         for (i = 0; i < HISTORY_QUEUE_MAX_TXT_ITEMS; i++)
116         {
117                 pos = get_current_history_position()+i;
118                 if (pos > HISTORY_QUEUE_MAX_TXT_ITEMS-1)
119                         pos = pos-HISTORY_QUEUE_MAX_TXT_ITEMS;
120                 if (get_item_contents_by_pos(pos) != NULL && strlen(get_item_contents_by_pos(pos)) > 0)
121                 {
122                         elm_list_item_append(ad->txtlist, get_item_contents_by_pos(pos), NULL, NULL, NULL, ad);
123                 }
124         }
125         elm_list_go(ad->txtlist);
126
127         /* FIXME : sometimes when list update, screen isn't updated */
128
129         return 0;
130 }
131
132 const char* clipdrawer_get_plain_string_from_escaped(char *escstr)
133 {
134         /* TODO : is it should be here? besides, remove dependency for entry */
135         /* NOTE : return string should be freed */
136         return elm_entry_markup_to_utf8(escstr);
137 }
138
139 Evas_Object* _grid_icon_get(const void *data, Evas_Object *obj, const char *part)
140 {
141         int delete_mode = get_clipdrawer_mode();
142         gridimgitem_t *ti = (gridimgitem_t *)data;
143         if (!strcmp(part, "elm.swallow.icon"))
144         {
145                 Evas_Object *icon = elm_icon_add(obj);
146                 elm_icon_file_set(icon, ti->path, NULL);
147                 evas_object_size_hint_aspect_set(icon, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
148                 evas_object_show(icon);
149                 return icon;
150         }
151         else if (!strcmp(part, "elm.swallow.end") && delete_mode)
152         {
153                 ti->delbtn = elm_check_add(obj);
154                 elm_object_style_set(ti->delbtn, "extended/imagegrid");
155                 elm_check_state_set(ti->delbtn, 1);
156                 evas_object_show(ti->delbtn);
157                 return ti->delbtn;
158         }
159            
160         return NULL;
161 }
162
163 static void _grid_longpress(void *data, Evas_Object *obj, void *event_info)
164 {
165         struct appdata *ad = data;
166         clipdrawer_change_mode(ad);
167 }
168
169
170 static void _grid_click_paste(void *data, Evas_Object *obj, void *event_info)
171 {
172         struct appdata *ad = data;
173         char *file, *p;
174         int len;
175         Elm_Gengrid_Item *sgobj = NULL;
176         sgobj = elm_gengrid_selected_item_get(ad->imggrid);
177         gridimgitem_t *ti = NULL;
178         ti = elm_gengrid_item_data_get(sgobj);
179
180         if (!sgobj || !ti)
181         {
182                 DTRACE("ERR: cbhm can't get the selected image\n");
183                 return;
184         }
185         len = strlen(ti->path);
186         p = malloc(len + 10);
187         snprintf(p,len+10, "file:///%s", ti->path);
188
189         elm_selection_set(/*secondary*/1,obj,/*ELM_SEL_FORMAT_IMAGE*/4,p);
190
191 //      clipdrawer_lower_view(ad);
192
193         elm_gengrid_item_selected_set(sgobj, EINA_FALSE);
194 }
195
196 static void _grid_del_response_cb(void *data, Evas_Object *obj, void *event_info)
197 {
198         Elm_Gengrid_Item *it = (Elm_Gengrid_Item *)data;
199         evas_object_del(obj);
200
201         if((int)event_info == ELM_POPUP_RESPONSE_OK)
202                 elm_gengrid_item_del(it);
203 }
204
205 static void _grid_click_delete(void *data, Evas_Object *obj, void *event_info)
206 {
207         struct appdata *ad = data;
208         Elm_Gengrid_Item *sgobj = NULL;
209         sgobj = elm_gengrid_selected_item_get(ad->imggrid);
210         gridimgitem_t *ti = NULL;
211         ti = elm_gengrid_item_data_get(sgobj);
212
213         if (!sgobj || !ti)
214         {
215                 DTRACE("ERR: cbhm can't get the clicked del image\n");
216                 return;
217         }
218
219         Evas_Object *popup = elm_popup_add(ad->win_main);
220         elm_popup_timeout_set(popup, 3);
221         evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
222         elm_popup_desc_set(popup, "Are you sure delete this?");
223         elm_popup_buttons_add(popup, 2,
224                                                   "Yes", ELM_POPUP_RESPONSE_OK,
225                                                   "No", ELM_POPUP_RESPONSE_CANCEL,
226                                                   NULL);
227         evas_object_smart_callback_add(popup, "response", _grid_del_response_cb, sgobj);
228         evas_object_show(popup);
229 }
230
231 void _grid_del(const void *data, Evas_Object *obj)
232 {
233         gridimgitem_t *ti = (gridimgitem_t *)data;
234         eina_stringshare_del(ti->path);
235         free(ti);
236 }
237
238 int clipdrawer_refresh_imghistory_item(void *data, int delete_mode)
239 {
240         struct appdata *ad = data;
241         Eina_List *oldlist = NULL;
242         const Eina_List *l;
243         Elm_Gengrid_Item *lgrid;
244         gridimgitem_t *lgitem;
245         Evas_Object *ngg;
246         Evas_Object *oldgg;
247         
248         oldlist = elm_gengrid_items_get(ad->imggrid);
249         elm_layout_content_unset(ad->ly_main, "imagehistory/list");
250         ngg = elm_gengrid_add(ad->win_main);
251         elm_layout_content_set(ad->ly_main, "imagehistory/list", ngg);
252         oldgg = ad->imggrid;
253         ad->imggrid = ngg;
254         elm_gengrid_item_size_set(ad->imggrid, GRID_ITEM_SIZE, GRID_ITEM_SIZE+3);
255         elm_gengrid_align_set(ad->imggrid, 0.0, 0.0);
256         elm_gengrid_horizontal_set(ad->imggrid, EINA_TRUE);
257         elm_gengrid_bounce_set(ad->imggrid, EINA_TRUE, EINA_FALSE);
258         elm_gengrid_multi_select_set(ad->imggrid, EINA_FALSE);
259         if (delete_mode)
260                 evas_object_smart_callback_add(ad->imggrid, "selected", _grid_click_delete, ad);
261         else
262                 evas_object_smart_callback_add(ad->imggrid, "selected", _grid_click_paste, ad);
263         evas_object_smart_callback_add(ad->imggrid, "longpressed", _grid_longpress, ad);
264         evas_object_size_hint_weight_set(ad->imggrid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
265
266         gic.item_style = "default_grid";
267         gic.func.label_get = NULL;
268         gic.func.icon_get = _grid_icon_get;
269         gic.func.state_get = NULL;
270         gic.func.del = _grid_del;
271
272         EINA_LIST_REVERSE_FOREACH(oldlist, l, lgrid)
273         {
274                 lgitem = elm_gengrid_item_data_get(lgrid);
275                 clipdrawer_add_image_item(lgitem->path);
276         }
277
278         evas_object_show (ad->imggrid);
279
280         elm_gengrid_clear(oldgg);
281         evas_object_hide(oldgg);
282         evas_object_del(oldgg);
283
284         return 0;
285 }
286
287 int clipdrawer_refresh_txthistory_item(void *data, int delete_mode)
288 {
289         struct appdata *ad = data;
290         Eina_List *oldlist = NULL;
291         const Eina_List *l;
292         Elm_List_Item *litem;
293         const char *ltext;
294         Evas_Object *ntl = NULL;
295 //      Evas_Object *ci = NULL;
296
297         oldlist = elm_list_items_get(ad->txtlist);
298         elm_layout_content_unset(ad->ly_main, "texthistory/list");
299         ntl = elm_list_add(ad->win_main);
300         elm_layout_content_set(ad->ly_main, "texthistory/list", ntl);
301         elm_object_style_set(ntl, "extended/historylist");
302
303         EINA_LIST_FOREACH(oldlist, l, litem)
304         {
305                 ltext = elm_list_item_label_get(litem);
306                 if (delete_mode)
307                 {
308                         Evas_Object *ci = elm_icon_add(ad->win_main);
309                         elm_icon_file_set(ci, "/usr/share/icon/cbhm/05_delete.png", NULL);
310                         evas_object_size_hint_min_set(ci, 33 * elm_scale_get(), 33 * elm_scale_get());
311 //                      evas_object_size_hint_aspect_set(ci, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
312                         evas_object_show(ci);
313                         elm_list_item_append(ntl, ltext, NULL, ci, NULL, ad);
314                 }
315                 else
316                 {
317                         elm_list_item_append(ntl, ltext, NULL, NULL, NULL, ad);
318                 }
319         }
320
321         elm_list_clear(ad->txtlist);
322         evas_object_hide(ad->txtlist);
323         evas_object_del(ad->txtlist);
324
325         ad->txtlist = ntl;
326         evas_object_size_hint_weight_set(ad->txtlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
327         if (delete_mode)
328                 evas_object_smart_callback_add(ad->txtlist, "selected", _list_click_delete, ad);
329         else
330                 evas_object_smart_callback_add(ad->txtlist, "selected", _list_click_paste, ad);
331         evas_object_smart_callback_add(ad->txtlist, "longpressed", _list_longpress, ad);
332
333         elm_list_go(ad->txtlist);
334
335         return 0;
336 }
337
338 int clipdrawer_change_mode(void *data)
339 {
340         struct appdata *ad = data;
341
342         toggle_clipdrawer_mode();
343
344         DTRACE("clipdrawer delete mode = %d\n", get_clipdrawer_mode());
345
346         clipdrawer_refresh_imghistory_item(ad, get_clipdrawer_mode());
347         clipdrawer_refresh_txthistory_item(ad, get_clipdrawer_mode());
348
349         return 0;
350 }
351
352 // FIXME: how to remove calling g_get_main_appdata()? 
353 //        it's mainly used at 'clipdrawer_add_image_item'
354 int clipdrawer_add_image_item(char *imagepath)
355 {
356         struct appdata *ad = g_get_main_appdata();
357         gridimgitem_t *newgenimg = NULL;
358         char* filepath = NULL;
359         Eina_List *igl = NULL;
360         unsigned int igl_counter = 0;
361
362         if (!check_regular_file(imagepath))
363         {
364                 DTRACE("Error : it isn't normal file = %s\n", imagepath);
365                 return -1;
366         }
367
368         igl = elm_gengrid_items_get(ad->imggrid);
369         igl_counter = eina_list_count(igl);
370         if (igl_counter >= HISTORY_QUEUE_MAX_IMG_ITEMS)
371         {
372                 elm_gengrid_item_del(eina_list_data_get(eina_list_last(igl)));
373         }
374
375         newgenimg = malloc(sizeof(gridimgitem_t));
376         newgenimg->path = eina_stringshare_add(imagepath);
377         newgenimg->item = elm_gengrid_item_prepend(ad->imggrid, &gic, newgenimg, NULL, NULL);
378
379         return TRUE;
380 }
381
382 static void
383 clipdrawer_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
384 {
385         struct appdata *ad = data;
386
387         #define EDJE_CLOSE_PART_PREFIX "closebutton/"
388         if (!strncmp(source, EDJE_CLOSE_PART_PREFIX, strlen(EDJE_CLOSE_PART_PREFIX)))
389         {
390                 clipdrawer_lower_view(ad);
391         }
392 }
393
394 int clipdrawer_init(void *data)
395 {
396         struct appdata *ad = data;
397         double cdy, cdw;
398
399         // for elm_check, elm_list
400         elm_theme_extension_add(NULL, APP_EDJ_FILE);
401
402         cdy = (1.0*CLIPDRAWER_HEIGHT/800)*ad->root_h;
403         cdw = (1.0*CLIPDRAWER_POS_Y/800*1.0)*ad->root_h;
404
405         evas_object_resize(ad->win_main, ad->root_w, (int)cdy);
406         evas_object_move(ad->win_main, CLIPDRAWER_POS_X, (int)cdw);
407         evas_object_resize(ad->ly_main, ad->root_w, (int)cdy);
408         evas_object_move(ad->ly_main, CLIPDRAWER_POS_X, (int)cdw);
409
410         edje_object_signal_callback_add(elm_layout_edje_get(ad->ly_main), "mouse,up,1", "*", clipdrawer_ly_clicked, ad);
411
412         ad->imggrid = NULL;
413         ad->imggrid = elm_gengrid_add(ad->win_main);
414         elm_layout_content_set(ad->ly_main, "imagehistory/list", ad->imggrid);
415         elm_gengrid_item_size_set(ad->imggrid, GRID_ITEM_SIZE, GRID_ITEM_SIZE+3);
416         elm_gengrid_align_set(ad->imggrid, 0.0, 0.0);
417         elm_gengrid_horizontal_set(ad->imggrid, EINA_TRUE);
418         elm_gengrid_bounce_set(ad->imggrid, EINA_TRUE, EINA_FALSE);
419         elm_gengrid_multi_select_set(ad->imggrid, EINA_FALSE);
420         evas_object_smart_callback_add(ad->imggrid, "selected", _grid_click_paste, ad);
421         evas_object_smart_callback_add(ad->imggrid, "longpressed", _grid_longpress, ad);
422         evas_object_size_hint_weight_set(ad->imggrid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
423
424         elm_gengrid_clear(ad->imggrid);
425
426         gic.item_style = "default_grid";
427         gic.func.label_get = NULL;
428         gic.func.icon_get = _grid_icon_get;
429         gic.func.state_get = NULL;
430         gic.func.del = _grid_del;
431
432         int i;
433         gridimgitem_t *newgenimg;
434
435         for (i = 0; i < N_IMAGES; i++)
436         {
437                 clipdrawer_add_image_item(g_images_path[i]);
438         }
439
440         evas_object_show (ad->imggrid);
441
442 // for debugging, calc image history pos
443 /*
444    Evas_Coord x, y, w, h;
445    Evas_Coord vx, vy, vw, vh;
446
447    edje_object_part_geometry_get(elm_layout_edje_get(ad->ly_main),"imagehistory/list",&x,&y,&w,&h);
448    evas_object_geometry_get (ad->imggrid, &vx,&vy,&vw,&vh);
449    fprintf(stderr, "## x = %d, y = %d, w = %d, h = %d\n", x, y, w, h);
450    fprintf(stderr, "## vx = %d, vy = %d, vw = %d, vh = %d\n", vx, vy, vw, vh);
451 */
452
453         ad->txtlist = elm_list_add(ad->win_main);
454         elm_layout_content_set(ad->ly_main, "texthistory/list", ad->txtlist);
455         elm_object_style_set(ad->txtlist, "extended/historylist");
456         evas_object_size_hint_weight_set(ad->txtlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
457         evas_object_smart_callback_add(ad->txtlist, "selected", _list_click_paste, ad);
458         evas_object_smart_callback_add(ad->txtlist, "longpressed", _list_longpress, ad);
459         elm_list_item_append(ad->txtlist, "default", NULL, NULL, NULL, ad);
460
461         elm_list_go(ad->txtlist);
462
463         if (get_item_counts() != 0)
464                 clipdrawer_update_contents(ad);
465
466         return 0;
467 }
468
469 int clipdrawer_create_view(void *data)
470 {
471         struct appdata *ad = data;
472
473         clipdrawer_init(ad);
474
475         // for debug
476         // at starting, showing app view
477         clipdrawer_activate_view(ad);
478
479         return 0;
480 }
481
482 void clipdrawer_activate_view(void *data)
483 {
484         struct appdata *ad = data;
485         
486         if (ad->win_main)
487         {
488                 evas_object_show(ad->win_main);
489                 elm_win_activate(ad->win_main);
490         }
491 }
492
493 void clipdrawer_lower_view(void *data)
494 {
495         struct appdata *ad = data;
496         
497         if (ad->win_main)
498         {
499                 evas_object_hide(ad->win_main);
500                 elm_win_lower(ad->win_main);
501
502                 // if delete mode, then back to normal mode
503                 if (get_clipdrawer_mode())
504                         clipdrawer_change_mode(ad);
505         }
506 }