apply FSL(Flora Software License)
[apps/home/smartsearch.git] / src / smartsearch.cpp
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  * 
4  * Licensed under the Flora License, Version 1.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  *     http://www.tizenopensource.org/license
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18
19
20
21
22 #include <stdio.h>
23 #include <utilX.h>
24 #include <ui-gadget.h>
25
26 #include "smartsearch.h"
27 #include "search_bar.h"
28 #include "ps_makeupviews.h"
29 #include "ps_searcher.h"
30
31 #include <contacts-svc.h>
32 #include <calendar-svc-provider.h>
33 #include <memo-db.h>
34 #include <appsvc.h>
35 #include <aul_service.h>
36
37 static int __search_app_terminate(void *data);
38
39 static void __search_win_delete_cb(void *data, Evas_Object * obj,
40                                    void *event_info)
41 {
42         SEARCH_FUNC_START;
43
44         elm_exit();
45
46         SEARCH_FUNC_END;
47 }
48
49 static Eina_Bool __search_mousedown_event(void *data, int type, void *event)
50 {
51         SEARCH_FUNC_START;
52
53         struct appdata *ad = (struct appdata *)data;
54
55         Ecore_Event_Mouse_Button *ev = (Ecore_Event_Mouse_Button *) event;
56         ad->touch_x = ev->x;
57         ad->touch_y = ev->y;
58         return ECORE_CALLBACK_CANCEL;
59 }
60
61
62 static Eina_Bool __search_keydown_event(void *data, int type, void *event)
63 {
64         SEARCH_FUNC_START;
65
66         Ecore_Event_Key *ev = (Ecore_Event_Key *) event;
67
68         if (!SEARCH_STRCMP(ev->keyname, KEY_END)) { 
69                 //end key concept is close.
70                 elm_exit();
71         }
72
73         SEARCH_FUNC_END;
74
75         return EINA_FALSE;
76 }
77
78 static Evas_Object *__search_create_layout_main(Evas_Object * parent)
79 {
80         SEARCH_FUNC_START;
81
82         Evas_Object *layout;
83         Evas_Object *bg;
84
85         SEARCH_RETV_IF(parent == NULL, NULL);
86
87         layout = elm_layout_add(parent);
88
89         SEARCH_RETV_IF(layout == NULL, NULL);
90
91         //elm_layout_theme_set(layout, "standard", "window", "integration");
92         elm_layout_theme_set(layout, "layout", "application", "default");
93
94         evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
95         evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
96         elm_win_resize_object_add(parent, layout);
97
98         bg = elm_bg_add(parent);
99         evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
100         elm_win_resize_object_add(parent, bg);
101         elm_object_part_content_set(layout, "elm.swallow.bg", bg);
102         
103     evas_object_show(bg);
104         
105         edje_object_signal_emit(_EDJ(layout), "elm,state,show,indicator","elm");
106         edje_object_signal_emit(_EDJ(layout), "elm,state,show,content", "elm");
107         evas_object_show(layout);
108
109         SEARCH_FUNC_END;
110
111         return layout;
112 }
113
114 static Evas_Object *__search_create_navigation_layout(Evas_Object * parent)
115 {
116         SEARCH_FUNC_START;
117
118         Evas_Object *navi_bar;  //, *sd;
119
120         SEARCH_RETV_IF(parent == NULL, NULL);
121
122         navi_bar = elm_naviframe_add(parent);
123
124         elm_object_part_content_set(parent, "elm.swallow.content", navi_bar);
125
126         evas_object_show(navi_bar);
127
128         SEARCH_FUNC_END;
129
130         return navi_bar;
131 }
132
133 static void __search_back_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
134 {
135         SEARCH_FUNC_START;
136         
137         struct appdata *ad = (struct appdata *)data;
138         
139                 elm_win_lower(ad->win_main);
140
141         if(ad->back_btn_type == BACK_BTN_TYPE_CLOSE)
142                 elm_exit();
143
144         SEARCH_FUNC_END;
145 }
146
147 static void __search_add_back_btn(struct appdata *ad)
148 {
149         SEARCH_FUNC_START;
150
151         Elm_Object_Item *navi_it;
152         
153         /* add back key */
154         Evas_Object *btn = elm_button_add(ad->navi_bar);
155         elm_object_style_set(btn, "naviframe/end_btn/default");
156         evas_object_smart_callback_add(btn, "clicked", __search_back_btn_clicked_cb, ad);
157
158 #ifdef __ENABLE_TOP_BACK_BTN
159         navi_it = elm_naviframe_item_push(ad->navi_bar,
160                                dgettext("sys_string", "IDS_COM_BODY_SEARCH"),
161                                NULL, NULL, ad->sb_layout, NULL);
162
163         elm_object_item_part_content_set(navi_it, "title_right_btn", btn);
164         elm_object_item_signal_emit(navi_it, "elm,state,controlbar,close", "");
165 #else
166         elm_naviframe_item_push(ad->navi_bar,
167                                dgettext("sys_string", "IDS_COM_BODY_SEARCH"),
168                                btn, NULL, ad->sb_layout, NULL);
169 #endif
170
171         ad->back_btn = btn;
172
173         SEARCH_FUNC_END;
174 }       
175
176 static int __search_init_smartsearch(struct appdata *ad)
177 {
178         SEARCH_FUNC_START;
179
180         SEARCH_RETV_IF(ad == NULL, -1);
181
182         // Base Layout
183         ad->layout_main = __search_create_layout_main(ad->win_main);
184         SEARCH_RETV_IF(ad->layout_main == NULL, -1);
185
186         // Indicator
187         elm_win_indicator_mode_set(ad->win_main, ELM_WIN_INDICATOR_SHOW);
188
189         // Navigation Bar
190         ad->navi_bar = __search_create_navigation_layout(ad->layout_main);
191
192         search_result_gl_init(ad);
193
194         search_searchbar_cb(ad, NULL, NULL);
195
196         __search_add_back_btn(ad);
197         SEARCH_FUNC_END;
198
199         return 0;
200 }
201
202 static int __search_deinit_smartsearch(struct appdata *ad)
203 {
204         SEARCH_FUNC_START;
205
206         SEARCH_RETV_IF(ad == NULL, -1);
207
208         search_result_gl_deinit(ad);
209
210         SEARCH_FUNC_END;
211
212         return 0;
213 }
214
215 static Evas_Object *__search_create_win(const char *name)
216 {
217         SEARCH_FUNC_START;
218
219         Evas_Object *eo;
220         int w, h;
221
222         eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
223         if (eo) {
224                 elm_win_title_set(eo, name);
225                 elm_win_borderless_set(eo, EINA_TRUE);
226                 evas_object_smart_callback_add(eo, "delete,request",
227                                                __search_win_delete_cb, NULL);
228                 ecore_x_window_size_get(ecore_x_window_root_first_get(), &w,
229                                         &h);
230                 evas_object_resize(eo, w, h);
231         }
232
233         SEARCH_FUNC_END;
234
235         return eo;
236 }
237
238 static int __search_init_app_connect(struct appdata *ad)
239 {
240         SEARCH_FUNC_START;
241
242         int rc = 0, conn_ret = 0, type = 0;
243         char sql_query[DB_QUERY_LEN] = { 0, };
244         int ret = SEARCH_RET_SUCCESS;
245
246         for (type = 0; type < PHONE_CATEGORY_LIST_CNT; type++) {
247
248                 switch(type) {
249
250                 case SEARCH_TYPE_PHONE_CONTACTS:
251                         {
252                                 rc = contacts_svc_connect();
253                                 if (rc != CTS_SUCCESS) {
254                                         SEARCH_DEBUG_WARNING
255                                             ("contacts svc connect fail : %d",
256                                              rc);
257                                 }
258                         }
259                         break;
260
261                 case SEARCH_TYPE_PHONE_MSG:
262                         {
263                                 MSG_ERROR_T err = MSG_SUCCESS;                          
264                                 err = msg_open_msg_handle(&ad->msg_handle);
265
266                                 if (err != MSG_SUCCESS) {
267                                         SEARCH_DEBUG_WARNING("msg_open_msg_handle error : %d", err);
268                                         ad->msg_handle = NULL;
269                                 }
270                         }
271                         break;
272                 case SEARCH_TYPE_PHONE_EMAIL:
273                         break;  
274                         
275                 /* IMAGE, MUSIC, VIDEO use common handle */
276                 case SEARCH_TYPE_PHONE_IMAGES:
277                 case SEARCH_TYPE_PHONE_MUSIC:
278                 case SEARCH_TYPE_PHONE_VIDEO:
279                         if( ad->media_handle == NULL ) {
280                                 conn_ret = media_svc_connect(&ad->media_handle);
281                                         if(conn_ret < 0) {
282                                                 SEARCH_DEBUG_WARNING("media_svc_connect failed : %d\n", conn_ret);
283                                         ad->media_handle = NULL;
284                                         }
285                         }                       
286                         break;
287                 case SEARCH_TYPE_PHONE_CALENDAR:
288                         {
289                                 rc = calendar_svc_connect();
290                                 if (rc != CAL_SUCCESS) {
291                                         SEARCH_DEBUG_WARNING
292                                             ("calendar svc connect fail : %d",
293                                              rc);
294                                 }
295                         }
296                         break;
297                 case SEARCH_TYPE_PHONE_MEMO:
298                         {
299                                 rc = memo_init(NULL);
300                                 if (rc == -1) {
301                                         SEARCH_DEBUG_WARNING
302                                             ("memo svc connect fail : %d", rc);
303                                 }
304                         }
305                         break;
306                 }       
307         }
308
309         SEARCH_FUNC_END;
310
311         return ret;
312 }
313
314 static int __search_deinit_app_disconnect(void *data)
315 {
316         SEARCH_FUNC_START;
317
318         struct appdata *ad = (struct appdata *)data;
319
320         int rc = 0, conn_ret = 0, type = 0;
321
322         for (type = 0; type < PHONE_CATEGORY_LIST_CNT; type++) {
323                 switch (type) {
324                         
325                 case SEARCH_TYPE_PHONE_CONTACTS:
326                         {
327                                 rc = contacts_svc_disconnect();
328                                 if (rc != CTS_SUCCESS) {
329                                         SEARCH_DEBUG_WARNING
330                                             ("contacts svc disconnect fail : %d",
331                                              rc);
332                                 }
333                         }
334                         break;
335                 case SEARCH_TYPE_PHONE_MSG:
336                         {
337                                 MSG_ERROR_T err = MSG_SUCCESS;                          
338                                 err = msg_close_msg_handle(&ad->msg_handle);
339
340                                 if (err != MSG_SUCCESS) {
341                                         SEARCH_DEBUG_WARNING("msg_close_msg_handle error : %d", err);
342                                 }                                                               
343
344                                 ad->msg_handle = NULL;
345                         }
346                         break;  
347                 case SEARCH_TYPE_PHONE_EMAIL:
348                         break;  
349                 case SEARCH_TYPE_PHONE_IMAGES:
350                 case SEARCH_TYPE_PHONE_MUSIC:
351                 case SEARCH_TYPE_PHONE_VIDEO:
352                         {
353                                 conn_ret = media_svc_disconnect(ad->media_handle);
354                                 if(conn_ret < 0) {
355                                         SEARCH_DEBUG_WARNING("media_svc_disconnect failed : %d\n", conn_ret);
356                                 }
357                                 ad->media_handle = NULL;
358                         }
359                         break;
360                 case SEARCH_TYPE_PHONE_CALENDAR:
361                         {
362                                 rc = calendar_svc_close();
363                                 if (rc != CAL_SUCCESS) {
364                                         SEARCH_DEBUG_WARNING
365                                             ("calendar svc disconnect fail : %d",
366                                              rc);
367                                 }
368                         }
369                         break;
370                 case SEARCH_TYPE_PHONE_MEMO:
371                         {
372                                 memo_fini();
373                         }
374                         break;
375                 }
376         }
377
378         SEARCH_FUNC_END;
379
380         return 0;
381 }
382
383 static Eina_Bool __search_init_after_ui_create(gpointer data)
384 {
385         SEARCH_FUNC_START;
386
387         struct appdata *ad = (struct appdata *)data;
388
389         ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, 
390                                                         __search_keydown_event,
391                                                         ad);
392
393         ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, 
394                                                         __search_mousedown_event,
395                                                         ad);
396
397         /* add system event callback */
398         appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE,
399                                                         search_util_date_time_format_init, 
400                                                         NULL);
401
402         UG_INIT_EFL(ad->win_main, UG_OPT_INDICATOR_ENABLE);
403
404         SEARCH_FUNC_END;
405
406         return ECORE_CALLBACK_CANCEL;
407 }
408
409 static int __search_app_create(void *data)
410 {
411         SEARCH_FUNC_START;
412
413         struct appdata *ad = (struct appdata *)data;
414
415         appcore_set_i18n(SEARCH_PACKAGE, LOCALEDIR);
416
417         ad->win_main = __search_create_win(SEARCH_PACKAGE);
418
419         SEARCH_RETV_IF(ad->win_main == NULL, -1);
420
421         evas_object_show(ad->win_main);
422
423         ad->scale_factor = elm_config_scale_get();
424
425         __search_init_smartsearch(ad);
426
427         search_util_date_time_format_init(NULL);
428
429         __search_init_app_connect(ad);
430
431         ad->idler_create_ui = ecore_idler_add(__search_init_after_ui_create, ad);
432
433         SEARCH_FUNC_END;
434
435         return 0;
436 }
437
438 static int __search_app_terminate(void *data)
439 {
440         SEARCH_FUNC_START;
441
442         struct appdata *ad = (struct appdata *)data;
443
444         if (ad->layout_main) {
445                 evas_object_del(ad->layout_main);
446                 ad->layout_main = NULL;
447         }
448
449         if (ad->win_main) {
450                 evas_object_del(ad->win_main);
451                 ad->win_main = NULL;
452         }
453
454         if(ad->idler_create_ui)
455                 ecore_idler_del(ad->idler_create_ui);
456         
457         if(ad->idler_search)
458                 ecore_idler_del(ad->idler_search);
459         
460         __search_deinit_smartsearch(ad);
461
462         __search_deinit_app_disconnect(ad);
463
464         search_util_date_time_format_deinit();
465
466         SEARCH_FREE(ad->search_word);
467         SEARCH_FREE(ad->not_markup_search_word);
468         
469         SEARCH_FUNC_END;
470
471         return 0;
472 }
473
474 static int __search_app_pause(void *data)
475 {
476         SEARCH_FUNC_START;
477
478         SEARCH_FUNC_END;
479
480         return 0;
481 }
482
483 static int __search_app_resume(void *data)
484 {
485         SEARCH_FUNC_START;
486
487         struct appdata *ad = (struct appdata *)data;
488
489         if (ad->win_main) {
490                 elm_object_focus_set(ad->back_btn, EINA_FALSE);
491         }
492         SEARCH_FUNC_END;
493
494         return 0;
495 }
496
497 static int __search_app_reset(bundle * b, void *data)
498 {
499         SEARCH_FUNC_START;
500
501         struct appdata *ad = (struct appdata *)data;
502         const char *query = NULL;
503         const char *svcname = NULL;
504         const char *category = NULL;
505         char* keyword = NULL;
506
507         Evas_Object *cate_icon;
508         int ret;
509
510         ad->back_btn_type = BACK_BTN_TYPE_LOWER;
511
512         if (b == NULL) {
513                 keyword = vconf_get_str(SMARTSEARCH_KEY_KEYWORD);
514         } else {
515                 svcname = appsvc_get_operation(b);
516                 if(svcname) {
517                         if(SEARCH_STRCMP(svcname, APPSVC_OPERATION_SEARCH) == 0) {
518                                 query = appsvc_get_data(b, APPSVC_DATA_KEYWORD);
519                         } else {
520                                 SEARCH_DEBUG_WARNING("wrong app service name : %s", svcname);
521                         }
522
523                         ad->back_btn_type = BACK_BTN_TYPE_CLOSE;
524                 } else {
525                         svcname = bundle_get_val(b, AUL_K_SERVICE_NAME);
526
527                         if(svcname) {
528                                 if(SEARCH_STRCMP(svcname, SEARCH_SVC) == 0) {
529                                         query = bundle_get_val(b, "query");
530                                 } else {
531                                         SEARCH_DEBUG_WARNING("wrong aul service name : %s", svcname);
532                                 }
533                         }
534                 }
535                                 
536                 cate_icon = search_searchbar_category_icon_add(SEARCH_TYPE_PHONE, SEARCH_CATE_BTN_IMG_TYPE_UNPRESSED, ad->sb_layout);
537                 elm_object_content_set(ad->cate_btn, cate_icon);
538
539                 /*
540                 * keyword input param is only enabled for phone search 
541                 * if there is no keyword input param, set latest search keyword for phone search
542                 */
543                 if( (query) && (strlen(query) > 0) ) {
544                         keyword = (char*)malloc(strlen(query)+1);
545                         memset(keyword, 0x00, strlen(query)+1);
546                         strncpy(keyword, query, strlen(query));
547                 } else {
548                         keyword = vconf_get_str(SMARTSEARCH_KEY_KEYWORD);
549                 }
550
551         }
552
553         if ((keyword) && (strlen(keyword) > 0)) {
554                 elm_object_text_set(ad->search_entry, keyword);
555         } else {
556                 elm_object_text_set(ad->search_entry, "");
557                 elm_object_signal_emit(ad->search_bar, "cancel,hide", "");
558
559                 search_set_result_list(ad);
560
561                 /* set focus to entry for launching ime */
562                 evas_object_show(ad->search_entry);
563                 elm_object_focus_set(ad->search_entry,EINA_TRUE);
564                 elm_object_signal_emit(ad->search_bar, "cancel,in", "");
565         }
566
567         SEARCH_FREE(keyword);
568
569         elm_entry_cursor_end_set(ad->search_entry);
570
571         if (ad->win_main)
572                 elm_win_activate(ad->win_main);
573
574         SEARCH_FUNC_END;
575
576         return 0;
577 }
578
579 int main(int argc, char *argv[])
580 {
581         SEARCH_FUNC_START;
582
583         struct appdata ad;
584         struct appcore_ops ops;
585         int ret = 0;
586         int i = 0;
587
588         ops.create = &__search_app_create;
589         ops.terminate = &__search_app_terminate;
590         ops.pause = &__search_app_pause;
591         ops.resume = &__search_app_resume;
592         ops.reset = &__search_app_reset;
593
594         memset(&ad, 0x0, sizeof(struct appdata));
595         ops.data = &ad;
596
597         for (i = 0; i < argc; i++)
598                 SEARCH_DEBUG_LOG("argv[%d] = [%s]\n", i, argv[i]);
599
600         ret = appcore_efl_main(SEARCH_PACKAGE, &argc, &argv, &ops);
601
602         SEARCH_FUNC_END;
603
604         return ret;
605 }