f3563601fe00a0f728d6c1cb9f0ec00d8dc16fc8
[apps/home/libug-worldclock-efl.git] / src / worldclock_add_view.c
1 /*
2 *
3 * Copyright 2012  Samsung Electronics Co., Ltd
4 *
5 * Licensed under the Flora License, Version 1.0 (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://www.tizenopensource.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 <appcore-efl.h>
21 #include <Elementary.h>
22 #include <Ecore_X.h>
23 #include <vconf.h>
24 #include <unicode/utf8.h>
25 #include <unicode/ustring.h>
26
27 #include "worldclock.h"
28 #include "worldclock_data.h"
29 #include "worldclock_dlog.h"
30 #include "worldclock_util.h"
31 #include "worldclock_add_view.h"
32 #include "clock_fwk_icu_label.h"
33
34 #define MAX_LEN_CITY_NAME       16
35 #define MAX_LEN_COUNTRY_NAME    24
36 #define MAX_LEN_GMT             10
37 #define MAX_LEN_INPUT           20
38 #define FIRST_UPDATE_ITEM_COUNT 14
39
40 static struct appdata *g_ad = NULL;
41 static Wcl_Return_Cb g_return_cb = NULL;
42 static Elm_Object_Item *g_btn_sort_by_name = NULL;
43 static Elm_Object_Item *g_btn_sort_by_time = NULL;
44 static char g_index_buf[BUF_MIN_SIZE] = { '\0' };
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 *__ugview_genlist_label_get(void *data, Evas_Object * obj,
58                                         const char *part);
59 static Evas_Object *__ugview_genlist_icon_get(void *data, Evas_Object * obj,
60                                               const char *part);
61 static void __ugview_genlist_item_del(void *data, Evas_Object * obj);
62 static Evas_Object *__ugview_index_add(Evas_Object * parent, void *data);
63 static Eina_Bool __ugview_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 = __ugview_genlist_label_get,
71         .func.content_get = __ugview_genlist_icon_get,
72         .func.state_get = NULL,
73         .func.del = __ugview_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 __ugview_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 __ugview_exit_cb(void *data)
130 {
131         __ugview_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 __ugview_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 *__ugview_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 *__ugview_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 __ugview_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 __ugview_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
297         // synchronize city status from db
298         ret = worldclock_ug_data_get_city_status_from_db(cs);
299
300         if (EINA_TRUE == ret) {
301                 if (0 == cs->selected) {
302                         ret = EINA_FALSE;
303                 }
304         }
305
306         CLK_FUN_END();
307         return ret;
308 }
309
310 /**
311  * Callback function which used for genlist selection event processing
312  *
313  * @param[in]  data         data which used in this function
314  * @param[in]  obj          the object which emit the selection event
315  * @param[in]  event_info   information about selection event
316  *
317  * @return
318  */
319 static void __ugview_genlist_item_sel(void *data, Evas_Object * obj,
320                                       void *event_info)
321 {
322         CLK_FUN_BEG();
323
324         Elm_Object_Item *gli = NULL;
325         // get selected genlist item
326         gli = elm_genlist_selected_item_get(obj);
327         elm_genlist_item_selected_set(gli, 0);
328
329         CLK_FUN_END();
330 }
331
332 /**
333  * Callback function used for genlist item selection event processing
334  * three things may happen to this funcion
335  *   1. replace an item of main list
336  *   2. add an item to main list
337  *   3. set system GMT and return to caller
338  *
339  * @param[in]  data         data which used for this function
340  * @param[in]  obj          Evas_Object which emit the selection event
341  * @param[in]  event_info   Information about event
342  *
343  * @return
344  */
345 static void __ugview_genlist_item_selected_cb(void *data, Evas_Object * obj,
346                                               void *event_info)
347 {
348         CLK_FUN_BEG();
349
350         ret_if(!g_ad);
351         CLK_INFO("normal now\n");
352
353         Elm_Object_Item *gli = NULL;
354         const Wcl_CitySet *cs = NULL;
355
356         // get selected genlist item
357         gli = (Elm_Object_Item *) (event_info);
358         // get the data of selected item
359         cs = elm_object_item_data_get(gli);
360
361         // reset quit timer
362         if (g_ad->add_view_quit_timer) {
363                 ecore_timer_del(g_ad->add_view_quit_timer);
364                 g_ad->add_view_quit_timer = NULL;
365         }
366
367         if (!cs) {
368                 // meet error, exit
369                 g_ad->add_view_quit_timer =
370                     ecore_timer_add(0.02, __ugview_exit_cb, NULL);
371                 return;
372         }
373         ////////// replace or append operation to mainview //////////
374         if (CALL_FROM_MAIN_VIEW == g_call_flag) {
375                 ////////// this is normal select, this item will be append to main list //////////
376                 if (__ugview_genlist_check_whether_selected(cs)) {
377                         CLK_INFO("this city has been selected, show notify\n");
378                         // if city already selected, show popup
379                         __ugview_notify_cb(S_("IDS_COM_OPT_ADDED"));
380                         CLK_FUN_END();
381                         return;
382                 } else {
383                         // create new structure to store new city
384                         Wcl_CitySet *t_cs = calloc(1, sizeof(Wcl_CitySet));
385                         if (NULL == t_cs) {
386                                 // if create failed, exit
387                                 g_ad->add_view_quit_timer =
388                                     ecore_timer_add(0.02, __ugview_exit_cb,
389                                                     NULL);
390                                 return;
391                         }
392
393                         memcpy(t_cs, cs, sizeof(Wcl_CitySet));
394                         // set selected flag
395                         t_cs->selected = 1;
396                         //t_cs->dst = worldclock_dst_get(cs);
397
398                         // append done, exit
399                         g_ad->add_view_quit_timer =
400                             ecore_timer_add(0.02, __ugview_exit_cb, t_cs);
401
402                         // save return data for UG
403                         g_ad->return_data = t_cs;
404
405                         CLK_FUN_END();
406                         return;
407                 }
408         }
409         /////////////// return city data to UI gadget /////////////
410         else if (CALL_FROM_UI_GADGET == g_call_flag) {
411                 // create new structure to store new city
412                 Wcl_CitySet *t_cs = calloc(1, sizeof(Wcl_CitySet));
413                 if (t_cs) {
414                         // copy selected data
415                         memcpy(t_cs, cs, sizeof(Wcl_CitySet));
416                         // get current dst value, and set it into result data
417                         t_cs->dst = worldclock_dst_get(cs);
418                         // save return data for UG
419                         g_ad->return_data = t_cs;
420                 } else {
421                         CLK_ERR("CALLOC ERROR!!!");
422                         // set NULL for UG
423                         g_ad->return_data = NULL;
424                 }
425
426                 // exit when save successfully
427                 g_ad->add_view_quit_timer =
428                     ecore_timer_add(0.02, __ugview_exit_cb, g_ad);
429                 CLK_FUN_END();
430                 return;
431         }
432 }
433
434 /**
435  * Search substring in string by UChar type
436  *
437  * @param[in]  string           The string to search
438  * @param[in]  substring        The substring to find
439  *
440  * @return    A pointer to the first occurrence of substring in string
441  */
442 const UChar *__ugview_search_in_ustring(const UChar *string,
443                                 UChar *substring)
444 {
445     int i = 0;
446         const UChar *pstr = string;
447     int substr_len = u_strlen(substring);
448     int str_len = u_strlen(string);
449
450     if (0 == substr_len) {
451         // NULL string
452         return pstr;
453     }
454     else if (substr_len > str_len) {
455         // substring to long
456         return NULL;
457     }
458
459         for (i = 0; i < str_len - substr_len + 1; i++) {
460                 if (!u_strncasecmp(substring, &pstr[i], substr_len, 0)) {
461             // match
462             return &pstr[i];
463                 }
464         }
465
466     // no match
467         return NULL;
468 }
469
470 static Eina_Bool __ugview_genlist_update_last(void *data)
471 {
472         CLK_FUN_BEG();
473         retv_if(!data || !g_ad, EINA_FALSE);
474         Eina_List *el = (Eina_List *) data;
475         Wcl_CitySet *cs = NULL; //  elm_object_item_data_get(gli);
476         Elm_Object_Item *gli = NULL;
477         Eina_Bool ret = EINA_TRUE;
478     UChar u_search_text[CITY_BUF_SIZE] = { 0 };
479
480         retv_if(!g_ad->add_genlist, EINA_FALSE);
481         retv_if(!g_ad->add_index, EINA_FALSE);
482
483         if (g_ad->add_view_update_last_timer) {
484                 ecore_timer_del(g_ad->add_view_update_last_timer);
485                 g_ad->add_view_update_last_timer = NULL;
486         }
487
488         u_uastrncpy(u_search_text, g_ad->search_text, CITY_BUF_SIZE);
489
490         while (el) {
491                 // get data
492                 cs = el->data;
493                 if (cs && ret) {
494             UChar u_city_name[CITY_BUF_SIZE] = { 0 };
495                 u_uastrncpy(u_city_name, _(cs->city), CITY_BUF_SIZE);
496             if (__ugview_search_in_ustring(u_city_name, u_search_text)) {
497                                 // append data to genlist
498                                 gli = elm_genlist_item_append(g_ad->add_genlist, &g_ts, cs,     /* item data */
499                                                               NULL,     /* parent */
500                                                               ELM_GENLIST_ITEM_NONE, __ugview_genlist_item_sel, /* func */
501                                                               cs        /* func data */
502                                     );
503
504                                 // update index with genlist item
505                                 ret =
506                                         __ugview_index_update(g_ad->add_index, g_ad->sort,
507                                                         g_index_buf, gli);
508             }
509             else {
510                 break;
511             }
512                 } else {
513                         break;
514                 }
515                 // get next data
516                 el = el->next;
517         }
518
519         // show index
520         evas_object_show(g_ad->add_index);
521         CLK_FUN_END();
522         return EINA_FALSE;
523 }
524
525 /**
526  * Update genlist which displaying in add view
527  *
528  * @param[in]  data   data used for this function
529  *
530  * @return     EINA_FALSE
531  */
532 static Eina_Bool __ugview_genlist_update(void *data)
533 {
534         CLK_FUN_BEG();
535         retv_if(!data, EINA_FALSE);
536         retv_if(!g_ad, EINA_FALSE);
537
538         struct appdata *ad = (struct appdata *)data;
539         Elm_Object_Item *gli = NULL;
540         Eina_List *el = NULL;
541         Wcl_CitySet *cs = NULL;
542         int count = 0;
543     UChar u_search_text[CITY_BUF_SIZE] = { 0 };
544
545         // init data list
546         memset(g_index_buf, 0X0, BUF_MIN_SIZE * sizeof(char));
547
548         // set data list
549         if (!ad->default_list) {
550                 // get all appendable cities
551                 ad->default_list =
552                     worldclock_ug_data_get_default_city_list(ad->selectionFlag);
553         }
554         // reset timer
555         if (g_ad->add_view_update_timer) {
556                 ecore_timer_del(g_ad->add_view_update_timer);
557                 g_ad->add_view_update_timer = NULL;
558         }
559         if (g_ad->add_view_update_last_timer) {
560                 ecore_timer_del(g_ad->add_view_update_last_timer);
561                 g_ad->add_view_update_last_timer = NULL;
562         }
563
564         retv_if(NULL == ad->search_text, EINA_FALSE);
565         if (!strcmp(ad->search_text, "")) {
566                 // if searchbar is been clicked, be filled in ""
567                 CLK_INFO("ad->search_text=%s\n", ad->search_text);
568         } else {
569                 CLK_INFO("ad->search_text=%s\n", ad->search_text);
570             u_uastrncpy(u_search_text, ad->search_text, CITY_BUF_SIZE);
571         }
572
573         if (WCL_SORT_BY_NAME == ad->sort) {
574                 // sort by name
575                 snprintf(g_index_buf, BUF_MIN_SIZE, "%c", 'Z');
576                 // sort default list
577                 ad->default_list =
578                     eina_list_sort(ad->default_list,
579                                    eina_list_count(ad->default_list),
580                                    worldclock_city_compare_cb);
581         } else if (WCL_SORT_BY_TIMEZONE == ad->sort) {
582                 // sort by time
583                 snprintf(g_index_buf, BUF_MIN_SIZE, "%s", "-18");
584                 // sort default list
585                 ad->default_list =
586                     eina_list_sort(ad->default_list,
587                                    eina_list_count(ad->default_list),
588                                    worldclock_time_compare_cb);
589         }
590         // reset genlist
591         elm_genlist_clear(ad->add_genlist);
592         if (ad->add_index) {
593                 //elm_index_item_clear(ad->add_index);
594                 evas_object_del(ad->add_index);
595                 ad->add_index = NULL;
596         }
597         // reset index
598         ad->add_index = __ugview_index_add(ad->add_layout, ad);
599         retv_if(!ad->add_index, EINA_FALSE);
600
601         el = ad->default_list;
602         while (el) {
603                 // get data
604                 cs = (Wcl_CitySet *)el->data;
605                 if (cs) {
606             UChar u_city_name[CITY_BUF_SIZE] = { 0 };
607                 u_uastrncpy(u_city_name, _(cs->city), CITY_BUF_SIZE);
608             if(__ugview_search_in_ustring(u_city_name, u_search_text)) {
609                             // append data to genlist
610                             gli = elm_genlist_item_append(ad->add_genlist, &g_ts, cs,   /* item data */
611                                                       NULL,     /* parent */
612                                                       ELM_GENLIST_ITEM_NONE, __ugview_genlist_item_sel, /* func */
613                                                       cs        /* func data */
614                                 );
615                             if (el == ad->default_list) {
616                                 elm_genlist_item_show(gli,
617                                                       ELM_GENLIST_ITEM_SCROLLTO_TOP);
618                             }
619                             // update index with genlist item
620                             __ugview_index_update(ad->add_index, ad->sort,
621                                               g_index_buf, gli);
622
623                             count++;
624                             if (FIRST_UPDATE_ITEM_COUNT <= count) {
625                                 // update genlist
626                                 ad->add_view_update_last_timer =
627                                     ecore_timer_add(0.5,
628                                                     __ugview_genlist_update_last,
629                                                     el->next);
630                                 break;
631                             }
632             }
633             else
634             {
635                         // get next data
636                         el = el->next;
637                 continue;
638             }
639                 } else {
640                         break;
641                 }
642                 // get next data
643                 el = el->next;
644         }
645         if (FIRST_UPDATE_ITEM_COUNT > count) {
646                 // show index
647                 evas_object_show(ad->add_index);
648         }
649
650         CLK_FUN_END();
651         return EINA_FALSE;
652 }
653
654 /**
655  * Add new genlist which used for displaying all cities which could be append
656  * into worldclock.
657  *
658  * @param[in]  parent   The parent object of the new genlist object
659  * @param[in]  data     Data used in this function
660  *
661  * @return     NULL if create genlist failed.
662  *             Pointer to the new genlist object if create genlist successfully.
663  */
664 static Evas_Object *__ugview_genlist_add(Evas_Object * parent, void *data)
665 {
666         CLK_FUN_BEG();
667         retv_if(!data, NULL);
668
669         Evas_Object *genlist = NULL;
670         // add genlist
671         genlist = elm_genlist_add(parent);
672         evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND,
673                                          EVAS_HINT_EXPAND);
674         evas_object_size_hint_align_set(genlist, -1.0, -1.0);
675         // swallow
676         edje_object_part_swallow(_EDJ(parent), "add/genlist", genlist);
677         // show
678         evas_object_show(genlist);
679         // register callback function for select event on genlist
680         evas_object_smart_callback_add(genlist, "selected",
681                                        __ugview_genlist_item_selected_cb, data);
682
683         // To use multiline textblock/entry/editfield in genlist, set height_for_width mode
684         // then the item's height is calculated while the item's width fits to genlist width.
685         elm_genlist_mode_set(genlist, EINA_TRUE);
686         CLK_FUN_END();
687         return genlist;
688 }
689
690 /////////////////////////////////// genlist related finish /////////////////////////////////////////
691
692 ////////////////////////// index ///////////////////////////////////////////////////////////
693 /**
694  * Callback function which is used for elm_index when level up event processing
695  *
696  * @param[in]  data        data used for this function
697  * @param[in]  obj         Evas_Object which emit level up event
698  * @param[in]  event_info  Information about this event
699  *
700  * @return
701  */
702 static void __ugview_index_level_up(void *data, Evas_Object * obj,
703                                     void *event_info)
704 {
705         CLK_FUN_BEG();
706         ret_if(!data);
707
708         // get current index level
709         int level = elm_index_item_level_get(obj);
710         ret_if(level != 1);
711
712         Elm_Object_Item *it = NULL;
713         char buf[BUF_SIZE] = { '\0', };
714
715         // get selected index item
716         it = elm_index_selected_item_get(obj, level - 1);
717         it = (Elm_Object_Item *) elm_object_item_data_get(it);
718         // clear index item
719         elm_index_item_clear(obj);
720         // get data of selected index
721         Wcl_CitySet *pi = (Wcl_CitySet *) elm_object_item_data_get(it);
722
723         snprintf(buf, BUF_SIZE, "%c", 'A');
724
725         while (it) {
726                 // get selected city
727                 Wcl_CitySet *gmt = (Wcl_CitySet *) elm_object_item_data_get(it);
728                 // append index item if do not exist
729                 if (!strncmp(pi->city, gmt->city, 1)) {
730                         if (buf[0] != gmt->city[1]) {
731                                 snprintf(buf, BUF_SIZE, "%c", gmt->city[1]);
732                                 Elm_Object_Item *item =
733                                     elm_index_item_append(obj, buf, NULL, NULL);
734                                 elm_object_item_data_set(item, it);
735                         }
736                 }
737                 // get next genlist item
738                 it = elm_genlist_item_next_get(it);
739         }
740         // goto item at level
741         elm_index_level_go(obj, level);
742         CLK_FUN_END();
743 }
744
745 /**
746  * Callback function which used for elm_index about delay change event processing
747  *
748  * @param[in]  data         Data which used in this function
749  * @param[in]  obj          Evas_Object which emit this event
750  * @param[in]  event_info   Information about this event
751  *
752  * @return
753  */
754 static void __ugview_index_index_changed_bring(void *data, Evas_Object * obj,
755                                                void *event_info)
756 {
757         elm_genlist_item_bring_in(event_info, ELM_GENLIST_ITEM_SCROLLTO_TOP);
758 }
759
760 /**
761  * Callback function which used for elm_index about index selection event processing
762  *
763  * @param[in]  data         Data which used in this function
764  * @param[in]  obj          Evas_Object which emit this event
765  * @param[in]  event_info   Information about this event
766  *
767  * @return
768  */
769 static void __ugview_index_index_selected(void *data, Evas_Object * obj,
770                                           void *event_info)
771 {
772         Elm_Object_Item *it = (Elm_Object_Item *) event_info;
773         it = (Elm_Object_Item *) elm_object_item_data_get(it);
774         elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
775 }
776
777 /**
778  * Create new elm_index used in add view
779  *
780  * @param[in] index     the elm_index which will be updated
781  * @param[in] sort      the sort type of genlist which bind index
782  * @param[in] buf       the buffer used to store pre data which append in elm_index
783  * @param[in] data      pointer to elm_genlist_item which need to be append
784  *
785  * @return
786  */
787 static Eina_Bool __ugview_index_update(Evas_Object * index,
788                                        Wcl_Addlist_Sort_Type sort, char *buf,
789                                        void *data)
790 {
791         char buf_name[BUF_MIN_SIZE] = { 0, };
792         char buf_zone[BUF_MIN_SIZE] = { 0, };
793         char *ppos = NULL, *pbegin = NULL;
794         Elm_Object_Item *gli = (Elm_Object_Item *) data;
795         Wcl_CitySet *cs = elm_object_item_data_get(gli);
796         retv_if(!index, EINA_FALSE);
797         static char *g_alphabetic_buf = NULL;
798
799         memset(buf_name, 0x0, BUF_MIN_SIZE * sizeof(char));
800         if (WCL_SORT_BY_NAME == sort) {
801                 // append index to elm_index
802                 char *bufalphabetic =
803                     get_alphabetic_index_name(get_alphabetic_index
804                                               (_(cs->city)));
805                 if (NULL == g_alphabetic_buf) {
806                         g_alphabetic_buf = bufalphabetic;
807                         Elm_Object_Item *it =
808                             elm_index_item_append(index, bufalphabetic,
809                                                   NULL, NULL);
810                         elm_object_item_data_set(it, gli);
811                 }
812                 if (NULL != bufalphabetic) {
813                         if (IS_STR_NOT_EQUAL(g_alphabetic_buf, bufalphabetic)) {
814                                 g_alphabetic_buf = bufalphabetic;
815                                 Elm_Object_Item *it =
816                                     elm_index_item_append(index, bufalphabetic,
817                                                           NULL, NULL);
818                                 elm_object_item_data_set(it, gli);
819                         }
820                 }
821         } else if (WCL_SORT_BY_TIMEZONE == sort) {
822                 // get timezone
823                 pbegin = cs->timezone + 3;
824                 // find dot
825                 ppos = strstr(pbegin, ":");
826                 if (ppos != NULL) {
827                         // if timezone is not integer, get the integer part
828                         g_strlcpy(buf_zone, pbegin, ppos - pbegin + 1);
829                 } else {
830                         // get timezone if it is integer
831                         g_strlcpy(buf_zone, pbegin, BUF_MIN_SIZE);
832                         buf_zone[strlen(cs->timezone)] = '\0';
833                 }
834
835                 if (strcmp(buf, buf_zone)) {
836                         // append timezone into index list if it is not exist
837                         snprintf(buf, BUF_MIN_SIZE, "%s", buf_zone);
838                         Elm_Object_Item *it =
839                             elm_index_item_append(index, buf, NULL, NULL);
840                         elm_object_item_data_set(it, gli);
841                 }
842         }
843
844         return EINA_TRUE;
845 }
846
847 /**
848  * Create new elm_index used in add view
849  *
850  * @param[in]  parent     Evas_Object which is the parent of new elm_index
851  * @param[in]  date       data which used int this function
852  *
853  * @return     NULL if create failed
854  *             Pointer to new elm_index if create successflly
855  */
856 static Evas_Object *__ugview_index_add(Evas_Object * parent, void *data)
857 {
858         CLK_FUN_BEG();
859         retv_if((!parent || !data), NULL);
860
861         Evas_Object *index = NULL;
862         // add index
863         index = elm_index_add(parent);
864         evas_object_size_hint_weight_set(index, EVAS_HINT_EXPAND,
865                                          EVAS_HINT_EXPAND);
866         //evas_object_resize(index, ad->root_w,ad->root_h - TB_PORTRAIT_H - SK_PORTRAIT_H);
867         //evas_object_move(index, ad->root_x, ad->root_y + TB_PORTRAIT_H + 12);
868         // swallow
869         edje_object_part_swallow(_EDJ(parent), "add/index", index);
870         // show index
871         evas_object_show(index);
872
873         // register callback function to index
874         evas_object_smart_callback_add(index, "level,up",
875                                        __ugview_index_level_up, NULL);
876         //evas_object_smart_callback_add(index, "level,down", __ugview_index_level_down, NULL);
877         evas_object_smart_callback_add(index, "delay,changed",
878                                        __ugview_index_index_changed_bring,
879                                        NULL);
880         //evas_object_smart_callback_add(index, "changed", __ugview_index_index_changed, NULL);
881         evas_object_smart_callback_add(index, "selected",
882                                        __ugview_index_index_selected, NULL);
883
884         // goto the top of index
885         elm_index_level_go(index, 0);
886
887         CLK_FUN_END();
888         return index;
889 }
890
891 ////////////////////////// index finished ///////////////////////////////////////////////////////////
892
893 /////////////////////// search bar ////////////////////////////
894 /**
895  * Callback function which used for searchbar object about click event processing
896  *
897  * @param[in]  data        data used for this function
898  * @param[in]  obj         Evas_Object which emit this event
899  * @param[in]  event_info  Information about this event
900  *
901  * @return
902  */
903 static void __ugview_searchbar_clicked_cb(void *data, Evas_Object * obj,
904                                           void *event_info)
905 {
906         CLK_FUN_BEG();
907         ret_if(!data);
908         if (!elm_entry_is_empty(obj))
909                 elm_object_signal_emit(searchbar_layout,
910                                        "elm,state,eraser,show", "elm");
911         elm_object_signal_emit(searchbar_layout, "elm,state,guidetext,hide",
912                                "elm");
913         elm_object_signal_emit(searchbar_layout, "cancel,in", "");
914
915         struct appdata *ad = (struct appdata *)data;
916         char *str = NULL;
917         // get entry
918         Evas_Object *entry = elm_object_part_content_get(searchbar_layout,
919                                                          "elm.swallow.content");
920         // get focus
921         elm_object_focus_set(obj, EINA_TRUE);
922         // get text from search bar
923         str = (char *)elm_object_text_get(entry);
924         ret_if(NULL == str);
925         // clear searchbar
926         if (!strcmp(str, S_("IDS_COM_SK_SEARCH"))) {
927                 memset(ad->search_text, '\0', BUF_SIZE);
928                 elm_object_text_set(entry, "");
929         }
930         // get imf context
931         Ecore_IMF_Context *imf_context = elm_entry_imf_context_get(entry);
932         if (NULL != imf_context) {
933                 // set default input language
934                 ecore_imf_context_input_panel_language_set(imf_context,
935                                                            ECORE_IMF_INPUT_PANEL_LANG_ALPHABET);
936                 // show input panel
937                 ecore_imf_context_input_panel_show(imf_context);
938         }
939         //if(str) {
940         //    free(str);
941         //}
942         CLK_FUN_END();
943 }
944
945 /**
946  * Callback function which used for entry object about content changing event processing
947  *
948  * @param[in]  data        data used for this function
949  * @param[in]  obj         Evas_Object which emit this event
950  * @param[in]  event_info  Information about this event
951  *
952  * @return
953  */
954 static void __ugview_searchbar_changed_cb(void *data, Evas_Object * obj,
955                                           void *event_info)
956 {
957
958         struct appdata *ad = NULL;
959         char *str = NULL;
960         int strLength = 0;
961         char input_text[BUF_SIZE] = { '\0' };
962         Eina_Bool isNeedUpdate = EINA_TRUE;
963
964         CLK_FUN_BEG();
965         ret_if(NULL == data);
966         ad = (struct appdata *)data;
967
968         if (elm_object_focus_get(searchbar_layout)) {
969                 if (elm_entry_is_empty(obj))
970                         elm_object_signal_emit(searchbar_layout,
971                                                "elm,state,eraser,hide", "elm");
972                 else
973                         elm_object_signal_emit(searchbar_layout,
974                                                "elm,state,eraser,show", "elm");
975         }
976         // get entry
977         Evas_Object *entry = elm_object_part_content_get(searchbar_layout,
978                                                          "elm.swallow.content");
979
980         // get text from search bar
981         str = (char *)elm_object_text_get(entry);
982
983         ret_if(NULL == str);
984         CLK_INFO("str get from entry: %s\n", str);
985         // get displaying part
986         worldclock_str_get_displaying_part(str, input_text);
987         CLK_INFO("str display in entry: %s\n", input_text);
988         // get previous search text
989         ret_if(NULL == ad->search_text);
990         CLK_INFO("ad->search_text: %s\n", ad->search_text);
991         ret_if(!strcmp(input_text, ad->search_text));
992
993         //  if string contains html flag, it is said that string do not been confirmed
994         //  so, return
995         Eina_Bool html_flag = worldclock_str_is_contain_html(input_text);
996
997         if (EINA_TRUE == html_flag) {
998                 CLK_INFO("HTML flag exist!\n");
999                 //return;
1000         }
1001
1002         if (!strcmp(ad->search_text, "")
1003             && !strcmp(input_text, S_("IDS_COM_SK_SEARCH"))) {
1004                 CLK_INFO("Not Update\n");
1005                 isNeedUpdate = EINA_FALSE;
1006         }
1007 //      // get entry
1008 //      Evas_Object *entry = elm_searchbar_entry_get(ad->add_search_bar);
1009
1010         // get size of unicode string
1011         UChar ustr[BUF_SIZE] = { 0 };
1012         u_uastrncpy(ustr, input_text, BUF_SIZE);
1013         strLength = u_strlen(ustr);
1014         CLK_INFO("string length : %d\n", strLength);
1015         if (strLength > MAX_LEN_INPUT) {
1016                 // the content of entry won't change if enter too many characters
1017                 elm_object_text_set(entry, ad->search_text);
1018                 // set cursor to the end of entry
1019                 elm_entry_cursor_end_set(entry);
1020                 // if input too long, show popup
1021                 //worldclock_show_popup(g_ad->add_ly, &(g_ad->popup), _("Input too long!"));
1022                 return;
1023         }
1024
1025         if (input_text != NULL) {
1026                 // reset search text
1027                 memset(ad->search_text, '\0', BUF_SIZE);
1028                 if (strcmp(input_text, S_("IDS_COM_SK_SEARCH"))
1029                     && strcmp(input_text, "")) {
1030                         g_strlcpy(ad->search_text, input_text, strlen(input_text)+1);
1031                 }
1032                 CLK_INFO_GREEN("ad->search_text:%s\n", ad->search_text);
1033         }
1034
1035         CLK_INFO("ad->search_text:%s\n", ad->search_text);
1036         // if search text in search_bar is not "Search", update genlist
1037         if (EINA_TRUE == isNeedUpdate) {
1038                 CLK_INFO("Update the search view text, search_text=%s\n",
1039                          ad->search_text);
1040                 if (g_ad->add_view_update_timer) {
1041                         ecore_timer_del(g_ad->add_view_update_timer);
1042                         g_ad->add_view_update_timer = NULL;
1043                 }
1044                 // update genlist
1045                 ad->add_view_update_timer =
1046                     ecore_timer_add(0.01, __ugview_genlist_update, ad);
1047         }
1048         //if(str) {
1049         //    free(str);
1050         //}
1051         CLK_FUN_END();
1052 }
1053
1054 /**
1055  * Callback function which used for searchbar object about cancel event processing
1056  *
1057  * @param[in]  data        data used for this function
1058  * @param[in]  obj         Evas_Object which emit this event
1059  * @param[in]  event_info  Information about this event
1060  *
1061  * @return
1062  */
1063 static void __ugview_searchbar_cancel_clicked_cb(void *data, Evas_Object * obj,
1064                                                  void *event_info)
1065 {
1066         CLK_FUN_BEG();
1067         ret_if(!data);
1068         struct appdata *ad = (struct appdata *)data;
1069         ret_if(!ad->add_search_bar);
1070
1071         // get entry
1072         Evas_Object *entry = elm_object_part_content_get(searchbar_layout,
1073                                                          "elm.swallow.content");
1074         const char *text;
1075         evas_object_hide(obj);
1076         elm_object_signal_emit(searchbar_layout, "cancel,out", "");
1077         text = elm_entry_entry_get(entry);
1078         if (text != NULL && strlen(text) > 0)
1079                 elm_entry_entry_set(entry, NULL);
1080         elm_object_focus_set(entry, EINA_FALSE);
1081
1082         // get imf context
1083         Ecore_IMF_Context *imf_context = elm_entry_imf_context_get(entry);
1084         if (imf_context) {
1085                 if (ECORE_IMF_INPUT_PANEL_STATE_HIDE !=
1086                     ecore_imf_context_input_panel_state_get(imf_context)) {
1087                         // hide input panel
1088                         ecore_imf_context_input_panel_hide(imf_context);
1089                 }
1090         }
1091         CLK_INFO("ad->search_text: %s\n", ad->search_text);
1092         // update genlist
1093         if (strcmp(ad->search_text, "")) {
1094                 // reset timer
1095                 if (g_ad->add_view_update_timer) {
1096                         ecore_timer_del(g_ad->add_view_update_timer);
1097                         g_ad->add_view_update_timer = NULL;
1098                 }
1099                 ad->add_view_update_timer =
1100                     ecore_timer_add(0.01, __ugview_genlist_update, ad);
1101         }
1102         // reset search text
1103         memset(ad->search_text, '\0', BUF_SIZE);
1104         // reset search bar
1105         //elm_searchbar_text_set(ad->add_search_bar, S_("IDS_COM_SK_SEARCH"));
1106
1107         CLK_FUN_END();
1108 }
1109
1110 /**
1111  * Callback function used for processing unfocused event about searchbar.
1112  * When touch out of searchbar , hide input panel
1113  *
1114  * @param[in]  data        data used for this function
1115  * @param[in]  obj         Evas_Object which emit this event
1116  * @param[in]  event_info  Information about this event
1117  *
1118  * @return
1119  */
1120 static void __ugview_searchbar_unfocused_cb(void *data, Evas_Object * obj,
1121                                             void *event_info)
1122 {
1123         CLK_FUN_BEG();
1124         ret_if(!data);
1125         struct appdata *ad = (struct appdata *)data;
1126
1127         if (elm_entry_is_empty(obj))
1128                 elm_object_signal_emit(searchbar_layout,
1129                                        "elm,state,guidetext,show", "elm");
1130         elm_object_signal_emit(searchbar_layout, "elm,state,eraser,hide",
1131                                "elm");
1132
1133         Ecore_IMF_Context *imf_context = NULL;
1134         if (ad->add_search_bar) {
1135                 // get entry from searchbar
1136                 Evas_Object *entry =
1137                     elm_object_part_content_get(searchbar_layout,
1138                                                 "elm.swallow.content");
1139                 // get imf context from entry
1140                 imf_context = elm_entry_imf_context_get(entry);
1141         }
1142         if (imf_context) {
1143                 CLK_INFO("\nto hide keypad\n\n");
1144                 // hide imf context keypad
1145                 ecore_imf_context_input_panel_hide(imf_context);
1146         }
1147
1148         CLK_FUN_END();
1149 }
1150
1151 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.
1152 {
1153         elm_entry_entry_set(data, "");
1154 }
1155
1156 static void _bg_clicked_cb(void *data, Evas_Object * obj, const char *emission,
1157                            const char *source)
1158 {
1159         elm_object_focus_set(data, EINA_TRUE);
1160 }
1161
1162 static void _searchsymbol_clicked_cb(void *data, Evas_Object * obj,
1163                                      const char *emission, const char *source)
1164 {
1165         elm_object_focus_set(data, EINA_TRUE);
1166         printf("\n[Search Bar] SearchSymbol Callback Called\n");
1167 }
1168
1169 #if 0
1170 static void __ugview_input_panel_event_cb(void *data, Ecore_IMF_Context * ctx,
1171                                           int value)
1172 {
1173         CLK_FUN_BEG();
1174         ret_if(!data);
1175         struct appdata *ad = (struct appdata *)data;
1176         ret_if(!ad->add_layout);
1177         if (value == ECORE_IMF_INPUT_PANEL_STATE_SHOW) {
1178                 // ISE state has changed to ECORE_IMF_INPUT_PANEL_STATE_SHOW status
1179                 edje_object_signal_emit(_EDJ(ad->add_layout), "abbrev_genlist",
1180                                         "add/genlist");
1181                 edje_object_signal_emit(_EDJ(ad->add_layout), "abbrev_index",
1182                                         "add/index");
1183         } else if (value == ECORE_IMF_INPUT_PANEL_STATE_HIDE) {
1184                 // ISE state has changed to ECORE_IMF_INPUT_PANEL_STATE_HIDE status
1185                 edje_object_signal_emit(_EDJ(ad->add_layout), "expand_genlist",
1186                                         "add/genlist");
1187                 edje_object_signal_emit(_EDJ(ad->add_layout), "expand_index",
1188                                         "add/index");
1189         }
1190         CLK_FUN_END();
1191 }
1192 #endif
1193 /**
1194  * Add new searchbar object which used for search cities which selected by user.
1195  *
1196  * @param[in]  parent   The parent object of the new genlist object
1197  * @param[in]  data     Data used in this function
1198  *
1199  * @return     NULL if create genlist failed.
1200  *             Pointer to the new searchbar object if create successfully.
1201  */
1202 static Evas_Object *__ugview_searchbar_add(Evas_Object * parent, void *data)
1203 {
1204         CLK_FUN_BEG();
1205         retv_if((!parent || !data), NULL);
1206
1207         //Evas_Object *searchbar_layout = NULL;
1208         Evas_Object *entry = NULL;
1209         Evas_Object *cancel_btn = NULL;
1210         // add search bar
1211         //search_bar = elm_searchbar_add(parent);
1212         //search_bar =
1213         //    edje_object_part_external_object_get(_EDJ(parent), "searchbar");
1214         //retv_if(!search_bar, NULL);
1215         searchbar_layout = elm_layout_add(parent);
1216         elm_layout_theme_set(searchbar_layout, "layout", "searchbar",
1217                              "cancel_button");
1218         elm_object_part_content_set(parent, "searchbar", searchbar_layout);
1219         entry = elm_entry_add(searchbar_layout);
1220         elm_entry_prediction_allow_set(entry, EINA_FALSE);
1221         elm_entry_scrollable_set(entry, EINA_TRUE);
1222         elm_entry_single_line_set(entry, EINA_TRUE);
1223         elm_object_part_content_set(searchbar_layout, "elm.swallow.content",
1224                                     entry);
1225         elm_object_part_text_set(searchbar_layout, "elm.guidetext", "Search");
1226         //evas_object_show(entry);              // entry should be shown before setting focus.
1227         //// enable animation
1228         //elm_searchbar_cancel_button_animation_set(search_bar, EINA_TRUE);
1229         // get entry
1230         //Evas_Object *entry = elm_searchbar_entry_get(search_bar);
1231         evas_object_smart_callback_add(entry, "changed",
1232                                        __ugview_searchbar_changed_cb, data);
1233         evas_object_smart_callback_add(entry, "focused",
1234                                        __ugview_searchbar_clicked_cb, data);
1235         evas_object_smart_callback_add(entry, "unfocused",
1236                                        __ugview_searchbar_unfocused_cb, data);
1237
1238         elm_object_signal_callback_add(searchbar_layout, "elm,eraser,clicked",
1239                                        "elm", _eraser_clicked_cb, entry);
1240         elm_object_signal_callback_add(searchbar_layout, "elm,bg,clicked",
1241                                        "elm", _bg_clicked_cb, entry);
1242         elm_entry_input_panel_layout_set(entry, ELM_INPUT_PANEL_LAYOUT_NORMAL);
1243         // disable input panel
1244         elm_entry_input_panel_enabled_set(entry, EINA_FALSE);
1245         // disable the context menu
1246         elm_entry_context_menu_disabled_set(entry, EINA_TRUE);
1247
1248         evas_object_size_hint_weight_set(searchbar_layout, EVAS_HINT_EXPAND,
1249                                          EVAS_HINT_EXPAND);
1250         evas_object_size_hint_align_set(searchbar_layout, EVAS_HINT_FILL,
1251                                         EVAS_HINT_FILL);
1252
1253         cancel_btn = elm_button_add(searchbar_layout);
1254         elm_object_part_content_set(searchbar_layout, "button_cancel",
1255                                     cancel_btn);
1256         elm_object_style_set(cancel_btn, "searchbar/default");
1257         elm_object_text_set(cancel_btn, "Cancel");
1258         evas_object_smart_callback_add(cancel_btn, "clicked",
1259                                        __ugview_searchbar_cancel_clicked_cb,
1260                                        data);
1261         elm_object_signal_callback_add(searchbar_layout, "elm,action,click", "",
1262                                        _searchsymbol_clicked_cb, entry);
1263
1264         // set color
1265         // register callback functions to search bar
1266 //      evas_object_smart_callback_add(entry, "unfocused",
1267 //                                     __ugview_searchbar_unfocused_cb, data);
1268 //      evas_object_smart_callback_add(entry, "changed",
1269 //                                     __ugview_searchbar_changed_cb, data);
1270 //      evas_object_smart_callback_add(searchbar_layout, "clicked",
1271 //                                     __ugview_searchbar_clicked_cb, data);
1272 //      evas_object_smart_callback_add(searchbar_layout, "cancel,clicked",
1273 //                                     __ugview_searchbar_cancel_clicked_cb,
1274 //                                     data);
1275
1276         // swallow
1277         //edje_object_part_swallow(_EDJ(parent), "add/search", searchbar_layout);
1278         // show it
1279         //evas_object_show(searchbar_layout);
1280
1281         CLK_FUN_END();
1282         return searchbar_layout;
1283 }
1284
1285 /////////////////////// search bar finished ////////////////////////////
1286
1287 /**
1288  * Callback function which used for change sorting type about genlist
1289  *
1290  * @param[in]  data        data which used in this function
1291  * @param[in]  obj         Evas_Object which emit this event
1292  * @param[in]  event_info  Information about such event.
1293  *
1294  * @return
1295  */
1296 static void __ugview_sortbar_clicked_cb(void *data, Evas_Object * obj,
1297                                         void *event_info)
1298 {
1299         CLK_FUN_BEG();
1300         ret_if(!data);
1301
1302         struct appdata *ad = (struct appdata *)data;
1303
1304         //// get entry
1305         //Evas_Object *entry = elm_searchbar_entry_get(ad->add_search_bar);
1306         //elm_object_focus_set(entry, EINA_TRUE);
1307         //// disable the context menu
1308         //elm_entry_context_menu_disabled_set(entry, EINA_TRUE);
1309         //elm_entry_context_menu_disabled_set(entry, EINA_FALSE);
1310
1311         Elm_Object_Item *select_item =
1312             elm_segment_control_item_selected_get(obj);
1313
1314         // set sort flag, and update genlist
1315         if (select_item == g_btn_sort_by_time) {
1316                 ad->sort = WCL_SORT_BY_TIMEZONE;
1317         } else if (select_item == g_btn_sort_by_name) {
1318                 ad->sort = WCL_SORT_BY_NAME;
1319         }
1320         // update genlist
1321         if (g_ad->add_view_update_timer) {
1322                 ecore_timer_del(g_ad->add_view_update_timer);
1323                 g_ad->add_view_update_timer = NULL;
1324         }
1325         ad->add_view_update_timer =
1326             ecore_timer_add(0.01, __ugview_genlist_update, ad);
1327
1328         CLK_FUN_END();
1329 }
1330
1331 /**
1332  * Add new sortbar object which used for sort cities which selected by user.
1333  *
1334  * @param[in]  parent   The parent object of the new genlist object
1335  * @param[in]  data        data which used in this function
1336  *
1337  * @return     NULL if create genlist failed.
1338  *             Pointer to the new sortbar object if create successfully.
1339  */
1340 static Evas_Object *__ugview_sortbar_add(Evas_Object * parent, void *data)
1341 {
1342         retv_if((!parent || !data), NULL);
1343         /* create controlbar */
1344         Evas_Object *ctrlbar = widget_create_controlbar(parent, NULL);
1345         /* create segment control on controlbar */
1346         Evas_Object *segment_ly = elm_layout_add(ctrlbar);
1347         retv_if(segment_ly == NULL, NULL);
1348         elm_layout_file_set(segment_ly, WCL_EDJ_NAME, GRP_SEGMENT_PANEL);
1349         evas_object_size_hint_weight_set(segment_ly, EVAS_HINT_EXPAND,
1350                                          EVAS_HINT_EXPAND);
1351         evas_object_size_hint_align_set(segment_ly, EVAS_HINT_FILL,
1352                                         EVAS_HINT_FILL);
1353         evas_object_show(segment_ly);
1354
1355         // create segment control
1356         Evas_Object *segment = elm_segment_control_add(ctrlbar);
1357         g_btn_sort_by_name =
1358             elm_segment_control_item_add(segment, NULL,
1359                                          S_("IDS_COM_BODY_DETAILS_NAME"));
1360         g_btn_sort_by_time =
1361             elm_segment_control_item_add(segment, NULL, S_("IDS_COM_POP_TIME"));
1362         evas_object_show(segment);
1363         // set default sort type
1364         elm_segment_control_item_selected_set(g_btn_sort_by_name, EINA_TRUE);
1365         // register callback to segment control
1366         evas_object_smart_callback_add(segment, "changed",
1367                                        __ugview_sortbar_clicked_cb, data);
1368
1369         elm_object_part_content_set(segment_ly, "segment", segment);
1370
1371         Elm_Object_Item *item = NULL;
1372
1373         item = elm_toolbar_item_append(ctrlbar, NULL, NULL, NULL, NULL);
1374         elm_object_item_disabled_set(item, EINA_TRUE);
1375
1376         item = elm_toolbar_item_append(ctrlbar, NULL, NULL, NULL, NULL);
1377         elm_object_item_part_content_set(item, "object", segment_ly);
1378
1379         item = elm_toolbar_item_append(ctrlbar, NULL, NULL, NULL, NULL);
1380         elm_object_item_disabled_set(item, EINA_TRUE);
1381         return ctrlbar;
1382 }
1383
1384 static Evas_Object *__ugview_layout_add(Evas_Object * parent)
1385 {
1386         CLK_FUN_BEG();
1387         retv_if(!parent, NULL);
1388
1389         // create window layout
1390         Evas_Object *layout = elm_layout_add(parent);
1391         retv_if(layout == NULL, NULL);
1392
1393         elm_layout_theme_set(layout, "layout", "application", "searchbar_base");
1394         elm_object_signal_emit(layout, "elm,state,show,searchbar", "elm");
1395
1396         //elm_layout_theme_set(layout, "layout", "application", "searchbar");
1397         //elm_object_signal_emit(layout, "elm,state,show,searchbar", "elm");
1398         //evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1399         //evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, 0);
1400         //elm_bg_color_set(layout, 0, 0, 0);
1401         //elm_object_style_set(layout, "group_list");
1402         // show layout
1403         //evas_object_show(layout);
1404
1405         return layout;
1406 }
1407
1408 /**
1409  * Create add view for append new city into the selection list of worldclock
1410  *
1411  * @param[in]  parent    Evas_Object which is the parent of add view
1412  * @param[in]  data      data which used in this function
1413  * @param[in]  func      Callback function which used for invoking when exit from add view
1414  *
1415  * @return    FAILED if create add view failed.
1416  *            SUCCESS if create add view successfully.
1417  */
1418 int worldclock_ugview_add(Evas_Object * parent, void *data, Wcl_Return_Cb func)
1419 {
1420         CLK_FUN_BEG();
1421         retv_if(!data, FAILED);
1422
1423         struct appdata *ad = (struct appdata *)data;
1424         init_alphabetic_index();
1425         ad->page = WCL_PAGE_ADD;
1426         g_ad = ad;
1427         g_return_cb = func;
1428         const char *group_name = NULL;
1429         const char *title_name = NULL;
1430
1431         // select call_flag & group name by caller
1432         switch (ad->caller) {
1433         case WCL_CALLER_IS_APP_IT_SELF:
1434                 g_call_flag = CALL_FROM_MAIN_VIEW;
1435                 group_name = GRP_ADD2;
1436                 title_name = _("IDS_WCL_HEADER_SELECT_TIME_ZONE");
1437                 break;
1438         case WCL_CALLER_IS_SHARED_LIBRARY:
1439                 g_call_flag = CALL_FROM_MAIN_VIEW;
1440                 group_name = GRP_ADD2;
1441                 title_name = _("IDS_WCL_HEADER_SELECT_TIME_ZONE");
1442                 break;
1443         case WCL_CALLER_IS_UI_GADGET:
1444                 g_call_flag = CALL_FROM_UI_GADGET;
1445                 group_name = GRP_ADD2;
1446                 title_name = _("IDS_WCL_BODY_TIME_ZONE");
1447                 break;
1448         default:
1449                 break;
1450         }
1451
1452         // open data base
1453         retv_if(EINA_FALSE == worldclock_ug_data_open_database(), FAILED);
1454
1455         /* add layout */
1456         ad->add_ly = __ugview_layout_add(parent);;
1457         retv_if(ad->add_ly == NULL, FAILED);
1458
1459         /* init search data */
1460         memset(ad->search_text, 0x0, BUF_SIZE * sizeof(char));
1461
1462         /* searchbar */
1463         ad->add_search_bar = __ugview_searchbar_add(ad->add_ly, data);
1464         retv_if(ad->add_search_bar == NULL, FAILED);
1465
1466         /* load edje */
1467         ad->add_layout =
1468             worldclock_load_edj(ad->add_ly, WCL_EDJ_NAME, group_name);
1469         retv_if(ad->add_layout == NULL, FAILED);
1470         elm_object_part_content_set(ad->add_ly, "elm.swallow.content",
1471                                     ad->add_layout);
1472
1473         //ad->add_search_bar = __ugview_searchbar_add(ad->add_layout, data);
1474         //retv_if(ad->add_search_bar == NULL, FAILED);
1475
1476         // index to quick search
1477         //ad->add_index = __ugview_index_add(ad->add_layout, data);
1478
1479         // genlist
1480         ad->sort = WCL_SORT_BY_NAME;    // sory by name
1481         ad->add_genlist = __ugview_genlist_add(ad->add_layout, data);
1482         retv_if(ad->add_genlist == NULL, FAILED);
1483
1484         Evas_Object *add_sortbar = __ugview_sortbar_add(ad->navi_bar, data);
1485         retv_if(add_sortbar == NULL, FAILED);
1486
1487         // create left button
1488         Evas_Object *back_btn = elm_button_add(ad->navi_bar);
1489         elm_object_style_set(back_btn, "naviframe/end_btn/default");
1490         evas_object_smart_callback_add(back_btn, "clicked", __ugview_quit_cb,
1491                                        NULL);
1492
1493         // set segment control as title about layout
1494         Elm_Object_Item *elm_item =
1495             elm_naviframe_item_push(ad->navi_bar, title_name, back_btn, NULL,
1496                                     ad->add_ly, NULL);
1497         elm_object_item_part_content_set(elm_item, "controlbar", add_sortbar);
1498         //elm_naviframe_item_title_visible_set(elm_item, EINA_FALSE);
1499
1500         // update genlist
1501         if (g_ad->add_view_update_timer) {
1502                 ecore_timer_del(g_ad->add_view_update_timer);
1503                 g_ad->add_view_update_timer = NULL;
1504         }
1505         ad->add_view_update_timer =
1506             ecore_timer_add(0.01, __ugview_genlist_update, ad);
1507
1508         CLK_FUN_END();
1509         return SUCCESS;
1510 }
1511
1512 /**
1513  * Release all resources which used in add view when exit from add view
1514  *
1515  * @param[in]  data   data which used in this function
1516  *
1517  * @return
1518  */
1519 void worldclock_ugview_free(void *data)
1520 {
1521         CLK_FUN_BEG();
1522         ret_if(!data);
1523
1524         struct appdata *ad = (struct appdata *)data;
1525         uninit_alphabetic_index();
1526         if (ad->add_ly) {
1527                 __ugview_quit_cb(NULL, NULL, NULL);
1528         }
1529         CLK_FUN_END();
1530 }
1531
1532 #undef MAX_LEN_CITY_NAME
1533 #undef MAX_LEN_COUNTRY_NAME
1534 #undef MAX_LEN_GMT
1535 #undef MAX_LEN_INPUT