From 7d42acc0bd06759194e5d2be7d702cc9d7f93440 Mon Sep 17 00:00:00 2001 From: "sungwook79.park" Date: Fri, 10 Feb 2017 09:29:08 +0900 Subject: [PATCH] Add template for smart reply Change-Id: I0e0dd321a54eeeac58cb670e32ac011e321c9811 Signed-off-by: sungwook79.park --- inc/w-input-template.h | 45 ++++++++ src/w-input-selector.cpp | 212 +++++++++++++++++++++++++++++++--- src/w-input-template.cpp | 290 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 529 insertions(+), 18 deletions(-) create mode 100755 inc/w-input-template.h create mode 100755 src/w-input-template.cpp diff --git a/inc/w-input-template.h b/inc/w-input-template.h new file mode 100755 index 0000000..f270cee --- /dev/null +++ b/inc/w-input-template.h @@ -0,0 +1,45 @@ +/* + * 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_TEMPLATE_H_ +#define __W_INPUT_TEMPLATE_H_ + +#include +#include + +#include + +struct TemplateData { + std::string text; + bool use_gettext; +}; + +typedef void (*input_template_changed) (void *user_data); + + +void input_template_init(app_control_h app_control); + +void input_template_deinit(void); + +const std::vector input_template_get_list(void); + +void input_template_set_notify(input_template_changed callback, void *user_data); + +void input_template_unset_notify(void); + +bool input_template_is_user_template(void); + +#endif diff --git a/src/w-input-selector.cpp b/src/w-input-selector.cpp index 828c9a5..61a55cb 100755 --- a/src/w-input-selector.cpp +++ b/src/w-input-selector.cpp @@ -23,8 +23,8 @@ #include #include -//#include "ui_extension.h" #include "w-input-selector.h" +#include "w-input-template.h" #include "w-input-keyboard.h" #include "w-input-stt-ise.h" #include "w-input-emoticon.h" @@ -43,6 +43,8 @@ InputTypeData g_input_type_data; static Elm_Object_Item *it_empty; static Elm_Object_Item *it_title; +static unsigned int g_template_item_size = 0; /* Current Template item size */ + Evas_Coord last_step; // 0 ~ 9 for gesture, 10~11 for rotary void _init_app_data(App_Data* app_data); @@ -50,25 +52,24 @@ static void _app_language_changed(app_event_info_h event_info, void *user_data); 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_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); - - void _init_app_data(App_Data* app_data) { - app_data->win_main = NULL; - app_data->layout_main = NULL; - app_data->conform = NULL; - app_data->naviframe = NULL; - app_data->genlist = NULL; + app_data->win_main = NULL; + app_data->layout_main = NULL; + app_data->conform = NULL; + app_data->naviframe = NULL; + app_data->genlist = NULL; - app_data->res_path = NULL; + app_data->res_path = NULL; } - - Evas_Object* load_edj(Evas_Object* parent, const char* file, const char* group) { Evas_Object* window; @@ -89,7 +90,6 @@ Evas_Object* load_edj(Evas_Object* parent, const char* file, const char* group) evas_object_size_hint_weight_set(window, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); } - return window; } @@ -108,9 +108,9 @@ 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(); - return EINA_FALSE; + reply_to_sender_by_callback_for_back(); + elm_exit(); + return EINA_FALSE; } static void _stt_clicked_cb(void *data, Evas_Object * obj, void *event_info) @@ -138,6 +138,11 @@ static void _stt_clicked_cb(void *data, Evas_Object * obj, void *event_info) } } +static void _input_template_notify_cb(void *user_data) +{ + _update_genlist_items((void *)app_data); +} + static void _emoticon_clicked_cb(void *data, Evas_Object * obj, void *event_info) { App_Data* ad = (App_Data*)data; @@ -147,7 +152,7 @@ static void _emoticon_clicked_cb(void *data, Evas_Object * obj, void *event_info if(!ad) return; - ise_show_emoticon_list(ad); + ise_show_emoticon_list(ad); } static void _keyboard_clicked_cb(void *data, Evas_Object * obj, void *event_info) @@ -162,6 +167,58 @@ static void _keyboard_clicked_cb(void *data, Evas_Object * obj, void *event_info input_keyboard_launch(ad->win_main, data); } +static void __ise_template_gl_sel(void *data, Evas_Object *obj, void *event_info) +{ + Elm_Object_Item *item = (Elm_Object_Item *) event_info; + int index = 0; + + if (item) { + elm_genlist_item_selected_set(item, EINA_FALSE); + + index = (unsigned int) elm_object_item_data_get(item); + 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"); + elm_exit(); + } + } +} + +static char * __ise_template_gl_text_get(void *data, Evas_Object *obj, const char *part) +{ + if(!strcmp(part, "elm.text")) { + unsigned int index = (unsigned int)data; + const std::vector template_list = input_template_get_list(); + + if(index < template_list.size()) { + if(template_list[index].use_gettext) { + return strdup(gettext(template_list[index].text.c_str())); + } else { + Eina_Strbuf *buf = NULL; + const char *str = NULL; + char *markup = NULL; + + buf = eina_strbuf_new(); + if(buf) { + eina_strbuf_append(buf, template_list[index].text.c_str()); + eina_strbuf_replace_all(buf, "\n", ""); + eina_strbuf_replace_all(buf, "\r", ""); + + str = eina_strbuf_string_get(buf); + + if (str) { + markup = elm_entry_utf8_to_markup(str); + } + eina_strbuf_free(buf); + } + return markup; + } + } + } + return NULL; +} + static Evas_Object * __ise_gl_2button_content_get(void *data, Evas_Object *obj, const char *part) { char *first_input_type = *(g_input_type_data.input_type_array + 0); @@ -556,8 +613,6 @@ _main_menu_title_text_get(void *data, Evas_Object *obj, const char *part) void _create_genlist_items(void* user_data) { - LOGD("[psw] _create_genlist_items"); - App_Data* app_data = (App_Data*) user_data; if(NULL == app_data->genlist) { @@ -604,6 +659,8 @@ void _create_genlist_items(void* user_data) elm_genlist_item_select_mode_set(it_title, ELM_OBJECT_SELECT_MODE_NONE); + g_template_item_size = _update_template_items(app_data); + Elm_Object_Item *item = elm_genlist_item_next_get(it_title); elm_genlist_item_show(item, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE); @@ -613,6 +670,118 @@ void _create_genlist_items(void* user_data) elm_genlist_item_class_free(itc1); } +void _create_header_items(void *user_data) +{ + Elm_Genlist_Item_Class * itc0 = elm_genlist_item_class_new(); + itc0->item_style = "title"; + itc0->func.text_get = NULL; + itc0->func.content_get = NULL; + itc0->func.state_get = NULL; + itc0->func.del = NULL; + + Elm_Genlist_Item_Class * itc1 = elm_genlist_item_class_new(); + if (g_input_type_data.input_type_array_len == 2) { + itc1->item_style = "2button_flat"; + itc1->func.text_get = NULL; + itc1->func.content_get = __ise_gl_2button_content_get; + itc1->func.state_get = NULL; + itc1->func.del = NULL; + } else { + itc1->item_style = "3button_flat"; + itc1->func.text_get = NULL; + itc1->func.content_get = __ise_gl_3button_content_get; + itc1->func.state_get = NULL; + itc1->func.del = NULL; + } + + // dummy title for empty space + it_empty = elm_genlist_item_append(app_data->genlist, itc0, + NULL, NULL, + ELM_GENLIST_ITEM_NONE, + NULL, NULL); + + // 3 Buttons + it_title = elm_genlist_item_append(app_data->genlist, itc1, + NULL, NULL, + ELM_GENLIST_ITEM_NONE, + NULL, NULL); + + elm_genlist_item_select_mode_set(it_title, ELM_OBJECT_SELECT_MODE_NONE); + + elm_genlist_item_class_free(itc0); + elm_genlist_item_class_free(itc1); +} + +void _update_genlist_items(void *user_data) +{ + elm_genlist_clear(app_data->genlist); + + _create_header_items(user_data); + + g_template_item_size = _update_template_items(user_data); + + /* Update genlist item position */ + Elm_Object_Item *item = elm_genlist_item_next_get(it_title); + elm_genlist_item_show(item, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE); +} + +unsigned int _update_template_items(void *user_data) +{ + App_Data* app_data; + + Elm_Object_Item *first; + + unsigned int i = 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; + } + + first = elm_genlist_first_item_get(app_data->genlist); + if (first == NULL) + return 0; + elm_genlist_item_next_get(first); + + /* Append New Template list */ + const std::vector template_list = input_template_get_list(); + + if (template_list.size() > 0) { + Elm_Genlist_Item_Class *itc; + + itc = elm_genlist_item_class_new(); + + itc->item_style = "1text"; + itc->func.text_get = __ise_template_gl_text_get; + itc->func.content_get = NULL; + itc->func.state_get = NULL; + itc->func.del = NULL; + + for (i = 0; i < template_list.size(); i++) { + elm_genlist_item_append(app_data->genlist, + itc, + (void *)i, + NULL, + ELM_GENLIST_ITEM_NONE, + __ise_template_gl_sel, + app_data); + item_size++; + } + elm_genlist_item_class_free(itc); + } + + return item_size; +} + bool _app_create(void* user_data) { int width = 1000, height = 1000; @@ -727,6 +896,9 @@ void _app_service(app_control_h service, void* user_data) input_keyboard_init(service); + input_template_init(service); + input_template_set_notify(_input_template_notify_cb, NULL); + _create_genlist_items(app_data); ACTIVATE : @@ -764,6 +936,10 @@ void _app_terminate(void* user_data) free(app_data->shared_res_path); input_keyboard_deinit(); + + input_template_unset_notify(); + input_template_deinit(); + input_type_deinit(); } diff --git a/src/w-input-template.cpp b/src/w-input-template.cpp new file mode 100755 index 0000000..afe2410 --- /dev/null +++ b/src/w-input-template.cpp @@ -0,0 +1,290 @@ +/* + * 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 "w-input-template.h" + + +#define INPUT_TEMPLATE_DB_VCONF "memory/wms/update_text_template_db" + +#define INPUT_TEMPLATE_DB_PATH "/opt/usr/dbspace/.WearableManagerService.db" +#define INPUT_TEMPLATE_QUERY_LEN 1024 + +struct InputTemplate { + std::vector template_list; + bool notify; + bool user_template; + input_template_changed callback; + void *user_data; +}; + +static struct InputTemplate g_input_template; + + +static void _input_template_db_vconf_changed(keynode_t *key, void *data); + +static bool input_template_init_app_control_list(app_control_h app_control); +static bool input_template_init_app_control(app_control_h app_control); +static bool input_template_init_db_util(void); +static bool input_template_init_default(void); + + +static void _input_template_db_vconf_changed(keynode_t *key, void *data) +{ + bool db_status = vconf_keynode_get_bool(key); + + PRINTFUNC(DLOG_DEBUG, "starts :: db_status = %d", db_status); + + if(db_status != 0) + return; + + if (g_input_template.callback) { + // Clear template list and reset to template_list from DB + g_input_template.template_list.clear(); + input_template_init_db_util(); + + g_input_template.callback(g_input_template.user_data); + } +} + +static bool input_template_init_app_control_list(app_control_h app_control) +{ + int ret; + int len; + + char **list = NULL; + + ret = app_control_get_extra_data_array(app_control, + "template_list", &list, &len); + + if (ret != APP_CONTROL_ERROR_NONE) + return false; + + if (list == NULL) + return false; + + for (int i = 0; i < len; i++) { + struct TemplateData data; + + if (*(list + i)) { + // if use_gettext is true, + // it's default template string that requires gettext. + data.use_gettext = false; + data.text = *(list + i); + + g_input_template.template_list.push_back(data); + + free(*(list + i)); + } + } + + free(list); + + g_input_template.user_template = true; + + return true; +} + +static bool input_template_init_app_control(app_control_h app_control) +{ + bool ret; + + if (app_control == NULL) + return false; + + ret = input_template_init_app_control_list(app_control); + if (ret) + return true; + + return false; +} + +static bool input_template_init_db_util(void) +{ + sqlite3 *g_tt_db = NULL; + sqlite3_stmt *stmt = NULL; + + int ret = -1; + + char query[INPUT_TEMPLATE_QUERY_LEN + 1] = {0, }; + + ret = db_util_open(INPUT_TEMPLATE_DB_PATH, &g_tt_db, 0); + + if (ret != SQLITE_OK) { + PRINTFUNC(DLOG_ERROR, "db_util open failed"); + return false; + } + + snprintf(query, INPUT_TEMPLATE_QUERY_LEN, + "select sortId, itemId, checked, message from %s", + "tmpl_msg_table"); + + sqlite3_prepare_v2(g_tt_db, query, strlen(query), &stmt, NULL); + + if (ret != SQLITE_OK) { + PRINTFUNC(DLOG_ERROR, "Can not get query"); + return false; + } + + ret = sqlite3_step(stmt); + + while(ret == SQLITE_ROW) { + struct TemplateData data; + int text_mode; + + // if checked is 0, + // it's default template string that requires gettext. + text_mode = sqlite3_column_int(stmt, 2); + if (text_mode) + data.use_gettext = false; + else + data.use_gettext = true; + + data.text = (char *)sqlite3_column_text(stmt, 3); + PRINTFUNC(DLOG_DEBUG, "db text %s", data.text.c_str()); + g_input_template.template_list.push_back(data); + + ret = sqlite3_step(stmt); + } + + ret = sqlite3_finalize(stmt); + if (ret != SQLITE_OK) + PRINTFUNC(DLOG_ERROR, "Can not finalize sqlite"); + + ret = db_util_close(g_tt_db); + if (ret != SQLITE_OK) + PRINTFUNC(DLOG_ERROR, "Can not close db_util"); + + /* set vconf callback for DB update */ + ret = vconf_notify_key_changed(INPUT_TEMPLATE_DB_VCONF, + _input_template_db_vconf_changed, NULL); + + if (ret < 0) + PRINTFUNC(DLOG_ERROR, "Can not create vconf notify"); + + g_input_template.user_template = false; + return true; +} + +static bool input_template_init_default(void) +{ + struct TemplateData data; + + data.text = "IDS_WMGR_MBODY_HOWS_IT_GOING_Q_M_TEXT_TEMPLATE"; + data.use_gettext = true; + + g_input_template.template_list.push_back(data); + + data.text = "IDS_WMGR_MBODY_WHATS_UP_Q_M_TEXT_TEMPLATE"; + data.use_gettext = true; + + g_input_template.template_list.push_back(data); + + data.text = "IDS_WMGR_MBODY_ILL_TALK_TO_YOU_SOON_M_TEXT_TEMPLATE"; + data.use_gettext = true; + + g_input_template.template_list.push_back(data); + + data.text = "IDS_WMGR_MBODY_ILL_CALL_YOU_LATER_M_TEXT_TEMPLATE"; + data.use_gettext = true; + + g_input_template.template_list.push_back(data); + + data.text = "IDS_MSG_BODY_WHERE_ARE_YOU_Q_M_TEXT_TEMPLATE"; + data.use_gettext = true; + + g_input_template.template_list.push_back(data); + + data.text = "IDS_MSG_BODY_WHEN_CAN_WE_MEET_Q_M_TEXT_TEMPLATE"; + data.use_gettext = true; + + g_input_template.template_list.push_back(data); + + data.text = "WDS_WMGR_MBODY_CALL_ME_LATER"; + data.use_gettext = true; + + g_input_template.template_list.push_back(data); + g_input_template.user_template = false; + + return true; +} + +static void input_template_deinit_db_util(void) +{ + vconf_ignore_key_changed(INPUT_TEMPLATE_DB_VCONF, + _input_template_db_vconf_changed); +} + +void input_template_init(app_control_h app_control) +{ + input_template_unset_notify(); + g_input_template.template_list.clear(); + g_input_template.user_template = false; + + bool ret; + + ret = input_template_init_app_control(app_control); + if (ret) + return; + + ret = input_template_init_db_util(); + if (ret) + return; + + input_template_init_default(); +} + +void input_template_deinit(void) +{ + input_template_unset_notify(); + input_template_deinit_db_util(); + + g_input_template.template_list.clear(); + g_input_template.user_template = false; +} + +const std::vector input_template_get_list(void) +{ + return g_input_template.template_list; +} + +void input_template_set_notify(input_template_changed callback, + void *user_data) +{ + if (callback == NULL) { + PRINTFUNC(DLOG_ERROR, "empty callback function"); + return; + } + + g_input_template.callback = callback; + g_input_template.user_data = user_data; +} + +void input_template_unset_notify(void) +{ + g_input_template.callback = NULL; + g_input_template.user_data = NULL; +} + +bool input_template_is_user_template(void) +{ + return (g_input_template.user_template); +} -- 2.7.4