2 * Copyright 2012 Samsung Electronics Co., Ltd
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
8 * http://www.tizenopensource.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.
24 #include <ui-gadget.h>
26 #include "smartsearch.h"
27 #include "search_bar.h"
28 #include "ps_makeupviews.h"
29 #include "ps_searcher.h"
34 struct search_content_object_default {
37 char name[DEF_BUF_LEN];
41 char def_pkg_name[DEF_BUF_LEN];
44 struct search_category_info_default {
45 char btn_icon_path[MAX_LENGTH_PER_PATH];
46 char btn_icon_press_path[MAX_LENGTH_PER_PATH];
49 static struct search_content_object_default def_obj[SEARCH_CONT_MAX] = {
50 { 0, EINA_TRUE, "IDS_COM_BODY_CONTACTS", SEARCH_STR_TYPE_SYSTEM_STRING,
51 SEARCH_CONT_PHONE_CONTACTS, SEARCH_OBJ_PHONE_CONTENTS, "org.tizen.contacts" },
52 { 1, EINA_TRUE, "IDS_COM_BODY_MESSAGES", SEARCH_STR_TYPE_SYSTEM_STRING,
53 SEARCH_CONT_PHONE_MSG, SEARCH_OBJ_PHONE_CONTENTS, "org.tizen.message" },
54 { 2, EINA_TRUE, "IDS_COM_BODY_EMAIL", SEARCH_STR_TYPE_SYSTEM_STRING,
55 SEARCH_CONT_PHONE_EMAIL, SEARCH_OBJ_PHONE_CONTENTS, "org.tizen.email" },
56 { 3, EINA_TRUE, "IDS_COM_BODY_IMAGES", SEARCH_STR_TYPE_SYSTEM_STRING,
57 SEARCH_CONT_PHONE_IMAGES, SEARCH_OBJ_PHONE_CONTENTS, "org.tizen.image-viewer"},
58 { 4, EINA_TRUE, "IDS_COM_BODY_MUSIC", SEARCH_STR_TYPE_SYSTEM_STRING,
59 SEARCH_CONT_PHONE_MUSIC, SEARCH_OBJ_PHONE_CONTENTS, "org.tizen.music-player"},
60 { 5, EINA_TRUE, "IDS_COM_BODY_VIDEOS", SEARCH_STR_TYPE_SYSTEM_STRING,
61 SEARCH_CONT_PHONE_VIDEO, SEARCH_OBJ_PHONE_CONTENTS, "org.tizen.video-player"},
62 { 6, EINA_TRUE, "IDS_COM_BODY_CALENDAR", SEARCH_STR_TYPE_SYSTEM_STRING,
63 SEARCH_CONT_PHONE_CALENDAR, SEARCH_OBJ_PHONE_CONTENTS, "org.tizen.efl-calendar"},
64 { 7, EINA_TRUE, "IDS_COM_BODY_MEMO", SEARCH_STR_TYPE_SYSTEM_STRING,
65 SEARCH_CONT_PHONE_MEMO, SEARCH_OBJ_PHONE_CONTENTS, "org.tizen.memo"},
66 { 8, EINA_TRUE, "IDS_COM_BODY_APPLICATIONS", SEARCH_STR_TYPE_SYSTEM_STRING,
67 SEARCH_CONT_PHONE_MENU, SEARCH_OBJ_PHONE_CONTENTS, {0} },
68 { 9, EINA_TRUE, "IDS_COM_BODY_INTERNET", SEARCH_STR_TYPE_SYSTEM_STRING,
69 SEARCH_CONT_PHONE_BROWSER, SEARCH_OBJ_PHONE_CONTENTS, "org.tizen.browser"},
72 static struct search_category_info_default def_category[SEARCH_CATE_MAX] = {
73 { "B10_btn_icon_Phone.png", "B10_btn_icon_Phone_press.png" },
76 static void __search_win_delete_cb(void *data, Evas_Object * obj,
86 static Eina_Bool __search_mousedown_event(void *data, int type, void *event)
90 struct appdata *ad = (struct appdata *)data;
92 Ecore_Event_Mouse_Button *ev = (Ecore_Event_Mouse_Button *) event;
95 return ECORE_CALLBACK_CANCEL;
99 static Eina_Bool __search_keydown_event(void *data, int type, void *event)
103 Ecore_Event_Key *ev = (Ecore_Event_Key *) event;
105 if (!SEARCH_STRCMP(ev->keyname, KEY_END)) {
106 //end key concept is close.
115 static Evas_Object *__search_create_layout_main(Evas_Object * parent)
122 SEARCH_RETV_IF(parent == NULL, NULL);
124 layout = elm_layout_add(parent);
126 SEARCH_RETV_IF(layout == NULL, NULL);
128 //elm_layout_theme_set(layout, "standard", "window", "integration");
129 elm_layout_theme_set(layout, "layout", "application", "default");
131 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
132 evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
133 elm_win_resize_object_add(parent, layout);
135 bg = elm_bg_add(parent);
136 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
137 elm_win_resize_object_add(parent, bg);
138 elm_object_part_content_set(layout, "elm.swallow.bg", bg);
140 evas_object_show(bg);
142 edje_object_signal_emit(_EDJ(layout), "elm,state,show,indicator","elm");
143 edje_object_signal_emit(_EDJ(layout), "elm,state,show,content", "elm");
144 evas_object_show(layout);
151 static Evas_Object *__search_create_navigation_layout(Evas_Object * parent)
155 Evas_Object *navi_bar; //, *sd;
157 SEARCH_RETV_IF(parent == NULL, NULL);
159 navi_bar = elm_naviframe_add(parent);
161 elm_object_part_content_set(parent, "elm.swallow.content", navi_bar);
163 evas_object_show(navi_bar);
170 static void __search_back_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
174 struct appdata *ad = (struct appdata *)data;
176 elm_win_lower(ad->win_main);
178 if(ad->back_btn_type == BACK_BTN_TYPE_CLOSE)
184 static void __search_add_back_btn(struct appdata *ad)
189 Evas_Object *btn = elm_button_add(ad->navi_bar);
190 elm_object_style_set(btn, "naviframe/end_btn/default");
191 evas_object_smart_callback_add(btn, "clicked", __search_back_btn_clicked_cb, ad);
193 #ifdef __ENABLE_TOP_BACK_BTN
194 ad->navi_it = elm_naviframe_item_push(ad->navi_bar,
195 dgettext("sys_string", "IDS_COM_BODY_SEARCH"),
196 NULL, NULL, ad->sb_layout, NULL);
198 elm_object_item_part_content_set(navi_it, "title_right_btn", btn);
199 elm_object_item_signal_emit(navi_it, "elm,state,controlbar,close", "");
201 ad->navi_it = elm_naviframe_item_push(ad->navi_bar,
202 dgettext("sys_string", "IDS_COM_BODY_SEARCH"),
203 btn, NULL, ad->sb_layout, NULL);
211 static int __search_init_smartsearch(struct appdata *ad)
215 SEARCH_RETV_IF(ad == NULL, -1);
218 ad->layout_main = __search_create_layout_main(ad->win_main);
219 SEARCH_RETV_IF(ad->layout_main == NULL, -1);
222 elm_win_indicator_mode_set(ad->win_main, ELM_WIN_INDICATOR_SHOW);
225 ad->navi_bar = __search_create_navigation_layout(ad->layout_main);
227 ad->search_category = SEARCH_CATE_PHONE;
228 search_searchbar_cb(ad, NULL, NULL);
230 __search_add_back_btn(ad);
236 static void __search_init_result_object(struct appdata *ad)
242 int ret = SEARCH_RET_SEARCH_NONE;
244 ail_appinfo_h handle = NULL;
245 ail_error_e ail_ret = AIL_ERROR_OK;
248 sqlite3_stmt *sql_load = NULL;
249 sqlite3_stmt *sql_insert = NULL;
252 sql_load = ad->search_db_sql[SEARCH_STMT_GET_CATEGORY_LIST_ALL];
254 rc = sqlite3_step(sql_load);
255 if (rc != SQLITE_ROW) {
256 if (rc == SQLITE_DONE) {
257 SEARCH_DEBUG_WARNING("SELECT STEP : SQLITE_DONE. No result");
258 ret = SEARCH_RET_SEARCH_NONE;
260 SEARCH_DEBUG_ERROR("SELECT STEP FAIL : (%d)", rc);
261 ret = SEARCH_RET_SEARCH_FAIL;
264 SEARCH_DEBUG_LOG("SELECT STEP SUCCESS");
265 ret = SEARCH_RET_SEARCH_SUCCESS;
268 /* Initialize Category */
269 for( i = 0 ; i < SEARCH_CATE_MAX; ++i ) {
270 ad->category_info[i].btn_icon_path = strdup(def_category[i].btn_icon_path);
271 ad->category_info[i].btn_icon_press_path = strdup(def_category[i].btn_icon_press_path);
274 if( ret != SEARCH_RET_SEARCH_SUCCESS ) {
275 /* If db result is NULL, initialize to default setting and insert this data to DB */
276 for( i = 0; i < SEARCH_CONT_MAX ; ++i ) {
277 sql_insert = ad->search_db_sql[SEARCH_STMT_INSERT_OBJECT_INFO];
278 ad->result_obj[i].order = def_obj[i].order;
279 ad->result_obj[i].visible = def_obj[i].visible;
280 ad->result_obj[i].contents_type = def_obj[i].contents_type;
281 ad->result_obj[i].category_type = def_obj[i].category_type;
282 ad->result_obj[i].name = strdup(def_obj[i].name);
283 ad->result_obj[i].string_type = def_obj[i].string_type;
284 ad->result_obj[i].def_pkg_name = strdup(def_obj[i].def_pkg_name);
286 ail_ret = ail_package_get_appinfo(def_obj[i].def_pkg_name, &handle);
288 if (ail_ret == AIL_ERROR_OK) {
289 ret = ail_appinfo_get_str(handle, AIL_PROP_ICON_STR, &str);
291 if (ail_ret == AIL_ERROR_OK)
292 ad->result_obj[i].obj_icon_path = strdup(str);
296 search_sql_bind_text(ad->search_db_hd, sql_insert, 1, ad->result_obj[i].name);
297 search_sql_bind_int(ad->search_db_hd, sql_insert, 2, ad->result_obj[i].string_type);
298 search_sql_bind_int(ad->search_db_hd, sql_insert, 3, ad->result_obj[i].visible);
299 search_sql_bind_int(ad->search_db_hd, sql_insert, 4, ad->result_obj[i].order);
300 search_sql_bind_int(ad->search_db_hd, sql_insert, 5, ad->result_obj[i].contents_type);
301 search_sql_bind_int(ad->search_db_hd, sql_insert, 6, ad->result_obj[i].category_type);
302 search_sql_bind_text(ad->search_db_hd, sql_insert, 7, ad->result_obj[i].def_pkg_name);
304 rc = sqlite3_step(sql_insert);
306 if( sql_insert != NULL )
307 search_sql_stmt_init(sql_insert);
310 /* Copy db data to structure */
311 for(i = 0; i < SEARCH_CONT_MAX && rc == SQLITE_ROW; ++i) {
312 char *name = (char *)sqlite3_column_text(sql_load, 0);
313 int string_type = sqlite3_column_int(sql_load, 1);
314 int visible = sqlite3_column_int(sql_load, 2);
315 int order = sqlite3_column_int(sql_load, 3);
316 int contents_type = sqlite3_column_int(sql_load, 4);
317 int category_type = sqlite3_column_int(sql_load, 5);
318 char *def_pkg_name = (char *)sqlite3_column_text(sql_load, 6);
320 ad->result_obj[i].order = order;
321 ad->result_obj[i].contents_type = contents_type;
322 ad->result_obj[i].string_type = string_type;
323 ad->result_obj[i].category_type = category_type;
324 ad->result_obj[i].name = ( name != NULL ) ? strdup(name): NULL;
325 ad->result_obj[i].visible = ( visible > 0 ) ? EINA_TRUE : EINA_FALSE;
326 ad->result_obj[i].def_pkg_name = ( def_pkg_name != NULL) ?
327 strdup(def_pkg_name) : NULL;
330 ail_ret = ail_package_get_appinfo(def_pkg_name, &handle);
332 if (ail_ret == AIL_ERROR_OK) {
333 ret = ail_appinfo_get_str(handle, AIL_PROP_ICON_STR, &str);
335 if (ail_ret == AIL_ERROR_OK)
336 ad->result_obj[i].obj_icon_path = strdup(str);
340 rc = sqlite3_step(sql_load);
344 if( sql_load != NULL )
345 search_sql_stmt_init(sql_load);
346 if( sql_insert != NULL )
347 search_sql_stmt_init(sql_insert);
352 static Evas_Object *__search_create_win(const char *name)
358 eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
360 elm_win_title_set(eo, name);
361 evas_object_smart_callback_add(eo, "delete,request",
362 __search_win_delete_cb, NULL);
370 static int __search_init_db_connect(struct appdata *ad)
375 int ret = SEARCH_RET_FAIL;
377 rc = db_util_open(SEARCH_DB_PATH,
380 if (rc != SQLITE_OK) {
382 ("db_util_open error : %d (%s)\n",
384 ret = SEARCH_RET_FAIL;
387 const char *query_list[SEARCH_STMT_MAX] = { SEARCH_DB_SQL_GET_CATEGORY_LIST_ALL,
388 SEARCH_DB_SQL_INSERT_OBJECT_IFNO,
389 SEARCH_DB_SQL_UPDATE_OBJECT_INFO
392 for (i = SEARCH_STMT_GET_CATEGORY_LIST_ALL; i < SEARCH_STMT_MAX ; ++i ) {
393 SEARCH_DEBUG_LOG("query : %s\n", query_list[i]);
395 ret = search_sql_prepare_stmt(ad->search_db_hd, query_list[i],
396 &(ad->search_db_sql[i]));
405 static void __search_deinit_db_connect(struct appdata *ad)
411 for (i = SEARCH_STMT_GET_CATEGORY_LIST_ALL; i < SEARCH_STMT_MAX ; ++i ) {
412 if (ad->search_db_sql[i]) {
413 search_sql_stmt_finalize(ad->search_db_sql[i]);
414 ad->search_db_sql[i] = NULL;
418 if (ad->search_db_hd) {
419 rc = db_util_close(ad->search_db_hd);
420 if (rc != SQLITE_OK) {
422 ("db_util_close error : %d / %s",
425 SEARCH_DEBUG_LOG("db_util_close success");
427 ad->search_db_hd = NULL;
429 SEARCH_DEBUG_WARNING("db_handle(%s) is null", SEARCH_DB_PATH);
435 static Eina_Bool __search_init_after_ui_create(gpointer data)
439 struct appdata *ad = (struct appdata *)data;
441 ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
442 __search_keydown_event,
445 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
446 __search_mousedown_event,
449 /* add system event callback */
450 appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE,
451 search_util_date_time_format_init,
454 UG_INIT_EFL(ad->win_main, UG_OPT_INDICATOR_ENABLE);
458 return ECORE_CALLBACK_CANCEL;
462 static void __search_update_lang(void *data)
465 struct appdata *ad = (struct appdata *)data;
468 /* Update Text for match to current language */
470 elm_object_item_text_set(ad->navi_it,
471 dgettext("sys_string", "IDS_COM_BODY_SEARCH"));
474 elm_object_part_text_set(ad->search_bar,
476 dgettext("sys_string", "IDS_COM_BODY_SEARCH"));
477 if (ad->noresult_view)
478 elm_object_part_text_set(ad->noresult_view,
480 dgettext("sys_string", "IDS_COM_BODY_NO_SEARCH_RESULTS"));
482 if (ad->search_cancel_btn)
483 elm_object_text_set(ad->search_cancel_btn,
484 dgettext("sys_string",
485 "IDS_COM_SK_CANCEL"));
487 for (i = 0; i < SEARCH_CONT_MAX; i++) {
488 Elm_Object_Item *it = ad->result_obj[i].gl_result_grp;
489 const char *item_name = ad->result_obj[i].name;
492 elm_genlist_item_fields_update(it, "elm.text", ELM_GENLIST_ITEM_FIELD_TEXT);
498 static bool __search_app_create(void *data)
502 struct appdata *ad = (struct appdata *)data;
504 appcore_set_i18n(SEARCH_PACKAGE, LOCALEDIR);
506 ad->win_main = __search_create_win(SEARCH_PACKAGE);
508 SEARCH_RETV_IF(ad->win_main == NULL, -1);
510 evas_object_show(ad->win_main);
512 ad->scale_factor = elm_config_scale_get();
514 __search_init_smartsearch(ad);
515 search_result_gl_init(ad);
516 search_util_date_time_format_init(NULL);
518 __search_init_db_connect(ad);
519 __search_init_result_object(ad);
520 search_app_connect(ad);
522 ad->idler_create_ui = ecore_idler_add(__search_init_after_ui_create, ad);
529 static void __search_app_terminate(void *data)
533 struct appdata *ad = (struct appdata *)data;
536 if (ad->layout_main) {
537 evas_object_del(ad->layout_main);
538 ad->layout_main = NULL;
542 evas_object_del(ad->win_main);
546 if(ad->idler_create_ui)
547 ecore_idler_del(ad->idler_create_ui);
550 ecore_idler_del(ad->idler_search);
552 search_result_gl_deinit(ad);
554 search_app_disconnect(ad);
555 __search_deinit_db_connect(ad);
557 search_util_date_time_format_deinit();
559 for ( i = 0 ; i < SEARCH_CONT_MAX ; ++i ) {
560 SEARCH_FREE(ad->result_obj[i].name);
561 SEARCH_FREE(ad->result_obj[i].obj_icon_path);
562 SEARCH_FREE(ad->result_obj[i].def_pkg_name);
565 for ( i = 0 ; i < SEARCH_CATE_MAX ; ++i ) {
566 SEARCH_FREE(ad->category_info[i].btn_icon_path);
567 SEARCH_FREE(ad->category_info[i].btn_icon_press_path);
570 SEARCH_FREE(ad->search_word);
571 SEARCH_FREE(ad->not_markup_search_word);
576 static void __search_app_pause(void *data)
583 static void __search_app_resume(void *data)
587 struct appdata *ad = (struct appdata *)data;
590 elm_object_focus_set(ad->back_btn, EINA_FALSE);
595 static void __search_app_service(service_h service, void *data)
599 struct appdata *ad = (struct appdata *)data;
602 char *keyword = NULL;
603 char *operation = NULL;
605 Evas_Object *cate_icon;
608 ad->back_btn_type = BACK_BTN_TYPE_LOWER;
609 ret = service_get_operation(service, &operation);
612 SEARCH_DEBUG_WARNING("Cannot get operation!");
616 if(operation == NULL ) {
617 SEARCH_DEBUG_WARNING("Operation is NULL!");
621 SEARCH_DEBUG_LOG("SERVICE OPERATION TYPE : %s", operation);
622 if (SEARCH_STRCMP(operation, SERVICE_OPERATION_SEARCH) == 0) {
623 ret = service_get_extra_data(service, "http://tizen.org/appsvc/data/keyword", &query);
626 SEARCH_DEBUG_WARNING("Fail to Get Keyword data!");
630 if( (query) && (strlen(query) > 0) ) {
631 keyword = (char*)malloc(strlen(query)+1);
632 memset(keyword, 0x00, strlen(query)+1);
633 strncpy(keyword, query, strlen(query));
636 ad->search_category = SEARCH_CATE_PHONE;
637 ad->back_btn_type = BACK_BTN_TYPE_CLOSE;
640 /* If Operation type is not SEARCH, Initializae valute to default */
641 keyword = vconf_get_str(SMARTSEARCH_KEY_KEYWORD);
644 SEARCH_DEBUG_WARNING("Error(%d) : get current key from vconf", ret);
646 ad->search_category = SEARCH_CATE_PHONE;
649 SEARCH_DEBUG_LOG("current category : %d", ad->search_category);
651 cate_icon = search_searchbar_category_icon_add(ad->category_info[ad->search_category].btn_icon_path,
653 elm_object_content_set(ad->cate_btn, cate_icon);
655 /* set current category to vconf */
656 ad->search_category = SEARCH_CATE_PHONE;
658 if ((keyword) && (strlen(keyword) > 0)) {
659 elm_object_text_set(ad->search_entry, keyword);
661 SEARCH_DEBUG_LOG("keyword is NULL");
663 elm_object_text_set(ad->search_entry, "");
664 elm_object_signal_emit(ad->search_bar, "cancel,hide", "");
666 search_set_result_list(ad);
668 /* set focus to entry for launching ime */
669 evas_object_show(ad->search_entry);
670 elm_object_focus_set(ad->search_entry,EINA_TRUE);
671 elm_object_signal_emit(ad->search_bar, "cancel,in", "");
674 SEARCH_FREE(keyword);
675 SEARCH_FREE(operation);
678 elm_entry_cursor_end_set(ad->search_entry);
681 elm_win_activate(ad->win_main);
686 static void __search_app_lang_change(void *data)
689 struct appdata *ad = (struct appdata *)data;
691 __search_update_lang(ad);
696 int main(int argc, char *argv[])
704 app_event_callback_s event_callback;
706 event_callback.create = __search_app_create;
707 event_callback.terminate = __search_app_terminate;
708 event_callback.pause = __search_app_pause;
709 event_callback.resume = __search_app_resume;
710 event_callback.service = __search_app_service;
711 event_callback.low_memory = NULL;
712 event_callback.low_battery = NULL;
713 event_callback.device_orientation = NULL;
714 event_callback.language_changed = __search_app_lang_change;
715 event_callback.region_format_changed = NULL;
717 memset(&ad, 0x0, sizeof(struct appdata));
719 for (i = 0; i < argc; i++)
720 SEARCH_DEBUG_LOG("argv[%d] = [%s]\n", i, argv[i]);
724 return app_efl_main(&argc, &argv, &event_callback, &ad);