Initialize Tizen 2.3
[apps/home/ug-memo-efl.git] / src / memo-assist.c
1 /*
2 *
3 * Copyright 2012  Samsung Electronics Co., Ltd
4 *
5 * Licensed under the Flora License, Version 1.1 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *    http://floralicense.org/license/
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19 #include <stdio.h>
20 #include <unicode/ustring.h>
21 #include <unicode/utypes.h>
22 #include <unicode/udat.h>
23 #include <unicode/udatpg.h>
24 #include <iniparser.h>
25 #include <dictionary.h>
26 #include <vconf-keys.h>
27 #include <vconf.h>
28 #include <gravel.h>
29 #include <extended-elm.h>
30 #include <supplement.h>
31 #include <memo-assist.h>
32 #include <appcore-common.h>
33
34 #define ICU_TIME_BUFFER 256
35 static UDateFormat* dfmt = NULL;
36
37 /**
38  * memo_get_doodle_title
39  *
40  * @brief
41  *
42  * @return
43  *
44  * @exception    None
45  *
46  * @remark       None
47  *
48  * @see
49  *
50  */
51 char *memo_get_doodle_title()
52 {
53     memo_data_list_t *l = NULL;
54     memo_data_list_t *t = NULL;
55     char buf[MEMO_BUFFER_SIZE];
56     int i = 0;
57     int d = 0;
58     l = memo_get_all_data_list();
59     for (t = l; t != NULL; t = t->next) {
60         if (t->md.has_doodle) {
61             d = atoi(t->md.content + strlen(DOODLE_TITLE_PREFIX));
62             i = (d > i) ? d : i;
63         }
64     }
65     i++;
66     snprintf(buf, MEMO_BUFFER_SIZE, "%s%04d", DOODLE_TITLE_PREFIX, i);
67     memo_free_data_list(l);
68     return strdup(buf);
69 }
70
71 void icu_init()
72 {
73     UErrorCode status = U_ZERO_ERROR;
74     const char *locale;
75     UChar ubuf[ICU_TIME_BUFFER];
76     UChar bestPattern[ICU_TIME_BUFFER];
77     UDateTimePatternGenerator *generator;
78     enum appcore_time_format timeformat;
79     char *timezone_id = NULL;
80     UChar utimezone_id[256] = {0,};
81
82     /* reset timezone according to vconf */
83     timezone_id = vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_ID);
84     u_uastrcpy(utimezone_id, timezone_id);
85     SFREE(timezone_id);
86     ucal_setDefaultTimeZone(utimezone_id , &status);
87     /* init */
88     uloc_setDefault(getenv("LC_TIME"), &status); /* ICU API to set default locale */
89     locale = uloc_getDefault();
90     /* format */
91     appcore_get_timeformat(&timeformat);
92     if (timeformat==APPCORE_TIME_FORMAT_24) {
93         /* 14 May 09 15:37 */
94         u_strFromUTF8(ubuf, MEMO_BUFFER_SIZE, NULL, "dMMMyyHHmm", -1, &status);
95     } else {
96         /* 14 May 09 03:37 PM */
97         u_strFromUTF8(ubuf, MEMO_BUFFER_SIZE, NULL, "dMMMyyhhmma", -1, &status);
98     }
99     /* get pattern */
100     generator = udatpg_open(locale, &status);
101     udatpg_getBestPattern(generator, ubuf, u_strlen(ubuf), bestPattern, ICU_TIME_BUFFER, &status);
102     udatpg_close(generator);
103     /* format */
104     if (dfmt != NULL) {
105         udat_close(dfmt);
106     }
107     dfmt = udat_open(UDAT_IGNORE, UDAT_IGNORE, locale, NULL, -1, bestPattern, -1, &status);
108 }
109
110 /**
111  * memo_time_format
112  *
113  * @brief
114  *
115  * @param   [in] buf    buffer used to store formated time
116  *
117  * @param   [in] len    length of buf
118  *
119  * @param   [in] time  actual time
120  *
121  * @return
122  *
123  * @exception    None
124  *
125  * @remark       None
126  *
127  * @see
128  *
129  */
130 void memo_time_format(char *buf, int len, time_t time)
131 {
132     UErrorCode status = U_ZERO_ERROR;
133     UChar ubuf[ICU_TIME_BUFFER];
134
135     if (dfmt == NULL) {
136         icu_init();
137     }
138     udat_format(dfmt, (UDate)time*1000, ubuf, ICU_TIME_BUFFER, NULL, &status);
139     u_strToUTF8(buf, len, NULL, ubuf, -1, &status);
140 }
141
142 time_t memo_get_binary_release_date()
143 {
144     struct tm time = {0};
145     char *date = NULL;
146     dictionary *about_dic = iniparser_load("/etc/info.ini");
147
148     RETVIF(about_dic==NULL, 0);
149     date = iniparser_getstr(about_dic, "Build:Date");
150     strptime(date, "%Y.%m.%d", &time);
151     iniparser_freedict(about_dic);
152     return timelocal(&time);
153 }
154
155 /**
156  * mouse_event_identify
157  *
158  * @brief
159  *
160  * @param   [in] startx
161  *
162  * @param   [in] starty
163  *
164  * @param   [in] endx
165  *
166  * @param   [in] endy
167  *
168  * @return
169  *
170  * @exception    None
171  *
172  * @remark       None
173  *
174  * @see
175  *
176  */
177 mouse_behaviour_t mouse_event_identify(int startx, int starty, int endx, int endy)
178 {
179     int gapx = 0;
180     int gapy = 0;
181
182     if ((startx == MOUSE_POSITION_INVALID)
183         || (starty == MOUSE_POSITION_INVALID)
184         || (endx == MOUSE_POSITION_INVALID)
185         || (endy == MOUSE_POSITION_INVALID)) {
186         return MOUSE_EVENT_INVALID;
187     }
188
189     gapx = endx - startx;
190     gapy = endy - starty;
191     if ((abs(gapx) <= 10) && (abs(gapy) <= 10)) {    /* click */
192         return MOUSE_EVENT_CLICK;
193     } else if (abs(gapx) > abs(gapy)) {    /* horizonal drag */
194         return gapx > 0 ? MOUSE_EVENT_DRAG_RIGHT : MOUSE_EVENT_DRAG_LEFT;
195     } else {        /* vertical drag */
196         return gapy > 0 ? MOUSE_EVENT_DRAG_DOWN : MOUSE_EVENT_DRAG_UP;
197     }
198 }
199
200 static void _evas_object_on_mouse_down(void *data, Evas *e, Evas_Object *evas_obj, void *event_info)
201 {
202     Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down *)event_info;
203     evas_object_data_set(evas_obj, "startx", (const void *)ev->output.x);
204     evas_object_data_set(evas_obj, "starty", (const void *)ev->output.y);
205 }
206
207 static void _evas_object_on_mouse_up(void *data, Evas *e, Evas_Object *evas_obj, void *event_info)
208 {
209     Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down *)event_info;
210     int startx = (int)evas_object_data_get(evas_obj, "startx");
211     int starty = (int)evas_object_data_get(evas_obj, "starty");
212     Evas_Smart_Cb on_flick = (Evas_Smart_Cb)evas_object_data_get(evas_obj, "on_flick");
213     mouse_behaviour_t mbt = mouse_event_identify(startx, starty, ev->output.x, ev->output.y);
214     evas_object_data_set(evas_obj, "startx", (const void *)MOUSE_POSITION_INVALID);
215     evas_object_data_set(evas_obj, "starty", (const void *)MOUSE_POSITION_INVALID);
216     if (on_flick != NULL) {
217         on_flick(data, evas_obj, (void *)mbt);
218     }
219 }
220
221 void evas_object_flick_callback_add(Evas_Object *obj, Evas_Smart_Cb on_flick, void *data)
222 {
223     evas_object_data_set(obj, "startx", (const void *)MOUSE_POSITION_INVALID);
224     evas_object_data_set(obj, "starty", (const void *)MOUSE_POSITION_INVALID);
225     evas_object_data_set(obj, "on_flick", (const void *)on_flick);
226     evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN, _evas_object_on_mouse_down, data);
227     evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP, _evas_object_on_mouse_up, data);
228 }
229
230 void memo_com_dummy_cb(void *data, const char *msg, void *event)
231 {
232     LOGD("msg : %s\n", msg);
233 }
234
235 typedef struct __pop_data_t {
236     Evas_Smart_Cb on_yes;
237     Evas_Smart_Cb on_no;
238     void *user_data;
239     Evas_Object *pop;
240 } pop_data_t;
241
242 static void _on_yes_cb(void *data, Evas_Object *obj, void *event_info)
243 {
244         pop_data_t *pData = (pop_data_t *)data;
245         if (pData->on_yes != NULL) {
246             pData->on_yes(pData->user_data, obj, event_info);
247         }
248         evas_object_del(pData->pop);
249         SFREE(pData);
250 }
251
252 static void _on_no_cb(void *data, Evas_Object *obj, void *event_info)
253 {
254         pop_data_t *pData = (pop_data_t *)data;
255         if (pData->on_no != NULL) {
256             pData->on_no(pData->user_data, obj, event_info);
257         }
258         evas_object_del(pData->pop);
259         SFREE(pData);
260 }
261
262 /**
263  * memo_create_yes_no_popup
264  *
265  * @brief
266  *
267  * @param   [in] win
268  *
269  * @param   [in] msg
270  *
271  * @param   [in] on_yes
272  *
273  * @param   [in] on_no
274  *
275  * @param   [in] data
276  *
277  * @return
278  *
279  * @exception    None
280  *
281  * @remark       None
282  *
283  * @see
284  *
285  */
286 void memo_create_yes_no_popup(Evas_Object *win, const char *msg, Evas_Smart_Cb on_yes, Evas_Smart_Cb on_no, void *data)
287 {
288     pop_data_t *pd = SMALLOC(pop_data_t);
289     RETIF(pd == NULL);
290
291     pd->on_yes = on_yes;
292     pd->on_no = on_no;
293     pd->user_data = data;
294     Evas_Object *popup = elm_popup_add(win);
295     pd->pop = popup;
296     evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
297     elm_object_text_set(popup, msg);
298     Evas_Object *btn1 = elm_button_add(popup);
299     elm_object_text_set(btn1, MEMO_I18N_YES);
300     elm_object_part_content_set(popup, "button1", btn1);
301     evas_object_smart_callback_add(btn1, "clicked", _on_yes_cb, pd);
302     Evas_Object *btn2 = elm_button_add(popup);
303     elm_object_text_set(btn2, MEMO_I18N_NO);
304     elm_object_part_content_set(popup, "button2", btn2);
305     evas_object_smart_callback_add(btn2, "clicked", _on_no_cb, pd);
306     evas_object_show(popup);
307 }
308
309 void memo_tool_btn_focus_set(Evas_Object *eo, Eina_Bool status)
310 {
311     edje_object_signal_emit(elm_layout_edje_get(eo), (status ? "focus" : "normal"), "elm");
312 }
313
314 static void _set_bg(Evas_Object *obj, service_h service)
315 {
316         unsigned char *color = NULL;
317         int bg_color = 0xFFFFFFFF; /* ARGB */
318         char *s = NULL;
319         service_get_extra_data(service, "bg_color" , &s);
320         if (s != NULL) {
321                 bg_color = atoi(s);
322                 SFREE(s);
323         }
324         color = (unsigned char *)&bg_color;
325         evas_object_color_set(obj, color[2], color[1], color[0], color[3]);
326 }
327
328 typedef struct __font_size_selector_t {
329     Evas_Object *parent;
330     Memo_Component_Callback cb;
331     void *data;
332     /* content */
333     Evas_Object *body_main;
334     Evas_Object *slider;
335     Evas_Object *label;
336     Evas_Object *event_rect; /* for sweep */
337     /* other */
338     int min;
339     int max;
340     int current;
341 }font_size_selector_t;
342
343 static void _on_font_size_change_cb(void *data, Evas_Object *obj, void *event_info)
344 {
345     font_size_selector_t *fss = (font_size_selector_t *)data;
346     fss->current = elm_slider_value_get(fss->slider);
347     char buf[MEMO_BUFFER_SIZE];
348     snprintf(buf, MEMO_BUFFER_SIZE, "<color=#000000FF><font_size=%d><align=center>Abc</align></font_size></color>", fss->current);
349     elm_object_text_set(fss->label, buf);
350     fss->cb(fss->data, "change", (void *)fss->current);
351 }
352
353 static void _fss_on_flick(void *data, Evas_Object *evas_obj, void *event_info)
354 {
355     font_size_selector_t *fss = (font_size_selector_t *)data;
356     if ((mouse_behaviour_t)event_info == MOUSE_EVENT_DRAG_DOWN) {
357         fss->cb(fss->data, "flick,down", (void *)fss->current);
358     }
359 }
360
361 void *memo_load_font_size_selector(Evas_Object *parent, service_h service, Memo_Component_Callback cb, void *data)
362 {
363         font_size_selector_t *fss = SMALLOC(font_size_selector_t);
364         RETVIF(fss==NULL, NULL);
365         service_dump(service);
366         fss->parent = parent;
367         fss->cb = (cb==NULL ? memo_com_dummy_cb : cb); /* make sure cb is not null, no need to check legitimacy of cb when call */
368         fss->data = data;
369
370         /* init */
371         fss->min = 20;
372         fss->max = 60;
373         fss->current = 30;
374         char *s = NULL;
375         service_get_extra_data(service, "current", &s);
376         if (s != NULL) {
377                 fss->current = atoi(s);
378                 SFREE(s);
379         }
380
381         fss->body_main = elm_layout_create(fss->parent, EDJ_FILE, "font_size_selector");
382         fss->cb(fss->data, "layout", fss->body_main);
383
384         /* background */
385         Evas_Object *bg = evas_object_rectangle_add(evas_object_evas_get(parent));
386         _set_bg(bg, service);
387         elm_object_part_content_set(fss->body_main, "bg.color", bg);
388         /* slider */
389         fss->slider = elm_slider_add(fss->body_main);
390         elm_object_style_set(fss->slider, "expanded_indicator_button");
391         elm_slider_indicator_show_set(fss->slider, EINA_TRUE);
392         elm_slider_min_max_set(fss->slider, fss->min, fss->max);
393         elm_slider_indicator_format_set(fss->slider, "%1.0f");
394         elm_slider_value_set(fss->slider, fss->current);
395         evas_object_smart_callback_add(fss->slider, "changed", _on_font_size_change_cb, fss);
396         elm_object_part_content_set(fss->body_main, "elm.swallow.selector", fss->slider);
397         /* preview text */
398         fss->label = elm_label_add(fss->body_main);
399         char buf[MEMO_BUFFER_SIZE];
400         snprintf(buf, MEMO_BUFFER_SIZE, "<color=#000000FF><font_size=%d><align=center>Abc</align></font_size></color>", fss->current);
401         elm_object_text_set(fss->label, buf);
402         elm_object_part_content_set(fss->body_main, "elm.swallow.label", fss->label);
403         /* for flick event */
404         fss->event_rect = (Evas_Object *)edje_object_part_object_get(elm_layout_edje_get(fss->body_main), "event");
405         evas_object_flick_callback_add(fss->event_rect, _fss_on_flick, fss);
406
407         return (void *)fss;
408 }
409
410 void memo_del_font_size_selector(void *h_fss)
411 {
412     font_size_selector_t *fss = (font_size_selector_t *)h_fss;
413     evas_object_del(fss->body_main);
414     SFREE(fss);
415 }
416
417 typedef struct __color_selector_t {
418     Evas_Object *parent;
419     Memo_Component_Callback cb;
420     void *data;
421     /* content */
422     Evas_Object *body_main;
423     Evas_Object *selector;
424     Evas_Object *rect; /* color rect */
425     Evas_Object *event_rect; /* for sweep */
426     /* other */
427     int color; /* ARGB */
428 }color_selector_t;
429
430 static void _on_color_change_cb(void *data, Evas_Object *obj, void *event_info)
431 {
432     int r, g, b, a;
433     color_selector_t *cs = (color_selector_t *)data;
434     elm_colorselector_color_get(cs->selector, &r, &g, &b, &a);
435     evas_object_color_set(cs->rect, r, g, b, a);
436     int color = ARGB_JOIN(a, r, g, b);
437     if (cs->color != color) {
438         cs->color = color;
439         cs->cb(cs->data, "change", (void *)cs->color);
440     }
441 }
442
443 static void _cs_on_flick(void *data, Evas_Object *evas_obj, void *event_info)
444 {
445     color_selector_t *cs = (color_selector_t *)data;
446     if ((mouse_behaviour_t)event_info == MOUSE_EVENT_DRAG_DOWN) {
447         cs->cb(cs->data, "flick,down", (void *)cs->color);
448     }
449 }
450
451 void *memo_load_color_selector(Evas_Object *parent, service_h service, Memo_Component_Callback cb, void *data)
452 {
453     color_selector_t *cs = SMALLOC(color_selector_t);
454     RETVIF(cs==NULL, NULL);
455     service_dump(service);
456     cs->parent = parent;
457     cs->cb = (cb==NULL ? memo_com_dummy_cb : cb); /* make sure cb is not null, no need to check legitimacy of cb when call */
458     cs->data = data;
459
460     /* init */
461     cs->color = 0xff000000;
462     char *s = NULL;
463     service_get_extra_data(service, "color" , &s);
464     if (s != NULL) {
465         cs->color = atoi(s);
466         SFREE(s);
467     }
468     cs->body_main = elm_layout_create(cs->parent, EDJ_FILE, "color_selector");
469     cs->cb(cs->data, "layout", cs->body_main);
470
471     /* background */
472     service_get_extra_data(service, "bg_color", &s);
473     if (s != NULL) {
474         edje_object_signal_emit(elm_layout_edje_get(cs->body_main), "white", "elm");
475         SFREE(s);
476     } else {
477         edje_object_signal_emit(elm_layout_edje_get(cs->body_main), "black", "elm");
478     }
479     /* selector */
480     cs->selector = elm_colorselector_add(cs->body_main);
481     elm_colorselector_mode_set(cs->selector, ELM_COLORSELECTOR_COMPONENTS);
482     elm_object_part_content_set(cs->body_main, "elm.swallow.selector", cs->selector);
483     unsigned char *color = (unsigned char *)&cs->color;
484     elm_colorselector_color_set(cs->selector, color[2], color[1], color[0], color[3]);
485     evas_object_smart_callback_add(cs->selector, "changed", _on_color_change_cb, cs);
486     /* preview color rect */
487     cs->rect = evas_object_rectangle_add(evas_object_evas_get(parent));
488     evas_object_color_set(cs->rect, color[2], color[1], color[0], color[3]);
489     elm_object_part_content_set(cs->body_main, "elm.swallow.color", cs->rect);
490     /* for flick event */
491     cs->event_rect = (Evas_Object *)edje_object_part_object_get(elm_layout_edje_get(cs->body_main), "event");
492     evas_object_flick_callback_add(cs->event_rect, _cs_on_flick, cs);
493
494     return (void *)cs;
495 }
496
497 void memo_del_color_selector(void *h_cs)
498 {
499     color_selector_t *cs = (color_selector_t *)h_cs;
500     evas_object_del(cs->body_main);
501     SFREE(cs);
502 }
503
504 typedef struct __pencil_size_selector_t {
505     Evas_Object *parent;
506     Memo_Component_Callback cb;
507     void *data;
508     /* content */
509     Evas_Object *body_main;
510     Evas_Object *slider;
511     Evas_Object *rect; /* previw rect */
512     Evas_Object *event_rect; /* for sweep */
513     /* other */
514     int min;
515     int max;
516     int current;
517 }pencil_size_selector_t;
518
519 static void _on_pencil_size_change_cb(void *data, Evas_Object *obj, void *event_info)
520 {
521     pencil_size_selector_t *pss = (pencil_size_selector_t *)data;
522     pss->current = elm_slider_value_get(pss->slider);
523     evas_object_size_hint_min_set(pss->rect, 0, pss->current);
524     pss->cb(pss->data, "change", (void *)pss->current);
525 }
526
527 static void _pss_on_flick(void *data, Evas_Object *evas_obj, void *event_info)
528 {
529     pencil_size_selector_t *pss = (pencil_size_selector_t *)data;
530     if ((mouse_behaviour_t)event_info == MOUSE_EVENT_DRAG_DOWN) {
531         pss->cb(pss->data, "flick,down", (void *)pss->current);
532     }
533 }
534
535 void *memo_load_pencil_size_selector(Evas_Object *parent, service_h service, Memo_Component_Callback cb, void *data)
536 {
537     pencil_size_selector_t *pss = SMALLOC(pencil_size_selector_t);
538     RETVIF(pss==NULL, NULL);
539     service_dump(service);
540     pss->parent = parent;
541     pss->cb = (cb==NULL ? memo_com_dummy_cb : cb); /* make sure cb is not null, no need to check legitimacy of cb when call */
542     pss->data = data;
543
544     /* init */
545     pss->min = 1;
546     pss->max = 8;
547     pss->current = 8;
548     char *s = NULL;
549     service_get_extra_data(service, "current", &s);
550     if (s != NULL) {
551         pss->current = atoi(s);
552         SFREE(s);
553     }
554
555     pss->body_main = elm_layout_create(pss->parent, EDJ_FILE, "pencil_size_selector");
556     pss->cb(pss->data, "layout", pss->body_main);
557
558     /* background */
559     Evas_Object *bg = evas_object_rectangle_add(evas_object_evas_get(parent));
560     _set_bg(bg, service);
561     elm_object_part_content_set(pss->body_main, "bg.color", bg);
562     /* slider */
563     pss->slider = elm_slider_add(pss->body_main);
564     elm_object_style_set(pss->slider, "expanded_indicator_button");
565     elm_slider_indicator_show_set(pss->slider, EINA_TRUE);
566     elm_slider_min_max_set(pss->slider, pss->min, pss->max);
567     elm_slider_indicator_format_set(pss->slider, "%1.0f");
568     elm_slider_value_set(pss->slider, pss->current);
569     evas_object_smart_callback_add(pss->slider, "changed", _on_pencil_size_change_cb, pss);
570     elm_object_part_content_set(pss->body_main, "elm.swallow.selector", pss->slider);
571     /* preview size rect */
572     pss->rect = evas_object_rectangle_add(evas_object_evas_get(parent));
573     evas_object_color_set(pss->rect, 0, 0, 0, 255);
574     evas_object_size_hint_min_set(pss->rect, 0, pss->current);
575     elm_object_part_content_set(pss->body_main, "elm.swallow.pencil", pss->rect);
576     /* for flick event */
577     pss->event_rect = (Evas_Object *)edje_object_part_object_get(elm_layout_edje_get(pss->body_main), "event");
578     evas_object_flick_callback_add(pss->event_rect, _pss_on_flick, pss);
579
580     return (void *)pss;
581 }
582
583 void memo_del_pencil_size_selector(void *h_pss)
584 {
585     pencil_size_selector_t *pss = (pencil_size_selector_t *)h_pss;
586     evas_object_del(pss->body_main);
587     SFREE(pss);
588 }
589
590 void memo_navigator_pop(Evas_Object *navi)
591 {
592     Elm_Object_Item *top_it = elm_naviframe_top_item_get(navi);
593     Evas_Object *eo = elm_object_item_content_get(top_it);
594     Evas_Object *prev_eo = evas_object_data_get(eo, "previous_obj");
595     if(prev_eo == NULL) { /* exit when view stack is empty */
596         elm_exit();
597     } else {
598         Evas_Smart_Cb cb = evas_object_data_get(prev_eo, "update_cb");
599         RETIF(cb == NULL);
600         void *cb_data = evas_object_data_get(prev_eo, "update_data");
601         cb(cb_data, NULL, NULL);
602     }
603     elm_naviframe_item_pop(navi);
604 }
605
606 Elm_Object_Item *memo_naviframe_item_push(Evas_Object *obj, const char *title_label,
607     Evas_Object *prev_btn, Evas_Object *next_btn, Evas_Object *content, const char *item_style)
608 {
609     Elm_Object_Item *top_it = elm_naviframe_top_item_get(obj);
610     if (top_it != NULL) {
611         Evas_Object *eo = elm_object_item_content_get(top_it);
612         if (eo != NULL) {
613             evas_object_data_set(content, "previous_obj", eo);
614         }
615     }
616
617     return elm_naviframe_item_push(obj, title_label, prev_btn, next_btn, content, item_style);
618 }
619
620 Evas_Object *memo_controlbar_add(Evas_Object *parent)
621 {
622         Evas_Object *toolbar = elm_toolbar_add(parent);
623         elm_toolbar_shrink_mode_set(toolbar, ELM_TOOLBAR_SHRINK_EXPAND);
624         elm_toolbar_homogeneous_set(toolbar, EINA_FALSE);
625         return toolbar;
626 }
627
628 void memo_comment_recover(Evas_Object *entry, const char *orig_utf8)
629 {
630     if (orig_utf8 == NULL) {
631         elm_entry_entry_set(entry, MEMO_I18N_ADD_COMMENT);
632     } else {
633         char *content = elm_entry_utf8_to_markup(orig_utf8);
634         elm_entry_entry_set(entry, content);
635         SFREE(content);
636     }
637 }