From c70fe77be488f4e7e20b9a49445fd05ba35fb483 Mon Sep 17 00:00:00 2001 From: "sungwook79.park" Date: Tue, 16 May 2017 19:18:43 +0900 Subject: [PATCH 01/16] Fix crash issue about item_style in elm_naviframe_item_push Change-Id: I7618d2a18d1f60545a2a2d7f786f9c4b704068e7 Signed-off-by: sungwook79.park --- src/MoreOption.cpp | 5 ++++- src/w-input-emoticon.cpp | 5 ++++- src/w-input-keyboard.cpp | 5 ++++- src/w-input-selector.cpp | 5 ++++- src/w-input-stt-voice.cpp | 5 ++++- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/MoreOption.cpp b/src/MoreOption.cpp index d0a4b36..5159e0c 100755 --- a/src/MoreOption.cpp +++ b/src/MoreOption.cpp @@ -119,7 +119,10 @@ void MoreOption::SetContentLayout(Evas_Object *content) { elm_object_part_content_set(more_option_layout, "elm.swallow.content", content); Elm_Object_Item *nit = NULL; - nit = elm_naviframe_item_push(nf, NULL, NULL, NULL, more_option_layout, "empty"); + const char *item_style = NULL; + if (_WEARABLE) + item_style = "empty"; + nit = elm_naviframe_item_push(nf, NULL, NULL, NULL, more_option_layout, item_style); elm_naviframe_item_title_enabled_set(nit, EINA_FALSE, EINA_FALSE); elm_naviframe_item_pop_cb_set(nit, diff --git a/src/w-input-emoticon.cpp b/src/w-input-emoticon.cpp index b7afb02..6c988c0 100755 --- a/src/w-input-emoticon.cpp +++ b/src/w-input-emoticon.cpp @@ -767,7 +767,10 @@ Evas_Object* _create_emoticon_genlist(void* data) evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(genlist); - Elm_Object_Item *nf_emoticon_item = elm_naviframe_item_push(ad->naviframe, NULL, NULL, NULL, genlist, "empty"); + const char *item_style = NULL; + if (_WEARABLE) + item_style = "empty"; + Elm_Object_Item *nf_emoticon_item = elm_naviframe_item_push(ad->naviframe, NULL, NULL, NULL, genlist, item_style); elm_naviframe_item_pop_cb_set(nf_emoticon_item, _custom_back_cb2, ad); diff --git a/src/w-input-keyboard.cpp b/src/w-input-keyboard.cpp index 0bfa13f..52051a6 100755 --- a/src/w-input-keyboard.cpp +++ b/src/w-input-keyboard.cpp @@ -134,7 +134,10 @@ void create_fullscreen_editor(void *data) evas_object_resize(ad->naviframe, 360, 360); evas_object_show(ad->naviframe); - Elm_Object_Item *nf_item = elm_naviframe_item_push(ad->naviframe, NULL, NULL, NULL, box, "empty"); + const char *item_style = NULL; + if (_WEARABLE) + item_style = "empty"; + Elm_Object_Item *nf_item = elm_naviframe_item_push(ad->naviframe, NULL, NULL, NULL, box, item_style); elm_naviframe_item_pop_cb_set(nf_item, custom_back_cb, NULL); } diff --git a/src/w-input-selector.cpp b/src/w-input-selector.cpp index 4c39358..6b096cb 100755 --- a/src/w-input-selector.cpp +++ b/src/w-input-selector.cpp @@ -608,12 +608,15 @@ Evas_Object* _create_genlist(Evas_Object* navi) show_gl_focus(EINA_FALSE); + const char *item_style = NULL; + if (_WEARABLE) + item_style = "empty"; Elm_Object_Item *nf_main_item = elm_naviframe_item_push(navi, NULL, NULL, NULL, genlist, - "empty"); + item_style); elm_naviframe_item_pop_cb_set(nf_main_item, back_cb, app_data); evas_object_smart_callback_add(genlist, "realized", _item_realized, NULL); diff --git a/src/w-input-stt-voice.cpp b/src/w-input-stt-voice.cpp index 10a5ec5..7fe546f 100755 --- a/src/w-input-stt-voice.cpp +++ b/src/w-input-stt-voice.cpp @@ -1324,8 +1324,11 @@ void create_setting_window(Evas_Object *more_option_layout) */ genlist = create_language_list(naviframe); + const char *item_style = NULL; + if (_WEARABLE) + item_style = "empty"; //item = elm_naviframe_item_push(naviframe, "IDS_VC_HEADER_VOICE_INPUT_LANGUAGE", NULL, NULL, genlist, NULL); - elm_naviframe_item_push(naviframe, NULL, NULL, NULL, genlist, "empty"); + elm_naviframe_item_push(naviframe, NULL, NULL, NULL, genlist, item_style); //elm_object_item_domain_text_translatable_set(item, PACKAGE, EINA_TRUE); g_setting_window = window; -- 2.7.4 From c50fe9fef899423321b8e3767c3feb3396e7af3d Mon Sep 17 00:00:00 2001 From: "sungwook79.park" Date: Wed, 17 May 2017 13:51:54 +0900 Subject: [PATCH 02/16] Modify edit UI in keyboard input Change-Id: I0e570a081fcc1f34f1ae45b47c45c98ef057cb0e Signed-off-by: sungwook79.park --- inc/w-input-keyboard.h | 2 +- src/w-input-keyboard.cpp | 87 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/inc/w-input-keyboard.h b/inc/w-input-keyboard.h index a04fccd..b127fdf 100755 --- a/inc/w-input-keyboard.h +++ b/inc/w-input-keyboard.h @@ -21,7 +21,7 @@ #include #include -const int KEYBOARD_EDITOR_CHAR_COUNT_MAX = 50; +const int KEYBOARD_EDITOR_CHAR_COUNT_MAX = 300; bool input_keyboard_init(app_control_h app_control); void input_keyboard_deinit(void); bool input_keyboard_launch(Evas_Object *window, void * data); diff --git a/src/w-input-keyboard.cpp b/src/w-input-keyboard.cpp index 52051a6..d7e2bf2 100755 --- a/src/w-input-keyboard.cpp +++ b/src/w-input-keyboard.cpp @@ -141,12 +141,97 @@ void create_fullscreen_editor(void *data) elm_naviframe_item_pop_cb_set(nf_item, custom_back_cb, NULL); } +static void editfield_focused_cb(void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *editfield = (Evas_Object *)data; + elm_object_signal_emit(editfield, "elm,state,focused", ""); + + if (!elm_entry_is_empty(obj)) + elm_object_signal_emit(editfield, "elm,action,show,button", ""); +} + +static void editfield_unfocused_cb(void *data, Evas_Object *obj, void *event_info) +{ + Evas_Object *editfield = (Evas_Object *)data; + elm_object_signal_emit(editfield, "elm,state,unfocused", ""); + elm_object_signal_emit(editfield, "elm,action,hide,button", ""); +} + +static Evas_Object *create_multiline_editfield_layout(Evas_Object *parent, void *data) +{ + Evas_Object *editfield; + + editfield = elm_layout_add(parent); + elm_layout_theme_set(editfield, "layout", "editfield", "multiline"); + evas_object_size_hint_align_set(editfield, EVAS_HINT_FILL, 0.0); + evas_object_size_hint_weight_set(editfield, EVAS_HINT_EXPAND, 0.0); + + entry = elm_entry_add(editfield); + static Elm_Entry_Filter_Limit_Size limit_filter_data; + limit_filter_data.max_char_count = KEYBOARD_EDITOR_CHAR_COUNT_MAX; + elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size, &limit_filter_data); + evas_object_smart_callback_add(entry, "maxlength,reached", maxlength_cb, data); + + elm_object_part_text_set(entry, "elm.guide", g_input_keyboard_data.guide_text); + evas_object_smart_callback_add(entry, "focused", editfield_focused_cb, editfield); + evas_object_smart_callback_add(entry, "unfocused", editfield_unfocused_cb, editfield); + elm_object_part_content_set(editfield, "elm.swallow.content", entry); + + return editfield; +} + +static Evas_Object *create_editfield_view(void *data) +{ + App_Data *ad = (App_Data *)data; + + Evas_Object *main_scroller, *main_box, *editfield; + + main_scroller = elm_scroller_add(ad->naviframe); + elm_scroller_bounce_set(main_scroller, EINA_FALSE, EINA_TRUE); + evas_object_size_hint_weight_set(main_scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(main_scroller, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(main_scroller); + + main_box = elm_box_add(main_scroller); + evas_object_size_hint_align_set(main_box, EVAS_HINT_FILL, 0.0); + evas_object_size_hint_weight_set(main_box, EVAS_HINT_EXPAND, 0.0); + evas_object_show(main_box); + + editfield = create_multiline_editfield_layout(main_box, data); + elm_box_pack_end(main_box, editfield); + evas_object_show(editfield); + + Evas_Object *btn = elm_button_add(main_box); + elm_object_text_set(btn, "OK"); + evas_object_size_hint_weight_set(btn, 0.5, 0.5); + evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_smart_callback_add(btn, "clicked", btn_clicked_cb, NULL); + evas_object_show(btn); + elm_box_pack_end(main_box, btn); + + elm_object_content_set(main_scroller, main_box); + + evas_object_show(ad->naviframe); + const char *item_style = NULL; + if (_WEARABLE) + item_style = "empty"; + Elm_Object_Item *nf_item = elm_naviframe_item_push(ad->naviframe, NULL, NULL, NULL, main_scroller, item_style); + elm_naviframe_item_pop_cb_set(nf_item, custom_back_cb, NULL); + + return main_scroller; +} + bool input_keyboard_launch(Evas_Object *window, void *data) { if (window == NULL) { PRINTFUNC(DLOG_ERROR, "Can not get window"); return false; } - create_fullscreen_editor(data); + + if (_WEARABLE) + create_fullscreen_editor(data); + else + create_editfield_view(data); + return true; } -- 2.7.4 From 908d95139ea028ae1540273837caca567c081312 Mon Sep 17 00:00:00 2001 From: "sungwook79.park" Date: Wed, 17 May 2017 14:22:27 +0900 Subject: [PATCH 03/16] Enable only keyboard input in TV profile Change-Id: I6a629fdcb5fc978b601d8e1e6b6e59ea4b00ea0e Signed-off-by: sungwook79.park --- src/w-input-selector.cpp | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/w-input-selector.cpp b/src/w-input-selector.cpp index 6b096cb..ed6cb80 100755 --- a/src/w-input-selector.cpp +++ b/src/w-input-selector.cpp @@ -924,23 +924,30 @@ void _app_service(app_control_h service, void* user_data) g_input_type_data.input_type_array = input_type_array; g_input_type_data.input_type_array_len = input_type_array_len; } else { - ret = app_control_get_extra_data(service, APP_CONTROL_DATA_INPUT_TYPE, &context); - if (ret == APP_CONTROL_ERROR_NONE) { - if (!strcmp(context, "input_voice")) { - app_data->app_type = APP_TYPE_STT; - _stt_clicked_cb((void *)app_data, NULL, NULL); - goto ACTIVATE; - } else if (!strcmp(context, "input_emoticon")) { - app_data->app_type = APP_TYPE_EMOTICON; - _emoticon_clicked_cb((void *)app_data, NULL, NULL); - goto ACTIVATE; - } else if (!strcmp(context, "input_keyboard")) { - app_data->app_type = APP_TYPE_KEYBOARD; - input_keyboard_init(service); - _keyboard_clicked_cb((void *)app_data, NULL, NULL); - goto ACTIVATE; - } else if (!strcmp(context, "input_reply")) { - app_data->app_type = APP_TYPE_REPLY; + if (_TV) { + app_data->app_type = APP_TYPE_KEYBOARD; + input_keyboard_init(service); + _keyboard_clicked_cb((void *)app_data, NULL, NULL); + goto ACTIVATE; + } else { + ret = app_control_get_extra_data(service, APP_CONTROL_DATA_INPUT_TYPE, &context); + if (ret == APP_CONTROL_ERROR_NONE) { + if (!strcmp(context, "input_voice")) { + app_data->app_type = APP_TYPE_STT; + _stt_clicked_cb((void *)app_data, NULL, NULL); + goto ACTIVATE; + } else if (!strcmp(context, "input_emoticon")) { + app_data->app_type = APP_TYPE_EMOTICON; + _emoticon_clicked_cb((void *)app_data, NULL, NULL); + goto ACTIVATE; + } else if (!strcmp(context, "input_keyboard")) { + app_data->app_type = APP_TYPE_KEYBOARD; + input_keyboard_init(service); + _keyboard_clicked_cb((void *)app_data, NULL, NULL); + goto ACTIVATE; + } else if (!strcmp(context, "input_reply")) { + app_data->app_type = APP_TYPE_REPLY; + } } } } -- 2.7.4 From b061524626e252af8a78e1f1e660be6df31f88bc Mon Sep 17 00:00:00 2001 From: "sungwook79.park" Date: Thu, 18 May 2017 13:23:43 +0900 Subject: [PATCH 04/16] Fix issue that remaining black screen when back key is pressed after launch keyboard input with app_control Change-Id: I89590d06606e535b4ef02ad18f30ad1939e16d2d Signed-off-by: sungwook79.park --- src/w-input-selector.cpp | 58 ++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/w-input-selector.cpp b/src/w-input-selector.cpp index ed6cb80..b79534b 100755 --- a/src/w-input-selector.cpp +++ b/src/w-input-selector.cpp @@ -569,15 +569,15 @@ void _back_to_genlist_for_selector() if (!app_data) return; - if (app_data->app_type == APP_TYPE_STT || app_data->app_type == APP_TYPE_EMOTICON){ - PRINTFUNC(DLOG_DEBUG, "launched as STT/EMOTICON mode, So exit here."); - reply_to_sender_by_callback(NULL, NULL); - elm_exit(); - } if (_WEARABLE) { Evas_Object *circle_genlist = (Evas_Object *) evas_object_data_get(app_data->genlist, "circle"); eext_rotary_object_event_activated_set(circle_genlist, EINA_TRUE); } + if (app_data->app_type == APP_TYPE_STT || app_data->app_type == APP_TYPE_EMOTICON || app_data->app_type == APP_TYPE_KEYBOARD){ + PRINTFUNC(DLOG_DEBUG, "launched as STT/EMOTICON/KEYBOARD mode, So exit here."); + reply_to_sender_by_callback(NULL, NULL); + elm_exit(); + } } static void _item_realized(void *data, Evas_Object *obj, void *event_info) //called when list scrolled @@ -918,36 +918,36 @@ void _app_service(app_control_h service, void* user_data) app_control_clone(&(app_data->source_app_control), service); app_data->reply_type = REPLY_APP_NORMAL; + if (_TV || _MOBILE) { + app_data->app_type = APP_TYPE_KEYBOARD; + input_keyboard_init(service); + _keyboard_clicked_cb((void *)app_data, NULL, NULL); + goto ACTIVATE; + } + ret = app_control_is_extra_data_array(service, APP_CONTROL_DATA_INPUT_TYPE, &is_extra_data_array); if ( is_extra_data_array == true) { ret = app_control_get_extra_data_array(service, APP_CONTROL_DATA_INPUT_TYPE, &input_type_array, &input_type_array_len); g_input_type_data.input_type_array = input_type_array; g_input_type_data.input_type_array_len = input_type_array_len; } else { - if (_TV) { - app_data->app_type = APP_TYPE_KEYBOARD; - input_keyboard_init(service); - _keyboard_clicked_cb((void *)app_data, NULL, NULL); - goto ACTIVATE; - } else { - ret = app_control_get_extra_data(service, APP_CONTROL_DATA_INPUT_TYPE, &context); - if (ret == APP_CONTROL_ERROR_NONE) { - if (!strcmp(context, "input_voice")) { - app_data->app_type = APP_TYPE_STT; - _stt_clicked_cb((void *)app_data, NULL, NULL); - goto ACTIVATE; - } else if (!strcmp(context, "input_emoticon")) { - app_data->app_type = APP_TYPE_EMOTICON; - _emoticon_clicked_cb((void *)app_data, NULL, NULL); - goto ACTIVATE; - } else if (!strcmp(context, "input_keyboard")) { - app_data->app_type = APP_TYPE_KEYBOARD; - input_keyboard_init(service); - _keyboard_clicked_cb((void *)app_data, NULL, NULL); - goto ACTIVATE; - } else if (!strcmp(context, "input_reply")) { - app_data->app_type = APP_TYPE_REPLY; - } + ret = app_control_get_extra_data(service, APP_CONTROL_DATA_INPUT_TYPE, &context); + if (ret == APP_CONTROL_ERROR_NONE) { + if (!strcmp(context, "input_voice")) { + app_data->app_type = APP_TYPE_STT; + _stt_clicked_cb((void *)app_data, NULL, NULL); + goto ACTIVATE; + } else if (!strcmp(context, "input_emoticon")) { + app_data->app_type = APP_TYPE_EMOTICON; + _emoticon_clicked_cb((void *)app_data, NULL, NULL); + goto ACTIVATE; + } else if (!strcmp(context, "input_keyboard")) { + app_data->app_type = APP_TYPE_KEYBOARD; + input_keyboard_init(service); + _keyboard_clicked_cb((void *)app_data, NULL, NULL); + goto ACTIVATE; + } else if (!strcmp(context, "input_reply")) { + app_data->app_type = APP_TYPE_REPLY; } } } -- 2.7.4 From 8458c11b54c012bc2999fc2e2e7b21d295e0b53a Mon Sep 17 00:00:00 2001 From: "sungwook79.park" Date: Thu, 18 May 2017 14:08:15 +0900 Subject: [PATCH 05/16] Change elm_exit to ui_app_exit Change-Id: Ic30784c4f6024e1c8d04aa4f93bd335d1db37f60 Signed-off-by: sungwook79.park --- src/w-input-emoticon.cpp | 3 ++- src/w-input-keyboard.cpp | 2 +- src/w-input-selector.cpp | 6 +++--- src/w-input-stt-voice.cpp | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/w-input-emoticon.cpp b/src/w-input-emoticon.cpp index 6c988c0..0ead5fb 100755 --- a/src/w-input-emoticon.cpp +++ b/src/w-input-emoticon.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include #include @@ -381,7 +382,7 @@ static void _emoticon_item_clicked_cb(void *data, Evas_Object * obj, void *event if (utf_8) free(utf_8); - elm_exit(); + ui_app_exit(); } Evas_Object* get_emoticon_button(Evas_Object* parent, int index){ diff --git a/src/w-input-keyboard.cpp b/src/w-input-keyboard.cpp index d7e2bf2..50d30c1 100755 --- a/src/w-input-keyboard.cpp +++ b/src/w-input-keyboard.cpp @@ -83,7 +83,7 @@ void btn_clicked_cb(void *data, Evas_Object *obj, void *event_info) set_source_caller_app_id(app_control); free(app_id); reply_to_sender_by_callback(getText, "keyboard"); - elm_exit(); + ui_app_exit(); } static Eina_Bool custom_back_cb(void *data, Elm_Object_Item *it) diff --git a/src/w-input-selector.cpp b/src/w-input-selector.cpp index b79534b..010d98b 100755 --- a/src/w-input-selector.cpp +++ b/src/w-input-selector.cpp @@ -152,7 +152,7 @@ void init_customizing_theme(void) static Eina_Bool back_cb(void *data, Elm_Object_Item *it) { reply_to_sender_by_callback_for_back(); - elm_exit(); + ui_app_exit(); return EINA_FALSE; } @@ -210,7 +210,7 @@ static void __ise_template_gl_sel(void *data, Evas_Object *obj, void *event_info if (index < (int)template_list.size()) { reply_to_sender_by_callback(gettext(template_list[index].text.c_str()), "template"); - elm_exit(); + ui_app_exit(); } } } @@ -576,7 +576,7 @@ void _back_to_genlist_for_selector() if (app_data->app_type == APP_TYPE_STT || app_data->app_type == APP_TYPE_EMOTICON || app_data->app_type == APP_TYPE_KEYBOARD){ PRINTFUNC(DLOG_DEBUG, "launched as STT/EMOTICON/KEYBOARD mode, So exit here."); reply_to_sender_by_callback(NULL, NULL); - elm_exit(); + ui_app_exit(); } } diff --git a/src/w-input-stt-voice.cpp b/src/w-input-stt-voice.cpp index 7fe546f..0aa4b21 100755 --- a/src/w-input-stt-voice.cpp +++ b/src/w-input-stt-voice.cpp @@ -476,7 +476,7 @@ static void on_confirm_button_clicked_cb(void *data, Evas_Object *obj, void *eve reply_to_sender_by_callback(result_text.c_str(), "voice"); destroy_voice(); powerUnlock(); - elm_exit(); + ui_app_exit(); return; } -- 2.7.4 From a51daaa428e13c61ab793478acc2c37cc2141707 Mon Sep 17 00:00:00 2001 From: "sungwook79.park" Date: Thu, 18 May 2017 15:21:39 +0900 Subject: [PATCH 06/16] Add property for entry in keyboard input Change-Id: I869fbb7de9cfde18f4262ee5a66a5cbff70d1bd8 Signed-off-by: sungwook79.park --- src/w-input-keyboard.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/w-input-keyboard.cpp b/src/w-input-keyboard.cpp index 50d30c1..869cfb5 100755 --- a/src/w-input-keyboard.cpp +++ b/src/w-input-keyboard.cpp @@ -172,9 +172,14 @@ static Evas_Object *create_multiline_editfield_layout(Evas_Object *parent, void elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size, &limit_filter_data); evas_object_smart_callback_add(entry, "maxlength,reached", maxlength_cb, data); + elm_entry_scrollable_set(entry, EINA_TRUE); + elm_scroller_policy_set(entry, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO); elm_object_part_text_set(entry, "elm.guide", g_input_keyboard_data.guide_text); + elm_entry_entry_set(entry, g_input_keyboard_data.default_text); + elm_entry_cursor_end_set(entry); evas_object_smart_callback_add(entry, "focused", editfield_focused_cb, editfield); evas_object_smart_callback_add(entry, "unfocused", editfield_unfocused_cb, editfield); + evas_object_show(entry); elm_object_part_content_set(editfield, "elm.swallow.content", entry); return editfield; -- 2.7.4 From 56a5a38d2d3928762cc2935b6c70e0f4e484aa59 Mon Sep 17 00:00:00 2001 From: "sungwook79.park" Date: Thu, 18 May 2017 16:56:11 +0900 Subject: [PATCH 07/16] Update package version to 0.1.170518 Change-Id: Ifaaec096fa185b0d4026d6052c293306d6902aae Signed-off-by: sungwook79.park --- org.tizen.inputdelegator.xml | 2 +- packaging/org.tizen.inputdelegator.spec | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/org.tizen.inputdelegator.xml b/org.tizen.inputdelegator.xml index bd8d4b3..8524353 100755 --- a/org.tizen.inputdelegator.xml +++ b/org.tizen.inputdelegator.xml @@ -1,5 +1,5 @@ - + diff --git a/packaging/org.tizen.inputdelegator.spec b/packaging/org.tizen.inputdelegator.spec index cd5f0f1..5d55508 100755 --- a/packaging/org.tizen.inputdelegator.spec +++ b/packaging/org.tizen.inputdelegator.spec @@ -9,7 +9,7 @@ Name: org.tizen.inputdelegator Summary: Input Delegator Application -Version: 0.1.170419 +Version: 0.1.170518 Release: 1 Group: Applications License: Apache-2.0 @@ -407,4 +407,4 @@ fi %manifest %{name}.manifest %defattr(-,root,root,-) %{TZ_SYS_RO_APP}/org.tizen.inputdelegator/wearable/* -%endif \ No newline at end of file +%endif -- 2.7.4 From 56549abbd3c454b0a0b0ce816e1c72c4bc987bbd Mon Sep 17 00:00:00 2001 From: "sungwook79.park" Date: Fri, 2 Jun 2017 17:38:20 +0900 Subject: [PATCH 08/16] Add smartreply feature Change-Id: I70c7ccfacb4e8da428a96e9f55167b9676d0db17 Signed-off-by: sungwook79.park --- CMakeLists.txt | 2 + inc/w-input-smartreply.h | 49 ++++ packaging/org.tizen.inputdelegator.spec | 1 + src/w-input-selector.cpp | 206 +++++++++++++- src/w-input-smartreply.cpp | 462 ++++++++++++++++++++++++++++++++ 5 files changed, 718 insertions(+), 2 deletions(-) create mode 100644 inc/w-input-smartreply.h create mode 100644 src/w-input-smartreply.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 85287b4..95b2d21 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ SET(INPUTDELEGATOR_SRCS src/WInputSttMicEffect.cpp src/w-input-stt-voice.cpp src/w-input-template.cpp + src/w-input-smartreply.cpp ) SET(INPUTDELEGATOR_PACKAGE ${PROJECT_NAME}) @@ -49,6 +50,7 @@ SET(PKGS_CHECK_MODULES sqlite3 capi-media-audio-io capi-system-info + smartreply ) diff --git a/inc/w-input-smartreply.h b/inc/w-input-smartreply.h new file mode 100644 index 0000000..619116f --- /dev/null +++ b/inc/w-input-smartreply.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _W_INPUT_SMARTREPLY_H_ +#define _W_INPUT_SMARTREPLY_H_ + +#include +#include + +typedef void (*input_smartreply_changed)(void *user_data); + + +bool input_smartreply_init(app_control_h app_control); + +void input_smartreply_deinit(void); + +const char *input_smartreply_get_lang(void); + +bool input_smartreply_get_reply(void); + +bool input_smartreply_get_reply_async(void); + +int input_smartreply_get_reply_num(void); + +char *input_smartreply_get_nth_item(int index, int *type); + +bool input_smartreply_send_feedback(const char *str); + +void input_smartreply_set_notify(input_smartreply_changed callback, + void *user_data); + +void input_smartreply_unset_notify(void); + +bool input_smartreply_is_enabled(void); + +#endif diff --git a/packaging/org.tizen.inputdelegator.spec b/packaging/org.tizen.inputdelegator.spec index 5d55508..33bf2d9 100755 --- a/packaging/org.tizen.inputdelegator.spec +++ b/packaging/org.tizen.inputdelegator.spec @@ -41,6 +41,7 @@ BuildRequires: pkgconfig(db-util) BuildRequires: pkgconfig(sqlite3) BuildRequires: pkgconfig(capi-media-audio-io) BuildRequires: pkgconfig(capi-system-info) +BuildRequires: pkgconfig(smartreply) %if %{enable_log_manager} BuildRequires: pkgconfig(bundle) diff --git a/src/w-input-selector.cpp b/src/w-input-selector.cpp index 010d98b..d6feeec 100755 --- a/src/w-input-selector.cpp +++ b/src/w-input-selector.cpp @@ -30,6 +30,7 @@ #include "w-input-keyboard.h" #include "w-input-stt-ise.h" #include "w-input-emoticon.h" +#include "w-input-smartreply.h" #include @@ -44,6 +45,7 @@ InputTypeData g_input_type_data; static Elm_Object_Item *it_empty; static Elm_Object_Item *it_title; +static unsigned int g_smartreply_item_size = 0; /* Current Smartreply item size */ static unsigned int g_template_item_size = 0; /* Current Template item size */ Evas_Coord last_step; // 0 ~ 9 for gesture, 10~11 for rotary @@ -89,11 +91,14 @@ Evas_Object* _create_genlist(Evas_Object* parent); void _create_genlist_items(void* user_data); void _create_header_items(void *user_data); void _update_genlist_items(void *user_data); +unsigned int _update_smartreply_items(void *user_data); unsigned int _update_template_items(void *user_data); static void _popup_close_cb(void *data, Evas_Object *obj, void *event_info); static void _popup_back_cb(void *data, Evas_Object *obj, void *event_info); static void input_type_deinit(void); +bool __compare_string(const char * src, const char * dst); + void _init_app_data(App_Data* app_data) { app_data->win_main = NULL; @@ -168,6 +173,12 @@ static void _stt_clicked_cb(void *data, Evas_Object * obj, void *event_info) ise_show_stt_popup(ad); } +static void _input_smartreply_notify_cb(void *user_data) +{ + ecore_main_loop_iterate(); + _update_genlist_items((void *)app_data); +} + static void _input_template_notify_cb(void *user_data) { _update_genlist_items((void *)app_data); @@ -197,6 +208,27 @@ static void _keyboard_clicked_cb(void *data, Evas_Object * obj, void *event_info input_keyboard_launch(ad->win_main, data); } +static void __ise_smartreply_gl_sel(void *data, Evas_Object *obj, void *event_info) +{ + App_Data* app_data = (App_Data*) data; + Elm_Object_Item *item = (Elm_Object_Item *) event_info; + + if (item) { + elm_genlist_item_selected_set(item, EINA_FALSE); + + int index = (intptr_t) elm_object_item_data_get(item); + + int type; + char *reply = input_smartreply_get_nth_item(index, &type); + if (reply) { + input_smartreply_send_feedback(reply); + reply_to_sender_by_callback(reply, "smartreply"); + free(reply); + elm_exit(); + } + } +} + static void __ise_template_gl_sel(void *data, Evas_Object *obj, void *event_info) { Elm_Object_Item *item = (Elm_Object_Item *) event_info; @@ -407,6 +439,23 @@ static Evas_Object * __ise_gl_3button_content_get(void *data, Evas_Object *obj, return NULL; } +static char * __ise_smartreply_gl_text_get(void *data, Evas_Object *obj, const char *part) +{ + if(!strcmp(part, "elm.text")) { + int index; + char *reply = NULL; + index = (intptr_t)data; + if (index < 0) + return NULL; + + reply = input_smartreply_get_nth_item(index, NULL); + if (reply == NULL) + return NULL; + + return reply; + } + return NULL; +} static void __ise_gl_lang_changed(void *data, Evas_Object *obj, void *event_info) { @@ -771,6 +820,11 @@ void _update_genlist_items(void *user_data) _create_header_items(user_data); + if (input_smartreply_is_enabled()) + g_smartreply_item_size = _update_smartreply_items(user_data); + else + g_smartreply_item_size = 0; + g_template_item_size = _update_template_items(user_data); /* Update genlist item position */ @@ -778,11 +832,111 @@ void _update_genlist_items(void *user_data) elm_genlist_item_show(item, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE); } +unsigned int _update_smartreply_items(void *user_data) +{ + App_Data* app_data; + + Elm_Object_Item *first; + Elm_Object_Item *menu; + Elm_Object_Item *pos; + + unsigned int i = 0; + unsigned int len = 0; + unsigned int item_size = 0; + + app_data = (App_Data *)user_data; + + if (app_data == NULL) { + PRINTFUNC(DLOG_ERROR, "Can not get app_data"); + return item_size; + } + + if (app_data->genlist == NULL) { + /* smartreply will update when genlist is exist only */ + PRINTFUNC(DLOG_ERROR, "Can not get getlist"); + return item_size; + } + + /* Move to smartreply */ + first = elm_genlist_first_item_get(app_data->genlist); + menu = elm_genlist_item_next_get(first); + + if (input_smartreply_is_enabled() == false) + return item_size; + + /* Append newly added smartreply list */ + len = input_smartreply_get_reply_num(); + + if (len > 0) { + const std::vector template_list = input_template_get_list(); + + Elm_Genlist_Item_Class *itc; + + itc = elm_genlist_item_class_new(); + itc->item_style = "1text"; + itc->func.text_get = __ise_smartreply_gl_text_get; + itc->func.content_get = NULL; + itc->func.state_get = NULL; + itc->func.del = NULL; + + pos = menu; + + for (i = 0; i < len; i++) { + char *reply = "hello"; + unsigned int j; + bool matched; + + matched = false; + + int type; + reply = input_smartreply_get_nth_item(i, &type); + if (reply == NULL) + continue; + PRINTFUNC(DLOG_DEBUG, "SmartReply = [%d]%s", i, reply); + + + for (j = 0; j < template_list.size(); j++) { + const char *template_str; + + if (template_list[j].use_gettext) + template_str = gettext(template_list[j].text.c_str()); + else + template_str = template_list[j].text.c_str(); + + if (!__compare_string(reply, template_str)) { + matched = true; + break; + } + } + + if (matched == true) + continue; + + pos = elm_genlist_item_append(app_data->genlist, + itc, + (void *)(uintptr_t)i, + NULL, + ELM_GENLIST_ITEM_NONE, + __ise_smartreply_gl_sel, + app_data); + + item_size++; + if (item_size >= 3) + break; + } + elm_genlist_item_class_free(itc); + } + return item_size; +} + + unsigned int _update_template_items(void *user_data) { App_Data* app_data; Elm_Object_Item *first; + Elm_Object_Item *menu; + Elm_Object_Item *pos; unsigned int i = 0; unsigned int item_size = 0; @@ -803,7 +957,20 @@ unsigned int _update_template_items(void *user_data) first = elm_genlist_first_item_get(app_data->genlist); if (first == NULL) return 0; - elm_genlist_item_next_get(first); + menu = elm_genlist_item_next_get(first); + + pos = menu; + /* move to smartreply next if it need */ + if (input_smartreply_is_enabled()) { + unsigned int j = 0; + + for (j = 0; j < g_smartreply_item_size; j++) { + if (pos == NULL) + break; + + pos = elm_genlist_item_next_get(pos); + } + } /* Append New Template list */ const std::vector template_list = input_template_get_list(); @@ -820,7 +987,7 @@ unsigned int _update_template_items(void *user_data) itc->func.del = NULL; for (i = 0; i < template_list.size(); i++) { - elm_genlist_item_append(app_data->genlist, + pos = elm_genlist_item_append(app_data->genlist, itc, (void *)(uintptr_t)i, NULL, @@ -835,6 +1002,34 @@ unsigned int _update_template_items(void *user_data) return item_size; } +bool __compare_string(const char * smart_str, const char * template_str) +{ + int src_len = 0; + int dst_len = 0; + bool ret = true; + + if(!smart_str||!template_str) + return ret; + + src_len = strlen(smart_str); + dst_len = strlen(template_str); + + if(smart_str[src_len-1] == '.') + src_len--; + + while(template_str[dst_len-1] == ' ') + dst_len--; + if(template_str[dst_len-1] == '.') + dst_len--; + + dst_len = (dst_len > src_len)? dst_len : src_len; + + if(!strncmp(smart_str, template_str, (size_t)dst_len)) + ret = false; + + return (ret); +} + bool _app_create(void* user_data) { int width = 1000, height = 1000; @@ -957,6 +1152,12 @@ void _app_service(app_control_h service, void* user_data) input_keyboard_init(service); + input_smartreply_init(service); + input_smartreply_set_notify(_input_smartreply_notify_cb, NULL); + + if (input_smartreply_is_enabled()) + input_smartreply_get_reply_async(); + input_template_init(service); input_template_set_notify(_input_template_notify_cb, NULL); @@ -997,6 +1198,7 @@ void _app_terminate(void* user_data) free(app_data->shared_res_path); input_keyboard_deinit(); + input_smartreply_deinit(); input_template_unset_notify(); input_template_deinit(); diff --git a/src/w-input-smartreply.cpp b/src/w-input-smartreply.cpp new file mode 100644 index 0000000..aae5a0e --- /dev/null +++ b/src/w-input-smartreply.cpp @@ -0,0 +1,462 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Debug.h" + +#include +#include +#include +#include + +#include +#include +//#include +#include + +#include "w-input-smartreply.h" + +#ifdef SUPPORT_SMART_ACTION +#include "w-input-smartaction.h" +#endif + +#ifndef INPUT_SMARTREPLY_VCONF +#define INPUT_SMARTREPLY_VCONF "db/wms/smart_reply" +#endif + + +typedef struct _InputSmartreplyData InputSmartreplyData; + +struct _InputSmartreplyData +{ + char *caller_id; + char *sender; + char *message; + char *lang; + + int enabled; + + input_smartreply_changed callback; + void *user_data; + + smartreply_reply_h *candidate_list; + int candidate_list_len; + bool enable_location; +}; + + +static void _input_smartreply_get_reply_callback(int handle, int error, + smartreply_reply_h* candidate_list, int length); +/* Disable smartreply on/off feature +static void _input_smartreply_vconf_changed(keynode_t *key, void *data); +*/ + + +static InputSmartreplyData *g_input_smartreply_data = NULL; + +static void _input_smartreply_get_reply_callback(int handle, int error, + smartreply_reply_h* candidate_list, int length) +{ + if (g_input_smartreply_data == NULL) { + PRINTFUNC(DLOG_ERROR, "InputSmartreplyData uninitialized"); + return; + } + + if (g_input_smartreply_data == NULL) { + PRINTFUNC(DLOG_ERROR, "InputSmartreplyData uninitialized"); + return; + } + + if (g_input_smartreply_data->candidate_list) { + int ret; + + ret = smartreply_service_destory_list(g_input_smartreply_data->candidate_list); + if (ret != SMARTREPLY_ERROR_NONE) + PRINTFUNC(DLOG_ERROR, "can not destroy list : %d", ret); + } + + if (error != SMARTREPLY_ERROR_NONE) { + PRINTFUNC(DLOG_ERROR, "can not get candidate list : %d", error); + + g_input_smartreply_data->candidate_list = NULL; + g_input_smartreply_data->candidate_list_len = 0; + + return; + } + + g_input_smartreply_data->candidate_list = candidate_list; + g_input_smartreply_data->candidate_list_len = length; + + if (g_input_smartreply_data->callback) + g_input_smartreply_data->callback(g_input_smartreply_data->user_data); +} + +static bool _smartreply_check_here_map_support(void) +{ + return true; +} + +/* Disable smartreply on/off feature +static void _input_smartreply_vconf_changed(keynode_t *key, void *data) +{ + int enabled = 0; + + if (g_input_smartreply_data == NULL) { + PRINTFUNC(DLOG_ERROR, "InputSmartreplyData uninitialized"); + return; + } + + enabled = vconf_keynode_get_int(key); + if (g_input_smartreply_data->enabled == enabled) + return; + + g_input_smartreply_data->enabled = enabled; + + if (g_input_smartreply_data->enabled && g_input_smartreply_data->candidate_list == NULL) { + input_smartreply_get_reply_async(); + return; + } + + if (g_input_smartreply_data->callback) + g_input_smartreply_data->callback(g_input_smartreply_data->user_data); +} +*/ + +bool input_smartreply_init(app_control_h app_control) +{ + int ret; + + char *caller_id = NULL; + char *sender = NULL; + char *message = NULL; + + /* Disable smartreply on/off feature + int enabled = 0; + */ + + ret = app_control_get_extra_data(app_control, + "template_context", &message); + + if (ret != APP_CONTROL_ERROR_NONE) { + PRINTFUNC(DLOG_WARN, "Can not get template_context %d", ret); + return false; + } + + ret = app_control_get_caller(app_control, &caller_id); + + if (ret != APP_CONTROL_ERROR_NONE) + PRINTFUNC(DLOG_WARN, "Can not get caller id %d", ret); + + ret = app_control_get_extra_data(app_control, + "template_sender", &sender); + + if (ret != APP_CONTROL_ERROR_NONE) + PRINTFUNC(DLOG_WARN, "Can not get template_sender %d", ret); + + if (g_input_smartreply_data == NULL) { + g_input_smartreply_data = (InputSmartreplyData *)calloc(1, sizeof(InputSmartreplyData)); + if (g_input_smartreply_data == NULL) { + PRINTFUNC(DLOG_ERROR, "Can not alloc InputSmartreplyData"); + if (message) + free(message); + + if (caller_id) + free(caller_id); + + if (sender) + free(sender); + + return false; + } + } + + if (g_input_smartreply_data->caller_id) + free(g_input_smartreply_data->caller_id); + + if (g_input_smartreply_data->sender) + free(g_input_smartreply_data->sender); + + if (g_input_smartreply_data->message) + free(g_input_smartreply_data->message); + + if (g_input_smartreply_data->lang) + free(g_input_smartreply_data->lang); + + if (g_input_smartreply_data->candidate_list) { + ret = smartreply_service_destory_list(g_input_smartreply_data->candidate_list); + if (ret != SMARTREPLY_ERROR_NONE) + PRINTFUNC(DLOG_ERROR, "can not destroy list : %d", ret); + } + + g_input_smartreply_data->caller_id = caller_id; + g_input_smartreply_data->sender = sender; + g_input_smartreply_data->message = message; + g_input_smartreply_data->lang = NULL; + + g_input_smartreply_data->enabled = 1; + + g_input_smartreply_data->callback = NULL; + g_input_smartreply_data->user_data = NULL; + + g_input_smartreply_data->candidate_list = NULL; + g_input_smartreply_data->candidate_list_len = 0; + + g_input_smartreply_data->enable_location = _smartreply_check_here_map_support(); + + + /* Disable smartreply on/off feature + ret = vconf_get_int(INPUT_SMARTREPLY_VCONF, &enabled); + if (ret == -1) + PRINTFUNC(DLOG_ERROR, "can not get vconf : %s", INPUT_SMARTREPLY_VCONF); + + g_input_smartreply_data->enabled = enabled; + + ret = vconf_notify_key_changed(INPUT_SMARTREPLY_VCONF, + _input_smartreply_vconf_changed, NULL); + if (ret == -1) + PRINTFUNC(DLOG_ERROR, "Can not create vconf notify : %s", INPUT_SMARTREPLY_VCONF); + */ + + return true; +} + +void input_smartreply_deinit(void) +{ + if (g_input_smartreply_data == NULL) { + PRINTFUNC(DLOG_WARN, "InputSmartreplyData uninitialized"); + return; + } + + if (g_input_smartreply_data->caller_id) + free(g_input_smartreply_data->caller_id); + + if (g_input_smartreply_data->sender) + free(g_input_smartreply_data->sender); + + if (g_input_smartreply_data->message) + free(g_input_smartreply_data->message); + + + if (g_input_smartreply_data->candidate_list) { + int ret; + + ret = smartreply_service_destory_list(g_input_smartreply_data->candidate_list); + if (ret != SMARTREPLY_ERROR_NONE) + PRINTFUNC(DLOG_ERROR, "can not destroy list : %d", ret); + } + + input_smartreply_unset_notify(); + + /* Disable smartreply on/off feature + vconf_ignore_key_changed(INPUT_SMARTREPLY_VCONF, + _input_smartreply_vconf_changed); + */ + + free(g_input_smartreply_data); + g_input_smartreply_data = NULL; + + return; +} + +bool input_smartreply_get_reply(void) +{ + int ret; + + smartreply_reply_h *candidate_list = NULL; + int candidate_list_len = 0; + + if (g_input_smartreply_data == NULL) { + PRINTFUNC(DLOG_ERROR, "InputSmartreplyData uninitialized"); + return false; + } + + if (g_input_smartreply_data->message == NULL) { + PRINTFUNC(DLOG_ERROR, "message is empty"); + return false; + } + + if (g_input_smartreply_data->enabled == 0) { + PRINTFUNC(DLOG_WARN, "Smartreply is disabled"); + return false; + } + + ret = smartreply_service_get_replies(g_input_smartreply_data->caller_id, + g_input_smartreply_data->sender, + g_input_smartreply_data->message, + &candidate_list, + &candidate_list_len); + + if (ret != SMARTREPLY_ERROR_NONE) { + PRINTFUNC(DLOG_ERROR, "Can not get replies : %d", ret); + return false; + } + + if (g_input_smartreply_data->candidate_list) { + ret = smartreply_service_destory_list(g_input_smartreply_data->candidate_list); + if (ret != SMARTREPLY_ERROR_NONE) + PRINTFUNC(DLOG_ERROR, "can not destroy list : %d", ret); + } + + g_input_smartreply_data->candidate_list = candidate_list; + g_input_smartreply_data->candidate_list_len = candidate_list_len; + + return true; +} + +bool input_smartreply_get_reply_async(void) +{ + int ret; + + if (g_input_smartreply_data == NULL) { + PRINTFUNC(DLOG_ERROR, "InputSmartreplyData uninitialized"); + return false; + } + + if (g_input_smartreply_data->message == NULL) { + PRINTFUNC(DLOG_ERROR, "message is empty"); + return false; + } + + if (g_input_smartreply_data->enabled == 0) { + PRINTFUNC(DLOG_WARN, "Smartreply is disabled"); + return false; + } + + ret = smartreply_service_get_replies_async(g_input_smartreply_data->caller_id, + g_input_smartreply_data->sender, + g_input_smartreply_data->message, + _input_smartreply_get_reply_callback); + + return true; +} + +int input_smartreply_get_reply_num(void) +{ + if (g_input_smartreply_data == NULL) { + PRINTFUNC(DLOG_ERROR, "InputSmartreplyData uninitialized"); + return 0; + } + + if (g_input_smartreply_data->enabled == 0) { + PRINTFUNC(DLOG_WARN, "Smartreply is disabled"); + return 0; + } + + return g_input_smartreply_data->candidate_list_len; +} + +char *input_smartreply_get_nth_item(int index, int *type) +{ + int ret; + char *message = NULL; + + if (g_input_smartreply_data == NULL) { + PRINTFUNC(DLOG_ERROR, "InputSmartreplyData uninitialized"); + return NULL; + } + + if (g_input_smartreply_data->candidate_list == NULL) { + PRINTFUNC(DLOG_ERROR, "Can not get candidate list"); + return NULL; + } + + if (g_input_smartreply_data->enabled == 0) { + PRINTFUNC(DLOG_WARN, "Smartreply is disabled"); + return NULL; + } + + + ret = smartreply_service_get_nth_reply_message(g_input_smartreply_data->candidate_list, + index, + &message); + + if (ret != SMARTREPLY_ERROR_NONE) { + PRINTFUNC(DLOG_ERROR, "Can not get message from index %d : %d", index, ret); + return NULL; + } + + return message; +} + +bool input_smartreply_send_feedback(const char *str) +{ + int ret; + + if (g_input_smartreply_data == NULL) { + PRINTFUNC(DLOG_ERROR, "InputSmartreplyData uninitialized"); + return false; + } + + if (str == NULL) { + PRINTFUNC(DLOG_ERROR, "str is empty"); + return false; + } + + ret = smartreply_service_record_user_reply(g_input_smartreply_data->caller_id, + g_input_smartreply_data->sender, + g_input_smartreply_data->message, + str); + + if (ret != SMARTREPLY_ERROR_NONE) { + PRINTFUNC(DLOG_ERROR, "Can not send feedback : %d", ret); + return false; + } + + return true; +} + + + +void input_smartreply_set_notify(input_smartreply_changed callback, + void *user_data) +{ + if (callback == NULL) { + PRINTFUNC(DLOG_ERROR, "empty callback function"); + return; + } + + if (g_input_smartreply_data == NULL) { + PRINTFUNC(DLOG_WARN, "InputSmartreplyData uninitialized"); + return; + } + + g_input_smartreply_data->callback = callback; + g_input_smartreply_data->user_data = user_data; +} + + +void input_smartreply_unset_notify(void) +{ + if (g_input_smartreply_data == NULL) { + PRINTFUNC(DLOG_WARN, "InputSmartreplyData uninitialized"); + return; + } + + g_input_smartreply_data->callback = NULL; + g_input_smartreply_data->user_data = NULL; +} + +bool input_smartreply_is_enabled(void) +{ + if (g_input_smartreply_data == NULL) { + PRINTFUNC(DLOG_WARN, "InputSmartreplyData uninitialized"); + return false; + } + + if (g_input_smartreply_data->enabled) + return true; + + return false; +} -- 2.7.4 From b6fdc562791b42fce553a8843e8cabf18275d4b1 Mon Sep 17 00:00:00 2001 From: "sungwook79.park" Date: Tue, 20 Jun 2017 15:46:08 +0900 Subject: [PATCH 09/16] Update package version to 0.1.170620 Change-Id: I24832165a26c74d5aa3c586d55598a7f4ad4d256 Signed-off-by: sungwook79.park --- org.tizen.inputdelegator.xml | 2 +- packaging/org.tizen.inputdelegator.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/org.tizen.inputdelegator.xml b/org.tizen.inputdelegator.xml index 8524353..7b43160 100755 --- a/org.tizen.inputdelegator.xml +++ b/org.tizen.inputdelegator.xml @@ -1,5 +1,5 @@ - + diff --git a/packaging/org.tizen.inputdelegator.spec b/packaging/org.tizen.inputdelegator.spec index 33bf2d9..389a9c4 100755 --- a/packaging/org.tizen.inputdelegator.spec +++ b/packaging/org.tizen.inputdelegator.spec @@ -9,7 +9,7 @@ Name: org.tizen.inputdelegator Summary: Input Delegator Application -Version: 0.1.170518 +Version: 0.1.170620 Release: 1 Group: Applications License: Apache-2.0 -- 2.7.4 From 4cc380f070db66e4c9593863ce582c1e97d1303b Mon Sep 17 00:00:00 2001 From: "sungwook79.park" Date: Wed, 5 Jul 2017 13:52:31 +0900 Subject: [PATCH 10/16] Support to delegate various MIME types to caller as like voice recording Change-Id: I2194134a1b599b79c5e05a6c4164fc9d94c619ad Signed-off-by: sungwook79.park --- CMakeLists.txt | 4 + inc/voice-recorder.h | 53 +++++++ inc/w-input-selector.h | 2 +- org.tizen.inputdelegator.xml | 2 + packaging/org.tizen.inputdelegator.spec | 3 + src/voice-recorder.cpp | 260 ++++++++++++++++++++++++++++++++ src/w-input-emoticon.cpp | 2 +- src/w-input-keyboard.cpp | 2 +- src/w-input-selector.cpp | 14 +- src/w-input-stt-ise.cpp | 3 + src/w-input-stt-voice.cpp | 14 +- 11 files changed, 350 insertions(+), 9 deletions(-) create mode 100644 inc/voice-recorder.h create mode 100644 src/voice-recorder.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 95b2d21..a2e1690 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ SET(INPUTDELEGATOR_SRCS src/w-input-stt-voice.cpp src/w-input-template.cpp src/w-input-smartreply.cpp + src/voice-recorder.cpp ) SET(INPUTDELEGATOR_PACKAGE ${PROJECT_NAME}) @@ -51,6 +52,9 @@ SET(PKGS_CHECK_MODULES capi-media-audio-io capi-system-info smartreply + capi-media-recorder + capi-content-media-content + storage ) diff --git a/inc/voice-recorder.h b/inc/voice-recorder.h new file mode 100644 index 0000000..b07d9ef --- /dev/null +++ b/inc/voice-recorder.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __VOICE_RECORDER_H__ +#define __VOICE_RECORDER_H__ + +#include + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +struct _voice_recorder { + recorder_h recorder; + recorder_audio_codec_e *codec_list; + int codec_list_len; + char file_path[PATH_MAX]; + char file_name[PATH_MAX]; + recorder_audio_codec_e codec; + recorder_file_format_e file_format; + FILE *preproc_file; + app_control_h service; + int bitrate; + int sample_rate; + bool is_recording; + long long int limitsize; +}; +typedef struct _voice_recorder voice_recorder; + +void init_voice_recorder(app_control_h service); +void destroy_voice_recorder(); +void start_voice_recorder(); +void stop_voice_recorder(); +void _voice_recorder_set_data(void *data); +voice_recorder *_voice_recorder_get_data(); + +#endif // __VOICE_RECORDER_H__ diff --git a/inc/w-input-selector.h b/inc/w-input-selector.h index 985ee98..92662e1 100755 --- a/inc/w-input-selector.h +++ b/inc/w-input-selector.h @@ -118,7 +118,7 @@ typedef struct _InputTypeData InputTypeData; void _app_terminate(void* user_data); void reply_to_sender_by_callback_for_back(); -void reply_to_sender_by_callback(const char *value, const char *type); +void reply_to_sender_by_callback(const char *value, const char *type, const char *path[]); char* get_resource_path(); char* get_shared_resource_path(); void show_gl_focus(Eina_Bool bVisible); diff --git a/org.tizen.inputdelegator.xml b/org.tizen.inputdelegator.xml index 7b43160..41f8f2e 100755 --- a/org.tizen.inputdelegator.xml +++ b/org.tizen.inputdelegator.xml @@ -14,5 +14,7 @@ http://tizen.org/privilege/display http://tizen.org/privilege/recorder http://tizen.org/privilege/appmanager.launch + http://tizen.org/privilege/content.write + http://tizen.org/privilege/mediastorage diff --git a/packaging/org.tizen.inputdelegator.spec b/packaging/org.tizen.inputdelegator.spec index 389a9c4..8063566 100755 --- a/packaging/org.tizen.inputdelegator.spec +++ b/packaging/org.tizen.inputdelegator.spec @@ -42,6 +42,9 @@ BuildRequires: pkgconfig(sqlite3) BuildRequires: pkgconfig(capi-media-audio-io) BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(smartreply) +BuildRequires: pkgconfig(capi-media-recorder) +BuildRequires: pkgconfig(capi-content-media-content) +BuildRequires: pkgconfig(storage) %if %{enable_log_manager} BuildRequires: pkgconfig(bundle) diff --git a/src/voice-recorder.cpp b/src/voice-recorder.cpp new file mode 100644 index 0000000..ef2c017 --- /dev/null +++ b/src/voice-recorder.cpp @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include "voice-recorder.h" + +#define MAX_TIME 1200 + +#define VR_AUDIO_SOURCE_SAMPLERATE_LOW 8000 +#define VR_AUDIO_SOURCE_SAMPLERATE_HIGH 44100 +#define VR_AUDIO_ENCODER_BITRATE_AMR 12200 +#define VR_AUDIO_ENCODER_BITRATE_AAC 64000 + +static voice_recorder *recorderhandle = NULL; + +static void _recorder_create(voice_recorder *view); +static void _recorder_start(voice_recorder *view); +static void _recorder_stop(voice_recorder *view); +static void _recorder_apply_settings(voice_recorder *view); +static void _on_recording_status_cb(unsigned long long elapsed_time, unsigned long long file_size, void *user_data); +static void _on_recording_limit_reached_cb(recorder_recording_limit_type_e type, void *user_data); +static bool _main_file_register(const char *filename); +static void _recorder_destroy(voice_recorder *view); + +void init_voice_recorder(app_control_h service) +{ + voice_recorder *recorder = (voice_recorder *)malloc(sizeof(voice_recorder)); + if (!recorder) { + LOGD("Error Failed to create recorder"); + return; + } + + _voice_recorder_set_data(recorder); + + recorder->is_recording = FALSE; + recorder->service = service; + recorder->limitsize = 1000000; + + _recorder_create(recorder); +} + +void destroy_voice_recorder() +{ + LOGD("destroy_voice_recorder()"); + voice_recorder *recorder = (voice_recorder *)_voice_recorder_get_data(); + if (recorder) { + _recorder_destroy(recorder); + } + _voice_recorder_set_data(NULL); +} + +void start_voice_recorder() +{ + voice_recorder *recorder = (voice_recorder *)_voice_recorder_get_data(); + _recorder_start(recorder); +} + +void stop_voice_recorder() +{ + voice_recorder *recorder = (voice_recorder *)_voice_recorder_get_data(); + _recorder_stop(recorder); +} + +void _voice_recorder_set_data(void *data) +{ + recorderhandle = (voice_recorder *)data; +} + +voice_recorder *_voice_recorder_get_data() +{ + if (recorderhandle) { + return recorderhandle; + } + return NULL; +} + +static void _recorder_create(voice_recorder *recorder) +{ + LOGD("_recorder_create"); + + int ret = recorder_create_audiorecorder(&recorder->recorder); + if (ret == RECORDER_ERROR_NONE) { + recorder_set_recording_status_cb(recorder->recorder, _on_recording_status_cb, recorder); + if (recorder->limitsize > 0) { + recorder_attr_set_size_limit(recorder->recorder, (recorder->limitsize) / 1024); + } + recorder_set_recording_limit_reached_cb(recorder->recorder, _on_recording_limit_reached_cb, recorder); + } else { + LOGD("recorder_create_audiorecorder not successful error code: %d", ret); + } +} + +static void _recorder_start(voice_recorder *recorder) +{ + LOGD("_recorder_start"); + if (!recorder->recorder) { + LOGD("Error recorder->recorder is null"); + return; + } + + recorder_state_e rec_state; + recorder_get_state(recorder->recorder, &rec_state); + + if (rec_state == RECORDER_STATE_PAUSED) { + recorder_start(recorder->recorder); + return; + } + + struct tm localtime = {0, }; + time_t rawtime = time(NULL); + char filename[256] = {'\0', }; + char *voice_content_path = NULL; + storage_get_directory(STORAGE_TYPE_INTERNAL, STORAGE_DIRECTORY_SOUNDS, &voice_content_path); + if (voice_content_path == NULL) { + LOGD("voice_content_path is NULL"); + return; + } + +#if 1 + /*For MMS*/ + recorder->codec = RECORDER_AUDIO_CODEC_AMR; + recorder->file_format = RECORDER_FILE_FORMAT_AMR; + recorder->sample_rate = VR_AUDIO_SOURCE_SAMPLERATE_LOW; + recorder->bitrate = VR_AUDIO_ENCODER_BITRATE_AMR; + if (localtime_r(&rawtime, &localtime) != NULL) { + snprintf(filename, sizeof(filename), "Voice-%04i-%02i-%02i_%02i:%02i:%02i.amr", + localtime.tm_year + 1900, localtime.tm_mon + 1, localtime.tm_mday, + localtime.tm_hour, localtime.tm_min, localtime.tm_sec); + } +#else + /*For High Quality*/ + recorder->codec = RECORDER_AUDIO_CODEC_AAC; + recorder->file_format = RECORDER_FILE_FORMAT_MP4; + recorder->sample_rate = VR_AUDIO_SOURCE_SAMPLERATE_HIGH; + recorder->bitrate = VR_AUDIO_ENCODER_BITRATE_AAC; + if (localtime_r(&rawtime, &localtime) != NULL) { + snprintf(filename, sizeof(filename), "Voice-%04i-%02i-%02i_%02i:%02i:%02i.m4a", + localtime.tm_year + 1900, localtime.tm_mon + 1, localtime.tm_mday, + localtime.tm_hour, localtime.tm_min, localtime.tm_sec); + } +#endif + /*set file path*/ + snprintf(recorder->file_path, PATH_MAX, "%s/%s", voice_content_path, filename); + LOGD("recorder->file_path = %s", recorder->file_path); + _recorder_apply_settings(recorder); + recorder_prepare(recorder->recorder); + recorder_start(recorder->recorder); +} + +static void _recorder_stop(voice_recorder *recorder) +{ + LOGD("_recorder_stop"); + int commitResult = RECORDER_ERROR_NONE; + + if (recorder->recorder) { + commitResult = recorder_commit(recorder->recorder); + if (commitResult != RECORDER_ERROR_NONE) { + LOGD("recorder_commit failed Error [%d]", recorder_commit); + } + _main_file_register(recorder->file_path); + } +} + +static void _recorder_apply_settings(voice_recorder *recorder) +{ + if (recorder->recorder) { + recorder_attr_set_audio_channel(recorder->recorder, 2); + recorder_attr_set_audio_device(recorder->recorder, RECORDER_AUDIO_DEVICE_MIC); + recorder_attr_set_time_limit(recorder->recorder, MAX_TIME); + + recorder_set_filename(recorder->recorder, recorder->file_path); + recorder_set_file_format(recorder->recorder, recorder->file_format); + LOGD("file_format: %d", recorder->file_format); + recorder_set_audio_encoder(recorder->recorder, recorder->codec); + recorder_attr_set_audio_samplerate(recorder->recorder, recorder->sample_rate); + recorder_attr_set_audio_encoder_bitrate(recorder->recorder, recorder->bitrate); + + recorder_prepare(recorder->recorder); + } +} + +static void _on_recording_status_cb(unsigned long long elapsed_time, unsigned long long file_size, void *user_data) +{ + voice_recorder *recorder = (voice_recorder *)user_data; + + if (recorder) { + recorder_state_e rec_state = RECORDER_STATE_NONE; + recorder_get_state(recorder->recorder, &rec_state); + if (rec_state == RECORDER_STATE_PAUSED || rec_state == RECORDER_STATE_READY) { + return; + } + } +} + +static void _on_recording_limit_reached_cb(recorder_recording_limit_type_e type, void *user_data) +{ + voice_recorder *recorder = (voice_recorder *)user_data; + if (recorder) { + if (type == RECORDER_RECORDING_LIMIT_TIME) { + _recorder_stop(recorder); + } else if (type == RECORDER_RECORDING_LIMIT_SIZE) { + _recorder_stop(recorder); + } + } +} + +static bool _main_file_register(const char *filename) +{ + LOGD("_main_file_register"); + int err_code = 0; + media_info_h info = NULL; + + char *register_file = strdup(filename); + if (register_file == NULL) { + LOGD("Failed to allocate memory"); + return FALSE; + } + + err_code = media_info_insert_to_db(register_file, &info); + if (err_code != MEDIA_CONTENT_ERROR_NONE) { + LOGD("failed to media_file_register() : [%s], [%d]", register_file, err_code); + media_info_destroy(info); + free(register_file); + return FALSE; + } + + media_info_destroy(info); + free(register_file); + + return TRUE; +} + +static void _recorder_destroy(voice_recorder *recorder) +{ + LOGD("_recorder_destroy"); + if (recorder->recorder) { + recorder_cancel(recorder->recorder); + recorder_unprepare(recorder->recorder); + recorder_destroy(recorder->recorder); + recorder->recorder = NULL; + } +} diff --git a/src/w-input-emoticon.cpp b/src/w-input-emoticon.cpp index 0ead5fb..4bd585b 100755 --- a/src/w-input-emoticon.cpp +++ b/src/w-input-emoticon.cpp @@ -376,7 +376,7 @@ static void _emoticon_item_clicked_cb(void *data, Evas_Object * obj, void *event const Eina_Unicode unicode_event[2] = { (Eina_Unicode)emoticon_info[index].code, 0 }; char* utf_8 = eina_unicode_unicode_to_utf8(unicode_event, &length); - reply_to_sender_by_callback((const char*)utf_8, "emoticon"); + reply_to_sender_by_callback((const char*)utf_8, "emoticon", NULL); PRINTFUNC(SECURE_DEBUG, "[%d]%s", index, utf_8); if (utf_8) diff --git a/src/w-input-keyboard.cpp b/src/w-input-keyboard.cpp index 869cfb5..9257a12 100755 --- a/src/w-input-keyboard.cpp +++ b/src/w-input-keyboard.cpp @@ -82,7 +82,7 @@ void btn_clicked_cb(void *data, Evas_Object *obj, void *event_info) app_control_set_operation(app_control, APP_CONTROL_OPERATION_DEFAULT); set_source_caller_app_id(app_control); free(app_id); - reply_to_sender_by_callback(getText, "keyboard"); + reply_to_sender_by_callback(getText, "keyboard", NULL); ui_app_exit(); } diff --git a/src/w-input-selector.cpp b/src/w-input-selector.cpp index d6feeec..ed22ea2 100755 --- a/src/w-input-selector.cpp +++ b/src/w-input-selector.cpp @@ -222,7 +222,7 @@ static void __ise_smartreply_gl_sel(void *data, Evas_Object *obj, void *event_in char *reply = input_smartreply_get_nth_item(index, &type); if (reply) { input_smartreply_send_feedback(reply); - reply_to_sender_by_callback(reply, "smartreply"); + reply_to_sender_by_callback(reply, "smartreply", NULL); free(reply); elm_exit(); } @@ -241,7 +241,7 @@ static void __ise_template_gl_sel(void *data, Evas_Object *obj, void *event_info const std::vector template_list = input_template_get_list(); if (index < (int)template_list.size()) { - reply_to_sender_by_callback(gettext(template_list[index].text.c_str()), "template"); + reply_to_sender_by_callback(gettext(template_list[index].text.c_str()), "template", NULL); ui_app_exit(); } } @@ -480,7 +480,7 @@ void set_source_caller_app_id(app_control_h app_control) } } -void reply_to_sender_by_callback(const char *value, const char *type) +void reply_to_sender_by_callback(const char *value, const char *type, const char *path[]) { PRINTFUNC(DLOG_DEBUG, ""); @@ -495,6 +495,10 @@ void reply_to_sender_by_callback(const char *value, const char *type) if (type) app_control_add_extra_data(app_control, "reply_type", type); + if (path != NULL) { + app_control_add_extra_data_array(app_control, APP_CONTROL_DATA_PATH, path, 1); + } + set_source_caller_app_id(app_control); ret = app_control_reply_to_launch_request(app_control, app_data->source_app_control, APP_CONTROL_RESULT_SUCCEEDED); @@ -624,7 +628,7 @@ void _back_to_genlist_for_selector() } if (app_data->app_type == APP_TYPE_STT || app_data->app_type == APP_TYPE_EMOTICON || app_data->app_type == APP_TYPE_KEYBOARD){ PRINTFUNC(DLOG_DEBUG, "launched as STT/EMOTICON/KEYBOARD mode, So exit here."); - reply_to_sender_by_callback(NULL, NULL); + reply_to_sender_by_callback(NULL, NULL, NULL); ui_app_exit(); } } @@ -1038,7 +1042,7 @@ bool _app_create(void* user_data) Evas_Object* conform = NULL; Evas_Object* bg = NULL; Evas_Object* window = NULL; - Eext_Circle_Surface *surface; + Eext_Circle_Surface *surface = NULL; if (!user_data) { return false; diff --git a/src/w-input-stt-ise.cpp b/src/w-input-stt-ise.cpp index 965d36d..da6e71f 100755 --- a/src/w-input-stt-ise.cpp +++ b/src/w-input-stt-ise.cpp @@ -21,6 +21,7 @@ #include "w-input-stt-ise.h" #include "w-input-stt-voice.h" #include "w-input-stt-engine.h" +#include "voice-recorder.h" VoiceData *my_voicedata = NULL; @@ -88,6 +89,8 @@ void pause_voice(){ on_destroy(my_voicedata); my_voicedata = NULL; } + + destroy_voice_recorder(); } int is_lang_supported_by_voice_input(const char *lang) diff --git a/src/w-input-stt-voice.cpp b/src/w-input-stt-voice.cpp index 0aa4b21..595d417 100755 --- a/src/w-input-stt-voice.cpp +++ b/src/w-input-stt-voice.cpp @@ -32,6 +32,7 @@ #include "w-input-stt-voice.h" #include "w-input-stt-engine.h" #include "w-input-stt-ise.h" +#include "voice-recorder.h" using namespace std; @@ -473,7 +474,12 @@ static void on_confirm_button_clicked_cb(void *data, Evas_Object *obj, void *eve PRINTFUNC(DLOG_DEBUG, "result_text = %s", result_text.c_str()); - reply_to_sender_by_callback(result_text.c_str(), "voice"); + char *filePath = NULL; + voice_recorder *vr = _voice_recorder_get_data(); + if (!vr) + filePath = vr->file_path; + char *path[] = {filePath, }; + reply_to_sender_by_callback(result_text.c_str(), "voice", (const char **)path); destroy_voice(); powerUnlock(); ui_app_exit(); @@ -779,6 +785,9 @@ static Eina_Bool _start_timer_cb(void* data) } voicedata->start_timer = NULL; } + + start_voice_recorder(); + return ECORE_CALLBACK_CANCEL; } @@ -920,6 +929,7 @@ char *__get_genlist_item_label(void *data, Evas_Object *obj, const char *part) strncpy(text, s, p-s); } else { strncpy(text, s, strlen(s)); + text[strlen(s)] = '\0'; } } else { strncpy(text, "", strlen("")); @@ -1808,6 +1818,8 @@ int init_voice(Evas_Object *parent, const char *lang, VoiceData *r_voicedata) voicedata->textblock_timer = NULL; } + init_voice_recorder(NULL); + return TRUE; } -- 2.7.4 From 5649745a562278dbf3d69a5e9438b057d4810c79 Mon Sep 17 00:00:00 2001 From: "sungwook79.park" Date: Mon, 10 Jul 2017 17:16:25 +0900 Subject: [PATCH 11/16] Support various MIME type to caller Change-Id: Icc91f888f5d03f488ab9cd685ef066ba0904be19 Signed-off-by: sungwook79.park --- org.tizen.inputdelegator.xml | 3 +++ src/w-input-selector.cpp | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/org.tizen.inputdelegator.xml b/org.tizen.inputdelegator.xml index 41f8f2e..ccb38de 100755 --- a/org.tizen.inputdelegator.xml +++ b/org.tizen.inputdelegator.xml @@ -7,6 +7,9 @@ + + + diff --git a/src/w-input-selector.cpp b/src/w-input-selector.cpp index ed22ea2..e22274d 100755 --- a/src/w-input-selector.cpp +++ b/src/w-input-selector.cpp @@ -1113,10 +1113,31 @@ void _app_service(app_control_h service, void* user_data) char **input_type_array = NULL; int input_type_array_len = -1; bool is_extra_data_array = false; + char *mime_type = NULL; app_control_clone(&(app_data->source_app_control), service); app_data->reply_type = REPLY_APP_NORMAL; + ret = app_control_get_mime(service, &mime_type); + if (ret != APP_CONTROL_ERROR_NONE) { + LOGD("Fail to get mime type : %d", ret); + } else { + if (mime_type) { + LOGD("mime type = %s", mime_type); + if (!strncmp(mime_type, "image/", strlen("image/"))) { + + } else if(!strncmp(mime_type, "audio/", strlen("audio/"))) { + app_data->app_type = APP_TYPE_STT; + _stt_clicked_cb((void *)app_data, NULL, NULL); + if (mime_type) + free(mime_type); + goto ACTIVATE; + } + } + } + if (mime_type) + free(mime_type); + if (_TV || _MOBILE) { app_data->app_type = APP_TYPE_KEYBOARD; input_keyboard_init(service); -- 2.7.4 From e88a9250753b2cb59f5061cbdc2c316c5e4fdc5e Mon Sep 17 00:00:00 2001 From: "sungwook79.park" Date: Mon, 17 Jul 2017 09:24:14 +0900 Subject: [PATCH 12/16] Support return key type in keyboard input mode Change-Id: I0f352fce837060728f7b8c4c9e2270ddaa4d19de Signed-off-by: sungwook79.park --- inc/w-input-selector.h | 1 + src/w-input-keyboard.cpp | 44 +++++++++++++++++++++++++++++++++++++++++++- src/w-input-stt-voice.cpp | 2 ++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/inc/w-input-selector.h b/inc/w-input-selector.h index 92662e1..774f351 100755 --- a/inc/w-input-selector.h +++ b/inc/w-input-selector.h @@ -106,6 +106,7 @@ struct _InputKeyboardData { char *guide_text; char *default_text; + char *return_key_type; }; typedef struct _InputKeyboardData InputKeyboardData; diff --git a/src/w-input-keyboard.cpp b/src/w-input-keyboard.cpp index 9257a12..7fe4860 100755 --- a/src/w-input-keyboard.cpp +++ b/src/w-input-keyboard.cpp @@ -34,6 +34,7 @@ bool input_keyboard_init(app_control_h app_control) int ret = -1; char *default_text = NULL; char *guide_text = NULL; + char *return_key_type = NULL; input_keyboard_deinit(); @@ -45,6 +46,10 @@ bool input_keyboard_init(app_control_h app_control) if (ret == APP_CONTROL_ERROR_NONE) { g_input_keyboard_data.guide_text = guide_text; } + ret = app_control_get_extra_data(app_control, "return_key_type", &return_key_type); + if (ret == APP_CONTROL_ERROR_NONE) { + g_input_keyboard_data.return_key_type = return_key_type; + } return true; } @@ -57,13 +62,17 @@ void input_keyboard_deinit(void) if (g_input_keyboard_data.default_text) free(g_input_keyboard_data.default_text); + if (g_input_keyboard_data.return_key_type) + free(g_input_keyboard_data.return_key_type); + g_input_keyboard_data.default_text = NULL; g_input_keyboard_data.guide_text = NULL; + g_input_keyboard_data.return_key_type = NULL; return; } -void btn_clicked_cb(void *data, Evas_Object *obj, void *event_info) +void exit_keyboard() { app_control_h app_control; int ret = app_control_create(&app_control); @@ -84,6 +93,12 @@ void btn_clicked_cb(void *data, Evas_Object *obj, void *event_info) free(app_id); reply_to_sender_by_callback(getText, "keyboard", NULL); ui_app_exit(); + +} + +void btn_clicked_cb(void *data, Evas_Object *obj, void *event_info) +{ + exit_keyboard(); } static Eina_Bool custom_back_cb(void *data, Elm_Object_Item *it) @@ -97,6 +112,23 @@ static void maxlength_cb(void *data, Evas_Object *obj, void *event_info) LOGD("maxlength_cb : size = %d", KEYBOARD_EDITOR_CHAR_COUNT_MAX); } +static void enter_keydown_cb(void *data, Evas_Object *obj, void *event_info) +{ + LOGD("enter_keydown_cb"); + Evas_Object *entry = obj; + if (entry == NULL) + return; + + Ecore_IMF_Context *imf_context = NULL; + imf_context = (Ecore_IMF_Context*)elm_entry_imf_context_get(entry); + if (imf_context) + ecore_imf_context_input_panel_hide(imf_context); + + elm_object_focus_set(entry, EINA_FALSE); + + exit_keyboard(); +} + void create_fullscreen_editor(void *data) { App_Data *ad = (App_Data *)data; @@ -121,6 +153,10 @@ void create_fullscreen_editor(void *data) elm_entry_cursor_end_set(entry); evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL); + if (g_input_keyboard_data.return_key_type && strcmp(g_input_keyboard_data.return_key_type, "DONE") == 0) { + elm_entry_input_panel_return_key_type_set(entry, ELM_INPUT_PANEL_RETURN_KEY_TYPE_DONE); + evas_object_smart_callback_add(entry, "activated", enter_keydown_cb, ad); + } evas_object_show(entry); elm_box_pack_end(box, entry); @@ -159,6 +195,7 @@ static void editfield_unfocused_cb(void *data, Evas_Object *obj, void *event_inf static Evas_Object *create_multiline_editfield_layout(Evas_Object *parent, void *data) { + App_Data *ad = (App_Data *)data; Evas_Object *editfield; editfield = elm_layout_add(parent); @@ -179,6 +216,11 @@ static Evas_Object *create_multiline_editfield_layout(Evas_Object *parent, void elm_entry_cursor_end_set(entry); evas_object_smart_callback_add(entry, "focused", editfield_focused_cb, editfield); evas_object_smart_callback_add(entry, "unfocused", editfield_unfocused_cb, editfield); + if (g_input_keyboard_data.return_key_type && strcmp(g_input_keyboard_data.return_key_type, "DONE") == 0) { + elm_entry_input_panel_return_key_type_set(entry, ELM_INPUT_PANEL_RETURN_KEY_TYPE_DONE); + evas_object_smart_callback_add(entry, "activated", enter_keydown_cb, ad); + } + evas_object_show(entry); elm_object_part_content_set(editfield, "elm.swallow.content", entry); diff --git a/src/w-input-stt-voice.cpp b/src/w-input-stt-voice.cpp index 595d417..ac682cc 100755 --- a/src/w-input-stt-voice.cpp +++ b/src/w-input-stt-voice.cpp @@ -933,6 +933,7 @@ char *__get_genlist_item_label(void *data, Evas_Object *obj, const char *part) } } else { strncpy(text, "", strlen("")); + text[strlen("")] = '\0'; } } return strdup(text); @@ -969,6 +970,7 @@ char *__get_genlist_item_label(void *data, Evas_Object *obj, const char *part) } } else { strncpy(text, "", strlen("")); + text[strlen("")] = '\0'; } return strdup(text); } -- 2.7.4 From e5dc7bcfb200e4b6d7c7290fb88ae62fac0e57a7 Mon Sep 17 00:00:00 2001 From: "sungwook79.park" Date: Tue, 18 Jul 2017 15:26:40 +0900 Subject: [PATCH 13/16] Support filter and popup notification for maximum characters length in keyboard input mode Change-Id: Ibd720794c674987b106c4cb01a7d22fd18b4471e Signed-off-by: sungwook79.park --- inc/w-input-keyboard.h | 2 ++ inc/w-input-selector.h | 1 + po/ar.po | 2 ++ po/az.po | 2 ++ po/bg.po | 2 ++ po/ca.po | 2 ++ po/cs.po | 2 ++ po/da.po | 2 ++ po/de.po | 2 ++ po/el_GR.po | 2 ++ po/en.po | 2 ++ po/en_PH.po | 2 ++ po/en_US.po | 3 +++ po/es_ES.po | 2 ++ po/es_US.po | 2 ++ po/et.po | 2 ++ po/eu.po | 2 ++ po/fi.po | 2 ++ po/fr.po | 2 ++ po/fr_CA.po | 2 ++ po/ga.po | 2 ++ po/gl.po | 2 ++ po/hi.po | 2 ++ po/hr.po | 2 ++ po/hu.po | 2 ++ po/hy.po | 2 ++ po/is.po | 2 ++ po/it_IT.po | 2 ++ po/ja_JP.po | 2 ++ po/ka.po | 2 ++ po/kk.po | 2 ++ po/ko_KR.po | 2 ++ po/lt.po | 2 ++ po/lv.po | 2 ++ po/mk.po | 2 ++ po/nb.po | 2 ++ po/nl.po | 2 ++ po/pl.po | 2 ++ po/pt_BR.po | 2 ++ po/pt_PT.po | 2 ++ po/ro.po | 2 ++ po/ru_RU.po | 2 ++ po/sk.po | 2 ++ po/sl.po | 2 ++ po/sr.po | 2 ++ po/sv.po | 2 ++ po/tr_TR.po | 2 ++ po/uk.po | 2 ++ po/uz.po | 2 ++ po/zh_CN.po | 2 ++ po/zh_HK.po | 2 ++ po/zh_TW.po | 2 ++ src/w-input-keyboard.cpp | 13 +++++++++++-- src/w-input-stt-voice.cpp | 15 ++++++--------- 54 files changed, 121 insertions(+), 11 deletions(-) diff --git a/inc/w-input-keyboard.h b/inc/w-input-keyboard.h index b127fdf..349dc54 100755 --- a/inc/w-input-keyboard.h +++ b/inc/w-input-keyboard.h @@ -21,6 +21,8 @@ #include #include +#define MAX_TEXT_LENGTH_REACH "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" + const int KEYBOARD_EDITOR_CHAR_COUNT_MAX = 300; bool input_keyboard_init(app_control_h app_control); void input_keyboard_deinit(void); diff --git a/inc/w-input-selector.h b/inc/w-input-selector.h index 774f351..c5afd21 100755 --- a/inc/w-input-selector.h +++ b/inc/w-input-selector.h @@ -107,6 +107,7 @@ struct _InputKeyboardData char *guide_text; char *default_text; char *return_key_type; + int max_text_length; }; typedef struct _InputKeyboardData InputKeyboardData; diff --git a/po/ar.po b/po/ar.po index c15b1b9..0283829 100644 --- a/po/ar.po +++ b/po/ar.po @@ -256,3 +256,5 @@ msgstr "إدخال ساعة Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "تأكد من أن تطبيق %s قيد التفعيل على هاتفك." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "تم تجاوز الحد الأقصى لعدد الأحرف (%d)." \ No newline at end of file diff --git a/po/az.po b/po/az.po index d9f741c..7d59e8e 100644 --- a/po/az.po +++ b/po/az.po @@ -256,3 +256,5 @@ msgstr "Gear Girişi" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Telefonda %s proqramının aktiv olduğundan əmin ol." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Simvolların sayı maksimumu (%d) keçdi." \ No newline at end of file diff --git a/po/bg.po b/po/bg.po index 230b745..cf1ce05 100644 --- a/po/bg.po +++ b/po/bg.po @@ -256,3 +256,5 @@ msgstr "Въвеждане на Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Уверете се, че приложението %s е активно в телефона." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Максималният брой знаци (%d) е надвишен." \ No newline at end of file diff --git a/po/ca.po b/po/ca.po index 29923a4..7f23fa6 100644 --- a/po/ca.po +++ b/po/ca.po @@ -256,3 +256,5 @@ msgstr "Entrada del Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Asseguri's que l'app %s estigui activa al telèfon." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "S'ha excedit el nombre màxim de caràcters (%d)." \ No newline at end of file diff --git a/po/cs.po b/po/cs.po index c602228..77fabba 100644 --- a/po/cs.po +++ b/po/cs.po @@ -256,3 +256,5 @@ msgstr "Zadávání do Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Zkontrolujte, zda je v telefonu aktivní aplikace %s." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Byl překročen maximální počet znaků (%d)." \ No newline at end of file diff --git a/po/da.po b/po/da.po index 2f0c88c..ef1b75e 100644 --- a/po/da.po +++ b/po/da.po @@ -256,3 +256,5 @@ msgstr "Gear-input" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Sørg for, at appen %s er aktiv på telefonen." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Det maksimale antal tegn er overskredet (%d)." \ No newline at end of file diff --git a/po/de.po b/po/de.po index 9e0c4e3..c10e87c 100644 --- a/po/de.po +++ b/po/de.po @@ -256,3 +256,5 @@ msgstr "Gear-Eingabe" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Stellen Sie sicher, dass die %s-App auf Ihrem Telefon aktiv ist." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Maximale Anzahl von Zeichen (%d) überschritten." \ No newline at end of file diff --git a/po/el_GR.po b/po/el_GR.po index 0319b34..fca2872 100644 --- a/po/el_GR.po +++ b/po/el_GR.po @@ -256,3 +256,5 @@ msgstr "Είσοδος Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Βεβαιωθείτε ότι η εφαρμογή %s είναι ενεργή στο τηλέφωνό σας." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Ξεπεράσατε το μέγιστο αριθμό χαρακτήρων (%d)." \ No newline at end of file diff --git a/po/en.po b/po/en.po index d7dc941..491b270 100644 --- a/po/en.po +++ b/po/en.po @@ -256,3 +256,5 @@ msgstr "Gear Input" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Make sure the %s app is active on your phone." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Maximum number of characters (%d) exceeded." \ No newline at end of file diff --git a/po/en_PH.po b/po/en_PH.po index 128fe6e..8c74d21 100644 --- a/po/en_PH.po +++ b/po/en_PH.po @@ -256,3 +256,5 @@ msgstr "Gear Input" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Make sure the %s app is active on your phone." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Maximum number of characters (%d) exceeded." \ No newline at end of file diff --git a/po/en_US.po b/po/en_US.po index 8f90a0a..4331d77 100644 --- a/po/en_US.po +++ b/po/en_US.po @@ -261,3 +261,6 @@ msgstr "Emojis" msgid "IDS_IME_HEADER_RECENT_M_RECETLY_SENT_EMOJIS_ABB" msgstr "Recent" + +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Maximum number of characters (%d) exceeded." \ No newline at end of file diff --git a/po/es_ES.po b/po/es_ES.po index 99412d0..6516753 100644 --- a/po/es_ES.po +++ b/po/es_ES.po @@ -256,3 +256,5 @@ msgstr "Entrada de Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Asegúrese de que la aplicación %s está activa en el teléfono." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Se ha superado el número máximo de caracteres (%d)." \ No newline at end of file diff --git a/po/es_US.po b/po/es_US.po index 4c679c9..690639d 100644 --- a/po/es_US.po +++ b/po/es_US.po @@ -256,3 +256,5 @@ msgstr "Tipo de entrada en Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Compruebe que la aplicación %s está activa en el teléfono." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Se superó el número máximo de caracteres (%d)." \ No newline at end of file diff --git a/po/et.po b/po/et.po index e65697a..99e9a3b 100644 --- a/po/et.po +++ b/po/et.po @@ -256,3 +256,5 @@ msgstr "Geari sisend" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Veenduge, et rakendus %s oleks teie telefonis aktiivne." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Maksimaalne tähemärkide arv (%d) on ületatud." \ No newline at end of file diff --git a/po/eu.po b/po/eu.po index 6101419..c92ad58 100644 --- a/po/eu.po +++ b/po/eu.po @@ -256,3 +256,5 @@ msgstr "Gear sarrera" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Ziurtatu %s aplikazioa telefonoan aktibo dagoela." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Gehienezko karaktere kopurua (%d) gainditu da." \ No newline at end of file diff --git a/po/fi.po b/po/fi.po index 3919efd..ede3969 100644 --- a/po/fi.po +++ b/po/fi.po @@ -256,3 +256,5 @@ msgstr "Gearin syöttö" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Varmista, että %s -sovellus on käynnissä puhelimessa." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Merkkien enimmäismäärä (%d) on ylitetty." \ No newline at end of file diff --git a/po/fr.po b/po/fr.po index 9ba7b8b..0f0cec8 100644 --- a/po/fr.po +++ b/po/fr.po @@ -256,3 +256,5 @@ msgstr "Saisie de la Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Assurez-vous que l'application %s est active sur votre téléphone." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Le nombre maximal de caractères (%d) a été dépassé." \ No newline at end of file diff --git a/po/fr_CA.po b/po/fr_CA.po index a926e61..e7233b3 100644 --- a/po/fr_CA.po +++ b/po/fr_CA.po @@ -256,3 +256,5 @@ msgstr "Saisie de la Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Assurez-vous que l'application %s est active sur votre téléphone." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Le nombre maximal de caractères (%d) a été dépassé." \ No newline at end of file diff --git a/po/ga.po b/po/ga.po index 70ed706..ed7bfd4 100644 --- a/po/ga.po +++ b/po/ga.po @@ -256,3 +256,5 @@ msgstr "Ionchur Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Cinntigh go bhfuil an feidhmchlár %s gníomhach ar d'fhón." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Uaslíon na gcarachtar (%d) sáraithe." \ No newline at end of file diff --git a/po/gl.po b/po/gl.po index 831300c..3760442 100644 --- a/po/gl.po +++ b/po/gl.po @@ -256,3 +256,5 @@ msgstr "Entrada de Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Asegúrate de que a aplicación %s estea activa no teu teléfono." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Superouse o número máximo de caracteres (%d)." \ No newline at end of file diff --git a/po/hi.po b/po/hi.po index c080819..b1b3f25 100644 --- a/po/hi.po +++ b/po/hi.po @@ -256,3 +256,5 @@ msgstr "गियर इनपुट" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "सुनिश्चित करें कि आपके फोन पर %s एप सक्रिय है।" +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "वर्णों की अधिकतम संख्या (%d) पार हो गई है।" \ No newline at end of file diff --git a/po/hr.po b/po/hr.po index f168589..514f251 100644 --- a/po/hr.po +++ b/po/hr.po @@ -256,3 +256,5 @@ msgstr "Unos za Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Provjerite je li aplikacija %s aktivna na vašem telefonu." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Premašen je maksimalni broj znakova (%d)." \ No newline at end of file diff --git a/po/hu.po b/po/hu.po index efbe276..ca5eda2 100644 --- a/po/hu.po +++ b/po/hu.po @@ -256,3 +256,5 @@ msgstr "Gear-bevitel" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Indítsa el a %s alkalmazást a telefonon." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Túllépte a karakterek maximális számát (%d)." \ No newline at end of file diff --git a/po/hy.po b/po/hy.po index 5ae818c..ce56265 100644 --- a/po/hy.po +++ b/po/hy.po @@ -256,3 +256,5 @@ msgstr "Gear-ի ներածում" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Համոզվեք, որ %s ծրագիրն ակտիվ է հեռախոսում:" +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Նիշերի առավելագույն քանակը (%d) գերազանցվել է:" \ No newline at end of file diff --git a/po/is.po b/po/is.po index 84cc092..d601d66 100644 --- a/po/is.po +++ b/po/is.po @@ -256,3 +256,5 @@ msgstr "Gear inntak" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Gakktu úr skugga um að forritið %s sé virkt í símanum." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Hámarksfjölda stafa (%d) náð." \ No newline at end of file diff --git a/po/it_IT.po b/po/it_IT.po index 64b331b..868e769 100644 --- a/po/it_IT.po +++ b/po/it_IT.po @@ -256,3 +256,5 @@ msgstr "Inserimento Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Assicuratevi che l'applicazione %s sia attiva sul dispositivo." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Il numero massimo di caratteri (%d) è stato superato." \ No newline at end of file diff --git a/po/ja_JP.po b/po/ja_JP.po index 7d16f63..947a368 100644 --- a/po/ja_JP.po +++ b/po/ja_JP.po @@ -256,3 +256,5 @@ msgstr "Gear入力" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "端末で%sアプリが実行されていることを確認してください。" +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "最大文字数(%d文字)を超えています。" \ No newline at end of file diff --git a/po/ka.po b/po/ka.po index 8461e81..f49e785 100644 --- a/po/ka.po +++ b/po/ka.po @@ -256,3 +256,5 @@ msgstr "Gear-ით შეყვანა" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "დარწმუნდით, რომ ტელეფონში აქტიურია %s აპლიკაცია." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "გადაჭარბებულია სიმბოლოების მაქსიმალური რაოდენობა (%d)." \ No newline at end of file diff --git a/po/kk.po b/po/kk.po index 34f6d99..052cbbf 100644 --- a/po/kk.po +++ b/po/kk.po @@ -256,3 +256,5 @@ msgstr "Gear енгізу" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "%s қолданбасының телефоныңызда қосулы екеніне көз жеткізіңіз." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Таңбалар ең көп (%d) санынан асып кетті." diff --git a/po/ko_KR.po b/po/ko_KR.po index f34f13a..1def068 100644 --- a/po/ko_KR.po +++ b/po/ko_KR.po @@ -256,3 +256,5 @@ msgstr "Gear 입력" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "폰에서 %s 앱이 실행되어 있는지 확인하세요." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "최대 글자 수(%d)를 초과했습니다." \ No newline at end of file diff --git a/po/lt.po b/po/lt.po index e78ef58..8ce18c8 100644 --- a/po/lt.po +++ b/po/lt.po @@ -256,3 +256,5 @@ msgstr "„Gear“ įvestis" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Įsitikinkite, kad telefone suaktyvinta %s programa." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Viršytas didžiausias simbolių skaičius (%d)." \ No newline at end of file diff --git a/po/lv.po b/po/lv.po index 3f0cfdf..d134eda 100644 --- a/po/lv.po +++ b/po/lv.po @@ -256,3 +256,5 @@ msgstr "Gear Input" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Aktivizējiet tālrunī programmu %s." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Pārsniegts maksimālais rakstzīmju skaits (%d)." \ No newline at end of file diff --git a/po/mk.po b/po/mk.po index 15989b0..e790aba 100644 --- a/po/mk.po +++ b/po/mk.po @@ -256,3 +256,5 @@ msgstr "Внес на Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Осигурете се дека апликацијата %s е активна на телефонот." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Надминат е максималниот број на знаци (%d)." \ No newline at end of file diff --git a/po/nb.po b/po/nb.po index a90f2d9..68e2219 100644 --- a/po/nb.po +++ b/po/nb.po @@ -256,3 +256,5 @@ msgstr "Gear-inndata" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Pass på at %s-appen er aktiv på telefonen." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Maksimalt antall tegn (%d) er oversteget." \ No newline at end of file diff --git a/po/nl.po b/po/nl.po index 45a5965..0ad134f 100644 --- a/po/nl.po +++ b/po/nl.po @@ -256,3 +256,5 @@ msgstr "Invoer Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Controleer of de app %s actief is op uw telefoon." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Maximumaantal tekens (%d) overschreden." \ No newline at end of file diff --git a/po/pl.po b/po/pl.po index 3baec11..99b3b99 100644 --- a/po/pl.po +++ b/po/pl.po @@ -256,3 +256,5 @@ msgstr "Wprowadzanie Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Upewnij się, że aplikacja %s jest aktywna w telefonie." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Przekroczono maksymalną liczbę znaków (%d)." \ No newline at end of file diff --git a/po/pt_BR.po b/po/pt_BR.po index ae1e3b4..42cabcc 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -256,3 +256,5 @@ msgstr "Entrada do Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Verifique se o aplicativo %s está ativo no telefone." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "O número máximo de caracteres (%d) foi excedido." \ No newline at end of file diff --git a/po/pt_PT.po b/po/pt_PT.po index 884d706..bf861e9 100644 --- a/po/pt_PT.po +++ b/po/pt_PT.po @@ -256,3 +256,5 @@ msgstr "Introdução do Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Certifique-se de que a aplicação %s está activa no seu telefone." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Número máximo de caracteres (%d) excedido." \ No newline at end of file diff --git a/po/ro.po b/po/ro.po index 24ccaa6..f449e08 100644 --- a/po/ro.po +++ b/po/ro.po @@ -256,3 +256,5 @@ msgstr "Introducere prin dispozitivul Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Asiguraţi-vă că aplicaţia %s este activă pe telefon." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "A fost depășit numărul maxim de caractere (%d)." \ No newline at end of file diff --git a/po/ru_RU.po b/po/ru_RU.po index c2abf82..f15c9d5 100644 --- a/po/ru_RU.po +++ b/po/ru_RU.po @@ -256,3 +256,5 @@ msgstr "Gear Input" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "На телефоне должно быть запущено приложение %s." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Превышено максимальное число символов (%d)." \ No newline at end of file diff --git a/po/sk.po b/po/sk.po index 5769a1c..b805618 100644 --- a/po/sk.po +++ b/po/sk.po @@ -256,3 +256,5 @@ msgstr "Vstup cez Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Skontrolujte, či je v telefóne aktívna aplikácia %s." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Prekročil sa maximálny počet znakov (%d)." \ No newline at end of file diff --git a/po/sl.po b/po/sl.po index a272122..0c2b3dd 100644 --- a/po/sl.po +++ b/po/sl.po @@ -256,3 +256,5 @@ msgstr "Vnos z napravo Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Preverite, ali je aplikacija %s aktivna v telefonu." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Največje dovoljeno število znakov (%d) je preseženo." \ No newline at end of file diff --git a/po/sr.po b/po/sr.po index 529528c..21f2542 100644 --- a/po/sr.po +++ b/po/sr.po @@ -256,3 +256,5 @@ msgstr "Unos za Gear" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Proverite da li je aplikacija %s aktivna na telefonu." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Prekoračen je maksimalan broj karaktera (%d)." \ No newline at end of file diff --git a/po/sv.po b/po/sv.po index a1e779b..0f60ae1 100644 --- a/po/sv.po +++ b/po/sv.po @@ -256,3 +256,5 @@ msgstr "Gear-inmatning" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Se till att programmet %s är aktivt på telefonen." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Max antal tecken (%d) överskreds." \ No newline at end of file diff --git a/po/tr_TR.po b/po/tr_TR.po index b98bbb5..a915b97 100644 --- a/po/tr_TR.po +++ b/po/tr_TR.po @@ -256,3 +256,5 @@ msgstr "Gear Girişi" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "%s uygulamasının telefonunuzda etkin olduğundan emin olun." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Maksimum karakter sayısı (%d) aşıldı." \ No newline at end of file diff --git a/po/uk.po b/po/uk.po index 8a8cb5d..7619449 100644 --- a/po/uk.po +++ b/po/uk.po @@ -256,3 +256,5 @@ msgstr "Gear Input" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "На телефоні потрібно відкрити програму %s." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Перевищено максимальну кількість символів (%d)." \ No newline at end of file diff --git a/po/uz.po b/po/uz.po index 2e51f8f..d29f33a 100644 --- a/po/uz.po +++ b/po/uz.po @@ -256,3 +256,5 @@ msgstr "Gear kiritish" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Telefonda %s ilovasi yoqilganligiga ishonch hosil qiling." +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "Belgilar soni maksimal miqdordan (%d) oshib ketdi." \ No newline at end of file diff --git a/po/zh_CN.po b/po/zh_CN.po index 65f4abf..15551c6 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -256,3 +256,5 @@ msgstr "Gear 输入" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "请确保 %s 应用程序已在您的手机上运行。" +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "已超过字符数上限 (%d)。" \ No newline at end of file diff --git a/po/zh_HK.po b/po/zh_HK.po index e72d325..0078af9 100644 --- a/po/zh_HK.po +++ b/po/zh_HK.po @@ -256,3 +256,5 @@ msgstr "Gear 輸入" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "請確保 %s 應用程式已在手機上啟動。" +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "已超過字元數目上限 (%d)。" \ No newline at end of file diff --git a/po/zh_TW.po b/po/zh_TW.po index bcd1d7d..a798590 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -256,3 +256,5 @@ msgstr "Gear 輸入" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "請確認手機上已執行 %s 應用程式。" +msgid "WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED" +msgstr "已超過字數上限 (%d)。" \ No newline at end of file diff --git a/src/w-input-keyboard.cpp b/src/w-input-keyboard.cpp index 7fe4860..9da2294 100755 --- a/src/w-input-keyboard.cpp +++ b/src/w-input-keyboard.cpp @@ -35,6 +35,7 @@ bool input_keyboard_init(app_control_h app_control) char *default_text = NULL; char *guide_text = NULL; char *return_key_type = NULL; + char *max_text_length = NULL; input_keyboard_deinit(); @@ -50,6 +51,10 @@ bool input_keyboard_init(app_control_h app_control) if (ret == APP_CONTROL_ERROR_NONE) { g_input_keyboard_data.return_key_type = return_key_type; } + ret = app_control_get_extra_data(app_control, "max_text_length", &max_text_length); + if (ret == APP_CONTROL_ERROR_NONE) { + g_input_keyboard_data.max_text_length = atoi(max_text_length); + } return true; } @@ -68,6 +73,7 @@ void input_keyboard_deinit(void) g_input_keyboard_data.default_text = NULL; g_input_keyboard_data.guide_text = NULL; g_input_keyboard_data.return_key_type = NULL; + g_input_keyboard_data.max_text_length = KEYBOARD_EDITOR_CHAR_COUNT_MAX; return; } @@ -110,6 +116,9 @@ static Eina_Bool custom_back_cb(void *data, Elm_Object_Item *it) static void maxlength_cb(void *data, Evas_Object *obj, void *event_info) { LOGD("maxlength_cb : size = %d", KEYBOARD_EDITOR_CHAR_COUNT_MAX); + char text[512]; + snprintf(text, sizeof(text), _(MAX_TEXT_LENGTH_REACH), g_input_keyboard_data.max_text_length); + show_popup_toast((const char *)text, false); } static void enter_keydown_cb(void *data, Evas_Object *obj, void *event_info) @@ -141,7 +150,7 @@ void create_fullscreen_editor(void *data) entry = elm_entry_add(box); static Elm_Entry_Filter_Limit_Size limit_filter_data; - limit_filter_data.max_char_count = KEYBOARD_EDITOR_CHAR_COUNT_MAX; + limit_filter_data.max_char_count = g_input_keyboard_data.max_text_length; elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size, &limit_filter_data); evas_object_smart_callback_add(entry, "maxlength,reached", maxlength_cb, data); @@ -205,7 +214,7 @@ static Evas_Object *create_multiline_editfield_layout(Evas_Object *parent, void entry = elm_entry_add(editfield); static Elm_Entry_Filter_Limit_Size limit_filter_data; - limit_filter_data.max_char_count = KEYBOARD_EDITOR_CHAR_COUNT_MAX; + limit_filter_data.max_char_count = g_input_keyboard_data.max_text_length; elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size, &limit_filter_data); evas_object_smart_callback_add(entry, "maxlength,reached", maxlength_cb, data); diff --git a/src/w-input-stt-voice.cpp b/src/w-input-stt-voice.cpp index ac682cc..820299c 100755 --- a/src/w-input-stt-voice.cpp +++ b/src/w-input-stt-voice.cpp @@ -913,7 +913,8 @@ static char *__get_genlist_title_label(void *data, Evas_Object *obj, const char char *__get_genlist_item_label(void *data, Evas_Object *obj, const char *part) { - char text[128] = {0, }; + const int BUF_LEN = 128; + char text[BUF_LEN] = {'\0', }; if(!strcmp(part, "elm.text")) { @@ -928,12 +929,10 @@ char *__get_genlist_item_label(void *data, Evas_Object *obj, const char *part) if(p) { strncpy(text, s, p-s); } else { - strncpy(text, s, strlen(s)); - text[strlen(s)] = '\0'; + snprintf(text, BUF_LEN, "%s", s); } } else { - strncpy(text, "", strlen("")); - text[strlen("")] = '\0'; + snprintf(text, BUF_LEN, "%s", ""); } } return strdup(text); @@ -965,12 +964,10 @@ char *__get_genlist_item_label(void *data, Evas_Object *obj, const char *part) if(p) { strncpy(text, p+1, strlen(s)-(p-s)-2); } else { - strncpy(text, s, strlen(s)); - text[strlen(s)] = '\0'; + snprintf(text, BUF_LEN, "%s", s); } } else { - strncpy(text, "", strlen("")); - text[strlen("")] = '\0'; + snprintf(text, BUF_LEN, "%s", ""); } return strdup(text); } -- 2.7.4 From af4b014f6e2927f7ac6fb44c94c175e34ac9e0c9 Mon Sep 17 00:00:00 2001 From: "sungwook79.park" Date: Tue, 18 Jul 2017 19:04:07 +0900 Subject: [PATCH 14/16] Update package version to 0.1.170718 Change-Id: Iafac823f5f67487f81d47a25c0d7b22a5ef3198b Signed-off-by: sungwook79.park --- org.tizen.inputdelegator.xml | 2 +- packaging/org.tizen.inputdelegator.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/org.tizen.inputdelegator.xml b/org.tizen.inputdelegator.xml index ccb38de..bad1540 100755 --- a/org.tizen.inputdelegator.xml +++ b/org.tizen.inputdelegator.xml @@ -1,5 +1,5 @@ - + diff --git a/packaging/org.tizen.inputdelegator.spec b/packaging/org.tizen.inputdelegator.spec index 8063566..47f117f 100755 --- a/packaging/org.tizen.inputdelegator.spec +++ b/packaging/org.tizen.inputdelegator.spec @@ -9,7 +9,7 @@ Name: org.tizen.inputdelegator Summary: Input Delegator Application -Version: 0.1.170620 +Version: 0.1.170718 Release: 1 Group: Applications License: Apache-2.0 -- 2.7.4 From ef5da1fb757f5035a36869652cd6d561f829f075 Mon Sep 17 00:00:00 2001 From: "sungwook79.park" Date: Thu, 20 Jul 2017 13:45:02 +0900 Subject: [PATCH 15/16] adopt the return type for caller to send button in keyboard mode Change-Id: I016683204d21ed5c3ef14c0569c41fde9e61a406 Signed-off-by: sungwook79.park --- src/w-input-keyboard.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/w-input-keyboard.cpp b/src/w-input-keyboard.cpp index 9da2294..cd6356f 100755 --- a/src/w-input-keyboard.cpp +++ b/src/w-input-keyboard.cpp @@ -34,7 +34,7 @@ bool input_keyboard_init(app_control_h app_control) int ret = -1; char *default_text = NULL; char *guide_text = NULL; - char *return_key_type = NULL; + char *return_key_type = "SEND"; char *max_text_length = NULL; input_keyboard_deinit(); @@ -72,7 +72,7 @@ void input_keyboard_deinit(void) g_input_keyboard_data.default_text = NULL; g_input_keyboard_data.guide_text = NULL; - g_input_keyboard_data.return_key_type = NULL; + g_input_keyboard_data.return_key_type = "SEND"; g_input_keyboard_data.max_text_length = KEYBOARD_EDITOR_CHAR_COUNT_MAX; return; @@ -170,7 +170,7 @@ void create_fullscreen_editor(void *data) elm_box_pack_end(box, entry); Evas_Object *btn = elm_button_add(box); - elm_object_text_set(btn, "SEND"); + elm_object_text_set(btn, g_input_keyboard_data.return_key_type); evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, 0.5); evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_smart_callback_add(btn, "clicked", btn_clicked_cb, NULL); -- 2.7.4 From 14f0deffe01d498bf18693417fac9f5b9a38ad0a Mon Sep 17 00:00:00 2001 From: "sungwook79.park" Date: Tue, 25 Jul 2017 13:35:20 +0900 Subject: [PATCH 16/16] Add drawing feature in emoticon input mode Change-Id: I58785c2289022243bc36a36e6623403c32d3abef Signed-off-by: sungwook79.park --- res/wearable/edje/w-input-selector.edc | 143 ++++++++++++++++++++++++++++++++- res/wearable/edje/w-input-stt.edc | 41 ++++++++++ src/w-input-emoticon.cpp | 113 +++++++++++++++++++++++--- 3 files changed, 283 insertions(+), 14 deletions(-) diff --git a/res/wearable/edje/w-input-selector.edc b/res/wearable/edje/w-input-selector.edc index c00e082..9be1ffa 100755 --- a/res/wearable/edje/w-input-selector.edc +++ b/res/wearable/edje/w-input-selector.edc @@ -805,4 +805,145 @@ collections { } ) } -} + } + +// ------------------------------------------------Drawing ---------------------------------------------// + styles{ + style { + name: "list_text_drawing_normal"; + base: "font=Tizen:style=Regular font_size=36 align=left color=#FFFFFF color_class=AT021 wrap=word text_class=AT021"; + } + } + + images { + image, "./fadeout_masking.#.png" COMP; + } + + group { + name: "elm/genlist/item/drawing/default"; + data.item: "treesize" 0; + data.item: "flips" "elm.flip.icon elm.flip.content"; + data.item: "texts" "elm.text"; + data.item: "contents" "base elm.icon"; + data.item: "vi_effect" "on"; + data.item: "dim" "off"; + data.item: "focus_bg" "off"; + + parts { + PART_LIST_BG + PART_LIST_PADDINGS( + 0, 0, + LIST_BUTTON_PADDING_2BUTTON_TOP_SIZE_INC, LIST_BUTTON_PADDING_BOTTOM_SIZE_INC + ) + + PART(SWALLOW, "base",DESC_LRTB("elm.padding.left", "elm.padding.right", "elm.padding.top", "elm.padding.bottom", min: 360 0; fixed: 1 0; visible: 1;)) + + part { + name: "elm.padding.text.left_a"; + type: SPACER; + scale: 1; + mouse_events: 0; + repeat_events: 0; + description { + state: "default" 0.0; + min: (30+76+24) 0; + max: (30+76+24) 51; + fixed: 1 0; + align: 0.0 0.5; + rel1 { relative: 1.0 1.0; to_x: "elm.padding.left"; to_y: "elm.padding.top"; } + rel2 { relative: 1.0 0.0; to_x: "elm.padding.left"; to_y: "elm.padding.bottom"; } + } + } + part { + name: "elm.padding.text.left_b"; + type: SPACER; + scale: 1; + mouse_events: 0; + repeat_events: 0; + description { + state: "default" 0.0; + min: (360-30) 0; + max: (360-30) 51; + fixed: 1 0; + align: 0.0 0.5; + rel1 { relative: 1.0 1.0; to_x: "elm.padding.left"; to_y: "elm.padding.top"; } + rel2 { relative: 1.0 0.0; to_x: "elm.padding.left"; to_y: "elm.padding.bottom"; } + } + } + + part { + name: "elm.text"; + type: TEXTBLOCK; + scale: 1; + mouse_events: 0; + repeat_events: 0; + description { + state: "default" 0.0; + min: 0 48; + max: -1 48; + fixed: 0 1; + align: 0.5 0.5; + text { + min: 0 1; + max: 1 1; + ellipsis: -1.0; + fade_ellipsis: 1.0; + style: "list_text_drawing_normal"; + } + rel1 { relative: 1.0 1.0; to_x: "elm.padding.text.left_a"; to_y: "elm.padding.top"; } + rel2 { relative: 1.0 0.0; to_x: "elm.padding.text.left_b"; to_y: "elm.padding.bottom"; } + } + } + + part { + name: "fadeout"; + type: IMAGE; + scale: 1; + mouse_events: 0; + repeat_events: 0; + description { + state: "default" 0.0; + align: 1.0 0.5; + min: 49 44; + max: 49 44; + fixed: 1 1; + rel1 { relative: 1.0 1.0; to_x: "elm.padding.text.left_b"; to_y: "elm.padding.top"; } + rel2 { relative: 1.0 0.0; to_x: "elm.padding.text.left_b"; to_y: "elm.padding.bottom"; } + image.normal: "./fadeout_masking.#.png"; + color: 0 0 0 10; + } + } + + part { + name: "elm.padding.icon.left"; + type: SPACER; + scale: 1; + mouse_events: 0; + repeat_events: 0; + description { + state: "default" 0.0; + min: 24 0; + max: 24 51; + fixed: 1 1; + align: 1.0 0.5; + rel1 { relative: 0.0 1.0; to_x: "elm.text"; to_y: "elm.padding.top"; } + rel2 { relative: 0.0 0.0; to_x: "elm.text"; to_y: "elm.padding.bottom"; } + } + } + + part { + name: "elm.icon"; + type: SWALLOW; + description { + state: "default" 0.0; + visible: 1; + align: 1.0 0.5; + fixed: 1 1; + min: 76 76; + max: 76 76; + rel1 { relative: 0.0 1.0; to_x: "elm.padding.icon.left"; to_y: "elm.padding.top"; } + rel2 { relative: 0.0 0.0; to_x: "elm.padding.icon.left"; to_y: "elm.padding.bottom"; } + } + } + } + } diff --git a/res/wearable/edje/w-input-stt.edc b/res/wearable/edje/w-input-stt.edc index 082731d..13168ba 100755 --- a/res/wearable/edje/w-input-stt.edc +++ b/res/wearable/edje/w-input-stt.edc @@ -58,6 +58,7 @@ collections image, "./tw_bottom_btn_bg.png" COMP; image, "./w_mode_ic_bg.png" COMP; + image, "./wi_drawing_bg.png" COMP; image, "./b_stt_text_fade_out.png" COMP; image, "./b_stt_icon_btn.png" COMP; @@ -433,6 +434,21 @@ collections name: "AT023D"; color: 0 0 0 40; } + color_class + { + name: "AO0391"; + color: 0 151 207 100; + } + color_class + { + name: "AO0391P"; + color: 0 0 0 50; + } + color_class + { + name: "AO0391D"; + color: 0 0 0 40; + } } styles @@ -1903,6 +1919,31 @@ collections } } + group { name: "elm/button/base/ime_button_drawing"; + inherit: "elm/button/base/ime_button"; + parts { + part { name: "bg"; + type: IMAGE; + scale: 1; + description { state: "default" 0.0; + min: 76 76; + max: 76 76; + color_class: "AO0391"; + visible: 1; + image.normal: "./wi_drawing_bg.png"; + } + description { state: "pressed" 0.0; + inherit: "default" 0.0; + color_class: "AO0391P"; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + color_class: "AO0391D"; + } + } + } + } + group { name: "elm/button/base/ime_button_stt_confirm"; inherit: "elm/button/base/ime_button"; parts { diff --git a/src/w-input-emoticon.cpp b/src/w-input-emoticon.cpp index 4bd585b..a7f9a9c 100755 --- a/src/w-input-emoticon.cpp +++ b/src/w-input-emoticon.cpp @@ -49,6 +49,7 @@ typedef struct { static Elm_Object_Item *it_emoticon_empty = NULL; static Elm_Object_Item *it_emoticon_recent_group = NULL; static Elm_Object_Item *it_emoticon_emoji_group = NULL; +static Elm_Object_Item* it_drawing = NULL; static Elm_Object_Item *it_last = NULL; static Elm_Genlist_Item_Class *itc_emoticon = NULL; @@ -72,6 +73,7 @@ typedef struct emoticon_content } emoticon_content_s; static emoticon_content_s emoticon_contents_pool[EMOTICON_CNT] = { 0, }; +static emoticon_content_s emoticon_drawing_pool = { 0, }; static emoticon_content_s emoticon_recents_pool[RECENT_CNT] = { 0, }; @@ -278,6 +280,11 @@ static Eina_Bool _custom_back_cb2(void *data, Elm_Object_Item *it) lazy_loading_timer_for_contents = NULL; } + if(emoticon_drawing_pool.used == 0){ + evas_object_del(emoticon_drawing_pool.content); + } + emoticon_drawing_pool.content = NULL; + //Recent EMOTICONS : the recent emoiton need to be updated whenever emoticon view is generated, so deleted here. for (i=0;i< RECENT_CNT;i++) { @@ -361,6 +368,44 @@ void set_recent_emoticons(vector &emoticon_list, int val) if (PREFERENCE_ERROR_NONE != ret) { PRINTFUNC(DLOG_ERROR, "preference_set_string error!(%d)", ret); } + +} + +static void _drawing_app_control_reply_cb(app_control_h request, app_control_h reply, app_control_result_e result, void *user_data) +{ + char* path = NULL; + app_control_get_extra_data(reply, APP_CONTROL_DATA_PATH, &path); + + if(path){ + PRINTFUNC(DLOG_DEBUG, "path=%s", path); + free(path); + reply_to_sender_by_callback((const char*)path, "image", NULL); + } + ui_app_exit(); +} + +static void _drawing_item_clicked_cb(void *data, Evas_Object * obj, void *event_info) +{ + PRINTFUNC(DLOG_DEBUG, "%s", __func__); + App_Data* ad = (App_Data*) data; + if (!ad) + return; + + Elm_Object_Item *item = (Elm_Object_Item *) event_info; + if (item) + elm_genlist_item_selected_set(item, EINA_FALSE); + + /* launch */ + app_control_h request = NULL; + app_control_create(&request); + app_control_set_app_id(request, "com.samsung.sketch"); + //app_control_set_app_id(request, "wearable-input.sketch"); + + int ret = app_control_send_launch_request(request, _drawing_app_control_reply_cb, NULL); + if (ret != APP_CONTROL_ERROR_NONE) { + PRINTFUNC(DLOG_DEBUG, "error code = 0x%x", ret); + } + app_control_destroy(request); } static void _emoticon_item_clicked_cb(void *data, Evas_Object * obj, void *event_info) @@ -442,7 +487,6 @@ static void _emoticon_gl_lang_changed(void *data, Evas_Object *obj, void *event_ static char * __emoticon_gl_text_get(void *data, Evas_Object *obj, const char *part) { //PRINTFUNC(DLOG_DEBUG,"part = %s", part); - const char* str = (const char*) data; if (!str) return NULL; @@ -460,7 +504,7 @@ static void _emoticon_gl_content_unswallowed_cb(void *data, Evas_Object *obj, vo const Elm_Genlist_Item_Class *itc = elm_genlist_item_item_class_get(it); -// PRINTFUNC(DLOG_DEBUG,"%s - stype[%s]", __func__, itc->item_style); + //PRINTFUNC(DLOG_DEBUG,"%s - stype[%s]", __func__, itc->item_style); if (!strcmp(itc->item_style, "3button_flat")) { int index = (uintptr_t)elm_object_item_data_get(it); //PRINTFUNC(DLOG_DEBUG,"it = %p", it); @@ -488,16 +532,55 @@ static void _emoticon_gl_content_unswallowed_cb(void *data, Evas_Object *obj, vo if (index + 2 < recent_emoji_list.size()) { emoticon_recents_pool[index+2].used = 0; } + } else if (it_drawing == it) { + //PRINTFUNC(DLOG_DEBUG,"it_drawing = %p", it_drawing); + emoticon_drawing_pool.used = 0; } } +static Evas_Object * __emoticon_gl_1_content_get(void *data, Evas_Object *obj, const char *part) +{ + if (!strcmp(part, "elm.icon")) { + Evas_Object* btn = elm_button_add(obj); + evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, EVAS_HINT_FILL); + Evas_Object* ic = elm_image_add(btn); + elm_image_resizable_set(ic, EINA_TRUE, EINA_TRUE); + + string path = get_resource_path(); + if (_WEARABLE) + path = path + "wearable/"; + else if (_TV) + path = path + "tv/"; + else + path = path + "mobile/"; + + elm_object_style_set(btn, "ime_button_drawing"); + string path_ic = path + "images/wi_drawing_icon.png"; + PRINTFUNC(DLOG_DEBUG, "path_ic = %s", path_ic.c_str()); + elm_image_file_set(ic, path_ic.c_str(), NULL); + elm_object_content_set(btn, ic); + evas_object_layer_set(btn, 32000); + + emoticon_drawing_pool.index = 0; + emoticon_drawing_pool.content = btn; + emoticon_drawing_pool.used = 0; + return btn; + } else if(!strcmp(part, "base")){ + Evas_Object* btn = elm_button_add(obj); + elm_object_style_set(btn, "ime/transparent"); + return btn; + } + return NULL; +} + static Evas_Object * __emoticon_gl_recent_content_get(void *data, Evas_Object *obj, const char *part) { if (is_content_reuse_on) { unsigned int index = (uintptr_t)data; int new_index = 0; - //PRINTFUNC(DLOG_DEBUG,"%s %d", part, index); + //PRINTFUNC(DLOG_DEBUG,"%s %d", part, index); if (!strcmp(part, "elm.icon.1") || (!strcmp(part, "elm.icon.2")) || (!strcmp(part, "elm.icon.3"))) { if (!strcmp(part, "elm.icon.1")) { if (index >= recent_emoji_list.size()) return NULL; @@ -523,7 +606,7 @@ static Evas_Object * __emoticon_gl_recent_content_get(void *data, Evas_Object *o unsigned int index = (uintptr_t)data; int new_index = 0; - // PRINTFUNC(DLOG_DEBUG,"%s %d", part, index); + //PRINTFUNC(DLOG_DEBUG,"%s %d", part, index); if (!strcmp(part, "elm.icon.1") || (!strcmp(part, "elm.icon.2")) || (!strcmp(part, "elm.icon.3"))) { if (!strcmp(part, "elm.icon.1")) { if (index >= recent_emoji_list.size()) return NULL; @@ -548,7 +631,6 @@ static Evas_Object * __emoticon_gl_recent_content_get(void *data, Evas_Object *o static Evas_Object * __emoticon_gl_emoticon_content_get(void *data, Evas_Object *obj, const char *part) { //PRINTFUNC(DLOG_DEBUG,"%s", __func__); - if (is_content_reuse_on) { int index = (uintptr_t)data; int new_index = 0; @@ -614,7 +696,6 @@ static Evas_Object * __emoticon_gl_emoticon_content_get(void *data, Evas_Object return NULL; } - void _create_reusable_recents(Evas_Object *parent) { if (!parent) { @@ -802,8 +883,14 @@ void _update_emoticon_items(void *data) itc_dummy->func.state_get = NULL; itc_dummy->func.del = NULL; - Elm_Genlist_Item_Class *itc_group = elm_genlist_item_class_new(); + Elm_Genlist_Item_Class *itc_1text_1icon = elm_genlist_item_class_new(); + itc_1text_1icon->item_style = "drawing"; + itc_1text_1icon->func.text_get = __emoticon_gl_text_get; + itc_1text_1icon->func.content_get = __emoticon_gl_1_content_get; + itc_1text_1icon->func.state_get = NULL; + itc_1text_1icon->func.del = NULL; + Elm_Genlist_Item_Class *itc_group = elm_genlist_item_class_new(); itc_group->item_style = "groupindex"; itc_group->func.text_get = __emoticon_gl_text_get; itc_group->func.content_get = NULL; @@ -811,9 +898,6 @@ void _update_emoticon_items(void *data) itc_group->func.del = NULL; Elm_Genlist_Item_Class *itc_recent = elm_genlist_item_class_new(); - if (is_content_reuse_on) { -// itc_recent->content_reusable = EINA_TRUE; - } itc_recent->item_style = "3button_flat_recent"; itc_recent->func.text_get = NULL; itc_recent->func.content_get = __emoticon_gl_recent_content_get; @@ -821,9 +905,6 @@ void _update_emoticon_items(void *data) itc_recent->func.del = NULL; itc_emoticon = elm_genlist_item_class_new(); - if (is_content_reuse_on) { -// itc_emoticon->content_reusable = EINA_TRUE; - } itc_emoticon->item_style = "3button_flat"; itc_emoticon->func.text_get = NULL; itc_emoticon->func.content_get = __emoticon_gl_emoticon_content_get; @@ -833,6 +914,10 @@ void _update_emoticon_items(void *data) // dummy title for empty space it_emoticon_empty = elm_genlist_item_append(gl, itc_dummy, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL); + // Drawing + it_drawing = elm_genlist_item_append(gl, itc_1text_1icon, "Doodle", NULL, ELM_GENLIST_ITEM_NONE, _drawing_item_clicked_cb, (void *)app_data); + first_it = it_drawing; + if (recent_emoji_list.size() > 0) { if (is_content_reuse_on) { _create_reusable_recents(gl); @@ -877,6 +962,7 @@ void _update_emoticon_items(void *data) elm_genlist_item_class_free(itc_recent); elm_genlist_item_class_free(itc_group); + elm_genlist_item_class_free(itc_1text_1icon); elm_genlist_item_class_free(itc_dummy); } @@ -889,6 +975,7 @@ void ise_show_emoticon_list(void *data) it_emoticon_empty = NULL; it_emoticon_recent_group = NULL; it_emoticon_emoji_group = NULL; + it_drawing = NULL; it_last = NULL; get_recent_emoticons(recent_emoji_list); -- 2.7.4