4 #include <Elementary.h>
14 typedef struct _Compose
17 Evas_Object *entry_msg;
18 Evas_Object *mb_entry;
20 Evas_Object *genlist_contacts;
21 Elm_Genlist_Item_Class *itc_inc;
22 Elm_Genlist_Item_Class *itc_out;
23 Elm_Genlist_Item_Class *itc_c_name;
25 Eina_List *current_thread;
27 Eina_List *composing_numbers;
28 Ecore_Poller *updater;
32 typedef struct _Contact_Genlist {
40 static OFono_Callback_List_Incoming_SMS_Node *incoming_sms = NULL;
41 static OFono_Callback_List_Sent_SMS_Node *sent_sms = NULL;
43 static void _send_sms(Compose *compose);
44 static void _compose_timer_updater_start(Compose *compose);
46 static void _message_remove_from_genlist(Message *msg)
50 it = message_object_item_get(msg);
51 EINA_SAFETY_ON_NULL_RETURN(it);
52 elm_object_item_del(it);
55 static void _message_from_file_delete(Compose *compose, Message *msg,
61 gui_message_from_file_delete(msg, contact);
62 _message_remove_from_genlist(msg);
64 last = eina_list_last(compose->current_thread);
65 msg_aux = eina_list_data_get(last);
68 msg_aux = eina_list_data_get(eina_list_prev(last));
70 gui_overview_genlist_update(msg_aux, contact);
72 compose->current_thread = eina_list_remove(compose->current_thread,
77 static void _on_del(void *data, Evas *e __UNUSED__,
78 Evas_Object *obj __UNUSED__, void *event __UNUSED__)
80 Compose *compose = data;
84 ofono_incoming_sms_cb_del(incoming_sms);
85 ofono_sent_sms_changed_cb_del(sent_sms);
86 elm_genlist_item_class_free(compose->itc_inc);
87 elm_genlist_item_class_free(compose->itc_out);
88 elm_genlist_item_class_free(compose->itc_c_name);
89 EINA_LIST_FREE(compose->current_thread, msg)
92 EINA_LIST_FREE(compose->composing_numbers, number)
93 eina_stringshare_del(number);
95 eina_stringshare_del(compose->number);
99 static void _compose_exit(Compose *compose)
104 compose->composing = EINA_TRUE;
105 eina_stringshare_replace(&(compose->number), NULL);
106 elm_object_part_text_set(compose->layout, "elm.text.name",
108 elm_object_signal_emit(compose->layout, "hidden,genlist", "gui");
109 elm_object_signal_emit(compose->layout, "composing", "gui");
110 elm_genlist_clear(compose->genlist);
111 elm_genlist_clear(compose->genlist_contacts);
113 EINA_LIST_FREE(compose->current_thread, msg)
116 EINA_LIST_FREE(compose->composing_numbers, number)
117 eina_stringshare_del(number);
119 elm_object_part_text_set(compose->entry_msg, NULL, "");
120 elm_genlist_decorate_mode_set(compose->genlist, EINA_FALSE);
121 elm_multibuttonentry_clear(compose->mb_entry);
122 elm_object_signal_emit(compose->layout, "contacts,hidden", "gui");
123 elm_object_signal_emit(compose->layout, "names_count,hidden", "gui");
127 static void _on_layout_clicked(void *data, Evas_Object *o,
128 const char *emission, const char *source __UNUSED__)
130 Compose *compose = data;
131 DBG("signal: %s", emission);
133 EINA_SAFETY_ON_FALSE_RETURN(eina_str_has_prefix(emission, "clicked,"));
134 emission += strlen("clicked,");
136 if (strcmp(emission, "back") == 0)
137 _compose_exit(compose);
138 else if (strcmp(emission, "send_msg") == 0)
140 else if (strcmp(emission, "edit") == 0) {
141 elm_object_signal_emit(o, "toggle,on,edit", "gui");
142 elm_genlist_decorate_mode_set(compose->genlist, EINA_TRUE);
143 } else if (strcmp(emission, "edit,done") == 0) {
144 elm_object_signal_emit(o, "toggle,off,edit", "gui");
145 elm_genlist_decorate_mode_set(compose->genlist, EINA_FALSE);
146 } else if (strcmp(emission, "clear") == 0) {
147 const char *contact = compose->number;
148 gui_overview_all_contact_messages_clear(contact);
150 EINA_LIST_FREE(compose->current_thread, msg) {
151 _message_remove_from_genlist(msg);
154 elm_object_signal_emit(o, "toggle,off,edit", "gui");
156 ERR("Unkown emission: %s", emission);
159 static void _send_sms_reply(void *data __UNUSED__, OFono_Error error,
162 if (error != OFONO_ERROR_NONE) {
163 ERR("Error when trying to send a new message");
167 DBG("SMS Sent to: %s, message: %s", ofono_sent_sms_destination_get(sms),
168 ofono_sent_sms_message_get(sms));
171 static void _send_sms(Compose *compose)
173 const char *msg_content;
177 Contact_Info *c_info;
181 if (elm_entry_is_empty(compose->entry_msg)) {
182 DBG("Returning, empty message");
186 if (compose->composing && (!compose->composing_numbers)) {
187 DBG("Returning, no contacts to send");
191 msg_content = elm_object_part_text_get(compose->entry_msg, NULL);
193 msg_utf = elm_entry_markup_to_utf8(msg_content);
195 msg = message_new(time(NULL), msg_utf,
196 EINA_FALSE, OFONO_SENT_SMS_STATE_PENDING);
197 EINA_SAFETY_ON_NULL_RETURN(msg);
198 message_data_set(msg, compose);
199 it = elm_genlist_item_append(compose->genlist, compose->itc_out,
200 msg, NULL, ELM_GENLIST_ITEM_NONE, NULL,
202 elm_genlist_item_show(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
203 message_object_item_set(msg, it);
204 elm_object_signal_emit(compose->layout, "show,genlist", "gui");
206 compose->current_thread =
207 eina_list_append(compose->current_thread, msg);
208 elm_object_part_text_set(compose->entry_msg, NULL, "");
210 _compose_timer_updater_start(compose);
212 if (!compose->composing) {
213 ofono_sms_send(compose->number, msg_utf, _send_sms_reply, NULL);
214 DBG("New Message to: %s content: %s", compose->number, msg_utf);
215 c_info = gui_contact_search(compose->number, NULL);
218 elm_object_part_text_set(compose->layout,
222 to = contact_info_full_name_get(c_info);
223 elm_object_part_text_set(compose->layout,
228 const char *names = NULL, *name;
230 const Eina_List *items;
232 items = elm_multibuttonentry_items_get(compose->mb_entry);
233 EINA_SAFETY_ON_NULL_GOTO(items, exit);
235 EINA_LIST_FOREACH(compose->composing_numbers, l, to) {
236 ofono_sms_send(to, msg_utf, _send_sms_reply, NULL);
237 DBG("New Message to: %s content: %s", to, msg_utf);
238 it = eina_list_nth(items, i);
239 name = elm_object_item_part_text_get(it, NULL);
241 names = eina_stringshare_add(name);
243 names = eina_stringshare_printf("%s, %s",
248 elm_object_part_text_set(compose->layout,
249 "elm.text.name", names);
250 snprintf(size, sizeof(size), "%d",
251 eina_list_count(compose->composing_numbers));
252 elm_object_signal_emit(compose->layout, "names_count,show",
254 elm_object_part_text_set(compose->layout,
255 "elm.text.names_count",
257 eina_stringshare_del(names);
263 static char *_item_c_name_label_get(void *data, Evas_Object *obj __UNUSED__,
266 Contact_Genlist *c_genlist = data;
268 if (strncmp(part, "text.contact.", strlen("text.contact.")))
271 part += strlen("text.contact.");
273 if (strcmp(part, "name") == 0)
274 return strdup(c_genlist->name);
275 else if (strcmp(part, "number") == 0)
276 return strdup(c_genlist->number);
277 else if (strcmp(part, "type") == 0)
278 return strdup(c_genlist->type);
280 ERR("Unexpected text part: %s", part);
284 static Evas_Object *_item_c_name_content_get(void *data, Evas_Object *obj,
287 Contact_Genlist *c_genlist = data;
289 if (strncmp(part, "elm.swallow.", strlen("elm.swallow.")))
292 part += strlen("elm.swallow.");
294 if (strcmp(part, "photo") == 0)
295 return picture_icon_get(obj, c_genlist->picture);
297 ERR("Unexpected part name: %s", part);
302 static char *_item_label_get(void *data, Evas_Object *obj __UNUSED__,
307 if (strncmp(part, "text.msg.", strlen("text.msg.")))
310 part += strlen("text.msg.");
312 if (strcmp(part, "content") == 0) {
313 const char *content = message_content_get(msg);
316 return elm_entry_utf8_to_markup(content);
319 if (strcmp(part, "time") == 0) {
320 time_t t_msg = message_time_get(msg);
323 return date_format(t_msg);
326 ERR("Unexpected text part: %s", part);
330 static Eina_Bool _item_state_get(void *data, Evas_Object *obj __UNUSED__,
335 if (strcmp(part, "sent") == 0) {
336 if (message_state_get(msg) == OFONO_SENT_SMS_STATE_SENT)
339 } else if (strcmp(part, "failed") == 0) {
340 if (message_state_get(msg) == OFONO_SENT_SMS_STATE_FAILED)
345 ERR("Unexpected state part: %s", part);
349 static void _sms_size_calc(const char *str, int *size, int *max)
351 Eina_Bool all_isprint = EINA_TRUE;
354 for (s = str; *s != '\0'; s++) {
356 all_isprint = EINA_FALSE;
367 *max = ((*size / 153) + 1) * 153;
372 *max = ((*size / 67) + 1) * 67;
376 static void _on_text_changed(void *data, Evas_Object *obj,
377 void *event_info __UNUSED__)
379 Compose *compose = data;
380 const char *msg = elm_object_part_text_get(obj, NULL);
385 Edje_Message_Int_Set *ed_msg;
390 msg_utf8 = elm_entry_markup_to_utf8(msg);
391 _sms_size_calc(msg_utf8, &size, &max);
392 snprintf(buf,sizeof(buf), "%d", size);
393 elm_object_part_text_set(compose->layout, "elm.text.size", buf);
394 snprintf(buf,sizeof(buf), "%d", max);
395 elm_object_part_text_set(compose->layout, "elm.text.max_size", buf);
398 ed_msg = alloca(sizeof(Edje_Message_Float_Set) + sizeof(int));
400 ed_msg->val[0] = size;
401 ed_msg->val[1] = max;
402 ed = elm_layout_edje_get(compose->layout);
403 edje_object_message_send(ed, EDJE_MESSAGE_INT_SET, 1, ed_msg);
406 static void _incoming_sms_cb(void *data, unsigned int sms_class,
407 time_t timestamp, const char *sender,
410 Compose *compose = data;
414 /* Users can only send class 1. This is OFono/GSM detail */
418 if (compose->number && strcmp(compose->number, sender) != 0)
421 msg = message_new(timestamp, message, EINA_FALSE,
422 OFONO_SENT_SMS_STATE_SENT);
424 EINA_SAFETY_ON_NULL_RETURN(msg);
425 message_data_set(msg, compose);
426 it = elm_genlist_item_append(compose->genlist, compose->itc_inc, msg,
427 NULL, ELM_GENLIST_ITEM_NONE, NULL,
429 elm_genlist_item_show(it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
430 message_object_item_set(msg, it);
431 compose->current_thread =
432 eina_list_append(compose->current_thread, msg);
434 _compose_timer_updater_start(compose);
437 static Eina_Bool _compose_time_updater(void *data)
440 double now = ecore_loop_time_get();
441 const double interval_threshold = 30.0;
443 const long long update_threshold = time(NULL) - WEEK - DAY;
445 if (!ctx->current_thread) {
450 if (now - ctx->last_update < interval_threshold)
452 ctx->last_update = now;
454 it = elm_genlist_first_item_get(ctx->genlist);
455 for (; it != NULL; it = elm_genlist_item_next_get(it)) {
456 Message *msg = elm_object_item_data_get(it);
457 long long t = message_time_get(msg);
458 if (EINA_UNLIKELY(t == 0)) {
459 t = message_time_get(msg);
461 if (EINA_UNLIKELY(t < update_threshold))
463 elm_genlist_item_update(it);
469 static void _compose_timer_updater_start(Compose *compose)
471 Evas *e = evas_object_evas_get(compose->layout);
472 Eina_Bool win_focused = evas_focus_state_get(e);
473 Eina_Bool obj_visible = evas_object_visible_get(compose->layout);
475 DBG("poller %p, win_focused=%hhu, obj_visible=%hhu",
476 compose->updater, win_focused, obj_visible);
477 if (compose->updater)
479 if (!compose->current_thread)
481 if ((!win_focused) || (!obj_visible))
484 DBG("start poller messages");
485 /* ECORE_POLLER_CORE is 1/8th of second. */
486 compose->updater = ecore_poller_add(ECORE_POLLER_CORE, 8 * 60,
487 _compose_time_updater,
489 _compose_time_updater(compose);
492 static void _compose_time_updater_stop(Compose *compose)
494 Evas *e = evas_object_evas_get(compose->layout);
495 Eina_Bool win_focused = evas_focus_state_get(e);
496 Eina_Bool obj_visible = evas_object_visible_get(compose->layout);
498 DBG("poller %p, win_focused=%hhu, obj_visible=%hhu",
499 compose->updater, win_focused, obj_visible);
500 if (!compose->updater)
502 if (win_focused && obj_visible)
505 DBG("delete poller %p", compose->updater);
506 ecore_poller_del(compose->updater);
507 compose->updater = NULL;
510 static void _on_show(void *data, Evas *e __UNUSED__,
511 Evas_Object *obj __UNUSED__, void *event __UNUSED__)
513 Compose *compose = data;
514 DBG("Overview became visible");
515 _compose_timer_updater_start(compose);
518 static void _on_win_focus_in(void *data, Evas *e __UNUSED__,
519 void *event_info __UNUSED__)
521 Compose *compose = data;
522 DBG("window is focused");
523 _compose_timer_updater_start(compose);
526 static void _on_win_focus_out(void *data, Evas *e __UNUSED__,
527 void *event_info __UNUSED__)
529 Compose *compose = data;
530 DBG("window is unfocused");
531 _compose_time_updater_stop(compose);
534 static void _on_hide(void *data, Evas *e __UNUSED__,
535 Evas_Object *obj __UNUSED__, void *event __UNUSED__)
537 Compose *compose = data;
538 DBG("Overview became hidden");
539 _compose_time_updater_stop(compose);
542 static void _on_del_clicked(void *data, Evas_Object *obj __UNUSED__,
543 void *event_info __UNUSED__)
546 Compose *compose = message_data_get(msg);
548 EINA_SAFETY_ON_NULL_RETURN(compose);
549 _message_from_file_delete(compose, msg, compose->number);
552 static void _on_resend_clicked(void *data, Evas_Object *obj __UNUSED__,
553 void *event_info __UNUSED__)
556 const char *content, *number;
557 Compose *compose = message_data_get(msg);
559 EINA_SAFETY_ON_NULL_RETURN(compose);
561 content = message_content_get(msg);
562 EINA_SAFETY_ON_NULL_RETURN(content);
563 number = message_phone_get(msg);
564 EINA_SAFETY_ON_NULL_RETURN(number);
566 INF("%s %s", number, content);
567 ofono_sms_send(number, content, _send_sms_reply, NULL);
570 static Evas_Object *_item_content_get(void *data, Evas_Object *obj,
573 Evas_Object *btn = NULL;
576 if (strcmp(part, "msg.swallow.delete") == 0) {
577 btn = elm_button_add(obj);
578 EINA_SAFETY_ON_NULL_RETURN_VAL(btn, NULL);
579 elm_object_style_set(btn, "history-delete");
580 elm_object_text_set(btn, "delete");
581 evas_object_smart_callback_add(btn, "clicked", _on_del_clicked,
583 evas_object_propagate_events_set(btn, EINA_FALSE);
584 } else if (strcmp(part, "swallow.btn.resend") == 0) {
585 btn = elm_button_add(obj);
586 EINA_SAFETY_ON_NULL_RETURN_VAL(btn, NULL);
587 elm_object_style_set(btn, "compose-resend");
588 elm_object_text_set(btn, "Failed. Try Again?");
589 evas_object_smart_callback_add(btn, "clicked", _on_resend_clicked,
591 evas_object_propagate_events_set(btn, EINA_FALSE);
593 ERR("unknown content part '%s'", part);
598 static void _sent_sms_cb(void *data, OFono_Error error, OFono_Sent_SMS *sms)
600 Compose *compose = data;
604 if (error != OFONO_ERROR_NONE) {
605 ERR("OFono error - Sending a SMS");
609 EINA_LIST_FOREACH(compose->current_thread, l, msg) {
610 const char *m_sms, *m_msg;
614 m_sms = ofono_sent_sms_message_get(sms);
615 m_msg = message_content_get(msg);
616 t_msg = message_time_get(msg);
617 state = message_state_get(msg);
618 t_sms = ofono_sent_sms_timestamp_get(sms);
620 if ((m_sms == m_msg && t_msg == t_sms) ||
621 (m_sms == m_msg && state == OFONO_SENT_SMS_STATE_FAILED)) {
622 message_state_set(msg, ofono_sent_sms_state_get(sms));
623 elm_genlist_item_update(message_object_item_get(msg));
629 static void _on_c_genlist_clicked(void *data, Evas_Object *obj __UNUSED__,
632 Elm_Object_Item *it = event_info;
633 Contact_Genlist *c_genlist = data;
634 Compose *compose = c_genlist->compose;
636 elm_genlist_item_selected_set(it, EINA_FALSE);
637 /* It will be used in _item_filter_cb so we will know if this
638 * number was added already
640 elm_multibuttonentry_item_prepend(compose->mb_entry, c_genlist->number,
644 Contact_Genlist *_contact_genlist_new(const char *name,
650 Contact_Genlist *c_genlist = calloc(1, sizeof(Contact_Genlist));
651 EINA_SAFETY_ON_NULL_RETURN_VAL(c_genlist, NULL);
652 c_genlist->name = eina_stringshare_add(name);
653 c_genlist->number = eina_stringshare_add(number);
654 c_genlist->type = eina_stringshare_add(type);
655 c_genlist->picture = eina_stringshare_add(picture);
656 c_genlist->compose = compose;
660 static void _on_text_mb_entry_changed(void *data, Evas_Object *obj,
661 void *event_info __UNUSED__)
663 Compose *compose = data;
664 Contact_Partial_Match *pm;
665 Eina_List *result, *l;
668 query = elm_object_part_text_get(obj, NULL);
670 elm_genlist_clear(compose->genlist_contacts);
672 if ((!query) || (*query == '\0')) {
673 elm_object_signal_emit(compose->layout,
674 "contacts,hidden", "gui");
678 DBG("Searching for contact with number: %s", query);
680 result = gui_contact_partial_match_search(query);
682 DBG("No contact match: '%s'", query);
683 elm_object_signal_emit(compose->layout,
684 "contacts,hidden", "gui");
688 EINA_LIST_FOREACH(result, l, pm) {
689 const Contact_Info *c_info;
690 const char *type, *name, *number, *picture;
691 Contact_Genlist *c_genlist;
693 type = contact_partial_match_type_get(pm);
694 c_info = contact_partial_match_info_get(pm);
695 name = contact_info_full_name_get(c_info);
696 number = contact_info_detail_get(c_info, type);
697 picture = contact_info_picture_get(c_info);
699 c_genlist = _contact_genlist_new(name, number, type,
701 EINA_SAFETY_ON_NULL_RETURN(c_genlist);
702 elm_genlist_item_append(compose->genlist_contacts,
705 ELM_GENLIST_ITEM_NONE,
706 _on_c_genlist_clicked,
709 contact_partial_match_search_free(result);
711 elm_object_signal_emit(compose->layout, "contacts,show", "gui");
714 static void _on_item_added(void *data, Evas_Object *obj __UNUSED__,
717 Compose *compose = data;
718 const char *number, *name;
719 Contact_Info *c_info;
720 Elm_Object_Item *it = event_info;
722 number = elm_object_item_part_text_get(it, NULL);
723 DBG("Item added number = %s", number);
725 elm_object_signal_emit(compose->layout, "contacts,hidden", "gui");
730 c_info = gui_contact_search(number, NULL);
733 DBG("No contact found");
737 name = contact_info_full_name_get(c_info);
738 DBG("Number=%s Name=%s", number, name);
739 elm_object_item_part_text_set(it, NULL, name);
742 static Eina_Bool entry_is_number(const char *str)
746 for(i = 0; str[i] != '\0'; i++) {
747 if (isdigit(str[i]) == 0)
754 static Eina_Bool _item_filter_cb(Evas_Object *obj, const char* item_label,
755 void *item_data __UNUSED__,
759 Compose *compose = data;
763 /* Did the user entered a phone number? */
764 if (entry_is_number(item_label)) {
765 EINA_LIST_FOREACH(compose->composing_numbers, l, number) {
766 DBG("current= %s, number= %s", number, item_label);
767 if (strcmp(number, item_label) == 0) {
768 entry = elm_multibuttonentry_entry_get(obj);
769 elm_object_part_text_set(entry, NULL, "");
770 DBG("Filtered, number already in.");
774 number = eina_stringshare_add(item_label);
775 compose->composing_numbers =
776 eina_list_append(compose->composing_numbers, number);
783 static void _item_c_genlist_del(void *data, Evas_Object *obj __UNUSED__)
785 Contact_Genlist *c_genlist = data;
787 DBG("Deleting item: %p name: %s number: %s", c_genlist,
788 c_genlist->name, c_genlist->number);
789 eina_stringshare_del(c_genlist->name);
790 eina_stringshare_del(c_genlist->number);
791 eina_stringshare_del(c_genlist->type);
792 eina_stringshare_del(c_genlist->picture);
796 Evas_Object *compose_add(Evas_Object *parent)
799 Evas_Object *obj, *entry, *genlist, *mb_entry;
802 compose = calloc(1, sizeof(Compose));
803 EINA_SAFETY_ON_NULL_RETURN_VAL(compose, NULL);
805 compose->layout = obj = layout_add(parent, "compose");
806 EINA_SAFETY_ON_NULL_GOTO(obj, err_obj);
808 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _on_del,
811 elm_object_signal_callback_add(obj, "clicked,*", "gui",
812 _on_layout_clicked, compose);
814 evas_object_data_set(obj, "compose.ctx", compose);
816 entry = elm_entry_add(obj);
817 EINA_SAFETY_ON_NULL_GOTO(entry, err_entry);
818 elm_object_part_content_set(obj, "elm.swallow.message", entry);
819 evas_object_smart_callback_add(entry, "changed", _on_text_changed,
821 elm_object_style_set(entry, "compose");
822 elm_entry_editable_set(entry, EINA_TRUE);
823 elm_entry_scrollable_set(entry, EINA_TRUE);
824 compose->entry_msg = entry;
826 mb_entry = elm_multibuttonentry_add(obj);
827 EINA_SAFETY_ON_NULL_GOTO(mb_entry, err_entry);
828 elm_object_part_content_set(obj, "elm.swallow.destination", mb_entry);
829 elm_object_style_set(mb_entry, "compose");
830 elm_object_text_set(mb_entry, "To: ");
831 elm_object_part_text_set(mb_entry, "guide", "Tap to add recipient");
832 compose->mb_entry = mb_entry;
834 evas_object_smart_callback_add(mb_entry, "item,added",
835 _on_item_added, compose);
836 /* Don't let equal numbers be added */
837 elm_multibuttonentry_item_filter_append(mb_entry, _item_filter_cb,
840 entry = elm_multibuttonentry_entry_get(mb_entry);
841 EINA_SAFETY_ON_NULL_GOTO(entry, err_entry);
842 evas_object_smart_callback_add(entry, "changed",
843 _on_text_mb_entry_changed,
846 genlist = elm_genlist_add(obj);
847 EINA_SAFETY_ON_NULL_GOTO(genlist, err_genlist);
848 elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
849 elm_object_style_set(genlist, "compose");
850 elm_object_part_content_set(obj, "elm.swallow.genlist", genlist);
851 compose->genlist = genlist;
853 genlist = elm_genlist_add(obj);
854 EINA_SAFETY_ON_NULL_GOTO(genlist, err_genlist);
855 elm_object_style_set(genlist, "compose");
856 elm_object_part_content_set(obj, "elm.swallow.genlist.contacts",
858 compose->genlist_contacts = genlist;
859 elm_object_focus_allow_set(genlist, EINA_FALSE);
861 elm_scroller_policy_set(compose->genlist,
862 ELM_SCROLLER_POLICY_OFF,
863 ELM_SCROLLER_POLICY_AUTO);
864 elm_scroller_policy_set(compose->genlist_contacts,
865 ELM_SCROLLER_POLICY_OFF,
866 ELM_SCROLLER_POLICY_AUTO);
868 compose->itc_inc = elm_genlist_item_class_new();
869 EINA_SAFETY_ON_NULL_GOTO(compose->itc_inc, err_itc);
870 compose->itc_inc->item_style = "messages-incoming";
871 compose->itc_inc->func.text_get = _item_label_get;
872 compose->itc_inc->func.content_get = _item_content_get;
873 compose->itc_inc->func.state_get = NULL;
874 compose->itc_inc->func.del = NULL;
875 compose->itc_inc->decorate_all_item_style = "incoming-delete";
876 compose->itc_inc->decorate_item_style = "incoming-delete";
878 compose->itc_out = elm_genlist_item_class_new();
879 EINA_SAFETY_ON_NULL_GOTO(compose->itc_out, err_itc_out);
880 compose->itc_out->item_style = "messages-outgoing";
881 compose->itc_out->func.text_get = _item_label_get;
882 compose->itc_out->func.content_get = _item_content_get;
883 compose->itc_out->func.state_get = _item_state_get;
884 compose->itc_out->func.del = NULL;
885 compose->itc_out->decorate_all_item_style = "outgoing-delete";
886 compose->itc_out->decorate_item_style = "outgoing-delete";
888 compose->itc_c_name = elm_genlist_item_class_new();
889 EINA_SAFETY_ON_NULL_GOTO(compose->itc_c_name, err_names);
890 compose->itc_c_name->item_style = "contacts-compose";
891 compose->itc_c_name->func.text_get = _item_c_name_label_get;
892 compose->itc_c_name->func.content_get = _item_c_name_content_get;
893 compose->itc_c_name->func.state_get = NULL;
894 compose->itc_c_name->func.del = _item_c_genlist_del;
896 elm_object_part_text_set(compose->layout, "elm.text.name",
898 elm_object_signal_emit(compose->layout, "hide,genlist", "gui");
899 compose->composing = EINA_TRUE;
900 elm_object_signal_emit(compose->layout, "composing", "gui");
902 incoming_sms = ofono_incoming_sms_cb_add(_incoming_sms_cb, compose);
903 sent_sms = ofono_sent_sms_changed_cb_add(_sent_sms_cb, compose);
905 evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _on_hide,
907 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _on_show,
910 e = evas_object_evas_get(obj);
911 evas_event_callback_add(e, EVAS_CALLBACK_CANVAS_FOCUS_OUT,
912 _on_win_focus_out, compose);
913 evas_event_callback_add(e, EVAS_CALLBACK_CANVAS_FOCUS_IN,
914 _on_win_focus_in, compose);
919 elm_genlist_item_class_free(compose->itc_out);
921 elm_genlist_item_class_free(compose->itc_inc);
923 evas_object_del(genlist);
925 evas_object_del(entry);
927 evas_object_del(obj);
933 void compose_set(Evas_Object *obj, const char *number, const char *message,
938 EINA_SAFETY_ON_NULL_RETURN(obj);
939 EINA_SAFETY_ON_NULL_RETURN(number);
940 EINA_SAFETY_ON_NULL_RETURN(message);
942 compose = evas_object_data_get(obj, "compose.ctx");
943 EINA_SAFETY_ON_NULL_RETURN(compose);
945 ERR("TODO '%s' '%s' %d", number, message, do_auto);
948 void compose_messages_set(Evas_Object *obj, Eina_List *list, const char *number)
953 Elm_Genlist_Item_Class *itc;
954 Elm_Object_Item *it = NULL;
955 Contact_Info *c_info;
957 EINA_SAFETY_ON_NULL_RETURN(obj);
958 compose = evas_object_data_get(obj, "compose.ctx");
959 EINA_SAFETY_ON_NULL_RETURN(compose);
961 eina_stringshare_replace(&(compose->number), number);
963 elm_genlist_clear(compose->genlist);
965 EINA_LIST_FOREACH(list, l, msg) {
966 Eina_Bool outgoing = message_outgoing_get(msg);
969 itc = compose->itc_out;
971 itc = compose->itc_inc;
972 message_data_set(msg, compose);
973 it = elm_genlist_item_append(compose->genlist, itc, msg, NULL,
974 ELM_GENLIST_ITEM_NONE, NULL,
976 message_object_item_set(msg, it);
980 elm_genlist_item_show(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
982 compose->current_thread = list;
983 elm_object_signal_emit(compose->layout, "show,genlist", "gui");
985 c_info = gui_contact_search(number, NULL);
988 elm_object_part_text_set(compose->layout, "elm.text.name",
991 elm_object_part_text_set(compose->layout, "elm.text.name",
992 contact_info_full_name_get(c_info));
994 compose->composing = EINA_FALSE;
995 _compose_timer_updater_start(compose);
996 elm_object_signal_emit(compose->layout, "viewing", "gui");