51089c1fe1bc0b0fc24cdb0d6b3369bbc71efd27
[platform/core/uifw/inputdelegator.git] / src / MoreOption.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "Debug.h"
18
19 #include <string>
20 #include <assert.h>
21 #include <iostream>
22 #include <stdexcept>
23
24 #include <app.h>
25 #include <app_common.h>
26
27 #include "MoreOption.h"
28 #include "w-input-selector.h"
29 #include "w-input-stt-ise.h"
30 #include "w-input-stt-voice.h"
31
32 using namespace std;
33
34 extern Evas_Object *g_setting_window;
35 static bool voice_input_back_agree = false;
36
37 static void
38 popup_hide_cb(void *data, Evas_Object *obj, void *event_info)
39 {
40         if (!obj) return;
41         elm_popup_dismiss(obj);
42 }
43
44 static void
45 popup_hide_finished_cb(void *data, Evas_Object *obj, void *event_info)
46 {
47         if (!obj) return;
48         evas_object_del(obj);
49 }
50
51 static void voice_input_back_disagree_cb(void *data, Evas_Object *obj, void *event_info)
52 {
53         if(!obj) return;
54         if(!data) return;
55
56         VoiceData *voicedata = (VoiceData *)data;
57         Evas_Object *popup = (Evas_Object *)evas_object_data_get(obj, "popup");
58
59         voicedata->mo->discard_popup_opened = EINA_FALSE;
60
61         if (popup)
62                 elm_popup_dismiss(popup);
63 }
64
65 static void voice_input_back_agree_cb(void *data, Evas_Object *obj, void *event_info)
66 {
67         if(!obj) return;
68         if(!data) return;
69
70         VoiceData *voicedata = (VoiceData *)data;
71         Evas_Object *popup = (Evas_Object *)evas_object_data_get(obj, "popup");
72
73         voicedata->mo->discard_popup_opened = EINA_FALSE;
74
75         if (popup)
76                 elm_popup_dismiss(popup);
77
78         if(voicedata->naviframe){
79                 voice_input_back_agree = true;
80
81                 if(voicedata->disclaimer == 1){
82                         voicedata->disclaimer = 0;
83                         elm_naviframe_item_pop_to(elm_naviframe_bottom_item_get(voicedata->naviframe));
84                 } else {
85                         elm_naviframe_item_pop(voicedata->naviframe);
86                 }
87         }
88 }
89
90 static void show_discard_popup(void *data)
91 {
92         if(!data) return;
93
94         VoiceData *voicedata = (VoiceData *)data;
95
96         Evas_Object *popup = NULL;
97         Evas_Object *layout = NULL;
98         Evas_Object *btn_popup = NULL;
99         Evas_Object *icon = NULL;
100
101         std::string path = get_resource_path();
102
103         popup = elm_popup_add(voicedata->naviframe);
104         elm_object_style_set(popup, "circle");
105 //      uxt_popup_set_rotary_event_enabled(popup, EINA_TRUE);
106         eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, popup_hide_cb, NULL);
107         evas_object_smart_callback_add(popup, "dismissed", popup_hide_finished_cb, NULL);
108         evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
109
110         layout = elm_layout_add(popup);
111         elm_layout_theme_set(layout, "layout", "popup", "content/circle/buttons2");
112         elm_object_domain_translatable_part_text_set(layout, "elm.text", PACKAGE, "IDS_ST_SK_OK");
113         elm_object_content_set(popup, layout);
114         evas_object_show(layout);
115
116         btn_popup = elm_button_add(popup);
117         elm_object_style_set(btn_popup, "popup/circle/left");
118         elm_object_part_content_set(popup, "button1", btn_popup);
119         elm_access_info_set(btn_popup, ELM_ACCESS_INFO, dgettext(PACKAGE, "IDS_ST_SK_OK"));
120         evas_object_smart_callback_add(btn_popup, "clicked", voice_input_back_disagree_cb, voicedata);
121         evas_object_data_set(btn_popup, "popup", popup);
122         evas_object_show(btn_popup);
123
124         std::string path_ic_left = path + "/images/tw_ic_popup_btn_delete.png";
125         icon = elm_image_add(btn_popup);
126         elm_image_file_set(icon, path_ic_left.c_str(), NULL);
127         evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
128         elm_object_part_content_set(btn_popup, "elm.swallow.content", icon);
129         evas_object_show(icon);
130
131         btn_popup = elm_button_add(popup);
132         elm_object_style_set(btn_popup, "popup/circle/right");
133         elm_access_info_set(btn_popup, ELM_ACCESS_INFO, dgettext(PACKAGE, "IDS_ST_SK_OK"));
134         elm_object_part_content_set(popup, "button2", btn_popup);
135         evas_object_smart_callback_add(btn_popup, "clicked", voice_input_back_agree_cb, voicedata);
136         evas_object_data_set(btn_popup, "popup", popup);
137         evas_object_show(btn_popup);
138
139         std::string path_ic_right = path + "/images/tw_ic_popup_btn_check.png";
140         icon = elm_image_add(btn_popup);
141         elm_image_file_set(icon, path_ic_right.c_str(), NULL);
142         evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
143         elm_object_part_content_set(btn_popup, "elm.swallow.content", icon);
144         evas_object_show(icon);
145
146         evas_object_show(popup);
147
148         voicedata->mo->discard_popup_opened = EINA_TRUE;
149 }
150
151 MoreOption::MoreOption(Evas_Object *naviframe, void* voicedata)
152         : nf(naviframe)
153         , more_option_layout(NULL)
154         , item(NULL)
155         , option_opened(EINA_FALSE)
156         , voicedata(voicedata)
157         , discard_popup_opened(EINA_FALSE) {
158         /** todo. implement constructor */
159         voice_input_back_agree = false;
160 }
161
162 MoreOption::~MoreOption() {
163         /** todo. implement destructor */
164
165         if(more_option_layout)
166         {
167                 PRINTFUNC(DLOG_DEBUG, "del callbacks");
168                 evas_object_smart_callback_del(more_option_layout, "item,clicked", moreItemClicked);
169                 evas_object_smart_callback_del(more_option_layout, "item,selected", moreItemSelected);
170
171                 evas_object_smart_callback_del(more_option_layout, "more,option,opened", moreOptionOpened);
172                 evas_object_smart_callback_del(more_option_layout, "more,option,closed", moreOptionClosed);
173         }
174 }
175
176 void MoreOption::Create() {
177         try {
178                 AddLayout();
179                 AddMorePage();
180         }
181         catch(std::exception &e) {
182                 PRINTFUNC(DLOG_ERROR, "%s", e.what());
183                 assert(0);
184         }
185 }
186
187 void MoreOption::AddLayout() {
188         /** validation */
189         if(!nf)
190                 PRINTFUNC(DLOG_ERROR, "Invalid naviframe.");
191
192         /** add layout */
193         more_option_layout = eext_more_option_add(nf);
194
195         if(!more_option_layout){
196                 PRINTFUNC(DLOG_ERROR, "It's failed to create layout");
197                 return;
198         }
199
200         evas_object_smart_callback_add(more_option_layout, "more,option,opened", moreOptionOpened, this);
201         evas_object_smart_callback_add(more_option_layout, "more,option,closed", moreOptionClosed, this);
202
203         hideCue();
204
205         evas_object_show(more_option_layout);
206 }
207
208 void MoreOption::SetContentLayout(Evas_Object *content) {
209         /**
210          * Set content layout
211          *
212          */
213         elm_object_part_content_set(more_option_layout, "elm.swallow.content", content);
214
215         Elm_Object_Item *nit = NULL;
216         const char *item_style = NULL;
217         if (_WEARABLE)
218                 item_style = "empty";
219         nit = elm_naviframe_item_push(nf, NULL, NULL, NULL, more_option_layout, item_style);
220         elm_naviframe_item_title_enabled_set(nit, EINA_FALSE, EINA_FALSE);
221
222         elm_naviframe_item_pop_cb_set(nit,
223                 [](void *data, Elm_Object_Item *it)->Eina_Bool
224                 {
225                         MoreOption *opt = (MoreOption *)data;
226                         VoiceData *vd = (VoiceData *) opt->voicedata;
227
228                         if(vd->disclaimer == 1){
229                                 PRINTFUNC(DLOG_ERROR, "pop to top"); //inb case of (selector view -> disclaimer view-> stt view)
230
231                                 if(opt->option_opened == EINA_FALSE){
232                                         PRINTFUNC(DLOG_DEBUG, "pop_cb called in STT view\n");
233
234                                         if(vd->sttmanager){
235                                                 if (vd->sttmanager->GetCurrent() == STT_STATE_CREATED ||
236                                                                    vd->sttmanager->GetCurrent() == STT_STATE_READY) {
237                                                         PRINTFUNC(DLOG_DEBUG, "STT_STATE_CREATED || STT_STATE_READY\n");
238
239                                                 } else if (vd->sttmanager->GetCurrent() == STT_STATE_RECORDING || vd->sttmanager->GetCurrent() == STT_STATE_PROCESSING) {
240                                                         PRINTFUNC(DLOG_DEBUG, "STT_STATE_RECORDING or STT_STATE_PROCESSING\n");
241                                                         try{
242                                                                 vd->sttmanager->Cancel();
243                                                         }catch(is::stt::SttException &e){
244                                                                 PRINTFUNC(DLOG_ERROR, "reason : %s", e.what());
245                                                         }
246                                                 }
247                                         }
248                                 }
249
250                                 if (voice_input_back_agree == false && !is_textblock_empty(vd)){
251                                         show_discard_popup(vd);
252                                         return EINA_FALSE;
253                                 }
254
255                                 elm_naviframe_item_pop_to(elm_naviframe_bottom_item_get(vd->naviframe));
256                                 vd->disclaimer  = 0;
257
258                                 powerUnlock();
259                                 _back_to_genlist_for_selector();
260
261                                 destroy_voice();
262
263                                 return EINA_TRUE;
264                         }
265
266                         if (opt->option_opened == EINA_FALSE){
267                                 PRINTFUNC(DLOG_DEBUG, "pop_cb called in STT view\n");
268
269                                 if (vd->sttmanager){
270                                         if (vd->sttmanager->GetCurrent() == STT_STATE_CREATED ||
271                                                            vd->sttmanager->GetCurrent() == STT_STATE_READY) {
272                                                 PRINTFUNC(DLOG_DEBUG, "STT_STATE_CREATED || STT_STATE_READY\n");
273
274                                         } else if (vd->sttmanager->GetCurrent() == STT_STATE_RECORDING || vd->sttmanager->GetCurrent() == STT_STATE_PROCESSING) {
275                                                 PRINTFUNC(DLOG_DEBUG, "STT_STATE_RECORDING or STT_STATE_PROCESSING\n");
276                                                 try{
277                                                         vd->sttmanager->Cancel();
278                                                 }catch(is::stt::SttException &e){
279                                                         PRINTFUNC(DLOG_ERROR, "reason : %s", e.what());
280                                                 }
281                                         }
282                                 }
283
284                                 if (voice_input_back_agree == false && !is_textblock_empty(vd)){
285                                         show_discard_popup(vd);
286                                         return EINA_FALSE;
287                                 }
288
289                                 _back_to_genlist_for_selector();
290                                 destroy_voice();
291                                 return EINA_TRUE;
292                         }
293                         return EINA_FALSE;
294                 }, this);
295 }
296
297 void MoreOption::Update()
298 {
299         char lang[6] = {0, };
300         strncpy(lang, ((VoiceData *)voicedata)->kbd_lang , 5);
301
302         const char* display_lang = get_lang_label(lang);
303         eext_more_option_item_part_text_set(item, "selector,sub_text", display_lang);
304
305         showCue();
306 }
307
308 Evas_Object* MoreOption::AddLanguageIcon(Evas_Object *parent) {
309         Evas_Object *icon = elm_image_add(parent);
310         if (!icon) {
311                 PRINTFUNC(DLOG_ERROR, "It's failed to add image.");
312         }
313
314         string res_path = get_resource_path();
315         if (_WEARABLE)
316                 res_path = res_path + "wearable/";
317         else if (_TV)
318                 res_path = res_path + "tv/";
319         else
320                 res_path = res_path + "mobile/";
321
322         std::string image_path = res_path + "images/prompt_ic_languages.png";
323
324         elm_image_file_set(icon, image_path.c_str(), NULL);
325         evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
326         evas_object_size_hint_align_set(icon, EVAS_HINT_FILL, EVAS_HINT_FILL);
327         evas_object_show(icon);
328
329         return icon;
330 }
331
332 void MoreOption::AddMorePage() {
333         Evas_Object *img;
334
335         item  = eext_more_option_item_append(more_option_layout);
336
337         /* Slider content */
338         eext_more_option_item_part_text_set(item, "selector,main_text", _("WDS_IME_HEADER_INPUT_LANGUAGES_ABB"));
339
340         img = AddLanguageIcon(more_option_layout);
341
342         eext_more_option_item_part_content_set(item, "item,icon", img);
343
344         evas_object_smart_callback_add(more_option_layout, "item,clicked", moreItemClicked, NULL);
345         evas_object_smart_callback_add(more_option_layout, "item,selected", moreItemSelected , NULL);
346 }
347
348 void MoreOption::moreOptionOpened(void *data, Evas_Object * obj, void *event_info)
349 {
350         PRINTFUNC(DLOG_DEBUG, "more option is opened!!! \n");
351
352         if(!data) return;
353
354         /**
355         * if more option is completed, stt have to be stopped.
356         *
357         */
358         MoreOption *opt = (MoreOption *)data;
359         VoiceData *vd = (VoiceData *) opt->voicedata;
360
361         if(vd && vd->setup_timer){
362                 ecore_timer_del(vd->setup_timer);
363                 vd->setup_timer = NULL;
364         }
365
366         try {
367                 if (vd && vd->sttmanager && (vd->sttmanager->GetCurrent() == STT_STATE_RECORDING ||
368                         vd->sttmanager->GetCurrent() == STT_STATE_PROCESSING)) {
369                         vd->sttmanager->Cancel();
370                 }
371         }
372         catch(is::stt::SttException &e) {
373                 PRINTFUNC(DLOG_ERROR, "%s", e.what());
374         }
375
376         // Clear guide text
377         if(vd && vd->layout_main){
378                 elm_object_signal_emit((Evas_Object *)vd->layout_main, "idle,state,text,hidden", "elm");
379         }
380
381         opt->option_opened = EINA_TRUE;
382 }
383
384 void MoreOption::moreOptionClosed(void *data, Evas_Object * obj, void *event_info)
385 {
386         PRINTFUNC(DLOG_DEBUG, "more option is closed!!! \n");
387
388         if (!data) return;
389
390         MoreOption *opt = (MoreOption *)data;
391         VoiceData *vd = (VoiceData *) opt->voicedata;
392
393         if (opt->option_opened == EINA_TRUE && is_textblock_empty(vd)) {
394                 restart_listening(2.0);
395         }
396
397         if (vd)
398                 activate_circle_scroller_for_stt_textbox(vd, EINA_TRUE);
399
400         opt->option_opened = EINA_FALSE;
401 }
402
403 void MoreOption::moreItemClicked(void *data, Evas_Object * obj, void *event_info)
404 {
405         PRINTFUNC(DLOG_DEBUG, "item,clicked");
406         if(g_setting_window == NULL)
407                 create_setting_window(obj);
408 }
409
410 void MoreOption::moreItemSelected(void *data, Evas_Object * obj, void *event_info)
411 {
412         PRINTFUNC(DLOG_DEBUG, "item,selected");
413         if(!obj) return;
414
415         Eext_Object_Item *selected_item = (Eext_Object_Item *)event_info;
416
417         //for custom accessibility
418         if (elm_config_access_get())
419         {
420                 Evas_Object *panel = elm_object_part_content_get(obj, "elm.swallow.right");
421                 if (!panel) return;
422
423                 Evas_Object *rotary_selector = elm_object_content_get(panel);
424                 if (!rotary_selector) return;
425
426                 Evas_Object *content = (Evas_Object *)edje_object_part_object_get(elm_layout_edje_get(rotary_selector), "content");
427                 if (!content) return;
428
429                 Evas_Object *content_access = elm_access_object_get(content);
430                 if (!content_access) return;
431
432                 if (eext_more_option_item_part_text_get(selected_item, "selector,main_text"))
433                 {
434                         std::string text;
435                         text = text + std::string(gettext("WDS_IME_HEADER_INPUT_LANGUAGES_ABB")) + " ";
436
437                         if(eext_more_option_item_part_text_get(selected_item, "selector,sub_text"))
438                                 text = text + std::string(eext_more_option_item_part_text_get(selected_item, "selector,sub_text"));
439
440                         elm_access_info_set(content_access, ELM_ACCESS_INFO, text.c_str());
441                 }
442         }
443 }
444
445 void MoreOption::hideCue()
446 {
447         Evas_Object *panel_right = NULL;
448         if (!more_option_layout) {
449                 PRINTFUNC(DLOG_ERROR, "more_option_layout == NULL");
450                 return;
451         }
452
453         panel_right = elm_object_part_content_get(more_option_layout, "elm.swallow.right");
454         if (!panel_right) {
455                 PRINTFUNC(DLOG_ERROR, "panel_right == NULL");
456                 return;
457         }
458
459         elm_object_signal_emit(panel_right, "cue,hide", "elm");
460 }
461
462 void MoreOption::showCue()
463 {
464         Evas_Object *panel_right = NULL;
465
466         if (!more_option_layout) {
467                 PRINTFUNC(DLOG_ERROR, "more_option_layout == NULL");
468                 return;
469         }
470
471         panel_right = elm_object_part_content_get(more_option_layout, "elm.swallow.right");
472         if (!panel_right) {
473                 PRINTFUNC(DLOG_ERROR, "panel_right == NULL");
474                 return;
475         }
476
477         elm_object_signal_emit(panel_right, "cue,show", "elm");
478 }
479