apply FSL(Flora Software License)
[apps/home/libug-worldclock-efl.git] / src / worldclock_add_view.c
1 /*
2   * Copyright 2012  Samsung Electronics Co., Ltd
3   * 
4   * Licensed under the Flora License, Version 1.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   * 
8   *     http://www.tizenopensource.org/license
9   * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16
17 #include <stdio.h>
18 #include <appcore-efl.h>
19 #include <Elementary.h>
20 #include <Ecore_X.h>
21 #include <vconf.h>
22 #include <unicode/utf8.h>
23 #include <unicode/ustring.h>
24
25 #include "worldclock.h"
26 #include "worldclock_data.h"
27 #include "worldclock_dlog.h"
28 #include "worldclock_util.h"
29 #include "worldclock_add_view.h"
30
31 #include "clock_fwk_icu_label.h"
32
33 #define MAX_LEN_CITY_NAME       16
34 #define MAX_LEN_COUNTRY_NAME    24
35 #define MAX_LEN_GMT             10
36 #define MAX_LEN_INPUT           20
37 #define FIRST_UPDATE_ITEM_COUNT 14
38
39 static struct appdata *g_ad = NULL;
40 static Wcl_Return_Cb g_return_cb = NULL;
41 static Elm_Object_Item *g_btn_sort_by_name = NULL;
42 static Elm_Object_Item *g_btn_sort_by_time = NULL;
43 static char g_index_buf[BUF_MIN_SIZE] = { '\0' };
44 static char *g_alphabetic_buf = NULL;
45
46 static Evas_Object *searchbar_layout = NULL;
47
48 typedef enum {
49         CALL_NONE = 0,
50         CALL_FROM_MAIN_VIEW,
51         CALL_FROM_UI_GADGET,
52
53         CALL_FROM_UNKNOW,
54 } ADDVIEW_CALL_FLAG;
55 static ADDVIEW_CALL_FLAG g_call_flag = CALL_NONE;
56
57 static char *__addview_genlist_label_get(void *data, Evas_Object *obj,
58                                          const char *part);
59 static Evas_Object *__addview_genlist_icon_get(void *data, Evas_Object *obj,
60                                                const char *part);
61 static void __addview_genlist_item_del(void *data, Evas_Object *obj);
62 static Evas_Object *__addview_index_add(Evas_Object *parent, void *data);
63 static Eina_Bool __addview_index_update(Evas_Object *index,
64                                         Wcl_Addlist_Sort_Type sort, char *buf,
65                                         void *data);
66
67 static Elm_Genlist_Item_Class g_ts = {
68         .item_style = "worldclock_addview_list",
69         //.item_style = "3text",
70         .func.text_get = __addview_genlist_label_get,
71         .func.content_get = __addview_genlist_icon_get,
72         .func.state_get = NULL,
73         .func.del = __addview_genlist_item_del,
74 };
75
76 /**
77  * Callback function used for quit event caused by Evas_Object event
78  *
79  * @param[in]  data        data used for this function
80  * @param[in]  obj         object which caused this function
81  * @param[in]  event_info  event data
82  *
83  * @return
84  */
85 static void __addview_quit_cb(void *data, Evas_Object *obj, void *event_info)
86 {
87         CLK_FUN_BEG();
88         ret_if(!g_ad);
89
90         struct appdata *ad = g_ad;
91
92         // execute callback function from previous view,
93         // which used to reload previous view
94         if (g_return_cb) {
95                 g_return_cb(data, EINA_FALSE);
96                 g_return_cb = NULL;
97         }
98         // remove default list used to store all appendable cities
99         if (ad->default_list) {
100                 worldclock_util_glist_remove_all(ad->default_list, EINA_TRUE);
101                 ad->default_list = NULL;
102         }
103         // remove timer
104         if (g_ad->add_view_update_timer) {
105                 ecore_timer_del(g_ad->add_view_update_timer);
106                 g_ad->add_view_update_timer = NULL;
107         }
108         if (g_ad->add_view_update_last_timer) {
109                 ecore_timer_del(g_ad->add_view_update_last_timer);
110                 g_ad->add_view_update_last_timer = NULL;
111         }
112         if (g_ad->add_view_quit_timer) {
113                 ecore_timer_del(g_ad->add_view_quit_timer);
114                 g_ad->add_view_quit_timer = NULL;
115         }
116
117         g_call_flag = CALL_NONE;
118         g_ad = NULL;
119         CLK_FUN_END();
120 }
121
122 /**
123  * Quit function called when exit event caused by timer
124  *
125  * @param[in]  data    data used for this function
126  *
127  * @return     EINA_FALSE
128  */
129 static Eina_Bool __addview_exit_cb(void *data)
130 {
131         __addview_quit_cb(data, NULL, NULL);
132         return EINA_FALSE;
133 }
134
135 /**
136  * Callback function used for selection info changed
137  *
138  * @return
139  */
140 static void __addview_notify_cb(const char *msg)
141 {
142         CLK_FUN_BEG();
143         ret_if(!g_ad);
144
145         if (!g_ad->add_selectioninfo) {
146                 // Add notify
147                 g_ad->add_selectioninfo = elm_notify_add(g_ad->add_ly);
148                 elm_notify_orient_set(g_ad->add_selectioninfo,
149                                       ELM_NOTIFY_ORIENT_BOTTOM);
150
151                 // selectioninfo layout add
152                 g_ad->add_selectioninfo_layout = elm_layout_add(g_ad->add_ly);
153                 // layout theme set
154                 elm_layout_theme_set(g_ad->add_selectioninfo_layout,
155                                      "standard", "selectioninfo",
156                                      "vertical/bottom_12");
157                 // selectioninfo layout content set to notify
158                 elm_object_content_set(g_ad->add_selectioninfo,
159                                        g_ad->add_selectioninfo_layout);
160         }
161         // text set and timeout set
162         edje_object_part_text_set(_EDJ(g_ad->add_selectioninfo_layout),
163                                   "elm.text", msg);
164         elm_notify_timeout_set(g_ad->add_selectioninfo, 5);
165         evas_object_show(g_ad->add_selectioninfo);
166
167         CLK_FUN_END();
168 }
169
170 //////////////////////////// gen list related /////////////////////////////////////////////////
171 /**
172  * Callback function used for get label as member in genlist item
173  *
174  * @param[in]  data   data used for this function
175  * @param[in]  obj    object which caused this function
176  * @param[in]  part   part name of the label member in genlist item
177  * @return     pointer to content of label
178  */
179 static char *__addview_genlist_label_get(void *data, Evas_Object *obj,
180                                          const char *part)
181 {
182         CLK_FUN_DEBUG_BEG();
183         retv_if(NULL == data || NULL == g_ad, NULL);
184
185         Wcl_CitySet *gmt = (Wcl_CitySet *)data;
186         char buf[BUF_SIZE] = "";
187         //float zone = 0.0;
188         //float gmt_diff = 0.0;
189
190         retv_if(NULL == part, NULL);
191         if (!strcmp(part, "elm.text.1")) {
192                 // city label
193                 snprintf(buf, BUF_SIZE, "%s", gmt->city);
194         } else if (!strcmp(part, "elm.text.2")) {
195                 // country label
196                 snprintf(buf, BUF_SIZE, "%s", gmt->country);
197         } else if (!strcmp(part, "elm.text.3")) {
198                 // city label
199                 snprintf(buf, BUF_SIZE, "%s", gmt->timezone);
200         } else if (!strcmp(part, "elm.text.city")) {
201                 // city label
202                 snprintf(buf, BUF_SIZE, "%s", _(gmt->city));
203         } else if (!strcmp(part, "elm.text.country")) {
204                 // country label
205                 snprintf(buf, BUF_SIZE, "%s", _(gmt->country));
206         } else if (!strcmp(part, "elm.text.gmt")) {
207                 // city label
208                 snprintf(buf, BUF_SIZE, "%s", gmt->timezone);
209         }
210
211         CLK_FUN_DEBUG_END();
212         return strdup(buf);
213 }
214
215 /**
216  * Get icon of given part in genlist item
217  *
218  * @param[in]  data   Data used in this function
219  * @param[in]  obj    Evas_Object who emit this event
220  * @param[in]  part   Name of the part in genlist item
221  *
222  * @return     NULL if meet error
223  *             Pointer to new icon
224  */
225 static Evas_Object *__addview_genlist_icon_get(void *data, Evas_Object *obj,
226                                                const char *part)
227 {
228         CLK_FUN_DEBUG_BEG();
229         retv_if(!data || !g_ad, NULL);
230         Wcl_CitySet *gmt = (Wcl_CitySet *)data;
231         char buf[BUF_SIZE] = "";
232         retv_if(NULL == part, NULL);
233         Evas_Object *label = NULL;
234         if (!strcmp(part, "elm.swallow.city")) {
235                 label = elm_label_add(obj);
236                 snprintf(buf, BUF_SIZE,
237                          "<+ font=SLP:style=Medium font_size=28 color=#000000>%s</>",
238                          worldclock_searchword_in_string(gmt->city,
239                                                          g_ad->search_text,
240                                                          MAX_LEN_CITY_NAME));
241                 elm_object_text_set(label, buf);
242                 evas_object_show(label);
243                 return label;
244         } else if (!strcmp(part, "elm.swallow.country")) {
245                 label = elm_label_add(obj);
246                 elm_label_ellipsis_set(label, EINA_TRUE);
247                 elm_label_wrap_width_set(label, 336);
248                 snprintf(buf, BUF_SIZE,
249                          "<+ font=SLP:style=Roman font_size=20 color=#6c6c6c>%s</>",
250                          worldclock_searchword_in_string(gmt->country,
251                                                          g_ad->search_text,
252                                                          MAX_LEN_COUNTRY_NAME));
253                 elm_object_text_set(label, buf);
254                 evas_object_show(label);
255                 return label;
256         } else if (!strcmp(part, "elm.swallow.gmt")) {
257                 label = elm_label_add(obj);
258                 snprintf(buf, BUF_SIZE,
259                          "<+ font=SLP:style=Medium font_size=20 color=#6c6c6c>%s</>",
260                          worldclock_searchword_in_string(gmt->timezone,
261                                                          g_ad->search_text,
262                                                          MAX_LEN_GMT));
263                 elm_object_text_set(label, buf);
264                 evas_object_show(label);
265                 return label;
266         }
267         CLK_FUN_DEBUG_END();
268         return label;
269 }
270
271 static void __addview_genlist_item_del(void *data, Evas_Object *obj)
272 {
273         //Wcl_CitySet *cs = NULL;
274         //cs = (Wcl_CitySet*)data;
275         //if(cs) {
276         //    free(cs);
277         //}
278 }
279
280 /**
281  * Check whether this city has been selected
282  *
283  * @param[in]  data   appointed citydata used for this function
284  *
285  * @return     EINA_TRUE   this city was already selected
286  *             EINA_FALSE  this city was not selected
287  */
288 static Eina_Bool __addview_genlist_check_whether_selected(const void *data)
289 {
290         CLK_FUN_BEG();
291         retv_if((!data || !g_ad), EINA_FALSE);
292
293         Eina_Bool ret = EINA_FALSE;
294
295         Wcl_CitySet *cs = (Wcl_CitySet *)data;
296         Wcl_CitySet *tmp = NULL;
297         Eina_List *el = NULL;
298
299         // get the pointer to data list which containing all selected cities
300         el = g_ad->eina_list;
301         while (el) {
302                 tmp = (Wcl_CitySet *)el->data;
303                 // compare selected city
304                 if (!strcmp(cs->city, tmp->city)
305                     && !strcmp(cs->country, tmp->country)) {
306                         //if city has been selected
307                         ret = EINA_TRUE;
308                         break;
309                 }
310                 // get next selected cities
311                 el = el->next;
312         }
313
314         CLK_FUN_END();
315         return ret;
316 }
317
318 /**
319  * Callback function which used for genlist selection event processing
320  *
321  * @param[in]  data         data which used in this function
322  * @param[in]  obj          the object which emit the selection event
323  * @param[in]  event_info   information about selection event
324  *
325  * @return
326  */
327 static void __addview_genlist_item_sel(void *data, Evas_Object *obj,
328                                        void *event_info)
329 {
330         CLK_FUN_BEG();
331
332         Elm_Object_Item *gli = NULL;
333         // get selected genlist item
334         gli = elm_genlist_selected_item_get(obj);
335         elm_genlist_item_selected_set(gli, 0);
336
337         CLK_FUN_END();
338 }
339
340 /**
341  * Callback function used for genlist item selection event processing
342  * three things may happen to this funcion
343  *   1. replace an item of main list
344  *   2. add an item to main list
345  *   3. set system GMT and return to caller
346  *
347  * @param[in]  data         data which used for this function
348  * @param[in]  obj          Evas_Object which emit the selection event
349  * @param[in]  event_info   Information about event
350  *
351  * @return
352  */
353 static void __addview_genlist_item_selected_cb(void *data, Evas_Object *obj,
354                                                void *event_info)
355 {
356         CLK_FUN_BEG();
357
358         ret_if(!g_ad);
359         CLK_INFO("normal now\n");
360
361         Elm_Object_Item *gli = NULL;
362         const Wcl_CitySet *cs = NULL;
363
364         // get selected genlist item
365         gli = (Elm_Object_Item *)(event_info);
366         // get the data of selected item
367         cs = elm_object_item_data_get(gli);
368
369         // reset quit timer
370         if (g_ad->add_view_quit_timer) {
371                 ecore_timer_del(g_ad->add_view_quit_timer);
372                 g_ad->add_view_quit_timer = NULL;
373         }
374
375         if (!cs) {
376                 // meet error, exit
377                 g_ad->add_view_quit_timer =
378                     ecore_timer_add(0.02, __addview_exit_cb, NULL);
379                 return;
380         }
381         ////////// replace or append operation to mainview //////////
382         if (CALL_FROM_MAIN_VIEW == g_call_flag) {
383                 ////////// this is normal select, this item will be append to main list //////////
384                 if (__addview_genlist_check_whether_selected(cs)) {
385                         CLK_INFO("this city has been selected, show notify\n");
386                         // if city already selected, show popup
387                         __addview_notify_cb(_("IDS_WCL_POP_ADDED"));
388                         CLK_FUN_END();
389                         return;
390                 } else {
391                         // create new structure to store new city
392                         Wcl_CitySet *t_cs = calloc(1, sizeof(Wcl_CitySet));
393                         if (NULL == t_cs) {
394                                 // if create failed, exit
395                                 g_ad->add_view_quit_timer =
396                                     ecore_timer_add(0.02, __addview_exit_cb,
397                                                     NULL);
398                                 return;
399                         }
400
401                         memcpy(t_cs, cs, sizeof(Wcl_CitySet));
402                         // set selected flag
403                         t_cs->selected = 1;
404                         //t_cs->dst = worldclock_dst_get(cs);
405
406                         // append done, exit
407                         g_ad->add_view_quit_timer =
408                             ecore_timer_add(0.02, __addview_exit_cb, t_cs);
409                         CLK_FUN_END();
410                         return;
411                 }
412         }
413         /////////////// return city data to UI gadget /////////////
414         else if (CALL_FROM_UI_GADGET == g_call_flag) {
415                 // create new structure to store new city
416                 Wcl_CitySet *t_cs = calloc(1, sizeof(Wcl_CitySet));
417                 if (t_cs) {
418                         // copy selected data
419                         memcpy(t_cs, cs, sizeof(Wcl_CitySet));
420                         // get current dst value, and set it into result data
421                         t_cs->dst = worldclock_dst_get(cs);
422                         // save return data for UG
423                         g_ad->return_data = t_cs;
424                 } else {
425                         CLK_ERR("CALLOC ERROR!!!");
426                         // set NULL for UG
427                         g_ad->return_data = NULL;
428                 }
429
430                 // exit when save successfully
431                 g_ad->add_view_quit_timer =
432                     ecore_timer_add(0.02, __addview_exit_cb, g_ad);
433                 CLK_FUN_END();
434                 return;
435         }
436 }
437
438 static Eina_Bool __addview_genlist_update_last(void *data)
439 {
440         CLK_FUN_BEG();
441         retv_if(!data || !g_ad, EINA_FALSE);
442         Eina_List *el = (Eina_List *)data;
443         Wcl_CitySet *cs = NULL; //  elm_genlist_item_data_get(gli);
444         Elm_Object_Item *gli = NULL;
445         Eina_Bool ret = EINA_TRUE;
446
447         retv_if(!g_ad->add_genlist, EINA_FALSE);
448         retv_if(!g_ad->add_index, EINA_FALSE);
449
450         if (g_ad->add_view_update_last_timer) {
451                 ecore_timer_del(g_ad->add_view_update_last_timer);
452                 g_ad->add_view_update_last_timer = NULL;
453         }
454
455         while (el) {
456                 // get data
457                 cs = el->data;
458                 if (cs && ret) {
459                         // append data to genlist
460                         gli = elm_genlist_item_append(g_ad->add_genlist, &g_ts, cs,     /* item data */
461                                                       NULL,     /* parent */
462                                                       ELM_GENLIST_ITEM_NONE, __addview_genlist_item_sel,        /* func */
463                                                       cs        /* func data */
464                             );
465
466                         // update index with genlist item
467                         ret =
468                             __addview_index_update(g_ad->add_index, g_ad->sort,
469                                                    g_index_buf, gli);
470                 } else {
471                         break;
472                 }
473                 // get next data
474                 el = el->next;
475         }
476
477         // show index
478         evas_object_show(g_ad->add_index);
479
480         CLK_FUN_END();
481         return EINA_FALSE;
482 }
483
484 /**
485  * Update genlist which displaying in add view
486  *
487  * @param[in]  data   data used for this function
488  *
489  * @return     EINA_FALSE
490  */
491 static Eina_Bool __addview_genlist_update(void *data)
492 {
493         CLK_FUN_BEG();
494         retv_if(!data, EINA_FALSE);
495         retv_if(!g_ad, EINA_FALSE);
496
497         struct appdata *ad = (struct appdata *)data;
498         Elm_Object_Item *gli = NULL;
499         Eina_List *el = NULL;
500         Wcl_CitySet *cs = NULL;
501         int count = 0;
502         //char *ppos = NULL, *pbegin = NULL;
503
504         // init data list
505         memset(g_index_buf, 0X0, BUF_MIN_SIZE * sizeof(char));
506
507         // reset data list
508         if (ad->default_list) {
509                 worldclock_util_glist_remove_all(ad->default_list, EINA_TRUE);
510                 ad->default_list = NULL;
511         }
512         // reset timer
513         if (g_ad->add_view_update_timer) {
514                 ecore_timer_del(g_ad->add_view_update_timer);
515                 g_ad->add_view_update_timer = NULL;
516         }
517         if (g_ad->add_view_update_last_timer) {
518                 ecore_timer_del(g_ad->add_view_update_last_timer);
519                 g_ad->add_view_update_last_timer = NULL;
520         }
521
522         retv_if(NULL == ad->search_text, EINA_FALSE);
523         if (!strcmp(ad->search_text, "")) {
524                 // if searchbar is been clicked, be filled in ""
525                 CLK_INFO("ad->search_text=%s\n", ad->search_text);
526                 // get all appendable cities
527                 ad->default_list =
528                     worldclock_data_get_default_city_list(ad->selectionFlag);
529         } else {
530                 CLK_INFO("ad->search_text=%s\n", ad->search_text);
531                 ad->default_list =
532                     worldclock_data_get_search_city_list(ad->search_text,
533                                                          WCL_SEARCH_BY_ALL_KEYWORDS,
534                                                          ad->selectionFlag);
535         }
536
537         if (WCL_SORT_BY_NAME == ad->sort) {
538                 // sort by name
539                 snprintf(g_index_buf, BUF_MIN_SIZE, "%c", 'Z');
540                 // sort default list
541                 ad->default_list =
542                     eina_list_sort(ad->default_list,
543                                    eina_list_count(ad->default_list),
544                                    worldclock_city_compare_cb);
545         } else if (WCL_SORT_BY_TIMEZONE == ad->sort) {
546                 // sort by time
547                 snprintf(g_index_buf, BUF_MIN_SIZE, "%s", "-18");
548                 // sort default list
549                 ad->default_list =
550                     eina_list_sort(ad->default_list,
551                                    eina_list_count(ad->default_list),
552                                    worldclock_time_compare_cb);
553         }
554         // reset genlist
555         elm_genlist_clear(ad->add_genlist);
556         if (ad->add_index) {
557                 //elm_index_item_clear(ad->add_index);
558                 evas_object_del(ad->add_index);
559                 ad->add_index = NULL;
560         }
561         // reset index
562         ad->add_index = __addview_index_add(ad->add_layout, ad);
563         retv_if(!ad->add_index, EINA_FALSE);
564
565         el = ad->default_list;
566         while (el) {
567                 // get data
568                 cs = el->data;
569                 if (cs) {
570                         // append data to genlist
571                         gli = elm_genlist_item_append(ad->add_genlist, &g_ts, cs,       /* item data */
572                                                       NULL,     /* parent */
573                                                       ELM_GENLIST_ITEM_NONE, __addview_genlist_item_sel,        /* func */
574                                                       cs        /* func data */
575                             );
576                         if (el == ad->default_list) {
577                                 elm_genlist_item_show(gli,
578                                                       ELM_GENLIST_ITEM_SCROLLTO_TOP);
579                         }
580                         // update index with genlist item
581                         __addview_index_update(ad->add_index, ad->sort,
582                                                g_index_buf, gli);
583
584                         count++;
585                         if (FIRST_UPDATE_ITEM_COUNT <= count) {
586                                 // update genlist
587                                 ad->add_view_update_last_timer =
588                                     ecore_timer_add(0.5,
589                                                     __addview_genlist_update_last,
590                                                     el->next);
591                                 break;
592                         }
593                 } else {
594                         break;
595                 }
596                 // get next data
597                 el = el->next;
598         }
599         if (FIRST_UPDATE_ITEM_COUNT > count) {
600                 // show index
601                 evas_object_show(ad->add_index);
602         }
603
604         CLK_FUN_END();
605         return EINA_FALSE;
606 }
607
608 /**
609  * Add new genlist which used for displaying all cities which could be append
610  * into worldclock.
611  *
612  * @param[in]  parent   The parent object of the new genlist object
613  * @param[in]  data     Data used in this function
614  *
615  * @return     NULL if create genlist failed.
616  *             Pointer to the new genlist object if create genlist successfully.
617  */
618 static Evas_Object *__addview_genlist_add(Evas_Object *parent, void *data)
619 {
620         CLK_FUN_BEG();
621         retv_if(!data, NULL);
622
623         Evas_Object *genlist = NULL;
624         // add genlist
625         genlist = elm_genlist_add(parent);
626         evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND,
627                                          EVAS_HINT_EXPAND);
628         evas_object_size_hint_align_set(genlist, -1.0, -1.0);
629         // swallow
630         edje_object_part_swallow(_EDJ(parent), "add/genlist", genlist);
631         // show
632         evas_object_show(genlist);
633         // register callback function for select event on genlist
634         evas_object_smart_callback_add(genlist, "selected",
635                                        __addview_genlist_item_selected_cb,
636                                        data);
637
638         // To use multiline textblock/entry/editfield in genlist, set height_for_width mode
639         // then the item's height is calculated while the item's width fits to genlist width.
640         elm_genlist_mode_set(genlist, EINA_TRUE);
641
642         // set selected theme
643         char *theme_name = vconf_get_str(SETTING_THEME_SELECTED_THEME);
644         if (theme_name) {
645                 g_ts.item_style = "worldclock_addview_list_black";
646         }
647         if (theme_name) {
648                 free(theme_name);
649                 theme_name = NULL;
650         }
651
652         CLK_FUN_END();
653         return genlist;
654 }
655
656 /////////////////////////////////// genlist related finish /////////////////////////////////////////
657
658 ////////////////////////// index ///////////////////////////////////////////////////////////
659 /**
660  * Callback function which is used for elm_index when level up event processing
661  *
662  * @param[in]  data        data used for this function
663  * @param[in]  obj         Evas_Object which emit level up event
664  * @param[in]  event_info  Information about this event
665  *
666  * @return
667  */
668 static void __addview_index_level_up(void *data, Evas_Object *obj,
669                                      void *event_info)
670 {
671         CLK_FUN_BEG();
672         ret_if(!data);
673
674         // get current index level
675         int level = elm_index_item_level_get(obj);
676         ret_if(level != 1);
677
678         Elm_Object_Item *it = NULL;
679         char buf[BUF_SIZE] = { '\0', };
680
681         // get selected index item
682         it = elm_index_selected_item_get(obj, level - 1);
683         it = (Elm_Object_Item *)elm_object_item_data_get(it);
684         // clear index item
685         elm_index_item_clear(obj);
686         // get data of selected index
687         Wcl_CitySet *pi = (Wcl_CitySet *)elm_object_item_data_get(it);
688
689         snprintf(buf, BUF_SIZE, "%c", 'A');
690
691         while (it) {
692                 // get selected city
693                 Wcl_CitySet *gmt = (Wcl_CitySet *)elm_object_item_data_get(it);
694                 // append index item if do not exist
695                 if (!strncmp(pi->city, gmt->city, 1)) {
696                         if (buf[0] != gmt->city[1]) {
697                                 snprintf(buf, BUF_SIZE, "%c", gmt->city[1]);
698                                 Elm_Object_Item *item =
699                                     elm_index_item_append(obj, buf, NULL, NULL);
700                                 elm_object_item_data_set(item, it);
701                         }
702                 }
703                 // get next genlist item
704                 it = elm_genlist_item_next_get(it);
705         }
706         // goto item at level
707         elm_index_level_go(obj, level);
708         CLK_FUN_END();
709 }
710
711 /**
712  * Callback function which used for elm_index about delay change event processing
713  *
714  * @param[in]  data         Data which used in this function
715  * @param[in]  obj          Evas_Object which emit this event
716  * @param[in]  event_info   Information about this event
717  *
718  * @return
719  */
720 static void __addview_index_index_changed_bring(void *data, Evas_Object *obj,
721                                                 void *event_info)
722 {
723         elm_genlist_item_bring_in(event_info, ELM_GENLIST_ITEM_SCROLLTO_TOP);
724 }
725
726 /**
727  * Callback function which used for elm_index about index selection event processing
728  *
729  * @param[in]  data         Data which used in this function
730  * @param[in]  obj          Evas_Object which emit this event
731  * @param[in]  event_info   Information about this event
732  *
733  * @return
734  */
735 static void __addview_index_index_selected(void *data, Evas_Object *obj,
736                                            void *event_info)
737 {
738         Elm_Object_Item *it = (Elm_Object_Item *)event_info;
739         it = (Elm_Object_Item *)elm_object_item_data_get(it);
740         elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
741 }
742
743 /**
744  * Create new elm_index used in add view
745  *
746  * @param[in] index     the elm_index which will be updated
747  * @param[in] sort      the sort type of genlist which bind index
748  * @param[in] buf       the buffer used to store pre data which append in elm_index
749  * @param[in] data      pointer to elm_genlist_item which need to be append
750  *
751  * @return
752  */
753
754 static Eina_Bool __addview_index_update(Evas_Object *index,
755                                         Wcl_Addlist_Sort_Type sort, char *buf,
756                                         void *data)
757 {
758         char buf_name[BUF_MIN_SIZE] = { 0, };
759         char buf_zone[BUF_MIN_SIZE] = { 0, };
760         char *ppos = NULL, *pbegin = NULL;
761         Elm_Object_Item *gli = (Elm_Object_Item *)data;
762         Wcl_CitySet *cs = elm_object_item_data_get(gli);
763         retv_if(!index, EINA_FALSE);
764         memset(buf_name, 0x0, BUF_MIN_SIZE * sizeof(char));
765         if (WCL_SORT_BY_NAME == sort) {
766                 // append index to elm_index
767                 char *bufalphabetic =
768                     get_alphabetic_index_name(get_alphabetic_index
769                                               (_(cs->city)));
770                 if (NULL == g_alphabetic_buf) {
771                         g_alphabetic_buf = bufalphabetic;
772                         Elm_Object_Item *it =
773                                 elm_index_item_append(index, bufalphabetic,
774                                                   NULL, NULL);
775                         elm_object_item_data_set(it, gli);
776
777                 }
778                 if (NULL != bufalphabetic) {
779                 if (IS_STR_NOT_EQUAL(g_alphabetic_buf, bufalphabetic)) {
780                         g_alphabetic_buf = bufalphabetic;
781                         Elm_Object_Item *it =
782                             elm_index_item_append(index, bufalphabetic, NULL,
783                                                   NULL);
784                         elm_object_item_data_set(it, gli);
785                 }
786                         }
787         } else if (WCL_SORT_BY_TIMEZONE == sort) {
788                 // get timezone
789                 pbegin = cs->timezone + 3;
790                 // find dot
791                 ppos = strstr(pbegin, ":");
792                 if (ppos != NULL) {
793                         // if timezone is not integer, get the integer part
794                         g_strlcpy(buf_zone, pbegin, ppos - pbegin + 1);
795                 } else {
796                         // get timezone if it is integer
797                         g_strlcpy(buf_zone, pbegin, BUF_MIN_SIZE);
798                         buf_zone[strlen(cs->timezone)] = '\0';
799                 }
800
801                 if (strcmp(buf, buf_zone)) {
802                         // append timezone into index list if it is not exist
803                         snprintf(buf, BUF_MIN_SIZE, "%s", buf_zone);
804                         Elm_Object_Item *it =
805                             elm_index_item_append(index, buf, NULL, NULL);
806                         elm_object_item_data_set(it, gli);
807                 }
808         }
809
810         return EINA_TRUE;
811 }
812
813 /**
814  * Create new elm_index used in add view
815  *
816  * @param[in]  parent     Evas_Object which is the parent of new elm_index
817  * @param[in]  date       data which used int this function
818  *
819  * @return     NULL if create failed
820  *             Pointer to new elm_index if create successflly
821  */
822 static Evas_Object *__addview_index_add(Evas_Object *parent, void *data)
823 {
824         CLK_FUN_BEG();
825         retv_if((!parent || !data), NULL);
826
827         Evas_Object *index = NULL;
828         // add index
829         index = elm_index_add(parent);
830         evas_object_size_hint_weight_set(index, EVAS_HINT_EXPAND,
831                                          EVAS_HINT_EXPAND);
832         //evas_object_resize(index, ad->root_w,ad->root_h - TB_PORTRAIT_H - SK_PORTRAIT_H);
833         //evas_object_move(index, ad->root_x, ad->root_y + TB_PORTRAIT_H + 12);
834         // swallow
835         edje_object_part_swallow(_EDJ(parent), "add/index", index);
836         // show index
837         evas_object_show(index);
838
839         // register callback function to index
840         evas_object_smart_callback_add(index, "level,up",
841                                        __addview_index_level_up, NULL);
842         //evas_object_smart_callback_add(index, "level,down", __addview_index_level_down, NULL);
843         evas_object_smart_callback_add(index, "delay,changed",
844                                        __addview_index_index_changed_bring,
845                                        NULL);
846         //evas_object_smart_callback_add(index, "changed", __addview_index_index_changed, NULL);
847         evas_object_smart_callback_add(index, "selected",
848                                        __addview_index_index_selected, NULL);
849
850         // goto the top of index
851         elm_index_level_go(index, 0);
852
853         CLK_FUN_END();
854         return index;
855 }
856
857 ////////////////////////// index finished ///////////////////////////////////////////////////////////
858
859 /////////////////////// search bar ////////////////////////////
860 /**
861  * Callback function which used for searchbar object about click event processing
862  *
863  * @param[in]  data        data used for this function
864  * @param[in]  obj         Evas_Object which emit this event
865  * @param[in]  event_info  Information about this event
866  *
867  * @return
868  */
869 static void __addview_searchbar_clicked_cb(void *data, Evas_Object *obj,
870                                            void *event_info)
871 {
872         CLK_FUN_BEG();
873         ret_if(!data);
874         if (!elm_entry_is_empty(obj))
875                 elm_object_signal_emit(searchbar_layout,
876                                        "elm,state,eraser,show", "elm");
877         elm_object_signal_emit(searchbar_layout, "elm,state,guidetext,hide",
878                                "elm");
879         elm_object_signal_emit(searchbar_layout, "cancel,in", "");
880
881         struct appdata *ad = (struct appdata *)data;
882         char *str = NULL;
883         Evas_Object *entry = elm_object_part_content_get(searchbar_layout,
884                                                          "elm.swallow.content");
885         // get focus
886         elm_object_focus_set(obj, EINA_TRUE);
887         // get text from search bar
888         str = (char *)elm_object_text_get(entry);
889         ret_if(NULL == str);
890         // clear searchbar
891         if (!strcmp(str, S_("IDS_COM_SK_SEARCH"))) {
892                 memset(ad->search_text, '\0', BUF_SIZE);
893                 elm_object_text_set(entry, "");
894         }
895         // get imf context
896         Ecore_IMF_Context *imf_context = elm_entry_imf_context_get(entry);
897         if (NULL != imf_context) {
898                 // set default input language
899                 ecore_imf_context_input_panel_language_set(imf_context,
900                                                            ECORE_IMF_INPUT_PANEL_LANG_ALPHABET);
901                 // show input panel
902                 ecore_imf_context_input_panel_show(imf_context);
903         }
904         //if(str) {
905         //    free(str);
906         //}
907         CLK_FUN_END();
908 }
909
910 /**
911  * Callback function which used for entry object about content changing event processing
912  *
913  * @param[in]  data        data used for this function
914  * @param[in]  obj         Evas_Object which emit this event
915  * @param[in]  event_info  Information about this event
916  *
917  * @return
918  */
919 static void __addview_searchbar_changed_cb(void *data, Evas_Object *obj,
920                                            void *event_info)
921 {
922         struct appdata *ad = NULL;
923         char *str = NULL;
924         int strLength = 0;
925         char input_text[BUF_SIZE] = { '\0' };
926         Eina_Bool isNeedUpdate = EINA_TRUE;
927
928         CLK_FUN_BEG();
929         ret_if(NULL == data);
930         ad = (struct appdata *)data;
931         if (elm_object_focus_get(searchbar_layout)) {
932                 if (elm_entry_is_empty(obj))
933                         elm_object_signal_emit(searchbar_layout,
934                                                "elm,state,eraser,hide", "elm");
935                 else
936                         elm_object_signal_emit(searchbar_layout,
937                                                "elm,state,eraser,show", "elm");
938         }
939         Evas_Object *entry = elm_object_part_content_get(searchbar_layout,
940                                                          "elm.swallow.content");
941         // get text from search bar
942         str = (char *)elm_object_text_get(entry);
943
944         ret_if(NULL == str);
945         CLK_INFO("str get from entry: %s\n", str);
946         // get displaying part
947         worldclock_str_get_displaying_part(str, input_text);
948         CLK_INFO("str display in entry: %s\n", input_text);
949         // get previous search text
950         ret_if(NULL == ad->search_text);
951         CLK_INFO("ad->search_text: %s\n", ad->search_text);
952         ret_if(!strcmp(input_text, ad->search_text));
953
954         //  if string contains html flag, it is said that string do not been confirmed
955         //  so, return
956         Eina_Bool html_flag = worldclock_str_is_contain_html(input_text);
957
958         if (EINA_TRUE == html_flag) {
959                 CLK_INFO("HTML flag exist!\n");
960                 //return;
961         }
962
963         if (!strcmp(ad->search_text, "")
964             && !strcmp(input_text, S_("IDS_COM_SK_SEARCH"))) {
965                 CLK_INFO("Not Update\n");
966                 isNeedUpdate = EINA_FALSE;
967         }
968         // get entry
969 //      Evas_Object *entry = elm_searchbar_entry_get(ad->add_search_bar);
970
971         // get size of unicode string
972         UChar ustr[BUF_SIZE] = { 0 };
973         u_uastrncpy(ustr, input_text, BUF_SIZE);
974         strLength = u_strlen(ustr);
975         CLK_INFO("string length : %d\n", strLength);
976         if (strLength > MAX_LEN_INPUT) {
977                 // the content of entry won't change if enter too many characters
978                 elm_object_text_set(entry, ad->search_text);
979                 // set cursor to the end of entry
980                 elm_entry_cursor_end_set(entry);
981                 // if input too long, show popup
982                 //worldclock_show_popup(g_ad->add_ly, &(g_ad->popup), _("Input too long!"));
983                 return;
984         }
985
986         if (input_text != NULL) {
987                 // reset search text
988                 memset(ad->search_text, '\0', BUF_SIZE);
989                 if (strcmp(input_text, S_("IDS_COM_SK_SEARCH"))
990                     && strcmp(input_text, "")) {
991                         // copy search text
992                         g_strlcpy(ad->search_text, input_text, BUF_SIZE);
993                 }
994                 CLK_INFO("ad->search_text:%s\n", ad->search_text);
995         }
996
997         CLK_INFO("ad->search_text:%s\n", ad->search_text);
998         // if search text in search_bar is not "Search", update genlist
999         if (EINA_TRUE == isNeedUpdate) {
1000                 CLK_INFO("Update the search view text, search_text=%s\n",
1001                          ad->search_text);
1002                 if (g_ad->add_view_update_timer) {
1003                         ecore_timer_del(g_ad->add_view_update_timer);
1004                         g_ad->add_view_update_timer = NULL;
1005                 }
1006                 // update genlist
1007                 ad->add_view_update_timer =
1008                     ecore_timer_add(0.01, __addview_genlist_update, ad);
1009         }
1010         //if(str) {
1011         //    free(str);
1012         //}
1013         CLK_FUN_END();
1014 }
1015
1016 /**
1017  * Callback function which used for searchbar object about cancel event processing
1018  *
1019  * @param[in]  data        data used for this function
1020  * @param[in]  obj         Evas_Object which emit this event
1021  * @param[in]  event_info  Information about this event
1022  *
1023  * @return
1024  */
1025 static void __addview_searchbar_cancel_clicked_cb(void *data, Evas_Object *obj,
1026                                                   void *event_info)
1027 {
1028         CLK_FUN_BEG();
1029         ret_if(!data);
1030         struct appdata *ad = (struct appdata *)data;
1031         ret_if(!ad->add_search_bar);
1032
1033         // get entry
1034         Evas_Object *entry = elm_object_part_content_get(searchbar_layout,
1035                                                          "elm.swallow.content");
1036         const char *text;
1037         evas_object_hide(obj);
1038         elm_object_signal_emit(searchbar_layout, "cancel,out", "");
1039         text = elm_entry_entry_get(entry);
1040         if (text != NULL && strlen(text) > 0)
1041                 elm_entry_entry_set(entry, NULL);
1042         elm_object_focus_set(entry, EINA_FALSE);
1043         // get imf context
1044         Ecore_IMF_Context *imf_context = elm_entry_imf_context_get(entry);
1045         if (imf_context) {
1046                 if (ECORE_IMF_INPUT_PANEL_STATE_HIDE !=
1047                     ecore_imf_context_input_panel_state_get(imf_context)) {
1048                         // hide input panel
1049                         ecore_imf_context_input_panel_hide(imf_context);
1050                 }
1051         }
1052         CLK_INFO("ad->search_text: %s\n", ad->search_text);
1053         // update genlist
1054         if (strcmp(ad->search_text, "")) {
1055                 // reset timer
1056                 if (g_ad->add_view_update_timer) {
1057                         ecore_timer_del(g_ad->add_view_update_timer);
1058                         g_ad->add_view_update_timer = NULL;
1059                 }
1060                 ad->add_view_update_timer =
1061                     ecore_timer_add(0.01, __addview_genlist_update, ad);
1062         }
1063         // reset search text
1064         memset(ad->search_text, '\0', BUF_SIZE);
1065         // reset search bar
1066         //elm_searchbar_text_set(ad->add_search_bar, S_("IDS_COM_SK_SEARCH"));
1067
1068         CLK_FUN_END();
1069 }
1070
1071 /**
1072  * Callback function used for processing unfocused event about searchbar.
1073  * When touch out of searchbar , hide input panel
1074  *
1075  * @param[in]  data        data used for this function
1076  * @param[in]  obj         Evas_Object which emit this event
1077  * @param[in]  event_info  Information about this event
1078  *
1079  * @return
1080  */
1081 static void __addview_searchbar_unfocused_cb(void *data, Evas_Object *obj,
1082                                              void *event_info)
1083 {
1084         CLK_FUN_BEG();
1085         ret_if(!data);
1086         struct appdata *ad = (struct appdata *)data;
1087
1088         if (elm_entry_is_empty(obj))
1089                 elm_object_signal_emit(searchbar_layout,
1090                                        "elm,state,guidetext,show", "elm");
1091         elm_object_signal_emit(searchbar_layout, "elm,state,eraser,hide",
1092                                "elm");
1093         Ecore_IMF_Context *imf_context = NULL;
1094         if (ad->add_search_bar) {
1095                 // get entry from searchbar
1096                 Evas_Object *entry =
1097                     elm_object_part_content_get(searchbar_layout,
1098                                                 "elm.swallow.content");
1099                 // get imf context from entry
1100                 imf_context = elm_entry_imf_context_get(entry);
1101         }
1102         if (imf_context) {
1103                 CLK_INFO("\nto hide keypad\n\n");
1104                 // hide imf context keypad
1105                 ecore_imf_context_input_panel_hide(imf_context);
1106         }
1107
1108         CLK_FUN_END();
1109 }
1110
1111 static void _eraser_clicked_cb(void *data, Evas_Object *obj, const char *emission, const char *source)  // When X marked button is clicked, empty entry's contents.
1112 {
1113         elm_entry_entry_set(data, "");
1114 }
1115
1116 static void _bg_clicked_cb(void *data, Evas_Object *obj, const char *emission,
1117                            const char *source)
1118 {
1119         elm_object_focus_set(data, EINA_TRUE);
1120 }
1121
1122 static void _searchsymbol_clicked_cb(void *data, Evas_Object *obj,
1123                                      const char *emission, const char *source)
1124 {
1125         elm_object_focus_set(data, EINA_TRUE);
1126         printf("\n[Search Bar] SearchSymbol Callback Called\n");
1127 }
1128
1129 #if 0
1130 static void __addview_input_panel_event_cb(void *data, Ecore_IMF_Context *ctx,
1131                                            int value)
1132 {
1133         CLK_FUN_BEG();
1134         ret_if(!data);
1135         struct appdata *ad = (struct appdata *)data;
1136         ret_if(!ad->add_layout);
1137         if (value == ECORE_IMF_INPUT_PANEL_STATE_SHOW) {
1138                 // ISE state has changed to ECORE_IMF_INPUT_PANEL_STATE_SHOW status
1139                 edje_object_signal_emit(_EDJ(ad->add_layout), "abbrev_genlist",
1140                                         "add/genlist");
1141                 edje_object_signal_emit(_EDJ(ad->add_layout), "abbrev_index",
1142                                         "add/index");
1143         } else if (value == ECORE_IMF_INPUT_PANEL_STATE_HIDE) {
1144                 // ISE state has changed to ECORE_IMF_INPUT_PANEL_STATE_HIDE status
1145                 edje_object_signal_emit(_EDJ(ad->add_layout), "expand_genlist",
1146                                         "add/genlist");
1147                 edje_object_signal_emit(_EDJ(ad->add_layout), "expand_index",
1148                                         "add/index");
1149         }
1150         CLK_FUN_END();
1151 }
1152 #endif
1153 /**
1154  * Add new searchbar object which used for search cities which selected by user.
1155  *
1156  * @param[in]  parent   The parent object of the new genlist object
1157  * @param[in]  data     Data used in this function
1158  *
1159  * @return     NULL if create genlist failed.
1160  *             Pointer to the new searchbar object if create successfully.
1161  */
1162 static Evas_Object *__addview_searchbar_add(Evas_Object *parent, void *data)
1163 {
1164         CLK_FUN_BEG();
1165         retv_if((!parent || !data), NULL);
1166
1167         //Evas_Object *searchbar_layout = NULL;
1168         Evas_Object *entry = NULL;
1169         Evas_Object *cancel_btn = NULL;
1170         // add search bar
1171         //search_bar = elm_searchbar_add(parent);
1172         //search_bar =
1173         //    edje_object_part_external_object_get(_EDJ(parent), "searchbar");
1174         //retv_if(!search_bar, NULL);
1175         searchbar_layout = elm_layout_add(parent);
1176         elm_layout_theme_set(searchbar_layout, "layout", "searchbar",
1177                              "cancel_button");
1178         elm_object_part_content_set(parent, "searchbar", searchbar_layout);
1179         entry = elm_entry_add(searchbar_layout);
1180         elm_entry_scrollable_set(entry, EINA_TRUE);
1181         elm_entry_single_line_set(entry, EINA_TRUE);
1182         elm_object_part_content_set(searchbar_layout, "elm.swallow.content",
1183                                     entry);
1184         elm_object_part_text_set(searchbar_layout, "elm.guidetext", "Search");
1185         //// enable animation
1186         //elm_searchbar_cancel_button_animation_set(search_bar, EINA_TRUE);
1187         // get entry
1188         //Evas_Object *entry = elm_searchbar_entry_get(search_bar);
1189         evas_object_smart_callback_add(entry, "changed",
1190                                        __addview_searchbar_changed_cb, data);
1191         evas_object_smart_callback_add(entry, "focused",
1192                                        __addview_searchbar_clicked_cb, data);
1193         evas_object_smart_callback_add(entry, "unfocused",
1194                                        __addview_searchbar_unfocused_cb, data);
1195         elm_object_signal_callback_add(searchbar_layout, "elm,eraser,clicked",
1196                                        "elm", _eraser_clicked_cb, entry);
1197         elm_object_signal_callback_add(searchbar_layout, "elm,bg,clicked",
1198                                        "elm", _bg_clicked_cb, entry);
1199         elm_entry_input_panel_layout_set(entry, ELM_INPUT_PANEL_LAYOUT_NORMAL);
1200         // disable input panel
1201         elm_entry_input_panel_enabled_set(entry, EINA_FALSE);
1202         // disable the context menu
1203         elm_entry_context_menu_disabled_set(entry, EINA_TRUE);
1204
1205         evas_object_size_hint_weight_set(searchbar_layout, EVAS_HINT_EXPAND,
1206                                          EVAS_HINT_EXPAND);
1207         evas_object_size_hint_align_set(searchbar_layout, EVAS_HINT_FILL,
1208                                         EVAS_HINT_FILL);
1209         cancel_btn = elm_button_add(searchbar_layout);
1210         elm_object_part_content_set(searchbar_layout, "button_cancel",
1211                                     cancel_btn);
1212         elm_object_style_set(cancel_btn, "searchbar/default");
1213         elm_object_text_set(cancel_btn, "Cancel");
1214         evas_object_smart_callback_add(cancel_btn, "clicked",
1215                                        __addview_searchbar_cancel_clicked_cb,
1216                                        data);
1217         // disable cancel btn animation
1218         elm_object_signal_callback_add(searchbar_layout, "elm,action,click", "",
1219                                        _searchsymbol_clicked_cb, entry);
1220         //elm_searchbar_text_set(search_bar, S_("IDS_COM_SK_SEARCH"));
1221
1222         // set color
1223         // register callback functions to search bar
1224 //      evas_object_smart_callback_add(entry, "unfocused",
1225 //                                     __addview_searchbar_unfocused_cb, data);
1226 //      evas_object_smart_callback_add(entry, "changed",
1227 //                                     __addview_searchbar_changed_cb, data);
1228 //      evas_object_smart_callback_add(searchbar_layout, "clicked",
1229 //                                     __addview_searchbar_clicked_cb, data);
1230 //      evas_object_smart_callback_add(searchbar_layout, "cancel,clicked",
1231 //                                     __addview_searchbar_cancel_clicked_cb,
1232 //                                     data);
1233
1234         // swallow
1235         //edje_object_part_swallow(_EDJ(parent), "add/search", search_bar);
1236         // show it
1237         //evas_object_show(search_bar);
1238
1239         CLK_FUN_END();
1240         return searchbar_layout;
1241 }
1242
1243 /////////////////////// search bar finished ////////////////////////////
1244
1245 /**
1246  * Callback function which used for change sorting type about genlist
1247  *
1248  * @param[in]  data        data which used in this function
1249  * @param[in]  obj         Evas_Object which emit this event
1250  * @param[in]  event_info  Information about such event.
1251  *
1252  * @return
1253  */
1254 static void __addview_sortbar_clicked_cb(void *data, Evas_Object *obj,
1255                                          void *event_info)
1256 {
1257         CLK_FUN_BEG();
1258         ret_if(!data);
1259
1260         struct appdata *ad = (struct appdata *)data;
1261
1262         //// get entry
1263         //Evas_Object *entry = elm_searchbar_entry_get(ad->add_search_bar);
1264         //elm_object_focus(entry);
1265         //// disable the context menu
1266         //elm_entry_context_menu_disabled_set(entry, EINA_TRUE);
1267         //elm_entry_context_menu_disabled_set(entry, EINA_FALSE);
1268
1269         Elm_Object_Item *select_item =
1270             elm_segment_control_item_selected_get(obj);
1271
1272         // set sort flag, and update genlist
1273         if (select_item == g_btn_sort_by_time) {
1274                 ad->sort = WCL_SORT_BY_TIMEZONE;
1275         } else if (select_item == g_btn_sort_by_name) {
1276                 ad->sort = WCL_SORT_BY_NAME;
1277         }
1278         // update genlist
1279         if (g_ad->add_view_update_timer) {
1280                 ecore_timer_del(g_ad->add_view_update_timer);
1281                 g_ad->add_view_update_timer = NULL;
1282         }
1283         ad->add_view_update_timer =
1284             ecore_timer_add(0.01, __addview_genlist_update, ad);
1285
1286         CLK_FUN_END();
1287 }
1288
1289 /**
1290  * Add new sortbar object which used for sort cities which selected by user.
1291  *
1292  * @param[in]  parent   The parent object of the new genlist object
1293  * @param[in]  data        data which used in this function
1294  *
1295  * @return     NULL if create genlist failed.
1296  *             Pointer to the new sortbar object if create successfully.
1297  */
1298 static Evas_Object *__addview_sortbar_add(Evas_Object *parent, void *data)
1299 {
1300         retv_if((!parent || !data), NULL);
1301         /* create controlbar */
1302         Evas_Object *ctrlbar = widget_create_controlbar(parent, NULL);
1303         /* create segment control on controlbar */
1304         Evas_Object *segment_ly = elm_layout_add(ctrlbar);
1305         retv_if(segment_ly == NULL, NULL);
1306         elm_layout_file_set(segment_ly, WCL_EDJ_NAME, GRP_SEGMENT_PANEL);
1307         evas_object_size_hint_weight_set(segment_ly, EVAS_HINT_EXPAND,
1308                                          EVAS_HINT_EXPAND);
1309         evas_object_size_hint_align_set(segment_ly, EVAS_HINT_FILL,
1310                                         EVAS_HINT_FILL);
1311         evas_object_show(segment_ly);
1312
1313         // create segment control
1314         Evas_Object *segment = elm_segment_control_add(ctrlbar);
1315         g_btn_sort_by_name =
1316             elm_segment_control_item_add(segment, NULL,
1317                                          S_("IDS_COM_BODY_DETAILS_NAME"));
1318         g_btn_sort_by_time =
1319             elm_segment_control_item_add(segment, NULL, S_("IDS_COM_POP_TIME"));
1320         evas_object_show(segment);
1321         // set default sort type
1322         elm_segment_control_item_selected_set(g_btn_sort_by_name, EINA_TRUE);
1323         // register callback to segment control
1324         evas_object_smart_callback_add(segment, "changed",
1325                                        __addview_sortbar_clicked_cb, data);
1326         Elm_Object_Item *eci;
1327         elm_object_part_content_set(segment_ly, "segment", segment);
1328         eci = elm_toolbar_item_append(ctrlbar, NULL, NULL, NULL, NULL);
1329         elm_object_item_disabled_set(eci, EINA_TRUE);
1330         Elm_Object_Item *item =
1331             elm_toolbar_item_append(ctrlbar, NULL, NULL, NULL, NULL);
1332         elm_object_item_part_content_set(item, "object", segment_ly);
1333         eci = elm_toolbar_item_append(ctrlbar, NULL, NULL, NULL, NULL);
1334         elm_object_item_disabled_set(eci, EINA_TRUE);
1335         return ctrlbar;
1336 }
1337
1338 static Evas_Object *__addview_layout_add(Evas_Object *parent)
1339 {
1340         CLK_FUN_BEG();
1341         retv_if(!parent, NULL);
1342
1343         // create window layout
1344         Evas_Object *layout = elm_layout_add(parent);
1345         retv_if(layout == NULL, NULL);
1346
1347         elm_layout_theme_set(layout, "layout", "application", "searchbar_base");
1348         elm_object_signal_emit(layout, "elm,state,show,searchbar", "elm");
1349         //evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1350         //evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, 0);
1351         //elm_bg_color_set(layout, 0, 0, 0);
1352         //elm_object_style_set(layout, "group_list");
1353         // show layout
1354         //evas_object_show(layout);
1355
1356         return layout;
1357 }
1358
1359 /**
1360  * Create add view for append new city into the selection list of worldclock
1361  *
1362  * @param[in]  parent    Evas_Object which is the parent of add view
1363  * @param[in]  data      data which used in this function
1364  * @param[in]  func      Callback function which used for invoking when exit from add view
1365  *
1366  * @return    FAILED if create add view failed.
1367  *            SUCCESS if create add view successfully.
1368  */
1369 int worldclock_addview_add(Evas_Object *parent, void *data, Wcl_Return_Cb func)
1370 {
1371         CLK_FUN_BEG();
1372         retv_if(!data, FAILED);
1373
1374         struct appdata *ad = (struct appdata *)data;
1375
1376         init_alphabetic_index();
1377
1378         ad->page = WCL_PAGE_ADD;
1379         g_ad = ad;
1380         g_return_cb = func;
1381         const char *group_name = NULL;
1382         const char *title_name = NULL;
1383
1384         // select call_flag & group name by caller
1385         switch (ad->caller) {
1386         case WCL_CALLER_IS_APP_IT_SELF:
1387                 g_call_flag = CALL_FROM_MAIN_VIEW;
1388                 group_name = GRP_ADD2;
1389                 title_name = S_("IDS_COM_ADD");
1390                 break;
1391         case WCL_CALLER_IS_SHARED_LIBRARY:
1392                 g_call_flag = CALL_FROM_MAIN_VIEW;
1393                 group_name = GRP_ADD2;
1394                 title_name = S_("IDS_COM_ADD");
1395                 break;
1396         case WCL_CALLER_IS_UI_GADGET:
1397                 g_call_flag = CALL_FROM_UI_GADGET;
1398                 group_name = GRP_ADD2;
1399                 title_name = _("IDS_WCL_BODY_TIME_ZONE");
1400                 break;
1401         default:
1402                 break;
1403         }
1404
1405         // open data base
1406         retv_if(EINA_FALSE == worldclock_data_open_database(), FAILED);
1407
1408         /* add layout */
1409         ad->add_ly = __addview_layout_add(parent);
1410         retv_if(ad->add_ly == NULL, FAILED);
1411
1412         /* init search data */
1413         memset(ad->search_text, 0x0, BUF_SIZE * sizeof(char));
1414
1415         /* searchbar */
1416         ad->add_search_bar = __addview_searchbar_add(ad->add_ly, data);
1417         retv_if(ad->add_search_bar == NULL, FAILED);
1418
1419         /* load edje */
1420         ad->add_layout =
1421             worldclock_load_edj(ad->add_ly, WCL_EDJ_NAME, group_name);
1422         retv_if(ad->add_layout == NULL, FAILED);
1423         elm_object_part_content_set(ad->add_ly, "elm.swallow.content",
1424                                     ad->add_layout);
1425
1426         // index to quick search
1427         //ad->add_index = __addview_index_add(ad->add_layout, data);
1428
1429         // genlist
1430         ad->sort = WCL_SORT_BY_NAME;    // sory by name
1431         ad->add_genlist = __addview_genlist_add(ad->add_layout, data);
1432         retv_if(ad->add_genlist == NULL, FAILED);
1433
1434         Evas_Object *add_sortbar = __addview_sortbar_add(ad->navi_bar, data);
1435         retv_if(add_sortbar == NULL, FAILED);
1436
1437         // create left button
1438         Evas_Object *back_btn = elm_button_add(ad->navi_bar);
1439         elm_object_style_set(back_btn, "naviframe/end_btn/default");
1440         evas_object_smart_callback_add(back_btn, "clicked", __addview_quit_cb,
1441                                        NULL);
1442
1443         // set segment control as title about layout
1444         Elm_Object_Item *elm_item =
1445             elm_naviframe_item_push(ad->navi_bar, title_name, back_btn, NULL,
1446                                     ad->add_ly, NULL);
1447         elm_object_item_part_content_set(elm_item, "controlbar", add_sortbar);
1448         elm_naviframe_item_title_visible_set(elm_item, EINA_FALSE);
1449
1450         // update genlist
1451         if (g_ad->add_view_update_timer) {
1452                 ecore_timer_del(g_ad->add_view_update_timer);
1453                 g_ad->add_view_update_timer = NULL;
1454         }
1455         ad->add_view_update_timer =
1456             ecore_timer_add(0.01, __addview_genlist_update, ad);
1457
1458         CLK_FUN_END();
1459         return SUCCESS;
1460 }
1461
1462 /**
1463  * Release all resources which used in add view when exit from add view
1464  *
1465  * @param[in]  data   data which used in this function
1466  *
1467  * @return
1468  */
1469 void worldclock_addview_free(void *data)
1470 {
1471         CLK_FUN_BEG();
1472         ret_if(!data);
1473
1474         uninit_alphabetic_index();
1475
1476         struct appdata *ad = (struct appdata *)data;
1477         if (ad->add_ly) {
1478                 __addview_quit_cb(NULL, NULL, NULL);
1479         }
1480         CLK_FUN_END();
1481 }
1482
1483 #undef MAX_LEN_CITY_NAME
1484 #undef MAX_LEN_COUNTRY_NAME
1485 #undef MAX_LEN_GMT
1486 #undef MAX_LEN_INPUT