Apply sip back key concept in composer
[apps/home/message-app.git] / composer / src / ui-composer / msg-ui-composer-recipient-callback.c
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://floralicense.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 "msg-ui-composer-common.h"
19 #include "msg-ui-composer-util.h"
20 #include "msg-ui-composer-popup.h"
21 #include "msg-ui-composer-external.h"
22 #include "msg-ui-composer-predictsearch.h"
23 #include "msg-ui-composer-recipient.h"
24 #include "msg-ui-composer-recipient-callback.h"
25 #include "msg-ui-composer-attachment.h"
26 #include "msg-ui-composer-body.h"
27 #include "msg-ui-composer-main.h"       /*for page duration, it should be removed if more option concept is changed*/
28
29 /*==================================================================================================
30 *                                                               FUNCTION IMPLEMENTATIONS
31 *==================================================================================================*/
32 /*change number popup cb*/
33 void msg_ui_recipient_change_number_popup_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
34 {
35         D_ENTER;
36         MSG_COMPOSER_VIEW_DATA_S *cd = data;
37         D_MSG_RETM_IF(cd == NULL, "Composer Data is NULL");
38
39         RECIPIENT_S *rd = cd->recipient;
40         D_MSG_RETM_IF(rd == NULL, "Recipient Data is NULL");
41
42         MSGC_EVAS_OBJECT_DEL(rd->popup_change_number);
43         D_LEAVE;
44 }
45
46 void msg_ui_recipient_change_number_popup_list_clicked_cb(void *data, Evas_Object *obj, void *event_info)
47 {
48         D_ENTER;
49         MSG_COMPOSER_VIEW_DATA_S *cd = (MSG_COMPOSER_VIEW_DATA_S *)data;
50         D_MSG_RETM_IF(cd == NULL, "Composer Data is NULL");
51
52         RECIPIENT_S *rd = cd->recipient;
53         D_MSG_RETM_IF(rd == NULL, "recipient data Data is NULL");
54
55         RECIPIENT_ITEM_S *r_item = evas_object_data_get(obj, "selected_item");;
56         D_MSG_RETM_IF(r_item == NULL, "Recipient Data is NULL");
57
58         Elm_Object_Item *item = (Elm_Object_Item *)event_info;
59         elm_genlist_item_selected_set(item, EINA_FALSE);
60
61         CONTACT_ITEM_S *ct_item = (CONTACT_ITEM_S *)elm_object_item_data_get(item);
62         D_MSG_RETM_IF(ct_item == NULL, "ct_item is NULL");
63
64         if (g_strcmp0(r_item->recipient, ct_item->recipient) == 0) {
65                 D_MSG("same recipient %s", ct_item->recipient);
66                 MSGC_EVAS_OBJECT_DEL(rd->popup_change_number);
67                 return;
68         }
69
70         if (COMPOSER_RETURN_RECIPIENT_DUPLICATE == msg_ui_composer_recipient_duplicate_check(cd->recipient, ct_item->recipient)) {
71                 msg_ui_composer_common_tickernoti(cd, COMPOSER_TICKERNOTI_DUP_RECP);
72         } else {
73                 memset(r_item->recipient, 0x00, sizeof(r_item->recipient));
74                 strncpy(r_item->recipient, ct_item->recipient, sizeof(r_item->recipient) - 1);
75                 r_item->type = msg_ui_composer_recipient_type_get(r_item->recipient);
76                 msg_ui_composer_message_type_check_and_change(cd);
77         }
78
79         MSGC_EVAS_OBJECT_DEL(rd->popup_change_number);
80         return;
81 }
82
83 static char *__contact_type_string_get(int type, int contact_type)
84 {
85         static char return_string[DEF_BUF_LEN + 1] = { 0, };
86         memset(return_string, 0, DEF_BUF_LEN + 1);
87
88         if (type == COMPOSER_ADDR_TYPE_NUMBER) {
89                 switch (contact_type) {
90                 case CONTACTS_NUMBER_TYPE_HOME:
91                         strncpy(return_string, _SYSSTR("IDS_COM_BODY_HOME"), sizeof(return_string) - 1);
92                         break;
93                 case CONTACTS_NUMBER_TYPE_WORK:
94                         strncpy(return_string, _SYSSTR("IDS_COM_BODY_WORK"), sizeof(return_string) - 1);
95                         break;
96                 case CONTACTS_NUMBER_TYPE_CELL:
97                         strncpy(return_string, _SYSSTR("IDS_COM_BODY_MOBILE"), sizeof(return_string) - 1);
98                         break;
99                 default:
100                         strncpy(return_string, _MSGSTR("IDS_MSGF_BODY_OTHER"), sizeof(return_string) - 1);
101                         break;
102                 }
103         } else if (type == COMPOSER_ADDR_TYPE_EMAIL) {
104                 switch (contact_type) {
105                 case CONTACTS_EMAIL_TYPE_HOME:
106                         strncpy(return_string, _SYSSTR("IDS_COM_BODY_HOME"), sizeof(return_string) - 1);
107                         break;
108                 case CONTACTS_EMAIL_TYPE_WORK:
109                         strncpy(return_string, _SYSSTR("IDS_COM_BODY_WORK"), sizeof(return_string) - 1);
110                         break;
111                 default:
112                         strncpy(return_string, _MSGSTR("IDS_MSGF_BODY_OTHER"), sizeof(return_string) - 1);
113                         break;
114                 }
115         } else {
116                 D_EMSG("Invalid number type !!!");
117                 strncpy(return_string, _MSGSTR("IDS_MSGF_BODY_OTHER"), sizeof(return_string) - 1);
118         }
119
120         return return_string;
121 }
122
123 char *msg_ui_recipient_change_number_gl_text_get(void *data, Evas_Object *obj, const char *part)
124 {
125         D_MSG_RETVM_IF(data == NULL, NULL, "data param is NULL");
126         CONTACT_ITEM_S *ct_item = (CONTACT_ITEM_S *)data;
127
128         if (!strcmp(part, "elm.text.1")) {
129                 return strdup(ct_item->recipient);
130         } else {
131                 return strdup(__contact_type_string_get(ct_item->type, ct_item->contact_type));
132         }
133 }
134
135 void msg_ui_recipient_change_number_gl_del(void *data, Evas_Object *obj)
136 {
137         D_MSG_RETM_IF(data == NULL, "RECIPIENT_ITEM_S data is NULL");
138         CONTACT_ITEM_S *ct_item = (CONTACT_ITEM_S *)data;
139
140         if (ct_item)
141                 free(ct_item);
142 }
143
144 /*select popup cb*/
145 void msg_ui_recipient_select_popup_list_clicked_cb(void *data, Evas_Object *obj, void *event_info)
146 {
147         D_ENTER;
148         MSG_COMPOSER_VIEW_DATA_S *cd = (MSG_COMPOSER_VIEW_DATA_S *)data;
149         RECIPIENT_S *rd = cd->recipient;
150         D_MSG_RETM_IF(rd == NULL, "Recipient Data is NULL");
151
152         Elm_Object_Item *item = (Elm_Object_Item *)event_info;
153         elm_list_item_selected_set(item, EINA_FALSE);
154
155         elm_multibuttonentry_item_selected_set(rd->sel_mbe_item, EINA_FALSE);
156
157         char *label = (char *)elm_object_item_text_get(item);
158
159         if (cd->isAppControl) {
160                 if (!strcmp(label, _SYSSTR("IDS_COM_OPT_DELETE"))) {
161                         msg_ui_composer_recipient_selected_delete(cd);
162                 } else if (!strcmp(label,_SYSSTR("IDS_COM_BODY_EDIT"))) {
163                         msg_ui_composer_recipient_selected_edit(cd);
164                 } else {
165                         D_EMSG("Invalid list type!!");
166                 }
167         } else {
168                 if (!strcmp(label, _SYSSTR("IDS_COM_OPT_DELETE"))) {
169                         msg_ui_composer_recipient_selected_delete(cd);
170                 } else if (!strcmp(label,_SYSSTR("IDS_COM_BODY_EDIT"))) {
171                         msg_ui_composer_recipient_selected_edit(cd);
172                 } else if (!strcmp(label, _MSGSTR("IDS_MSGC_OPT_USE_OTHER_CONTACT_INFO_ABB"))) {
173                         msg_ui_composer_recipient_create_change_number_popup(cd);
174                 } else if (!strcmp(label, _MSGSTR("IDS_MSGC_OPT_VIEW_CONTACT"))) {
175                         RECIPIENT_ITEM_S *r_item = msg_ui_composer_recipient_selected_item_data_get(cd);
176                         msg_ui_composer_launch_contact_detail_ug(cd, r_item->index);
177
178                         /* set focus to back_btn to resolve invalid focus tree issue */
179                         elm_object_focus_set(cd->back_btn, EINA_TRUE);
180                 } else if (!strcmp(label, _SYSSTR("IDS_COM_OPT_ADD_TO_CONTACTS"))) {
181                         RECIPIENT_ITEM_S *r_item = msg_ui_composer_recipient_selected_item_data_get(cd);
182                         int type = MSG_CT_UG_REQUEST_UPDATE_WITH_NUM;
183
184                         if (IsVaildEmailAddress(r_item->recipient))
185                                 type = MSG_CT_UG_REQUEST_UPDATE_WITH_EMAIL;
186
187                         msg_ui_composer_launch_contact_list_ug(cd, type, r_item->recipient);
188
189                         /* set focus to back_btn to resolve invalid focus tree issue */
190                         elm_object_focus_set(cd->back_btn, EINA_TRUE);
191                 } else {
192                         D_EMSG("Invalid list type!!");
193                 }
194         }
195
196         rd->sel_r_item = NULL;
197         rd->sel_mbe_item = NULL;
198         MSGC_EVAS_OBJECT_DEL(rd->popup_selected);
199
200         D_LEAVE;
201 }
202
203 void msg_ui_recipient_select_popup_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
204 {
205         D_ENTER;
206         MSG_COMPOSER_VIEW_DATA_S *cd = (MSG_COMPOSER_VIEW_DATA_S *)data;
207         RECIPIENT_S *rd = cd->recipient;
208
209         elm_multibuttonentry_item_selected_set(rd->sel_mbe_item, EINA_FALSE);
210         rd->sel_r_item = NULL;
211         rd->sel_mbe_item = NULL;
212         MSGC_EVAS_OBJECT_DEL(rd->popup_selected);
213
214         D_LEAVE;
215 }
216
217 void msg_ui_recipient_contact_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
218 {
219         D_ENTER;
220
221         MSG_COMPOSER_VIEW_DATA_S *cd = data;
222         D_MSG_RETM_IF(cd == NULL, "Composer Data is NULL");
223         /*set focus to back_btn to resolve invalid focus tree issue regarding contact_btn show/hide*/
224         elm_object_focus_set(cd->back_btn, EINA_TRUE);
225         msg_ui_composer_external_call(cd, COMPOSER_EXT_TYPE_CONTACT_PHONEUI, NULL);
226
227         D_LEAVE;
228 }
229
230 /* multibuttonentry cb */
231 void msg_ui_recipient_mbe_focused_cb(void *data, Evas_Object *obj, void *event_info)
232 {
233         D_ENTER;
234         MSG_COMPOSER_VIEW_DATA_S *cd = NULL;
235         RECIPIENT_S *rd = NULL;
236         PREDICTSEARCH_S *ps = NULL;
237
238         cd = data;
239         D_MSG_RETM_IF(cd == NULL, "Composer Data is NULL");
240
241         rd = cd->recipient;
242         D_MSG_RETM_IF(rd == NULL, "Recipient Data is NULL");
243
244         ps = cd->predictsearch;
245         D_MSG_RETM_IF(rd == NULL, "Predict Data is NULL");
246
247         msg_ui_composer_last_focused_entry_set(cd, obj);
248         /* it is added to prevent unfocused_cb of entry on mbe */
249         Elm_Object_Item *item = elm_multibuttonentry_selected_item_get(obj);
250         elm_multibuttonentry_item_selected_set(item, EINA_FALSE);
251
252         elm_multibuttonentry_expanded_set(obj, EINA_TRUE);
253
254         if (!cd->isAppControl || !cd->isEmulator)
255                 edje_object_signal_emit(_EDJ(rd->ly_to), "show.ct_button", "*");
256
257         D_LEAVE;
258 }
259
260 void msg_ui_recipient_mbe_unfocused_cb(void *data, Evas_Object *obj, void *event_info)
261 {
262         D_ENTER;
263         MSG_COMPOSER_VIEW_DATA_S *cd = data;
264         D_MSG_RETM_IF(cd == NULL, "Composer Data is NULL");
265         RECIPIENT_S *rd = cd->recipient;
266
267         /*If it exist Selected item popup, then it should not shrink mode set == 1*/
268         if (msg_ui_composer_popup_exist(cd) == EINA_TRUE)
269                 return;
270
271         elm_multibuttonentry_expanded_set(obj, EINA_FALSE);
272
273         if (!cd->isAppControl || !cd->isEmulator)
274                 edje_object_signal_emit(_EDJ(rd->ly_to), "hide.ct_button", "*");
275
276         D_LEAVE;
277 }
278
279 void msg_ui_recipient_mbe_clicked_cb(void *data, Evas_Object *obj, void *event_info)
280 {
281         D_ENTER;
282         MSG_COMPOSER_VIEW_DATA_S *cd = data;
283         D_MSG_RETM_IF(cd == NULL, "Composer Data is NULL");
284
285         /* reset hide_keypad_op */
286         cd->hide_keypad_op = false;
287
288         int attach_count = msg_ui_composer_get_attach_count(cd);
289
290         if (attach_count > 1)
291                 msg_ui_composer_contract_attach_list(cd);
292
293         if(msg_ui_composer_popup_exist(cd) == EINA_TRUE) {
294                 msg_ui_composer_popup_focus(cd);
295                 return;
296         }
297
298         D_LEAVE;
299 }
300
301 void msg_ui_recipient_mbe_item_clicked_cb(void *data, Evas_Object *obj, void *event_info)
302 {
303         D_ENTER;
304         MSG_COMPOSER_VIEW_DATA_S *cd = data;
305         D_MSG_RETM_IF(cd == NULL, "Composer Data is NULL");
306
307         RECIPIENT_S *rd = cd->recipient;
308         D_MSG_RETM_IF(rd == NULL, "Recipient Data is NULL");
309
310         Elm_Object_Item *item = (Elm_Object_Item *)event_info;
311         D_MSG_RETM_IF(item == NULL, "Selected Object Item is NULL");
312
313         RECIPIENT_ITEM_S *r_item;
314
315         r_item = elm_object_item_data_get(item);
316         if (r_item == NULL) {
317                 D_MSG("There are no item data");
318                 return;
319         }
320
321         rd->sel_r_item = r_item;
322         rd->sel_mbe_item = item;
323         msg_ui_composer_last_focused_entry_set(cd, rd->mbe);
324         msg_ui_composer_recipient_select_popup_create(cd);
325
326         D_LEAVE;
327 }
328
329 Eina_Bool msg_ui_recipient_mbe_item_verify_cb(Evas_Object *obj, const char *item_label, const void *item_data, const void *data)
330 {
331         D_ENTER;
332         D_MSG_RETVM_IF(item_label == NULL, EINA_FALSE, "item_label is NULL");
333
334         MSG_COMPOSER_VIEW_DATA_S *cd = (MSG_COMPOSER_VIEW_DATA_S *)data;
335         D_MSG_RETVM_IF(cd == NULL, EINA_FALSE, "Composer Data is NULL");
336
337         RECIPIENT_S *rd = cd->recipient;
338         D_MSG_RETVM_IF(rd == NULL, EINA_FALSE, "Recipient Data is NULL");
339
340         RECIPIENT_ITEM_S *r_item = NULL;
341
342         if (cd->state == COMPOSER_STATE_TYPE_PAUSE)
343                 return EINA_FALSE;
344
345         msg_ui_composer_recipient_addr_type_set(rd, COMPOSER_RECP_ADDR_NONE);
346
347         /*Check recipient count*/
348         int r_count = msg_ui_composer_recipient_count_get(rd);
349         if (r_count >= COMPOSER_RECIPIENT_COUNT_MAX) {
350                 D_EMSG("recipient is over max count %d ", COMPOSER_RECIPIENT_COUNT_MAX);
351                 msg_ui_composer_common_tickernoti(cd, COMPOSER_TICKERNOTI_COUNT_MAX);
352                 msg_ui_composer_recipient_entry_text_set(rd, "");
353                 return EINA_FALSE;
354         }
355
356         if (item_data) {
357                 D_MSG("This is a checked item before append");
358                 return EINA_TRUE;
359         }
360
361         if (msg_ui_composer_recipient_duplicate_check(cd->recipient, item_label) == COMPOSER_RETURN_RECIPIENT_DUPLICATE) {
362                 D_EMSG("Input recipient is duplication");
363                 msg_ui_composer_common_tickernoti(cd, COMPOSER_TICKERNOTI_DUP_RECP);
364                 msg_ui_composer_recipient_entry_text_set(rd, "");
365                 return EINA_FALSE;
366         }
367
368         r_item = msg_ui_composer_recipient_item_make_by_string(item_label);
369         if (r_item == NULL)
370                 return EINA_FALSE;
371
372         if (r_item->type == COMPOSER_RECP_ADDR_INVALID) {
373                 D_EMSG("recipient is invalid recipient");
374                 msg_ui_composer_recipient_addr_type_set(rd, COMPOSER_RECP_ADDR_INVALID);
375
376                 if (rd->notify_popup_idler) {
377                         ecore_idler_del(rd->notify_popup_idler);
378                         rd->notify_popup_idler = NULL;
379                 }
380                 rd->notify_popup_idler = ecore_idler_add(msg_ui_composer_recipient_show_invalid_address_popup, cd);
381
382                 g_free(r_item);
383                 return EINA_FALSE;
384         }
385
386         g_free(r_item);
387         D_LEAVE;
388         return EINA_TRUE;
389 }
390
391 void msg_ui_recipient_mbe_item_added_cb(void *data, Evas_Object *obj, void *event_info)
392 {
393         D_ENTER;
394         MSG_COMPOSER_VIEW_DATA_S *cd = (MSG_COMPOSER_VIEW_DATA_S *)data;;
395         D_MSG_RETM_IF(cd == NULL, "Composer Data is NULL");
396
397         Elm_Object_Item *item = (Elm_Object_Item *)event_info;
398         D_MSG_RETM_IF(item == NULL, "Mbe item is NULL");
399
400         RECIPIENT_ITEM_S *recipient_item = NULL;
401
402         if (elm_object_item_data_get(item) == NULL) {
403                 char *bt_label = elm_entry_markup_to_utf8(elm_object_item_text_get(item));
404                 if (bt_label) {
405                         recipient_item = msg_ui_composer_recipient_item_make_by_string(bt_label);
406                         if (recipient_item) {
407                                 elm_object_item_text_set(item, recipient_item->display_name);
408                                 elm_object_item_data_set(item, recipient_item);
409                         } else {
410                                 elm_object_item_del(item);
411                         }
412
413                         g_free(bt_label);
414                 } else {
415                         D_EMSG("button label is null");
416                 }
417         } else {
418                 recipient_item = elm_object_item_data_get(item);
419                 D_MSG(" recipient_item index [%d], recipient_item recipient [%s], recipient_item display_name [%s], recipient_item->image_path [%s]", recipient_item->index, recipient_item->recipient, recipient_item->display_name, recipient_item->image_path);
420         }
421
422         if (recipient_item) {
423                 if (recipient_item->type == COMPOSER_RECP_ADDR_VALID_NUMBER || recipient_item->type == COMPOSER_RECP_ADDR_VALID_EMAIL) {
424                         msg_ui_composer_message_type_check_and_change(cd);
425                 } else {
426                         D_EMSG("Invalid recipient added!!");
427                 }
428         } else {
429                 D_EMSG("No recipient item");
430         }
431 }
432
433 void msg_ui_recipient_mbe_item_deleted_cb(void *data, Evas_Object *obj, void *event_info)
434 {
435         D_ENTER;
436         MSG_COMPOSER_VIEW_DATA_S *cd = (MSG_COMPOSER_VIEW_DATA_S *)data;;
437         D_MSG_RETM_IF(cd == NULL, "Composer Data is NULL");
438
439         RECIPIENT_ITEM_S *recipient_item = elm_object_item_data_get(event_info);
440         D_MSG_RETM_IF(recipient_item == NULL,"reicpient item is NULL");
441
442         D_MSG("===== START of recipient_item free =====");
443         D_MSG("recipient_item index [%d]", recipient_item->index);
444         D_MSG("recipient_item recipient [%s]", recipient_item->recipient);
445         D_MSG("recipient_item display_name [%s]", recipient_item->display_name);
446         D_MSG("===== END of recipient_item free =====");
447         g_free(recipient_item);
448
449         msg_ui_composer_message_type_check_and_change(cd);
450         D_LEAVE;
451 }
452
453 static Eina_Bool __move_to_scroll_end(void *data)
454 {
455         D_ENTER;
456         RECIPIENT_S *rd = (RECIPIENT_S *)data;
457         D_MSG_RETVM_IF(rd == NULL, EINA_FALSE, "recipient data is NULL");
458
459         rd->scroll_down_idler = NULL;
460
461         Evas_Coord scr_w;
462         Evas_Coord scr_h;
463         Evas_Coord box_h;
464         evas_render(evas_object_evas_get(rd->bx_main));
465
466         elm_scroller_region_get(rd->sc, NULL, NULL, &scr_w, &scr_h);
467         D_PRINT("scroller region w = %d, h = %d ", scr_w, scr_h);
468
469         evas_object_geometry_get(rd->mbe, NULL, NULL, NULL, &box_h);
470         D_PRINT("mbe geometry h = %d ", box_h);
471
472         elm_scroller_region_show(rd->sc, 0, box_h - scr_h, scr_w, scr_h);
473         D_PRINT("scroller region show x = %d, y = %d, w = %d, h = %d ", 0, box_h - scr_h, scr_w, scr_h);
474
475         D_LEAVE;
476         return EINA_FALSE;
477 }
478
479 void msg_ui_recipient_mbe_expanded_cb(void *data, Evas_Object *obj, void *event_info)
480 {
481         D_ENTER;
482         RECIPIENT_S *rd = (RECIPIENT_S *)data;
483         D_MSG_RETM_IF(rd == NULL, "recipient data is NULL");
484
485         if (rd->scroll_down_idler) {
486                 ecore_idler_del(rd->scroll_down_idler);
487                 rd->scroll_down_idler = NULL;
488         }
489
490         int r_count = msg_ui_composer_recipient_count_get(rd);
491         if (r_count > 1)
492                 rd->scroll_down_idler = ecore_idler_add(__move_to_scroll_end, rd);
493
494         D_LEAVE;
495 }
496
497 void msg_ui_recipient_mbe_contracted_cb(void *data, Evas_Object *obj, void *event_info)
498 {
499         D_ENTER;
500         RECIPIENT_S *rd = (RECIPIENT_S *)data;
501         D_MSG_RETM_IF(rd == NULL, "recipient data is NULL");
502
503         if (rd->scroll_down_idler) {
504                 ecore_idler_del(rd->scroll_down_idler);
505                 rd->scroll_down_idler = NULL;
506         }
507
508         D_LEAVE;
509 }
510
511 void msg_ui_recipient_mbe_delete_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
512 {
513         D_ENTER;
514         D_MSG_RETM_IF(obj == NULL,"Mbe object is NULL point");
515
516         RECIPIENT_ITEM_S *r_item;
517         Elm_Object_Item *mbe_item = elm_multibuttonentry_first_item_get(obj);
518
519         D_MSG("===== START of mbe_items free =====");
520         while (mbe_item) {
521                 r_item = elm_object_item_data_get(mbe_item);
522                 if (r_item) {
523                         D_MSG("===== START of r_item free =====");
524                         D_MSG("r_item index [%d]", r_item->index);
525                         D_MSG("r_item recipient [%s]", r_item->recipient);
526                         D_MSG("r_item display_name [%s]", r_item->display_name);
527                         D_MSG("===== END of r_item free =====");
528                         g_free(r_item);
529                 }
530
531                 mbe_item = elm_multibuttonentry_item_next_get(mbe_item);
532         }
533         D_MSG("===== END of mbe_items free =====");
534
535         D_LEAVE;
536 }
537
538 static void __msg_ui_recipient_process_delimiter_char(void *data, char *full_str, char **text, int type)
539 {
540         D_ENTER;
541
542         MSG_COMPOSER_VIEW_DATA_S *cd = (MSG_COMPOSER_VIEW_DATA_S *)data;
543         D_MSG_RETM_IF(cd == NULL, "Composer Data is NULL");
544         D_MSG_RETM_IF(full_str == NULL, "param is NULL");
545
546         RECIPIENT_S *rd = cd->recipient;
547         D_MSG_RETM_IF(rd == NULL, "Recipient Data is NULL");
548
549         int full_str_len = strlen(full_str);
550         bool is_required_parsing = false;
551
552         if (full_str_len < 1) {
553                 D_EMSG("full_str_len is %d", full_str_len);
554                 return;
555         }
556
557         if (type == RECIPIENT_PARSING_TYPE_ENTER_KEY) { /*enter key case*/
558                 is_required_parsing = true;
559         } else {
560                 /* check last character is either ',' or ';' */
561                 if (full_str[full_str_len - 1] == ',' || full_str[full_str_len - 1] == ';') {
562                         D_MSG("full_str [%s]", full_str);
563
564                         /* remove last ',' or ';' */
565                         full_str[full_str_len - 1] = '\0';
566                         --full_str_len;
567
568                         is_required_parsing = true;
569                 }
570         }
571
572         if (is_required_parsing) {
573                 /* parse full str with delimeter , ; */
574                 gchar **split_str = NULL;
575                 split_str = g_strsplit_set(full_str, ",;", -1);
576
577                 if (split_str) {
578                         int count = g_strv_length(split_str);
579                         int i = 0;
580                         MSG_BOOL is_added = FALSE;
581                         MSG_BOOL is_count_max = FALSE;
582                         MSG_BOOL *is_used_list = NULL;
583
584                         D_MSG("splitted string count = %d", count);
585
586                         is_used_list = (MSG_BOOL *)calloc(count, sizeof(MSG_BOOL));
587
588                         if (is_used_list) {
589                                 for (i = 0; i < count; i++) {
590                                         D_MSG("%dth string is [%s]", i+1, split_str[i]);
591
592                                         if (split_str[i] && strlen(split_str[i])) {
593                                                 if (msg_ui_composer_recipient_vaild_check(split_str[i]) == EINA_TRUE) {
594                                                         /*Check recipient count*/
595                                                         int r_count = msg_ui_composer_recipient_count_get(rd);
596                                                         if (r_count >= COMPOSER_RECIPIENT_COUNT_MAX) {
597                                                                 D_EMSG("recipient is over max count %d ", COMPOSER_RECIPIENT_COUNT_MAX);
598                                                                 is_count_max = TRUE;
599                                                                 is_added = TRUE;
600                                                                 is_used_list[i] = TRUE;
601                                                                 continue;
602                                                         }
603
604                                                         if (msg_ui_composer_recipient_duplicate_check(rd, split_str[i]) == COMPOSER_RETURN_RECIPIENT_DUPLICATE) {
605                                                                 D_EMSG("Input recipient is duplicated");
606                                                                 is_added = TRUE;
607                                                                 is_used_list[i] = TRUE;
608                                                                 continue;
609                                                         }
610
611                                                         if (msg_ui_composer_recipient_append(cd->recipient, split_str[i], 0) == COMPOSER_RETURN_SUCCESS) {
612                                                                 is_added = TRUE;
613                                                                 is_used_list[i] = TRUE;
614                                                         }
615                                                 }
616                                         }
617                                 }
618
619                                 if (is_count_max)
620                                         msg_ui_composer_common_tickernoti(cd, COMPOSER_TICKERNOTI_COUNT_MAX);
621
622                                 /* re-assemble string */
623                                 if (is_added) {
624                                         char *re_assembled_str = NULL;
625
626                                         re_assembled_str = (char *)calloc(full_str_len + 1, sizeof(char));
627
628                                         if (re_assembled_str) {
629                                                 for (i = 0; i < count - 1; i++) {
630                                                         if (split_str[i] && strlen(split_str[i])) {
631                                                                 if (!is_used_list[i]) {
632                                                                         strncat(re_assembled_str, split_str[i], strlen(split_str[i]));
633                                                                         strncat(re_assembled_str, ",", 1);
634                                                                 }
635                                                         } else {
636                                                                 strncat(re_assembled_str, ",", 1);
637                                                         }
638                                                 }
639                                                 /* append last parsted string */
640                                                 if (split_str[i] && strlen(split_str[i])) {
641                                                         if (!is_used_list[i])
642                                                                 strncat(re_assembled_str, split_str[i], strlen(split_str[i]));
643                                                 }
644
645                                                 /* remove ',' ';' of last position */
646                                                 int str_len = strlen(re_assembled_str);
647                                                 if (str_len > 1) {
648                                                         while (re_assembled_str[str_len - 1] == ',' || re_assembled_str[str_len - 1] == ';') {
649                                                                 re_assembled_str[str_len - 1] = '\0';
650                                                                 --str_len;
651
652                                                                 if (str_len == 0)
653                                                                         break;
654                                                         }
655                                                 }
656
657                                                 D_MSG("reassembeld str = [%s]", re_assembled_str);
658                                                 /*set re-assembed str to text */
659                                                 Evas_Object *entry = elm_multibuttonentry_entry_get(rd->mbe);
660
661                                                 if (type == RECIPIENT_PARSING_TYPE_DELETE_CHAR ||
662                                                         type == RECIPIENT_PARSING_TYPE_ENTER_KEY) {     /* entry_changed_cb | enter key case */
663                                                         elm_entry_entry_set(entry, re_assembled_str);
664                                                         elm_entry_cursor_end_set(entry);
665
666                                                         if (strlen(re_assembled_str)) {
667                                                                 rd->is_required_address_popup = true;
668                                                         }
669                                                 } else {        /* entry_filter_cb */
670                                                         elm_entry_entry_set(entry, "");
671                                                         free(*text);
672
673                                                         if (strlen(re_assembled_str)) {
674                                                                 rd->is_required_address_popup = true;
675                                                                 *text = strdup(re_assembled_str);
676                                                         } else {
677                                                                 *text = NULL;
678                                                         }
679                                                 }
680
681                                                 free(re_assembled_str);
682                                         } else {
683                                                 D_EMSG("calloc is failed");
684                                         }
685                                 }
686
687                                 free(is_used_list);
688                         } else {
689                                 D_EMSG("calloc is failed");
690                         }
691
692                         g_strfreev(split_str);
693                 } else {
694                         D_EMSG("g_strsplit_set is failed");
695                 }
696         }
697 }
698
699 void msg_ui_recipient_entry_changed_cb(void *data, Evas_Object *obj, void *event_info)
700 {
701         D_ENTER;
702         MSG_COMPOSER_VIEW_DATA_S *cd = (MSG_COMPOSER_VIEW_DATA_S *)data;
703         D_MSG_RETM_IF(cd == NULL, "Composer Data is NULL");
704
705         RECIPIENT_S *rd = cd->recipient;
706         D_MSG_RETM_IF(rd == NULL, "Recipient Data is NULL");
707
708         char *recipient_str;
709         static char saved_str[COMPOSER_RECIPIENT_ADDRESS_VAL_LEN_MAX + 1] = { 0, };
710
711         /* show invalid address popup, after either inserting text(keypad, paste) or deleting text  */
712         if (rd->is_required_address_popup) {
713                 msg_ui_composer_recipient_addr_type_set(rd, COMPOSER_RECP_ADDR_INVALID);
714
715                 if (rd->notify_popup_idler) {
716                         ecore_idler_del(rd->notify_popup_idler);
717                         rd->notify_popup_idler = NULL;
718                 }
719                 rd->notify_popup_idler = ecore_idler_add(msg_ui_composer_recipient_show_invalid_address_popup, cd);
720
721                 rd->is_required_address_popup = false;
722         }
723
724         recipient_str = elm_entry_markup_to_utf8(elm_entry_entry_get(obj));
725         if (recipient_str == NULL)
726                 return;
727
728         COMPOSER_RECP_ADDR_E addr_type = COMPOSER_RECP_ADDR_NONE;
729
730         if (recipient_str && strlen(recipient_str)) {
731                 addr_type = msg_ui_composer_recipient_type_get(recipient_str);
732
733                 int str_len = strlen(recipient_str);
734
735                 if (str_len > 1) {
736                         /* remove ',' ';' character of last position, it is used for deleting character case  */
737                         if (recipient_str[str_len - 1] == ',' || recipient_str[str_len - 1] == ';') {
738                                 __msg_ui_recipient_process_delimiter_char(cd, recipient_str, NULL, RECIPIENT_PARSING_TYPE_DELETE_CHAR);
739                                 free(recipient_str);
740                                 return;
741                         }
742                 }
743         }
744
745         D_MSG("changed_str = %s", recipient_str);
746         D_MSG("saved_str = %s", saved_str);
747
748         msg_ui_composer_recipient_addr_type_set(rd, addr_type);
749         D_MSG("recipient is invalid recipient addr_type = %d", addr_type);
750
751         if (g_strcmp0(saved_str, recipient_str) == 0) {
752                 D_MSG("It is same string before str(%s), current str(%s)", saved_str, recipient_str);
753                 g_free(recipient_str);
754                 return;
755         }
756
757         strncpy(saved_str, recipient_str, sizeof(saved_str) - 1);
758         saved_str[COMPOSER_RECIPIENT_ADDRESS_VAL_LEN_MAX] = '\0';
759
760         if (strlen(recipient_str) > 0 ) {
761                 msg_ui_composer_predictsearch_request(cd, recipient_str);
762         } else {
763                 msg_ui_composer_predictsearch_clear(cd);
764         }
765
766         g_free(recipient_str);
767         D_LEAVE;
768 }
769
770 void msg_ui_recipient_entry_activated_cb(void *data, Evas_Object *obj, void *event_info)
771 {
772         D_ENTER;
773         MSG_COMPOSER_VIEW_DATA_S *cd = (MSG_COMPOSER_VIEW_DATA_S *)data;
774         D_MSG_RETM_IF(cd == NULL, "Composer Data is NULL");
775
776         char *recipient_str = elm_entry_markup_to_utf8(elm_entry_entry_get(obj));
777         if (recipient_str == NULL)
778                 return;
779
780         __msg_ui_recipient_process_delimiter_char(cd, recipient_str, NULL, RECIPIENT_PARSING_TYPE_ENTER_KEY);
781
782         free(recipient_str);
783
784         msg_ui_composer_body_focus_set(cd, 0);
785
786         D_LEAVE;
787 }
788
789 void msg_ui_recipient_entry_filter_cb(void *data, Evas_Object *entry, char **text)
790 {
791         D_ENTER;
792         D_MSG_RETM_IF(text == NULL || *text == NULL, "New Text is NULL");
793
794         MSG_COMPOSER_VIEW_DATA_S *cd = (MSG_COMPOSER_VIEW_DATA_S *)data;
795         D_MSG_RETM_IF(cd == NULL, "Composer Data is NULL");
796
797         RECIPIENT_S *rd = cd->recipient;
798         D_MSG_RETM_IF(rd == NULL, "Recipient Data is NULL");
799
800         const char *pre_str = NULL;
801         char *utf8_text = NULL;
802         gchar *full_str = NULL;
803
804         utf8_text  = elm_entry_markup_to_utf8(*text);
805         if (utf8_text) {
806                 /* get previous entered str */
807                 pre_str = elm_entry_entry_get(entry);
808
809                 /* make full str */
810                 if (pre_str)
811                         full_str = g_strconcat(pre_str, utf8_text, NULL);
812                 else
813                         full_str = g_strdup(utf8_text);
814
815                 if (full_str) {
816                         __msg_ui_recipient_process_delimiter_char(data, full_str, text, RECIPIENT_PARSING_TYPE_ADD_CHAR);
817                         g_free(full_str);
818                 } else {
819                         D_EMSG("full_str is NULL");
820                 }
821
822                 free(utf8_text);
823         }
824
825         D_LEAVE;
826 }
827
828 void msg_ui_recipient_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
829 {
830         D_ENTER;
831         RECIPIENT_S *rd = (RECIPIENT_S *)data;
832         D_MSG_RETM_IF(rd == NULL, "rd is NULL");
833         D_MSG_RETM_IF(obj == NULL, "obj is NULL");
834         MSG_COMPOSER_VIEW_DATA_S *cd = (MSG_COMPOSER_VIEW_DATA_S *)rd->cd;
835         Evas_Coord x = 0;
836         Evas_Coord y = 0;
837         Evas_Coord w = 0;
838         Evas_Coord h = 0;
839
840         evas_object_geometry_get(obj, &x, &y, &w, &h);
841         D_MSG("recipient box x = %d, y = %d, w = %d, h = %d", x, y, w, h);
842         if (rd->recipient_h != h) {
843                 rd->recipient_h = h;
844
845                 if (cd->isclosed == false) {    /* evas_object_resize makes bs during closing composer*/
846                         Evas_Object *entry = elm_multibuttonentry_entry_get(rd->mbe);
847                         int keypad_h = msg_ui_composer_get_keypad_height(entry);
848
849                         msg_ui_composer_change_body_scroll_size(cd, keypad_h);
850                 }
851         }
852
853         D_LEAVE;
854 }
855