2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (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
8 * http://floralicense.org/license/
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.
20 #include <appcore-efl.h>
21 #include <Elementary.h>
24 #include <unicode/ustring.h>
25 #include <unicode/ucol.h>
27 #include "worldclock_util.h"
28 #include "worldclock_dlog.h"
29 #include "worldclock_fwk_icu.h"
30 #include "worldclock_data.h"
33 * Compare the city name of two cities
35 * @param[in] data1 record data of city1
36 * @param[in] data2 record data of city2
38 * @return -1 if city name of city2 is bigger than city1's
39 * 1 if city name of city1 is bigger than city2's
40 * 0 if city name of city2 is equal to city1, or meet error
42 int worldclock_city_compare_cb(const void *data1, const void *data2)
44 retv_if(!data1 || !data2, 0);
46 UChar bufcity1[CITY_BUF_SIZE] = { 0 };
47 UChar bufcity2[CITY_BUF_SIZE] = { 0 };
49 const Wcl_CitySet *cs1, *cs2;
51 cs1 = (const Wcl_CitySet *)data1;
52 cs2 = (const Wcl_CitySet *)data2;
54 char *city1 = _(cs1->city);
55 char *city2 = _(cs2->city);
57 u_uastrcpy(bufcity1, city1);
58 u_uastrcpy(bufcity2, city2);
60 UErrorCode status = U_ZERO_ERROR;
61 UCollator *coll = ucol_open(getenv("LANG"), &status);
62 UCollationResult ret = ucol_strcoll(coll, bufcity1, -1, bufcity2, -1);
79 * Compare timezone of two cities
81 * @param[in] data1 recorder of city1
82 * @param[in] data2 recorder of city2
84 * @return 1 if timezone of city1 is bigger than city2's
85 * 0 if timezone of city2 is equal to city1, or meet error
86 * -1 if timezone of city2 is bigger than city1's
88 int worldclock_time_compare_cb(const void *data1, const void *data2)
90 retv_if(!data1 || !data2, 0);
95 const Wcl_CitySet *cs1 = (const Wcl_CitySet *)data1;
96 const Wcl_CitySet *cs2 = (const Wcl_CitySet *)data2;
98 char buf_tz1[TIMEZONE_BUF_SIZE] = { 0, };
99 char buf_tz2[TIMEZONE_BUF_SIZE] = { 0, };
101 const char *pbegin = NULL;
102 const char *ppos = NULL;
104 g_strlcpy(buf_tz1, cs1->timezone + 3, TIMEZONE_BUF_SIZE);
106 ppos = strstr(buf_tz1, ":");
108 buf_tz1[ppos - pbegin] = '.';
111 g_strlcpy(buf_tz2, cs2->timezone + 3, TIMEZONE_BUF_SIZE);
113 ppos = strstr(buf_tz2, ":");
115 buf_tz2[ppos - pbegin] = '.';
118 float d1 = atof(buf_tz1);
119 float d2 = atof(buf_tz2);
121 // get diff between of two cities
126 } else if (diff_val < 0) {
135 * Compare sequence of two cities
137 * @param[in] data1 recorder of city1
138 * @param[in] data2 recorder of city2
140 * @return 1 if sequence of city1 is bigger than city2's
141 * 0 if sequence of city2 is equal to city1, or meet error
142 * -1 if sequence of city2 is bigger than city1's
144 int worldclock_sequence_compare_cb(const void *data1, const void *data2)
146 retv_if(!data1 || !data2, 0);
149 const Wcl_CitySet *cs1 = (const Wcl_CitySet *)data1;
150 const Wcl_CitySet *cs2 = (const Wcl_CitySet *)data2;
153 if (cs1->sequence > cs2->sequence) {
155 } else if (cs1->sequence < cs2->sequence) {
164 * Checking whether the count of city list meet the max number
166 * @param[in] ap given data used in this function
167 * @param[in] cs given city
169 * @return EINA_TRUE if list full
172 Eina_Bool worldclock_is_city_list_full(Eina_List * eina_list)
175 retv_if(!eina_list, EINA_FALSE);
176 Eina_Bool ret = EINA_FALSE;
178 int count = eina_list_count(eina_list);
179 if (count >= WORLDCLOCK_MAX_CITY_COUNT) {
180 CLK_INFO("list full, please delete some\n");
188 * Insert given city into given eina list
190 * @param[in] p_eina_list given data used in this function
191 * @param[in] cs given city
192 * @param[in] position position where the city is insert into(-1: append to list)
194 * @return -1 if not exist
196 * list-count if success,
198 int worldclock_insert_city_to_list(Eina_List ** p_eina_list, Wcl_CitySet * cs,
202 retv_if(!p_eina_list || !cs, -1);
205 count = eina_list_count(*p_eina_list);
206 if (count >= WORLDCLOCK_MAX_CITY_COUNT) {
207 CLK_INFO("list full, please delete some\n");
214 *p_eina_list = eina_list_append(*p_eina_list, cs);
217 cs->sequence = count;
218 } else if (0 == position) {
219 *p_eina_list = eina_list_prepend(*p_eina_list, cs);
222 Eina_List *el = *p_eina_list;
225 cs = (Wcl_CitySet *) el->data;
226 cs->sequence = index;
227 worldclock_data_update_db_record(cs);
237 count = eina_list_count(*p_eina_list);
244 * Remove all items in eina_list
246 * @param[in] glist given eina list
247 * @param[in] is_free_element flag to define if free data in every item is needed
249 * @return EINA_TRUE if remove successfully
251 Eina_Bool worldclock_util_glist_remove_all(Eina_List * glist,
252 Eina_Bool is_free_element)
256 if (EINA_TRUE == is_free_element) {
257 void *user_data = NULL;
258 Eina_List *tmp_list = glist;
260 user_data = tmp_list->data;
266 tmp_list = tmp_list->next;
270 eina_list_free(glist);
279 * Creat new popup window, and show it
281 * @param[in] data Data used in this function
282 * @param[in] info String displayed on popup
286 void worldclock_show_popup(Evas_Object * parent, Evas_Object ** p_popup,
290 Evas_Object *popup = *p_popup;
292 EVAS_OBJECT_DELIF(popup);
294 popup = elm_popup_add(parent);
295 evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND,
297 elm_popup_orient_set(popup, ELM_POPUP_ORIENT_CENTER);
298 elm_object_part_text_set(popup, "title", S_("IDS_COM_POP_WARNING"));
299 elm_object_text_set(popup, _(info));
300 Evas_Object *btn = elm_button_add(popup);
301 elm_object_text_set(btn, S_("IDS_COM_SK_OK"));
302 elm_object_part_content_set(popup, "button1", btn);
304 evas_object_show(popup);
307 // if exist, return EINA_TRUE, else return EINA_FALSE
309 * Check whether given city exist in given eina_list
311 * @param[in] eina_list given eina list
312 * @param[in] cs record of given city
313 * @return EINA_FALSE if not exist
316 Eina_Bool worldclock_whether_city_exist_in_eina_list(Eina_List * eina_list,
320 Wcl_CitySet *cs_tmp = NULL;
321 Eina_List *el = NULL;
326 cs_tmp = (Wcl_CitySet *) el->data;
327 if (cs_tmp->index == cs->index) {
340 * Reset now time of genlist item data
342 * @param[in] data Data used in this function
346 void worldclock_reset_now_time(Eina_List * eina_list)
351 Wcl_CitySet *cs = NULL;
353 Eina_List *el = eina_list;
355 cs = (Wcl_CitySet *) el->data;
365 * Create layout by load edj according group name from edj file
367 * @param[in] parent Parent of new layout
368 * @param[in] file EDJE file
369 * @param[in] group name of group
371 * @return NULL if meet error
372 * Pointer to new layout
374 Evas_Object *worldclock_load_edj(Evas_Object * parent, const char *file,
378 Evas_Object *eo = NULL;
381 eo = elm_layout_add(parent);
383 // set edje file & name of group
384 r = elm_layout_file_set(eo, file, group);
390 evas_object_size_hint_weight_set(eo, EVAS_HINT_EXPAND,
399 * Search word in string
400 * * Set color on the word if found
401 * * Set max length to aimed string, replace tail with ...
403 * @param[in] string source string for search
404 * @param[in] searchword word which used for search
405 * @param[in] max_len Max length of string which to display
407 * @return string which for displaying
409 const char *worldclock_searchword_in_string(const char *string,
410 char *searchword, int max_len)
413 char pstr[BUF_LARGE_SIZE] = { 0, };
414 char result_str[BUF_LARGE_SIZE] = { 0, }, start_str[BUF_LARGE_SIZE] = {
416 static char return_string[BUF_LARGE_SIZE] = { 0, };
417 int word_len = 0, search_len = 0, i = 0; //, hilight_len = 0, hilight_len_2 = 0;
418 Eina_Bool found = EINA_FALSE;
419 g_strlcpy(pstr, string, BUF_LARGE_SIZE);
420 word_len = strlen(pstr);
421 search_len = strlen(searchword);
422 if (word_len > max_len) {
423 snprintf(&pstr[max_len], BUF_LARGE_SIZE - max_len - 1, "%s",
426 for (i = 0; i < word_len; i++) {
427 if (!strncasecmp(searchword, &pstr[i], search_len)) {
432 if (EINA_TRUE == found) {
434 strncpy(result_str, &pstr[i], search_len);
435 result_str[search_len] = '\0';
436 snprintf(return_string, BUF_LARGE_SIZE,
437 "<color=#e58616>%s</color>%s", &result_str[0],
440 strncpy(start_str, &pstr[0], i);
441 start_str[i + 1] = '\0';
442 strncpy(result_str, &pstr[i], search_len);
443 result_str[search_len] = '\0';
444 snprintf(return_string, BUF_LARGE_SIZE,
445 "%s<color=#e58616>%s</color>%s", &start_str[0],
446 &result_str[0], &pstr[i + search_len]);
449 snprintf(return_string, BUF_LARGE_SIZE, "%s", pstr);
452 return return_string;
456 * This function is used to compute the length of string which displaying on entry
457 * The html flag which could change the actual length of string should be ignored.
459 * @param[in] str source string which got from entry
461 * @return The length of the displaying part about str
463 int worldclock_str_get_displaying_length(const char *str)
465 retv_if(NULL == str, -1);
466 int len = strlen(str);
468 char *pre_flag = strchr(str, '<');
472 char *end_flag = strchr(pre_flag, '>');
474 sub_num += end_flag - pre_flag;
475 pre_flag = strchr(end_flag, '<');
484 * This function is used to get the displaying of string which displaying on entry
486 * @param[in] src source string which got from entry
487 * @param[in] dst dest string which write the displaying part to
489 * @return The length of displaying part
491 int worldclock_str_get_displaying_part(const char *src, char *dst)
493 retv_if(NULL == src || NULL == dst, -1);
494 int len = strlen(src);
496 char *pre_flag = NULL;
497 char *end_flag = NULL;
498 char tmp_buf1[BUF_SIZE] = { '\0' };
499 char tmp_buf2[BUF_SIZE] = { '\0' };
501 snprintf(tmp_buf1, BUF_SIZE, src);
503 // get the first position where '<' found
504 pre_flag = strchr(tmp_buf1, '<');
507 // get the begin position of '<' found
508 int begin_pos = pre_flag - tmp_buf1;
509 snprintf(tmp_buf2, begin_pos + 1, tmp_buf1);
510 //CLK_ERR("tmp_buf2 : %s\n", tmp_buf2);
512 // get the position of '>' which match previous '<'
513 end_flag = strchr(pre_flag, '>');
515 snprintf(tmp_buf2 + begin_pos, BUF_SIZE, end_flag + 1);
516 sub_num += end_flag - pre_flag;
521 snprintf(tmp_buf1, BUF_SIZE, tmp_buf2);
522 pre_flag = strchr(tmp_buf1, '<');
523 //CLK_ERR("tmp_buf1 : %s\n", tmp_buf1);
526 snprintf(dst, BUF_SIZE, tmp_buf1);
531 * This function is used to justify whethet html flag exist in string
533 * @param[in] str source string which got from entry
535 * @return EINA_TRUE if contain html
537 Eina_Bool worldclock_str_is_contain_html(const char *str)
539 retv_if(NULL == str, EINA_FALSE);
540 Eina_Bool ret = EINA_FALSE;
542 char *pre_flag = strchr(str, '<');
552 * This function is used to convert string type from Unicode to UTF8
554 * @param[in] unichars source string whose type is Unicode
556 * @return The result string whose type is UTF8
558 char *worldclock_strToUTF8(const UChar * unichars)
560 retv_if(unichars == NULL, NULL);
565 UErrorCode status = U_ZERO_ERROR;
567 len = u_strlen(unichars);
568 len_str = sizeof(char) * 4 * (len + 1);
569 str = (char *)calloc(1, len_str);
570 retv_if(NULL == str, NULL);
572 u_strToUTF8(str, len_str, &len_utf8, unichars, len, &status);
576 /*BEG: Gong Xingsheng<x536.gong@samsung.com> add in Mon Nov 21 01:10:19 PST 2011
577 * this function is used to get dst value by cs->dst_type
579 int worldclock_dst_get(const Wcl_CitySet * cs)
583 if (cs->dst_enabled) {
584 switch (cs->dst_type) {
586 dst = worldclock_icu_dst_get(cs->tz_path);
591 case WCL_DST_2_HOURS:
603 /*END: Gong Xingsheng<x536.gong@samsung.com> add in Mon Nov 21 01:10:19 PST 2011 */
605 /* BEG:Gong Xingsheng<x536.gong@samsung.com> added Mon Nov 21 00:57:05 PST 2011
606 * this is for set date before show genlist, it is used to set dst value
607 * dst value is include three type:
608 * off : off, need to sub the dst value, which is got from icu
609 * auto : auto, get default dst value from icu
610 * user set : user set, get user set, which is saved in db
612 time_t worldclock_genlist_time_get(Wcl_CitySet * cs, void *data)
614 retv_if(!cs || !data, 0);
615 struct appdata *ad = (struct appdata *)data;
616 Wcl_CitySet *home_cs;
620 home_cs = ad->home_cs;
621 home_cs->now_time = time(NULL);
624 home_cs = worldclock_data_get_local_city();
625 retv_if(!home_cs, FAILED);
626 ad->home_cs = home_cs;
628 cs->dst = worldclock_dst_get(cs);
629 cs->now_time = home_cs->now_time;
633 time_t ntime = cs->now_time;
634 if (!cs->dst_enabled) {
635 inc = (-1) * worldclock_icu_dst_get(cs->tz_path);
636 } else if (!IS_EQUAL(cs->dst_type, WCL_DST_AUTO)) {
640 localtime_r(&ntime, &tm);
641 tm.tm_hour = (tm.tm_hour + 24 + (inc)) % 24;
647 /* END:Gong Xingsheng<x536.gong@samsung.com> added Mon Nov 21 00:57:05 PST 2011 */