f8aa8b4456aeb1c2b2677d29d6f93932c9f26a74
[apps/core/preloaded/message-app.git] / composer / src / bubble / msg-ui-composer-bubble-main.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 #include "msg-ui-composer-bubble.h"
18 #include "msg-ui-composer-data.h"
19
20 static int _parse_bundle_data(PMSG_BUBBLE_DATA bubble_data, service_h svc_handle)
21 {
22         D_ENTER;
23
24         if (!svc_handle)
25                 return -1;
26
27         char *thread_id = NULL;
28         msg_struct_t threadInfo = NULL;
29         int err;
30
31         service_get_extra_data(svc_handle, MSG_BUNDLE_KEY_THREAD_ID, &thread_id);
32         bubble_data->threadId = thread_id?(msg_thread_id_t)atoi(thread_id):0;
33         MSG_UI_DEBUG(MSG_UI_LEVEL_DEBUG, "Thread ID from bundle data=%d", bubble_data->threadId);
34
35         msg_struct_list_s addrList;
36         int i = 0;
37         memset(&addrList, 0x00, sizeof(msg_struct_list_s));
38
39         err = msg_get_address_list(bubble_data->msgHandle, bubble_data->threadId, &addrList);
40         if (err == MSG_SUCCESS) {
41                 bubble_data->addr_list.addr_cnt = addrList.nCount;
42
43                 for (i =0; i<addrList.nCount; i++) {
44                         msg_get_int_value(addrList.msg_struct_info[i], MSG_ADDRESS_INFO_CONTACT_ID_INT, &bubble_data->addr_list.addr_info[i].contact_id);
45                         msg_get_str_value(addrList.msg_struct_info[i], MSG_ADDRESS_INFO_DISPLAYNAME_STR, bubble_data->addr_list.addr_info[i].name, DEF_THREAD_NAME_LEN);
46                         msg_get_str_value(addrList.msg_struct_info[i], MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, bubble_data->addr_list.addr_info[i].address, DEF_THREAD_ADDR_LEN);
47                 }
48
49                 msg_release_list_struct(&addrList);
50
51         } else {
52                 D_MSG("[ERROR] msg_get_address_list return error [%d]", err);
53         }
54
55         threadInfo = msg_create_struct(MSG_STRUCT_THREAD_INFO);
56         err = msg_get_thread(bubble_data->msgHandle, bubble_data->threadId, threadInfo);
57         if (err == MSG_SUCCESS)
58                 msg_get_str_value(threadInfo, MSG_THREAD_NAME_STR, bubble_data->threadName, DEF_THREAD_NAME_LEN);
59         else
60                 D_MSG("[ERROR] msg_get_thread return error [%d]", err);
61
62         msg_release_struct(&threadInfo);
63
64         D_LEAVE;
65         return 0;
66 }
67
68 static int _parse_bundle_with_msg_id(PMSG_BUBBLE_DATA bubble_data, int msgId)
69 {
70         D_ENTER;
71
72         msg_error_t err = MSG_SUCCESS;
73         msg_struct_t msgInfo = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
74         msg_struct_t sendOpt = msg_create_struct(MSG_STRUCT_SENDOPT);
75         msg_struct_list_s addrList;
76         int i = 0;
77
78         D_MSG("Message ID from bundle = %d", msgId);
79
80         err = msg_get_message(bubble_data->msgHandle, msgId, msgInfo, sendOpt);
81         if (err != MSG_SUCCESS) {
82                 D_EMSG("msg_get_message is failed err = %d", err);
83                 msg_release_struct(&msgInfo);
84                 msg_release_struct(&sendOpt);
85                 return -1;
86         }
87
88         msg_get_int_value(msgInfo, MSG_MESSAGE_THREAD_ID_INT, (int *)(&bubble_data->threadId));
89         MSG_UI_DEBUG(MSG_UI_LEVEL_DEBUG, "Thread ID from bundle data=%d", bubble_data->threadId);
90
91         memset(&addrList, 0x00, sizeof(msg_struct_list_s));
92         msg_get_address_list(bubble_data->msgHandle, bubble_data->threadId, &addrList);
93
94         bubble_data->addr_list.addr_cnt = addrList.nCount;
95
96         for (i=0; i<addrList.nCount; i++) {
97                 /** contact ID & display name */
98                 int contact_id = 0;
99                 msg_get_int_value(addrList.msg_struct_info[i], MSG_ADDRESS_INFO_CONTACT_ID_INT, &contact_id);
100
101                 if (contact_id > 0) {
102                         bubble_data->addr_list.addr_info[i].contact_id = contact_id;
103                         msg_get_str_value(addrList.msg_struct_info[i], MSG_ADDRESS_INFO_DISPLAYNAME_STR, bubble_data->addr_list.addr_info[i].name, DEF_THREAD_NAME_LEN);
104                 } else {
105                         bubble_data->addr_list.addr_info[i].contact_id = 0;
106                 }
107
108                 /** addresss */
109                 msg_get_str_value(addrList.msg_struct_info[i], MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, bubble_data->addr_list.addr_info[i].address, DEF_THREAD_ADDR_LEN);
110         }
111
112         msg_release_list_struct(&addrList);
113
114         if (bubble_data->addr_list.addr_info[0].contact_id > 0)
115                 snprintf(bubble_data->threadName, DEF_THREAD_NAME_LEN, "%s", bubble_data->addr_list.addr_info[0].name);
116         else
117                 snprintf(bubble_data->threadName, DEF_THREAD_NAME_LEN, "%s", bubble_data->addr_list.addr_info[0].address);
118
119         msg_release_struct(&msgInfo);
120         msg_release_struct(&sendOpt);
121
122         D_LEAVE;
123
124         return 0;
125 }
126
127
128 PMSG_BUBBLE_DATA msg_ui_bubble_init_bubble_data(msg_handle_t msgHandle, void *callback_data)
129 {
130         D_ENTER;
131
132         PMSG_BUBBLE_DATA bubble_data = NULL;
133
134         bubble_data = (PMSG_BUBBLE_DATA)calloc(1, sizeof(MSG_BUBBLE_DATA));
135
136         bubble_data->msgHandle = msgHandle;
137
138         bubble_data->viewmode = BUBBLE_NORMAL_VIEW;
139         bubble_data->ug_state = BUBBLE_UG_START;
140
141         if (callback_data)
142                 bubble_data->callback_data = callback_data;
143
144         D_LEAVE;
145         return bubble_data;
146 }
147
148 void msg_ui_bubble_deinit_bubble_data(void *data)
149 {
150         D_ENTER;
151
152         if (!data)
153                 return;
154
155         PMSG_BUBBLE_DATA bubble_data = data;
156
157         evas_object_smart_callback_del(bubble_data->scrl, "edge,top", msg_ui_bubble_scroll_edge_top_cb);
158
159         msg_ui_bubble_init_bubble_list(bubble_data);
160
161         if (bubble_data->title_menu_opened)
162                 msg_ui_bubble_close_title_menu_genlist(bubble_data);
163
164         if (bubble_data->date_ptn_default) {
165                 free(bubble_data->date_ptn_default);
166                 bubble_data->date_ptn_default = NULL;
167         }
168
169         if (bubble_data->date_ptn_year) {
170                 free(bubble_data->date_ptn_year);
171                 bubble_data->date_ptn_year = NULL;
172         }
173
174         if (bubble_data->time_12h_ptn) {
175                 free(bubble_data->time_12h_ptn);
176                 bubble_data->time_12h_ptn = NULL;
177         }
178
179         if (bubble_data->time_24h_ptn) {
180                 free(bubble_data->time_24h_ptn);
181                 bubble_data->time_24h_ptn = NULL;
182         }
183
184         if (bubble_data->del_thread) {
185                 if (ecore_thread_cancel(bubble_data->del_thread) == EINA_FALSE) {
186                         D_MSG("ecore_thread_cancel is done.");
187                 } else {
188                         D_MSG("ecore_thread_cancel is failed.");
189                 }
190
191                 bubble_data->del_thread = NULL;
192         }
193
194         if (bubble_data->resend_idler) {
195                 ecore_idler_del(bubble_data->resend_idler);
196                 bubble_data->resend_idler = NULL;
197         }
198
199         if (bubble_data->retrieve_idler) {
200                 ecore_idler_del(bubble_data->retrieve_idler);
201                 bubble_data->retrieve_idler = NULL;
202         }
203         if (bubble_data->bubble_layout) {
204                 evas_object_del(bubble_data->bubble_layout);
205                 bubble_data->bubble_layout = NULL;
206         }
207         if (bubble_data->title_button) {
208                 evas_object_del(bubble_data->title_button);
209                 bubble_data->title_button = NULL;
210         }
211
212         if (vconf_ignore_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, msg_ui_bubble_timezone_change_cb) < 0) {
213                 D_EMSG("Fail to remove vconf CB with [%s]", VCONFKEY_SYSTEM_TIME_CHANGED);
214         }
215
216         free(bubble_data);
217
218         D_LEAVE;
219 }
220
221 void msg_ui_bubble_parse_bubble_data(PMSG_BUBBLE_DATA bubble_data, service_h svc_handle)
222 {
223         char *key_type = NULL;
224
225         service_get_extra_data(svc_handle, MSG_BUNDLE_KEY_TYPE, &key_type);
226         if (key_type && g_strcmp0(key_type, MSG_BUNDLE_VALUE_MSG_ID) == 0) { /* From logs */
227                 int msg_id = 0;
228                 char *msg_id_str = NULL;
229                 service_get_extra_data(svc_handle, MSG_BUNDLE_KEY_MSG_ID, &msg_id_str);
230
231                 if (!msg_id_str)
232                         return;
233
234                 msg_id = atoi(msg_id_str);
235                 _parse_bundle_with_msg_id(bubble_data, msg_id);
236
237         } else {
238                 _parse_bundle_data(bubble_data, svc_handle);
239         }
240 }
241
242 void msg_ui_bubble_start_bubble_list(PMSG_BUBBLE_DATA bubble_data)
243 {
244         D_ENTER;
245
246         MSG_UI_RETM_IF(MSG_UI_LEVEL_ERR, bubble_data == NULL, "PMSG_BUBBLE_DATA is NULL");
247
248         msg_ui_bubble_init_bubble_list(bubble_data);
249
250         bubble_data->box = elm_box_add(bubble_data->bubble_layout);
251         evas_object_size_hint_weight_set(bubble_data->box, EVAS_HINT_EXPAND, 0.0);
252         elm_object_content_set(bubble_data->scrl, bubble_data->box);
253
254         if (bubble_data->viewmode == BUBBLE_EDIT_VIEW) {
255                 msg_ui_bubble_change_normal_navi_control(bubble_data);
256         }
257
258         bubble_data->viewmode = BUBBLE_NORMAL_VIEW;
259
260         /* To avoid a fluctuation of bubble list on split view. */
261         //elm_scroller_region_show(bubble_data->scrl, 0, 0, 0, 0);
262
263         D_LEAVE;
264 }
265
266 void msg_ui_bubble_init_bubble_list(PMSG_BUBBLE_DATA bubble_data)
267 {
268         D_ENTER;
269
270         MSG_UI_RETM_IF(MSG_UI_LEVEL_ERR, bubble_data == NULL, "PMSG_BUBBLE_DATA is NULL");
271
272         PMSG_APP_CONV_DATA_S item_data = NULL;
273         BUBBLE_PACK_INFO *pack_info = NULL;
274
275         bubble_data->bubble_count = 0;
276         bubble_data->bubble_index = 0;
277         bubble_data->added_count = 0;
278         bubble_data->check_cnt = 0;
279         bubble_data->copy_id = 0;
280         bubble_data->resend_id = 0;
281         bubble_data->retrieve_id = 0;
282
283         if (bubble_data->load_animator) {
284                 ecore_animator_del(bubble_data->load_animator);
285                 bubble_data->load_animator = NULL;
286         }
287
288         if (bubble_data->add_animator) {
289                 ecore_animator_del(bubble_data->add_animator);
290                 bubble_data->add_animator = NULL;
291         }
292
293         if (bubble_data->box && bubble_data->scrl) {
294                 elm_object_content_unset(bubble_data->scrl);
295                 evas_object_del(bubble_data->box);
296                 bubble_data->box = NULL;
297         }
298
299         EINA_LIST_FREE(bubble_data->bubble_list, item_data) {
300                 if (item_data) {
301                         if (item_data->msgTime)
302                                 free(item_data->msgTime);
303
304                         free(item_data);
305                 }
306         }
307
308         EINA_LIST_FREE(bubble_data->added_list, pack_info) {
309                 if (pack_info)
310                         free(pack_info);
311         }
312
313         bubble_data->realized_list = eina_list_free(bubble_data->realized_list);
314         bubble_data->chk_list = eina_list_free(bubble_data->chk_list);
315
316         D_LEAVE;
317 }
318
319 Evas_Object *msg_ui_bubble_create_toolbar(void *user_data)
320 {
321         if (!user_data) {
322                 D_EMSG("[ERROR] user_data is NULL");
323                 return NULL;
324         }
325
326         PMSG_BUBBLE_DATA bubble_data = (PMSG_BUBBLE_DATA)user_data;
327         MSG_COMPOSER_VIEW_DATA_S *cd = (MSG_COMPOSER_VIEW_DATA_S*)bubble_data->callback_data;
328
329         Evas_Object *toolbar = elm_toolbar_add(cd->navi_bar);
330
331         if (!toolbar) {
332                 D_EMSG("toolbar is NULL");
333                 return NULL;
334         }
335
336         elm_toolbar_shrink_mode_set(toolbar, ELM_TOOLBAR_SHRINK_EXPAND);
337         elm_object_style_set(toolbar, "naviframe");
338
339         return toolbar;
340 }
341
342 Evas_Object *msg_ui_bubble_create_view(Evas_Object *parent, void *user_data)
343 {
344         if (!parent || !user_data)
345                 return NULL;
346
347         PMSG_BUBBLE_DATA bubble_data = user_data;
348
349         Evas_Object *bubble_layout = NULL;
350         Evas_Object *scroller = NULL;
351
352         bubble_layout = elm_layout_add(parent);
353         elm_layout_theme_set(bubble_layout, "layout", "application", "noindicator");
354         evas_object_size_hint_weight_set(bubble_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
355         evas_object_size_hint_fill_set(bubble_layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
356         evas_object_show(bubble_layout);
357
358         scroller = elm_scroller_add(parent);
359         evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
360         elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE);
361         elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
362         elm_object_part_content_set(bubble_layout, "elm.swallow.content", scroller);
363         evas_object_smart_callback_add(scroller, "scroll,drag,start", msg_ui_bubble_scroll_drag_start_cb, user_data);
364         evas_object_event_callback_add(bubble_layout, EVAS_CALLBACK_MOUSE_UP, msg_ui_bubble_main_layout_clicked_cb, bubble_data->callback_data);
365
366         bubble_data->parent_layout = parent;
367         bubble_data->bubble_layout = bubble_layout;
368         bubble_data->scrl = scroller;
369
370         return bubble_layout;
371 }
372
373 void msg_ui_bubble_start_view(PMSG_BUBBLE_DATA bubble_data)
374 {
375         if (!bubble_data)
376                 return;
377
378         msg_ui_bubble_reg_bubble_cb_func(bubble_data);
379         msg_ui_bubble_get_locale(bubble_data);
380         msg_ui_bubble_get_time_format(bubble_data);
381         bubble_data->time_12h_ptn = msg_common_get_date_best_pattern(bubble_data->locale, MSG_UI_TIME_PATTERN_12H);
382         bubble_data->time_24h_ptn = msg_common_get_date_best_pattern(bubble_data->locale, MSG_UI_TIME_PATTERN_24H);
383         bubble_data->date_ptn_default = msg_common_get_date_best_pattern(bubble_data->locale, MSG_UI_DATE_PATTERN_DEFAULT);
384         bubble_data->date_ptn_year = msg_common_get_date_best_pattern(bubble_data->locale, MSG_UI_DATE_PATTERN_YEAR);
385
386         if (vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, msg_ui_bubble_timezone_change_cb, (void *)bubble_data) < 0) {
387                 D_EMSG("Fail to register vconf CB with [%s]", VCONFKEY_SYSTEM_TIME_CHANGED);
388         }
389
390 #ifdef _BUBBLE_FLICK_EVENT
391         evas_object_event_callback_add(bubble_data->bubble_layout, EVAS_CALLBACK_MOUSE_DOWN, msg_ui_bubble_layout_mouse_down_cb, (const void*)bubble_data);
392 #endif
393         msg_ui_bubble_list_load(bubble_data);
394 }
395
396 Evas_Object *msg_ui_bubble_toolbar_btn_create(Evas_Object *parent, char *icon_path, char *button_text)
397 {
398         D_ENTER;
399         D_MSG_RETVM_IF(parent == NULL, NULL, "parent == NULL");
400
401         Evas_Object *button = elm_button_add(parent);
402
403         evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
404         evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL);
405
406         elm_object_style_set(button, "naviframe_control/default");
407
408         if (icon_path) {
409                 Evas_Object *icon = elm_icon_add(button);
410                 elm_image_file_set(icon, MSG_IMAGES_EDJ, icon_path);
411                 elm_object_content_set(button,icon);
412                 evas_object_size_hint_min_set(icon, 50, 50);
413                 evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
414                 evas_object_size_hint_align_set(icon, EVAS_HINT_FILL, EVAS_HINT_FILL);
415         } else if (button_text) {
416                 elm_object_text_set(button, button_text);
417         }
418         evas_object_show(button);
419
420         D_LEAVE;
421         return button;
422 }
423
424 void msg_ui_bubble_reg_bubble_cb_func(PMSG_BUBBLE_DATA pData)
425 {
426         MSG_UI_ENTER(MSG_UI_LEVEL_DEBUG);
427
428         MSG_UI_RETM_IF(MSG_UI_LEVEL_ERR, pData == NULL, "PMSG_BUBBLE_DATA is NULL");
429
430         MSG_COMPOSER_VIEW_DATA_S *cd = (MSG_COMPOSER_VIEW_DATA_S *)pData->callback_data;
431
432         msg_reg_storage_change_callback(pData->msgHandle, &msg_ui_bubble_msg_storage_change_cb, (void *)cd);
433
434         MSG_UI_LEAVE(MSG_UI_LEVEL_DEBUG);
435 }
436