2 * Copyright 2012 Samsung Electronics Co., Ltd
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
8 * http://www.tizenopensource.org/license
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.
17 #include <Elementary.h>
21 #include <devman_haptic.h>
22 #include "msg-ui-composer-common.h"
23 #include "msg-ui-composer-body.h"
24 #include "msg-ui-composer-recipient.h"
25 #include "msg-ui-composer-popup.h"
26 #include "msg-ui-composer-data.h"
27 #include "msg-ui-composer-bubble.h"
28 #include "msg-ui-composer-main.h"
30 /* vib feedback apply when message type change*/
31 static bool bVibrating;
32 static int dev_handle;
34 char *msg_ui_composer_edj_get(MSG_COMPOSER_VIEW_DATA_S *cd)
36 if (cd->current_theme == MSG_UI_THEME_WHITE)
37 return MSGC_UI_WHITE_EDJ;
39 return MSGC_UI_DEFAULT_EDJ; /*black*/
42 Evas_Object *msg_ui_composer_load_edj(Evas_Object *parent, const char *edj_file, const char *group)
45 layout = elm_layout_add(parent);
47 elm_layout_file_set(layout, edj_file, group);
51 Evas_Object *msg_ui_composer_layout_create(Evas_Object *parent, bool indicator)
54 D_MSG_RETVM_IF(parent == NULL, NULL, "parent object == NULL");
58 layout = elm_layout_add(parent);
60 D_EMSG("[ASSERT] elm_layout_add failed!!");
64 if (indicator == true)
65 elm_layout_theme_set(layout, "layout", "application", "default");
67 elm_layout_theme_set(layout, "layout", "application", "noindicator");
69 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
70 evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
71 evas_object_show(layout);
76 Evas_Object *msg_ui_composer_conformant_create(Evas_Object *parent_win, Evas_Object *inner)
80 D_MSG_RETVM_IF(!parent_win, NULL,"Inputted Paremeter Window is Invalid");
81 D_MSG_RETVM_IF(!inner, NULL,"Inputted Paremeter Content is Invalid");
83 conform = elm_conformant_add(parent_win);
84 D_MSG_RETVM_IF(!conform, NULL,"Fail to Create conformant object");
86 elm_win_conformant_set(parent_win, EINA_TRUE);
87 evas_object_size_hint_weight_set(conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
88 evas_object_size_hint_align_set(conform, EVAS_HINT_FILL, EVAS_HINT_FILL);
89 elm_win_resize_object_add(parent_win, conform);
90 evas_object_show(conform);
92 elm_object_content_set(conform, inner);
97 Evas_Object *msg_ui_composer_bg_create(Evas_Object *parent)
99 D_MSG_RETVM_IF(parent == NULL, NULL, "parent object == NULL");
100 Evas_Object *bg = elm_bg_add(parent);
101 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
102 evas_object_show(bg);
106 int64 msg_composer_get_file_size(const char *path)
108 return ecore_file_size(path);
111 char *msg_common_get_file_ext(const char *a_pszfile_name)
113 if (a_pszfile_name != NULL) {
114 int nlen = strlen(a_pszfile_name);
115 char *psztemp = (char *)a_pszfile_name + nlen;
119 if (*psztemp == '.') {
130 void msg_ui_composer_clear(MSG_COMPOSER_VIEW_DATA_S *cd)
133 D_MSG_RETM_IF(cd == NULL, "Composer Data is NULL");
137 msg_ui_composer_recipient_clear(cd->recipient);
139 msg_ui_composer_body_clear(cd);
144 Eina_Bool msg_ui_composer_last_focus_load(void *data)
147 MSG_COMPOSER_VIEW_DATA_S *cd = (MSG_COMPOSER_VIEW_DATA_S *)data;
148 if(!cd) return EINA_FALSE;
150 if (cd->last_focus_entry == NULL) {
151 D_MSG("NO ENTRY FOCUS");
155 elm_object_focus_set(cd->last_focus_entry, EINA_TRUE);
156 D_MSG("### Focused Entry Load = %p",cd->last_focus_entry);
161 void msg_ui_composer_last_focused_entry_set(void *data, Evas_Object *entry)
163 MSG_COMPOSER_VIEW_DATA_S *cd;
164 cd = (MSG_COMPOSER_VIEW_DATA_S *)data;
165 cd->last_focus_entry = entry;
168 Evas_Object *msg_ui_composer_last_focused_entry_get(void *data)
170 MSG_COMPOSER_VIEW_DATA_S *cd;
171 cd = (MSG_COMPOSER_VIEW_DATA_S *)data;
172 if (!cd) return NULL;
174 return cd->last_focus_entry;
177 Evas_Object *msg_ui_composer_last_body_entry_get(void *data)
181 MSG_COMPOSER_VIEW_DATA_S *cd = (MSG_COMPOSER_VIEW_DATA_S *)data;
183 MSG_COMPOSER_BODY_PAGE_S *page_data = eina_list_nth(cd->body_data.page_list, cd->current_edit_entry);
184 D_MSG("cd->current_edit_entry = %d", cd->current_edit_entry);
186 if (page_data && page_data->entry) {
187 return page_data->entry;
189 D_MSG("No Entry Saved");
197 void bundle_send_to_result(void *data, char *key, char *val)
200 D_MSG("key = %s, val = %s", key, val);
202 MSG_COMPOSER_VIEW_DATA_S *cd = (MSG_COMPOSER_VIEW_DATA_S *)data;
206 bundle_add(b, key, val);
208 ug_send_result(cd->ug, b);
215 int msg_ui_composer_thread_id_get(MSG_HANDLE_T msg_handle, const char *recipient)
217 char tmp_recipient[DEF_BUF_LEN] = {0,};
218 MSG_ERROR_T err = MSG_SUCCESS;
219 MSG_SORT_RULE_S sortRule = {0, };
220 MSG_THREAD_VIEW_LIST_S peerList = {0,};
222 char thread_addr_r[DEF_THREAD_ADDR_LEN] = {0};
224 sortRule.sortType = MSG_SORT_BY_THREAD_DATE;
225 sortRule.bAscending = false;
227 strncpy(tmp_recipient, recipient, sizeof(tmp_recipient)-1);
228 D_MSG("recipient = %s:%s, tmp recipient = %s", recipient, strdup(recipient), tmp_recipient);
229 g_strreverse(tmp_recipient);
230 D_MSG("tmp_recipient = %s", tmp_recipient);
231 err = msg_get_thread_view_list(msg_handle, &sortRule, &peerList);
232 for (row = 0; row < peerList.nCount; row++) {
233 if (strlen(msg_thread_view_get_address(peerList.msgThreadInfo[row]))) {
234 strncpy(thread_addr_r, msg_thread_view_get_address(peerList.msgThreadInfo[row]), strlen(msg_thread_view_get_address(peerList.msgThreadInfo[row])));
235 g_strreverse(thread_addr_r);
236 if (g_ascii_strncasecmp(thread_addr_r, tmp_recipient, COMPARE_STRING_NUM) == 0) {
237 D_MSG("FIND THREAD ADDRESS = %s", msg_thread_view_get_address(peerList.msgThreadInfo[row]));
243 if (row >= peerList.nCount) {
244 msg_release_thread_view_list(&peerList);
245 D_MSG("CANNOT FIND THREAD");
249 int retid = msg_thread_view_get_thread_id(peerList.msgThreadInfo[row]);
250 msg_release_thread_view_list(&peerList);
254 char *msg_ui_composer_thread_recipient_get(MSG_HANDLE_T msg_handle, int inp_tid)
256 MSG_ERROR_T err = MSG_SUCCESS;
257 MSG_SORT_RULE_S sortRule = {0, };
258 MSG_THREAD_VIEW_LIST_S peerList = {0,};
260 char *ret_recipient = NULL;
261 sortRule.sortType = MSG_SORT_BY_THREAD_DATE;
262 sortRule.bAscending = false;
264 err = msg_get_thread_view_list(msg_handle, &sortRule, &peerList);
265 for (row = 0; row < peerList.nCount; row++) {
266 if (inp_tid == msg_thread_view_get_thread_id(peerList.msgThreadInfo[row])) {
267 ret_recipient = strdup(msg_thread_view_get_address(peerList.msgThreadInfo[row]));
272 msg_release_thread_view_list(&peerList);
273 return ret_recipient;
276 bool msg_ui_composer_common_is_send_possible(MSG_COMPOSER_VIEW_DATA_S *cd)
281 MSG_UI_DEBUG(MSG_UI_LEVEL_ASSERT, "[ASSERT] composer data is NULL");
285 MSG_COMPOSER_BODY_S *body_data = &cd->body_data;
286 MSG_COMPOSER_BODY_PAGE_S *page_data = NULL;
288 if (cd->msg_type == COMPOSER_MSG_TYPE_SMS) {
289 page_data = (MSG_COMPOSER_BODY_PAGE_S *)eina_list_nth(body_data->page_list, 0);
291 char *body_text = elm_entry_markup_to_utf8(elm_entry_entry_get(page_data->entry));
293 if (strlen(body_text) > 0) {
301 MSG_UI_DEBUG(MSG_UI_LEVEL_ASSERT, "[ASSERT] invalid message type");
309 static gboolean __msg_ui_composer_vib_timeout_cb(gpointer data)
315 if (bVibrating == true) {
316 ret = device_haptic_stop_play(dev_handle);
319 MSG_UI_DEBUG(MSG_UI_LEVEL_ASSERT, "[ASSERT] Fail to stop haptic : [%d]", ret);
322 ret = device_haptic_close(dev_handle);
325 MSG_UI_DEBUG(MSG_UI_LEVEL_ASSERT, "[ASSERT] Fail to close haptic : [%d]", ret);
336 void msg_ui_composer_common_play_vibration()
341 int vibPattern = EFFCTVIBE_NOTIFICATION;
344 dev_handle = device_haptic_open(DEV_IDX_0, 0);
346 g_timeout_add(150, __msg_ui_composer_vib_timeout_cb, NULL);
348 ret = device_haptic_play_pattern(dev_handle, vibPattern, 1, HAPTIC_FEEDBACK_LEVEL_5);
351 MSG_UI_DEBUG(MSG_UI_LEVEL_ASSERT, "[ASSERT] Fail to play haptic : [%d]", ret);
357 void msg_composer_entry_filter_remove_markup(void *data, Evas_Object *entry, char **text)
360 D_MSG_RETM_IF(text == NULL || *text == NULL, "New Text is NULL");
362 char *preedit_str = NULL;
363 char *utf8_text = NULL;
364 char *convert_text = NULL;
365 D_MSG("text %s", *text);
366 /* Check preeditting text and return if it exist*/
367 preedit_str = strstr(*text, "<preedit_sel>");
368 if (preedit_str) return;
370 /* convert from markup text to utf8 text from entry */
371 utf8_text = elm_entry_markup_to_utf8(*text);
374 /* If the string contains "Carrage return ('\n'), it should be changed "<br>" to show properly*/
375 convert_text = elm_entry_utf8_to_markup(utf8_text);
378 *text = strdup(convert_text);
387 int msg_ui_composer_convert_UTF8ToUCS2(unsigned char *pDestText, int maxLength, const char *pSrcText, int srcTextLen)
391 unsigned char *unicodeTemp = (unsigned char*)pDestText;
394 int remainedBuffer = maxLength;
396 if(maxLength == 0 || pSrcText == NULL || pDestText == NULL)
398 MSG_UI_DEBUG(MSG_UI_LEVEL_ASSERT,"[ASSERT]UTF8 to UCS2 Failed as text length is NULL \n");
402 // null terminated string
403 if (srcTextLen == -1) {
404 textLen = strlen((char*)pSrcText);
405 srcTextLen = textLen;
407 textLen = srcTextLen;
413 cd = g_iconv_open("UCS-2BE", "UTF8");
417 err = g_iconv(cd, (char**)&pSrcText, (gsize*)&textLen, (char**)&unicodeTemp, (gsize*)&remainedBuffer);
420 ucs2Length = maxLength - remainedBuffer;
428 void msg_ui_composer_common_tickernoti(MSG_COMPOSER_VIEW_DATA_S *cd, COMPOSER_TICKERNOTI_TYPE_E tickertype)
430 char popup_msg[DEF_BUF_LEN_L] = {0,};
431 MSGC_NOTIFY_ORIENT orient;
432 Evas_Object *parent_notify;
434 D_MSG_RETM_IF(cd == NULL, "Composer Data is Invalid");
436 if (tickertype == COMPOSER_TICKERNOTI_COUNT_MAX) {
437 snprintf(popup_msg, sizeof(popup_msg)-1, MSGC_STR_NOTI_RECIPIENT_MAX, COMPOSER_RECIPIENT_COUNT_MAX);
438 parent_notify = cd->recipient->bx_main;
439 orient = MSGC_NOTIFY_ORIENT_BOTTOM;
440 } else if (tickertype == COMPOSER_TICKERNOTI_DUP_RECP) {
441 snprintf(popup_msg, sizeof(popup_msg)-1, MSGC_STR_NOTI_RECIPIENT_DUP);
442 parent_notify = cd->recipient->bx_main;
443 orient = MSGC_NOTIFY_ORIENT_BOTTOM;
444 } else if (tickertype == COMPOSER_TICKERNOTI_INVALID_RECP) {
445 snprintf(popup_msg, sizeof(popup_msg)-1, MSGC_STR_NOTI_RECIPIENT_INVALID);
446 parent_notify = cd->recipient->bx_main;
447 orient = MSGC_NOTIFY_ORIENT_BOTTOM;
448 } else if (tickertype == COMPOSER_TICKERNOTI_CHANGED_SMS) {
449 snprintf(popup_msg, sizeof(popup_msg)-1, MSGC_STR_NOTI_CHANGE_SMS);
450 parent_notify = cd->ly_body;
451 orient = MSGC_NOTIFY_ORIENT_BOTTOM;
457 evas_object_del(cd->noti);
460 cd->noti = msg_ui_composer_notify_show(parent_notify, popup_msg, COMPOSER_STATUS_POPUP_DEFAULT_TIME, orient, false);
463 void msg_ui_composer_entry_imf_state_cb(void * data, Ecore_IMF_Context *ctx, int value)
467 MSG_COMPOSER_VIEW_DATA_S *cd = (MSG_COMPOSER_VIEW_DATA_S *)data;
469 D_MSG_RETM_IF(cd == NULL, "Composer Data is Invalid");
470 D_MSG_RETM_IF(ctx == NULL, "Ecore_IMF_Context is Invalid");
472 if (value == ECORE_IMF_INPUT_PANEL_STATE_SHOW) {
473 D_MSG("Imf status SHOW");
474 edje_object_signal_emit(_EDJ(cd->ly_body), "body_contract","*");
475 } else if (value == ECORE_IMF_INPUT_PANEL_STATE_HIDE) {
476 D_MSG("Imf status HIDE");
478 if (msg_ui_composer_common_is_send_possible(cd) == false) {
479 D_MSG("body_EXPAND and send button HIDE ");
480 edje_object_signal_emit(_EDJ(cd->ly_body), "body_expand","*");
483 D_EMSG("imf status INVALID");
489 void msg_ui_composer_evas_object_delete_cb(void *data, Evas * e, Evas_Object *obj, void *event_info)
495 D_PRINT("delete = %s[%p]", (char *)data, obj);