Update changed code
[apps/home/smartsearch.git] / src / ps_makeupviews.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 #include "smartsearch.h"
19 #include "ps_searcher.h"
20 #include "ps_app_interface.h"
21 #include <contacts-svc.h>
22 #include <calendar-svc-provider.h>
23 #include <memo-db.h>
24 #include <media_content.h>
25 #include <msg_types.h>
26 #include <msg_storage.h>
27 #include <msg.h>
28
29 struct search_thread_data {
30         struct appdata *ad;
31         char *keyword;
32         int is_search_result;
33 };
34
35 struct search_genlist_item_info* search_add_genlist_item(int type,
36                 struct search_content_object *obj, Elm_Genlist_Item_Class *itc_style, void *data,
37                 Elm_Object_Item *parent)
38 {
39         struct search_genlist_item_info *item = (struct search_genlist_item_info *)
40                                                                                         calloc(1,
41                                                                                         sizeof(struct search_genlist_item_info));
42
43         if (item) {
44                 item->type = type;
45                 item->obj = obj;
46                 item->itc_style = itc_style;
47                 item->data = data;
48                 item->parent = parent;
49         }
50
51         return item;
52 }
53
54 static void
55 ecore_exe_pipe_cb(void *data, void *buf, unsigned int size)
56 {
57         SEARCH_FUNC_START;
58
59
60         struct appdata *ad = (struct appdata *)data;
61         struct search_pipe_data *pipe_data = *((struct search_pipe_data**)buf);
62
63         struct search_content_object *obj = NULL;
64         struct search_genlist_item_info *item = NULL;
65         struct search_genlist_info *result_info = pipe_data->result_list;
66
67         int cmd = pipe_data->cmd;
68
69         SEARCH_DEBUG_LOG("Pipe Command : %d ret : %d", cmd, pipe_data->search_ret);
70
71         switch (cmd) {
72         case SEARCH_PIPE_CMD_CLEAR_GENLIST:
73                 elm_genlist_clear(ad->search_gl);
74                 break;
75         case SEARCH_PIPE_CMD_SET_LAYOUT:
76                 if (pipe_data->search_ret == SEARCH_RET_SEARCH_SUCCESS)
77                         search_layout_set_search_list(ad);
78                 else
79                         search_layout_set_search_no_result(ad);
80                 break;
81         case SEARCH_PIPE_CMD_ADD_GENLIST_PHONE:
82                 if (result_info) {
83                         if (result_info->group) {
84                                 item = result_info->group;
85                                 obj = item->obj;
86
87                                 obj->gl_result_grp = elm_genlist_item_append(ad->search_gl,
88                                                                         item->itc_style,
89                                                                         item->data,
90                                                                         NULL,
91                                                                         ELM_GENLIST_ITEM_GROUP,
92                                                                         NULL,
93                                                                         NULL);
94                                 SEARCH_FREE(item);
95                         }
96
97                         if (result_info->itemlist) {
98                                 GList *node = g_list_first(result_info->itemlist);
99
100                                 while (node != NULL) {
101                                         item = (struct search_genlist_item_info *)node->data;
102                                         obj = item->obj;
103                                         if (item) {
104                                                 elm_genlist_item_append(ad->search_gl,
105                                                                                         item->itc_style,
106                                                                                         item->data,
107                                                                                         obj->gl_result_grp,
108                                                                                         ELM_GENLIST_ITEM_NONE,
109                                                                                         search_gl_phone_result_sel,
110                                                                                         ad);
111                                                 SEARCH_FREE(item);
112                                         }
113                                         node = g_list_next(node);
114                                 }
115                                 g_list_free(result_info->itemlist);
116                                 result_info->itemlist = NULL;
117                         }
118
119                         if (result_info->more) {
120                                 item = result_info->more;
121                                 obj = item->obj;
122                                 elm_genlist_item_append(ad->search_gl,
123                                                                 item->itc_style,
124                                                                 item->data,
125                                                                 obj->gl_result_grp,
126                                                                 ELM_GENLIST_ITEM_NONE,
127                                                                 search_gl_result_more_item_append_cb,
128                                                                 ad);
129                                 SEARCH_FREE(item);
130                         }
131
132                         SEARCH_FREE(result_info);
133                 }
134                 break;
135                 }
136
137         SEARCH_FREE(pipe_data);
138         SEARCH_FUNC_END;
139 }
140
141 static Evas_Object *__search_gl_content_get_search_item_type(void *data, Evas_Object *obj, const char *part)
142                 {
143         Evas_Object *icon = NULL;
144         int icon_size = 0;
145
146         struct search_item_sel *sel_mem_info = (struct search_item_sel *)data;
147
148         if (!SEARCH_STRCMP(part, "elm.icon") || !SEARCH_STRCMP(part, "elm.icon.1")) {
149                 if (strlen(sel_mem_info->icon1_path) > 0 ) {
150                         icon = elm_icon_add(obj);
151                         icon_size = (int)(SEARCH_THUMBNAIL_SIZE * elm_scale_get());
152                         elm_icon_prescale_set(icon, icon_size);
153                         elm_icon_file_set(icon, sel_mem_info->icon1_path, NULL);
154                         evas_object_size_hint_aspect_set(icon, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
155                 }
156         } else if(!strcmp(part, "elm.icon.2")) {
157                 if (strlen(sel_mem_info->icon2_path) > 0 ) {
158                         icon = elm_icon_add(obj);
159                         icon_size = (int)(SEARCH_ICON_SIZE * elm_scale_get());
160                         elm_icon_prescale_set(icon, icon_size);
161                         elm_icon_file_set(icon, sel_mem_info->icon2_path, NULL);
162                         evas_object_size_hint_aspect_set(icon, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
163                 }
164                 }
165         return icon;
166                 }
167
168 static Eina_Bool __search_gl_state_get(void *data, Evas_Object * obj,
169                                        const char *part)
170 {
171         return EINA_FALSE;
172 }
173
174 static char *__search_gl_label_get_search_item_type(void *data, Evas_Object * obj,
175                                    const char *part)
176 {
177         if (data == NULL) {
178                 return g_strdup("");
179         }
180
181         char *buf;
182         struct search_item_sel *sel_mem_info = (struct search_item_sel *)data;
183
184         if (!SEARCH_STRCMP(part, "elm.text") || !SEARCH_STRCMP(part, "elm.text.1")) {
185                 buf = g_strdup(sel_mem_info->main_buf);
186         } else if (!SEARCH_STRCMP(part, "elm.text.sub") || !SEARCH_STRCMP(part, "elm.text.2")) {
187                 buf = g_strdup(sel_mem_info->sub_buf);
188         } else {
189                 buf = NULL;
190         }
191
192         return buf;
193 }
194
195 static char *__search_gl_label_get_normal_type(void *data, Evas_Object * obj,
196                                          const char *part)
197 {
198         char *title_string = (char*)data;
199         if(title_string)
200                 return strdup(dgettext("sys_string", title_string));
201         else
202                 return strdup("");
203 }
204
205 static char *__search_gl_label_get_group(void *data, Evas_Object * obj,
206                                          const char *part)
207 {
208         struct search_content_object *object = (struct search_content_object*)data;
209         SEARCH_DEBUG_WARNING("%s %d", object->name, object->string_type);
210         if (object) {
211                 if (object->string_type == SEARCH_STR_TYPE_APP_STRING)
212                         return strdup(gettext(object->name));
213                 else
214                         return strdup(dgettext("sys_string", object->name));
215         }
216
217                 return strdup("");
218 }
219
220 static char *__search_gl_label_get_more(void *data, Evas_Object * obj,
221                                         const char *part)
222 {
223         return strdup(gettext("IDS_SSEARCH_BODY_MORE_RESULTS"));
224 }
225
226 static void __search_gl_del_grouptitle(void *data, Evas_Object * obj)
227 {
228         SEARCH_FUNC_START;
229
230         SEARCH_FUNC_END;
231         return;
232 }
233
234 static void __search_gl_del(void *data, Evas_Object * obj)
235 {
236         struct search_item_sel *sel_mem_info = (struct search_item_sel *)data;
237
238         SEARCH_FREE(sel_mem_info);
239
240         return;
241 }
242
243 static void __search_gl_del_more_button(void *data, Evas_Object * obj)
244 {
245         struct search_item_more_sel *sel_mem_more = (struct search_item_more_sel *)data;
246
247         SEARCH_FREE(sel_mem_more);
248
249         return;
250 }
251
252 int search_app_connect(void *data)
253 {
254         SEARCH_FUNC_START;
255
256         struct appdata *ad = (struct appdata *)data;
257
258         int rc = 0, conn_ret = 0;
259         int ret = SEARCH_RET_SUCCESS;
260         int i = 0;
261
262         for (i = 0; i < SEARCH_CONT_MAX ; ++i) {
263                 switch (ad->result_obj[i].contents_type) {
264                         case SEARCH_CONT_PHONE_CONTACTS:
265                                 {
266                                         if (ad->result_obj[i].visible == EINA_TRUE) {
267                                                 rc = contacts_svc_connect();
268                                                 if (rc != CTS_SUCCESS) {
269                                                         SEARCH_DEBUG_WARNING("contacts svc connect fail : %d",rc);
270                                                 }
271                                         } else {
272                                                 rc = contacts_svc_disconnect();
273                                                 if (rc != CTS_SUCCESS) {
274                                                         SEARCH_DEBUG_WARNING("contacts svc disconnect fail : %d",rc);
275                                                 }
276                                         }
277                                 }
278                                 break;
279
280                         /* Contact-service should be conneted for display Message result.
281                            Because We should display message with contact photo
282                            if user have contact photo which have matched to tel-number of sender or receiver */
283                         case SEARCH_CONT_PHONE_MSG:
284                                 {
285                                         msg_error_t err = MSG_SUCCESS;
286
287                                         if (ad->result_obj[i].visible == EINA_TRUE) {
288
289                                                 /* Connect Contact-service if contact category status is invisible */
290                                                 if (ad->result_obj[SEARCH_CONT_PHONE_CONTACTS].visible == EINA_FALSE) {
291                                                         rc = contacts_svc_connect();
292                                                         if (rc != CTS_SUCCESS) {
293                                                                 /* If we fail to connect contact-service, display message-app icon */
294                                                                 SEARCH_DEBUG_WARNING("contacts svc connect fail : %d",rc);
295                                                         }
296                                                 }
297
298                                                 /* Connect Message-Service */
299                                                 err = msg_open_msg_handle(&ad->msg_handle);
300
301                                                 if (err != MSG_SUCCESS) {
302                                                         SEARCH_DEBUG_WARNING("msg_open_msg_handle error : %d", err);
303                                                         ad->msg_handle = NULL;
304                                                 }
305                                         } else {
306                                                 /* Disconnect Contact-service if contact category status is invisible */
307                                                 if (ad->result_obj[SEARCH_CONT_PHONE_CONTACTS].visible == EINA_FALSE) {
308                                                         rc = contacts_svc_disconnect();
309                                                         if (rc != CTS_SUCCESS)
310                                                                 SEARCH_DEBUG_WARNING("contacts svc connect fail : %d",rc);
311                                                 }
312
313                                                 /* Disconnect Message-Service */
314                                                 if (ad->msg_handle != NULL ) {
315                                                         err = msg_close_msg_handle(&ad->msg_handle);
316
317                                                         if (err != MSG_SUCCESS)
318                                                                 SEARCH_DEBUG_WARNING("msg_close_msg_handle error : %d", err);
319                                                         ad->msg_handle = NULL;
320                                                 }
321                                         }
322                                 }
323                                 break;
324                         case SEARCH_CONT_PHONE_EMAIL:
325                                 break;
326                         /* IMAGE, MUSIC, VIDEO use common handle */
327                         case SEARCH_CONT_PHONE_IMAGES:
328                         case SEARCH_CONT_PHONE_MUSIC:
329                         case SEARCH_CONT_PHONE_VIDEO:
330                                 {
331                                         if (ad->result_obj[SEARCH_CONT_PHONE_IMAGES].visible == EINA_TRUE
332                                                 || ad->result_obj[SEARCH_CONT_PHONE_MUSIC].visible == EINA_TRUE
333                                                 || ad->result_obj[SEARCH_CONT_PHONE_VIDEO].visible == EINA_TRUE ) {
334                                                 conn_ret = media_content_connect();
335
336                                                 if (conn_ret != 0)
337                                                         SEARCH_DEBUG_WARNING("media_content_connect failed : %d\n", conn_ret);
338                                         } else {
339                                                         conn_ret = media_content_disconnect();
340
341                                                         if(conn_ret < 0)
342                                                                 SEARCH_DEBUG_WARNING("media_content_disconnect failed : %d\n", conn_ret);
343                                         }
344                                 }
345                                 break;
346                         case SEARCH_CONT_PHONE_CALENDAR:
347                                 {
348                                         if (ad->result_obj[i].visible == EINA_TRUE) {
349                                                 rc = calendar_svc_connect();
350                                                 if (rc != CAL_SUCCESS) {
351                                                         SEARCH_DEBUG_WARNING
352                                                             ("calendar svc connect fail : %d",
353                                                              rc);
354                                                 }
355                                         } else {
356                                                 rc = calendar_svc_close();
357                                                 if (rc != CAL_SUCCESS) {
358                                                         SEARCH_DEBUG_WARNING
359                                                             ("calendar svc disconnect fail : %d",
360                                                              rc);
361                                                 }
362                                         }
363                                 }
364                                 break;
365                         case SEARCH_CONT_PHONE_MEMO:
366                                 {
367                                         if (ad->result_obj[i].visible == EINA_TRUE) {
368                                                 rc = memo_init(NULL);
369                                                 if (rc == -1) {
370                                                         SEARCH_DEBUG_WARNING
371                                                             ("memo svc connect fail : %d", rc);
372                                                 }
373                                         } else
374                                                 memo_fini();
375                                 }
376                                 break;
377                         }
378         }
379
380         SEARCH_FUNC_END;
381
382         return ret;
383 }
384
385 int search_app_disconnect(void *data)
386 {
387         SEARCH_FUNC_START;
388
389         struct appdata *ad = (struct appdata *)data;
390
391         int rc = 0, conn_ret = 0;
392         int i = 0;
393
394         for (i = 0; i < SEARCH_CONT_MAX ; ++i) {
395                 switch (ad->result_obj[i].contents_type) {
396                         case SEARCH_CONT_PHONE_CONTACTS:
397                                 {
398                                         rc = contacts_svc_disconnect();
399                                         if (rc != CTS_SUCCESS) {
400                                                 SEARCH_DEBUG_WARNING
401                                                     ("contacts svc disconnect fail : %d",
402                                                      rc);
403                                         }
404                                 }
405                                 break;
406                         case SEARCH_CONT_PHONE_MSG:
407                                 {
408                                         if (ad->msg_handle != NULL ) {
409                                                 msg_error_t err = MSG_SUCCESS;
410                                                 err = msg_close_msg_handle(&ad->msg_handle);
411
412                                                 if (err != MSG_SUCCESS) {
413                                                         SEARCH_DEBUG_WARNING("msg_close_msg_handle error : %d", err);
414                                                 }
415
416                                                 ad->msg_handle = NULL;
417                                         }
418                                 }
419                                 break;
420                         case SEARCH_CONT_PHONE_EMAIL:
421                                 break;
422                         case SEARCH_CONT_PHONE_IMAGES:
423                         case SEARCH_CONT_PHONE_MUSIC:
424                         case SEARCH_CONT_PHONE_VIDEO:
425                                 {
426                                         conn_ret = media_content_disconnect();
427                                         if(conn_ret != 0)
428                                                 SEARCH_DEBUG_WARNING("media_content_disconnect failed : %d\n", conn_ret);
429                                 }
430                                 break;
431                         case SEARCH_CONT_PHONE_CALENDAR:
432                                 {
433                                         rc = calendar_svc_close();
434                                         if (rc != CAL_SUCCESS) {
435                                                 SEARCH_DEBUG_WARNING
436                                                     ("calendar svc disconnect fail : %d",
437                                                      rc);
438                                         }
439                                 }
440                                 break;
441                         case SEARCH_CONT_PHONE_MEMO:
442                                 {
443                                         memo_fini();
444                                 }
445                                 break;
446                 }
447         }
448
449         SEARCH_FUNC_END;
450
451         return 0;
452 }
453
454 void search_gl_phone_result_sel(void *data, Evas_Object * obj, void *event_info)
455 {
456         SEARCH_FUNC_START;
457
458         struct appdata *ad = (struct appdata *)data;
459         struct search_item_sel *cur_category_mem;
460         Elm_Object_Item *it = (Elm_Object_Item *) event_info;
461
462         cur_category_mem =
463             (struct search_item_sel *)elm_object_item_data_get(it);
464         if (cur_category_mem == NULL) {
465                 return;
466         }
467
468         SEARCH_DEBUG_LOG("cur_category_mem->type : %d", cur_category_mem->type);
469
470         switch (cur_category_mem->type) {
471         case SEARCH_CONT_PHONE_CONTACTS:
472                 search_launch_contact_view(ad, cur_category_mem);
473                 break;
474
475         case SEARCH_CONT_PHONE_MSG:
476                 search_launch_msg_view(ad, cur_category_mem);
477                 break;
478
479         case SEARCH_CONT_PHONE_EMAIL:
480                 search_launch_email_view(ad, cur_category_mem);
481                 break;
482
483         case SEARCH_CONT_PHONE_IMAGES:
484                 search_launch_image_view(ad, cur_category_mem);
485                 break;
486
487         case SEARCH_CONT_PHONE_VIDEO:
488                 search_launch_video_view(ad, cur_category_mem);
489                 break;
490
491         case SEARCH_CONT_PHONE_MUSIC:
492                 search_launch_music_view(ad, cur_category_mem);
493                 break;
494
495         case SEARCH_CONT_PHONE_CALENDAR:
496                 search_launch_calendar_view(ad, cur_category_mem);
497                 break;
498
499         case SEARCH_CONT_PHONE_MEMO:
500                 search_launch_memo_view(ad, cur_category_mem);
501                 break;
502
503         case SEARCH_CONT_PHONE_MENU:
504                 search_launch_menu_view(ad, cur_category_mem);
505                 break;
506
507         case SEARCH_CONT_PHONE_BROWSER:
508                 search_launch_browser_view(ad, cur_category_mem);
509
510         default:
511                 break;
512         }
513
514         elm_genlist_item_selected_set(it, EINA_FALSE);
515
516         SEARCH_FUNC_END;
517 }
518
519 static int __search_gl_set_phone_search_result(struct search_content_object *obj,
520                                                                                                         int offset,
521                                                                                                         char *keyword,
522                                                                                                         void *data,
523                                                                                                         struct search_genlist_info *result_info)
524 {
525         SEARCH_FUNC_START;
526
527         int sel_cnt = SEARCH_CATEGORY_LIST_MORE_CNT + 1;
528         int func_ret = 1;
529
530         struct appdata *ad = (struct appdata *)data;
531
532         obj->mr_info.offset = offset;
533
534         if (obj->mr_info.offset == 0) {
535                 obj->mr_info.next_point = 0;
536         }
537
538         SEARCH_DEBUG_LOG("offset : %d, limit : %d keyword : %s", offset, sel_cnt, keyword);
539
540         if (obj->visible == EINA_TRUE ) {
541                 switch (obj->contents_type) {
542                         case SEARCH_CONT_PHONE_CONTACTS:
543                 {
544                         func_ret =
545                                             search_sql_contact_search_result_by_api(obj,
546                                                                     offset,
547                                                                     sel_cnt,
548                                                             keyword,
549                                                             ad,
550                                                             result_info);
551                 }
552                 break;
553
554                         case SEARCH_CONT_PHONE_MSG:
555                 {
556                         if (ad->msg_handle != NULL) {
557                         func_ret =
558                                                     search_sql_msg_search_result_by_api(obj,
559                                                                 offset,
560                                                                         sel_cnt,
561                                                             keyword,
562                                                             ad,
563                                                             result_info);
564                 }
565                 }
566                 break;
567
568                         case SEARCH_CONT_PHONE_EMAIL:
569                 {
570                         func_ret =
571                                             search_sql_email_search_result_by_api(obj,
572                                                                 offset,
573                                                                         sel_cnt,
574                                                     keyword,
575                                                     ad,
576                                                     result_info);
577                 }
578                 break;
579                         case SEARCH_CONT_PHONE_IMAGES:
580                 {
581                         func_ret =
582                                             search_sql_image_search_result_by_api(obj,
583                                                                 offset,
584                                                                         sel_cnt,
585                                                     keyword,
586                                                     ad,
587                                                     result_info);
588                 }
589                         break;
590                         case SEARCH_CONT_PHONE_MUSIC:
591                         {
592                                         func_ret =
593                                             search_sql_music_search_result_by_api(obj,
594                                                 offset,
595                                                     sel_cnt,
596                                                     keyword,
597                                                     ad,
598                                                     result_info);
599                 }
600                 break;
601                         case SEARCH_CONT_PHONE_VIDEO:
602                 {
603                         func_ret =
604                                             search_sql_video_search_result_by_api(obj,
605                                                                 offset,
606                                                                         sel_cnt,
607                                                     keyword,
608                                                     ad,
609                                                     result_info);
610                 }
611                 break;
612                         case SEARCH_CONT_PHONE_CALENDAR:
613                 {
614                         func_ret =
615                                             search_sql_calendar_search_result_by_api(obj,
616                                                                 offset,
617                                                                         sel_cnt,
618                                                     keyword,
619                                                     ad,
620                                                     result_info);
621                 }
622                 break;
623                         case SEARCH_CONT_PHONE_MEMO:
624                 {
625                         func_ret =
626                                             search_sql_memo_search_result_by_api(obj,
627                                                                         offset,
628                                                                         sel_cnt,
629                                                     keyword,
630                                                     ad,
631                                                     result_info);
632                 }
633                 break;
634                         case SEARCH_CONT_PHONE_MENU:
635                 {
636                         func_ret =
637                                             search_sql_menu_search_result_by_api(obj,
638                                                                 offset,
639                                                                         sel_cnt,
640                                                     keyword,
641                                                     ad,
642                                                     result_info);
643                 }
644                 break;
645                         case SEARCH_CONT_PHONE_BROWSER:
646                 {
647                         func_ret =
648                                                 search_sql_browser_search_result_by_api(obj,
649                                                                         offset,
650                                                                         sel_cnt,
651                                                                         keyword,
652                                                     ad,
653                                                     result_info);
654                 }
655         }
656         }
657
658         SEARCH_FUNC_END;
659         return func_ret;
660 }
661
662 static void __search_thread_heavy_cb(void *data, Ecore_Thread *th)
663 {
664         SEARCH_FUNC_START;
665
666         struct search_thread_data *thread_data = (struct search_thread_data*)data;
667         struct appdata *ad = thread_data->ad;
668         struct search_content_object *obj = NULL;
669         struct search_genlist_info *result_info = NULL;
670
671         int ret = 0;
672
673         int i = SEARCH_CONT_PHONE_MIN;
674         int category_type = 0;
675
676         SEARCH_DEBUG_LOG("Thread ID : %p Keyword : %s", th, thread_data->keyword);
677
678         thread_data->ad = ad;
679         thread_data->is_search_result = SEARCH_RET_SEARCH_NONE;
680
681         while (i <= SEARCH_CONT_PHONE_MAX) {
682                 int offset = 0;
683                 obj = &ad->result_obj[i];
684                 category_type = obj->category_type;
685
686                 if (category_type == SEARCH_OBJ_PHONE_CONTENTS) {
687                         if (ecore_thread_check(th) != EINA_TRUE) {
688                                 result_info = (struct search_genlist_info *)calloc(1, sizeof(struct search_genlist_info));
689                                 ret = __search_gl_set_phone_search_result(obj,
690                                                                 offset,
691                                                                 thread_data->keyword,
692                                                                 ad,
693                                                                 result_info);
694
695                                 if (ret == SEARCH_RET_SEARCH_SUCCESS) {
696                                         SEARCH_DEBUG_LOG("Succes to Matched result : %s %d", obj->name, ret);
697                                         thread_data->is_search_result = SEARCH_RET_SEARCH_SUCCESS;
698                                         ecore_thread_feedback(th, result_info);
699                                 } else {
700                                         SEARCH_FREE(result_info);
701                                 }
702                         }
703                 }
704                 i++;
705         }
706         SEARCH_FUNC_END;
707 }
708
709
710 static void __search_thread_feedback_cb(void *data, Ecore_Thread *th, void *msg_data)
711 {
712         SEARCH_FUNC_START;
713
714         struct search_thread_data *thread_data = (struct search_thread_data *)data;
715         struct appdata *ad = thread_data->ad;
716         struct search_genlist_info *result_list = (struct search_genlist_info *)msg_data;
717         struct search_pipe_data *pdata = NULL;
718
719         pdata = (struct search_pipe_data *)calloc(1,sizeof(struct search_pipe_data));
720         pdata->cmd = SEARCH_PIPE_CMD_ADD_GENLIST_PHONE;
721         pdata->obj = NULL;
722         pdata->result_list = result_list;
723         pdata->search_ret = thread_data->is_search_result;
724
725         if (ecore_thread_check(th) == EINA_TRUE)
726                 return;
727
728         ecore_pipe_write(ad->pipe, &pdata, sizeof(struct search_pipe_data));
729
730         SEARCH_FUNC_END;
731 }
732
733 static void __search_thread_end_cb(void *data, Ecore_Thread *th)
734 {
735         SEARCH_FUNC_START;
736
737         struct search_thread_data *thread_data = (struct search_thread_data *)data;
738         struct appdata *ad = thread_data->ad;
739         struct search_pipe_data *pdata = NULL;
740
741         pdata = (struct search_pipe_data *)calloc(1,sizeof(struct search_pipe_data));
742         pdata->cmd = SEARCH_PIPE_CMD_SET_LAYOUT;
743         pdata->search_ret = thread_data->is_search_result;
744
745         if (ecore_thread_check(th) == EINA_TRUE)
746                 return;
747
748         ecore_pipe_write(ad->pipe, &pdata, sizeof(struct search_pipe_data));
749
750         SEARCH_FREE(thread_data->keyword);
751         SEARCH_FREE(thread_data);
752
753         SEARCH_FUNC_END;
754 }
755
756 static void __search_thread_cancel_cb(void *data, Ecore_Thread *th)
757 {
758         SEARCH_FUNC_START;
759
760         struct search_thread_data *thread_data = (struct search_thread_data *)data;
761
762         SEARCH_FREE(thread_data->keyword);
763         SEARCH_FREE(thread_data);
764
765         SEARCH_FUNC_END;
766 }
767
768 void search_stop_search(void *data)
769 {
770         SEARCH_FUNC_START;
771
772         struct appdata *ad = (struct appdata *)data;
773
774         if (ad->search_thread) {
775                 ecore_thread_cancel(ad->search_thread);
776                 ad->search_thread = NULL;
777         }
778
779         if (ad->search_timer) {
780                 ecore_timer_del(ad->search_timer);
781                 ad->search_timer = NULL;
782         }
783
784         SEARCH_FUNC_END;
785 }
786
787 Ecore_Thread* search_make_result_thread(void *data)
788 {
789         SEARCH_FUNC_START;
790
791         int ret = 0;
792         Ecore_Thread *th = NULL;
793         struct appdata *ad = (struct appdata *)data;
794         struct search_thread_data *thread_data = NULL;
795
796         /* set keyword to vconf for save last search histroy */
797         ret = vconf_set_str(SMARTSEARCH_KEY_KEYWORD, ad->not_markup_search_word);
798
799         if (ret < 0)
800        SEARCH_DEBUG_WARNING("Error : set keyword to vconf");
801
802         /* Create Thread for Phone Search */
803         thread_data = (struct search_thread_data *)calloc(1, sizeof(struct search_thread_data));
804         thread_data->ad = ad;
805         thread_data->is_search_result = SEARCH_RET_SEARCH_NONE;
806         thread_data->keyword = strdup(ad->search_word);
807
808         th = ecore_thread_feedback_run(__search_thread_heavy_cb,
809                                 __search_thread_feedback_cb,
810                                 __search_thread_end_cb,
811                                 __search_thread_cancel_cb,
812                                 thread_data,
813                                 EINA_TRUE);
814
815         SEARCH_FUNC_END;
816         return th;
817 }
818
819
820 void search_result_gl_init(void *data)
821 {
822         SEARCH_FUNC_START;
823
824         struct appdata *ad = (struct appdata *)data;
825
826         ad->pipe = ecore_pipe_add(ecore_exe_pipe_cb, ad);
827         eina_lock_new(&ad->mutex);
828         eina_condition_new(&ad->condition, &ad->mutex);
829
830         Evas_Object *genlist;
831
832         if (ad->itc_pslist_1line == NULL) {
833                 ad->itc_pslist_1line = elm_genlist_item_class_new();
834                 ad->itc_pslist_1line->item_style = "1text.2";
835                 ad->itc_pslist_1line->func.text_get = __search_gl_label_get_search_item_type;
836                 ad->itc_pslist_1line->func.content_get = __search_gl_content_get_search_item_type;
837                 ad->itc_pslist_1line->func.state_get = __search_gl_state_get;
838                 ad->itc_pslist_1line->func.del = __search_gl_del;
839         }
840
841         if (ad->itc_pslist_1line_1icon == NULL) {
842                 ad->itc_pslist_1line_1icon = elm_genlist_item_class_new();
843                 ad->itc_pslist_1line_1icon->item_style = "1text.1icon.2.tb";
844                 ad->itc_pslist_1line_1icon->func.text_get = __search_gl_label_get_search_item_type;
845                 ad->itc_pslist_1line_1icon->func.content_get = __search_gl_content_get_search_item_type;
846                 ad->itc_pslist_1line_1icon->func.state_get = __search_gl_state_get;
847                 ad->itc_pslist_1line_1icon->func.del = __search_gl_del;
848         }
849
850         if (ad->itc_pslist_1line_2icon == NULL) {
851                 ad->itc_pslist_1line_2icon = elm_genlist_item_class_new();
852                 ad->itc_pslist_1line_2icon->item_style = "1text.2icon.6.tb";
853                 ad->itc_pslist_1line_2icon->func.text_get = __search_gl_label_get_search_item_type;
854                 ad->itc_pslist_1line_2icon->func.content_get = __search_gl_content_get_search_item_type;
855                 ad->itc_pslist_1line_2icon->func.state_get = __search_gl_state_get;
856                 ad->itc_pslist_1line_2icon->func.del = __search_gl_del;
857         }
858
859         if (ad->itc_pslist_2line_1icon == NULL) {
860                 ad->itc_pslist_2line_1icon = elm_genlist_item_class_new();
861                 ad->itc_pslist_2line_1icon->item_style = "2text.1icon.4.tb";
862                 ad->itc_pslist_2line_1icon->func.text_get = __search_gl_label_get_search_item_type;
863                 ad->itc_pslist_2line_1icon->func.content_get = __search_gl_content_get_search_item_type;
864                 ad->itc_pslist_2line_1icon->func.state_get = __search_gl_state_get;
865                 ad->itc_pslist_2line_1icon->func.del = __search_gl_del;
866         }
867
868         if (ad->itc_pslist_2line_2icon == NULL) {
869                 ad->itc_pslist_2line_2icon = elm_genlist_item_class_new();
870                 ad->itc_pslist_2line_2icon->item_style = "2text.2icon.4.tb";
871                 ad->itc_pslist_2line_2icon->func.text_get = __search_gl_label_get_search_item_type;
872                 ad->itc_pslist_2line_2icon->func.content_get = __search_gl_content_get_search_item_type;
873                 ad->itc_pslist_2line_2icon->func.state_get = __search_gl_state_get;
874                 ad->itc_pslist_2line_2icon->func.del = __search_gl_del;
875         }
876
877         if (ad->itc_grouptitle == NULL) {
878                 ad->itc_grouptitle = elm_genlist_item_class_new();
879                 ad->itc_grouptitle->item_style = "grouptitle";
880                 ad->itc_grouptitle->func.text_get = __search_gl_label_get_group;
881                 ad->itc_grouptitle->func.state_get = __search_gl_state_get;
882                 ad->itc_grouptitle->func.del = __search_gl_del_grouptitle;
883         }
884
885         if (ad->itc_label == NULL) {
886                 ad->itc_label = elm_genlist_item_class_new();
887                 ad->itc_label->item_style = "grouptitle";
888                 ad->itc_label->func.text_get = __search_gl_label_get_normal_type;
889                 ad->itc_label->func.state_get = __search_gl_state_get;
890                 ad->itc_label->func.del = __search_gl_del_grouptitle;
891                         }
892
893         if (ad->itc_listmore == NULL) {
894                 ad->itc_listmore = elm_genlist_item_class_new();
895                 ad->itc_listmore->item_style = "1text.2";
896                 ad->itc_listmore->func.text_get = __search_gl_label_get_more;
897                 ad->itc_listmore->func.state_get = __search_gl_state_get;
898                 ad->itc_listmore->func.del = __search_gl_del_more_button;
899         }
900
901         ad->search_gl = NULL;
902
903         genlist = elm_genlist_add(ad->navi_bar);
904
905         // To use multiline textblock/entry/editfield in genlist, set height_for_width mode
906         // then the item's height is calculated while the item's width fits to genlist width.
907         elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
908         elm_genlist_tree_effect_enabled_set(genlist, EINA_TRUE);
909
910         ad->search_gl = genlist;
911
912         evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND,
913                                          EVAS_HINT_EXPAND);
914         evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL,
915                                         EVAS_HINT_FILL);
916         SEARCH_FUNC_END;
917 }
918
919 void search_result_gl_deinit(void *data)
920 {
921         SEARCH_FUNC_START;
922
923         struct appdata *ad = (struct appdata *)data;
924
925         ecore_pipe_del(ad->pipe);
926         eina_condition_free(&ad->condition);
927         eina_lock_free(&ad->mutex);
928
929         if (ad->itc_pslist_1line != NULL)
930                 elm_genlist_item_class_free(ad->itc_pslist_1line);
931
932         if (ad->itc_pslist_1line_1icon != NULL)
933                 elm_genlist_item_class_free(ad->itc_pslist_1line_1icon);
934
935         if (ad->itc_pslist_1line_2icon != NULL)
936                 elm_genlist_item_class_free(ad->itc_pslist_2line_1icon);
937
938         if (ad->itc_pslist_2line_1icon != NULL)
939                 elm_genlist_item_class_free(ad->itc_pslist_2line_1icon);
940
941         if (ad->itc_pslist_2line_2icon != NULL)
942                 elm_genlist_item_class_free(ad->itc_pslist_2line_2icon);
943
944         if (ad->itc_grouptitle != NULL)
945                 elm_genlist_item_class_free(ad->itc_grouptitle);
946
947         if (ad->itc_label != NULL)
948                 elm_genlist_item_class_free(ad->itc_label);
949
950         if (ad->itc_listmore != NULL)
951                 elm_genlist_item_class_free(ad->itc_listmore);
952
953         SEARCH_FUNC_END;
954 }
955
956
957 void search_gl_result_more_item_append_cb(void *data, Evas_Object * obj,
958                                           void *event_info)
959 {
960         SEARCH_FUNC_START;
961
962         struct appdata *ad = (struct appdata *)data;
963         Elm_Object_Item *it = (Elm_Object_Item *) event_info;
964         struct search_pipe_data *pdata = NULL;
965         struct search_genlist_info *result_info = NULL;
966         struct search_item_more_sel *sel_more =
967             (search_item_more_sel *)elm_object_item_data_get(it);
968
969         struct search_content_object *content_obj = sel_more->obj;
970         int offset = content_obj->mr_info.next_point;
971         int ret = SEARCH_RET_SEARCH_NONE;
972
973         elm_object_item_del(it);
974
975         result_info = (struct search_genlist_info *)calloc(1, sizeof(struct search_genlist_info));
976         ret = __search_gl_set_phone_search_result(content_obj,
977                                                 offset,
978                                                 ad->search_word,
979                                                 ad,
980                                                 result_info);
981
982         pdata = (struct search_pipe_data *)calloc(1,sizeof(struct search_pipe_data));
983         pdata->cmd = SEARCH_PIPE_CMD_ADD_GENLIST_PHONE;
984         pdata->obj = NULL;
985         pdata->result_list = result_info;
986         pdata->search_ret = ret;
987         ecore_pipe_write(ad->pipe, &pdata, sizeof(struct search_pipe_data));
988
989         pdata = (struct search_pipe_data *)calloc(1,sizeof(struct search_pipe_data));
990         pdata->cmd = SEARCH_PIPE_CMD_SET_LAYOUT;
991         pdata->search_ret = ret;
992         ecore_pipe_write(ad->pipe, &pdata, sizeof(struct search_pipe_data));
993
994         SEARCH_FUNC_END;
995 }
996
997 void search_set_result_list(void *data)
998 {
999         struct appdata *ad = (struct appdata *)data;
1000         int category = ad->search_category;
1001
1002         bool is_input_keyword = false;
1003         struct search_pipe_data *pipe_data = NULL;
1004         char *text = NULL;
1005
1006         search_stop_search(ad);
1007
1008         text = elm_entry_markup_to_utf8(elm_object_text_get(ad->search_entry));
1009         SEARCH_FREE(ad->not_markup_search_word);
1010         SEARCH_FREE(ad->search_word);
1011
1012         if((text) && (strlen(text) > 0)) {
1013                 ad->not_markup_search_word = strdup(elm_object_text_get(ad->search_entry));
1014                 ad->search_word = text;
1015                 is_input_keyword = true;
1016         } else if ( category == SEARCH_CATE_PHONE) {
1017                 pipe_data = (struct search_pipe_data *)calloc(1, sizeof(struct search_pipe_data));
1018                 pipe_data->cmd = SEARCH_PIPE_CMD_SET_LAYOUT;
1019                 pipe_data->search_ret = SEARCH_RET_SEARCH_NONE;
1020                 ecore_pipe_write(ad->pipe, &pipe_data, sizeof(struct search_pipe_data));
1021                 return;
1022         }
1023
1024         /* If category is Phone, make a thread for search */
1025         pipe_data = (struct search_pipe_data *)calloc(1, sizeof(struct search_pipe_data));
1026         pipe_data->cmd = SEARCH_PIPE_CMD_CLEAR_GENLIST;
1027         ecore_pipe_write(ad->pipe, &pipe_data, sizeof(struct search_pipe_data));
1028
1029         switch(category) {
1030         case SEARCH_CATE_PHONE:
1031                 ad->search_thread = search_make_result_thread(ad);
1032                 break;
1033         }
1034 }
1035
1036 void search_layout_set_search_list(void* data)
1037 {
1038         SEARCH_FUNC_START;
1039
1040         struct appdata *ad = (struct appdata *)data;
1041
1042         if (elm_object_part_content_get(ad->sb_layout,"list_noresult")) {
1043                 elm_object_part_content_unset(ad->sb_layout,"list_noresult");
1044                 evas_object_hide(ad->noresult_view);
1045
1046                 if (ad->search_gl) {
1047                 elm_object_part_content_set(ad->sb_layout, "list", ad->search_gl);
1048                 evas_object_show(ad->search_gl);
1049         }
1050         }
1051
1052         if (ad->search_gl)
1053         elm_genlist_item_show(elm_genlist_first_item_get(ad->search_gl), ELM_GENLIST_ITEM_SCROLLTO_TOP);
1054         SEARCH_FUNC_END;
1055
1056         return;
1057 }
1058
1059 void search_layout_set_search_no_result(void* data)
1060 {
1061         SEARCH_FUNC_START;
1062
1063         struct appdata *ad = (struct appdata *)data;
1064
1065         if (elm_object_part_content_get(ad->sb_layout,"list")) {
1066                 elm_object_part_content_unset(ad->sb_layout, "list");
1067
1068                 if (ad->search_gl)
1069                 evas_object_hide(ad->search_gl);
1070
1071                 elm_object_part_content_set(ad->sb_layout,"list_noresult", ad->noresult_view);
1072                 evas_object_show(ad->noresult_view);
1073         }
1074
1075         SEARCH_FUNC_END;
1076
1077         return;
1078 }
1079
1080 int search_layout_get_content_list_set_status(void* data)
1081 {
1082         SEARCH_FUNC_START;
1083
1084         struct appdata *ad = (struct appdata *)data;
1085         int ret;
1086
1087         if (elm_object_part_content_get(ad->sb_layout,"list")) {
1088                 ret = SEARCH_RET_SUCCESS;
1089         } else {
1090                 ret = SEARCH_RET_FAIL;
1091         }
1092
1093         SEARCH_FUNC_END;
1094
1095         return ret;
1096 }
1097
1098