Exit app and sub-catalog on remote back key press
[profile/tv/apps/native/settings.git] / src / view_maincatalog.c
1 /*
2  * Copyright (c) 2014 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 <app.h>
18
19 #include <KeyDefine.h>
20
21 #include "dbg.h"
22 #include "def.h"
23 #include "stdbool.h"
24 #include "viewmgr.h"
25 #include "utils.h"
26 #include "view_maincatalog.h"
27 #include "data_wrapper.h"
28 #include "settings_provider.h"
29
30 #define DATA_ID "main_setting_data"
31 #define SUBITEM_DATA_ID "subitem_data_id"
32 #define SYSTEM_CLOCK_DATA "system_clock_data"
33 #define ICON_PART "iconpart"
34 #define PROGRESS_BAR_DATA "progressbar"
35
36 #define SETTING_ID "setting_id"
37 #define E_CREATE_ITEMS 0
38
39 #define MAX_PROGRESS_VALUE 100.0
40 #define MIN_PROGRESS_VALUE 0.0
41 #define ICON_BUTTON_NO_DISP_NAME "No Display Name"
42 #define CHANGE_PASSCODE_NAME "change-passcode"
43 #define PASSCODE_MASK "****"
44 #define DISABLED "disabled"
45 #define ENABLED "enabled"
46 #define SIG_CLICKED "clicked"
47
48 #define KEY_PASSCODE "settings/system/change_passcode"
49 #define ITEM_CHANNEL_LOCK_ID "channel-lock"
50
51 enum focused_state {
52         FOCUS_MAIN_ITEM = 1,
53         FOCUS_SUB_ITEM
54 };
55
56 struct _view_data {
57         Evas_Object *win;
58         Evas_Object *base;
59         Eina_Array *sub_item_btn;
60         Eina_Array *main_item_btn;
61         Eina_Array *main_icon_base;
62         Eina_Array *item_path;
63         Evas_Object *focused_sub_item_btn;
64         Evas_Object *focused_main_item_btn;
65         Evas_Object *subitem_box;
66         Evas_Object *mainitem_box;
67
68         int focus_status;
69         int main_item_count;
70         int sub_item_count;
71
72         struct setting_mgr *mgr;
73         struct settingview_data *main_setting_view;
74         struct settingview_data *subsetting_view;
75 };
76
77 /**
78 * This function will be invoked when focus moves from subitem to main item.
79 *
80 * @param[in]: data : the user data.
81 * @param[in]: btn : subitem which focus is on.
82 *
83 * @return: void.
84 */
85 static void _move_from_subitem_to_main_item(struct _view_data *data,
86                 Evas_Object *btn)
87 {
88         if (!data || !btn)
89                 return;
90
91         data->focus_status = FOCUS_MAIN_ITEM;
92         data->focused_sub_item_btn = btn;
93
94         elm_object_focus_set(data->focused_main_item_btn, EINA_TRUE);
95 }
96
97 /**
98 * Evas_Object_Event_Cb type callback for handling key press event.
99 *
100 * @param[in]: data : the user data.
101 * @param[in]: e : the evas canvas.
102 * @param[in]: obj : the corresponding object which the key press event occurred.
103 * @param[in]: ei : event info.
104 *
105 * @return: void.
106 */
107 static void _subitem_key_pressed_cb(void *data, Evas *e,
108                 Evas_Object *obj, void *ei)
109 {
110         Evas_Event_Key_Down *ev;
111         struct _view_data *priv;
112         Evas_Object *pb;
113         Evas_Object *next;
114
115         if (!data || !ei || !obj)
116                 return;
117
118         ev = ei;
119         if (!ev->keyname)
120                 return;
121
122         priv = data;
123
124         if (!strcmp(ev->keyname, KEY_LEFT)
125                         || !strcmp(ev->keyname, KEY_BACK)
126                         || !strcmp(ev->keyname, KEY_BACK_REMOTE)) {
127                 pb = evas_object_data_get(obj, PROGRESS_BAR_DATA);
128                 if (pb)
129                         elm_object_signal_emit(pb,
130                                         SIG_UNCTRL_PB_UNFOCUSED, SRC_PB_PROG);
131
132                 _move_from_subitem_to_main_item(priv, obj);
133         } else if (!strncmp(ev->keyname, KEY_DOWN, strlen(ev->keyname))) {
134                 pb = evas_object_data_get(obj, PROGRESS_BAR_DATA);
135                 if (pb)
136                         elm_object_signal_emit(pb,
137                                         SIG_UNCTRL_PB_UNFOCUSED, SRC_PB_PROG);
138
139                 next = elm_object_focus_next_object_get(obj,
140                                 ELM_FOCUS_DOWN);
141                 if (!next) {
142                         _ERR("focus next object get failed.");
143                         return;
144                 }
145
146                 pb = evas_object_data_get(next, PROGRESS_BAR_DATA);
147                 if (pb)
148                         elm_object_signal_emit(pb,
149                                         SIG_UNCTRL_PB_FOCUSED, SRC_PB_PROG);
150         } else if (!strncmp(ev->keyname, KEY_UP, strlen(ev->keyname))) {
151                 pb = evas_object_data_get(obj, PROGRESS_BAR_DATA);
152                 if (pb)
153                         elm_object_signal_emit(pb,
154                                         SIG_UNCTRL_PB_UNFOCUSED, SRC_PB_PROG);
155
156                 next = elm_object_focus_next_object_get(obj, ELM_FOCUS_UP);
157                 if (!next) {
158                         _ERR("focus next object get failed.");
159                         return;
160                 }
161
162                 pb = evas_object_data_get(next, PROGRESS_BAR_DATA);
163                 if (pb)
164                         elm_object_signal_emit(pb,
165                                         SIG_UNCTRL_PB_FOCUSED, SRC_PB_PROG);
166         } else if (!strncmp(ev->keyname, KEY_EXIT, strlen(ev->keyname))) {
167                 app_efl_exit();
168         }
169 }
170
171 /**
172 * Get geometry data of object such as width, height.
173 *
174 * @param[in]: obj : the object which you want to get geometry data from.
175 * @param[out]: param : the geometry data.
176 *
177 * @return: void.
178 */
179 static void _get_geometry_data(Evas_Object *obj,
180                 struct obj_geometry_data *param)
181 {
182         int x, y, w, h;
183
184         if (!param || !obj) {
185                 _ERR("Invalid argument");
186                 return;
187         }
188
189         x = y = w = h = 0;
190
191         evas_object_geometry_get(obj, &x, &y, &w, &h);
192
193         param->x = x;
194         param->y = y;
195         param->width = w;
196         param->height = h;
197 }
198
199 /**
200 * Entry of showing UI gadget views.
201 *
202 * param[in]: data : the user data.
203 * param[in]: item : item data.
204 * param[in]: obj : object whose next view is UI gadget.
205 *
206 * @return: 0 - success, -1 - fail.
207 */
208 static int _push_ug_view(struct _view_data *data,
209                 struct settingitem *item, Evas_Object *obj)
210 {
211         const char *id;
212         struct evas_obj_data param;
213         int r;
214
215         if (!data || !item || !obj) {
216                 _ERR("Invalid argument");
217                 return -1;
218         }
219
220         id = settingitem_get_id(item);
221         if (!id) {
222                 _ERR("Fail to get item id");
223                 return -1;
224         }
225
226         param.subitem_box = data->subitem_box;
227         param.display_name = settingitem_get_display_name(item);
228         param.cur_btn = obj;
229
230         r = settingmgr_view_push(data->mgr, id, (void *)&param);
231         if (r != 0) {
232                 _ERR("Fail to push view");
233                 return -1;
234         }
235
236         return 0;
237 }
238
239 /**
240 * Entry of showing sublist views.
241 *
242 * param[in]: data : the user data.
243 * param[in]: item : item data.
244 * param[in]: obj : object whose next view is sublist.
245 *
246 * @return: 0 - success, -1 - fail.
247 */
248 static int _push_sublist_view(struct _view_data *data,
249                 struct settingitem *item, Evas_Object *obj)
250 {
251         const char *id;
252         int r;
253         struct obj_geometry_data ogd;
254
255         if (!data || !item || !obj) {
256                 _ERR("Invalid argument");
257                 return -1;
258         }
259
260         id = settingitem_get_id(item);
261         if (!id) {
262                 _ERR("Fail to get item id");
263                 return -1;
264         }
265
266         _get_geometry_data(obj, &ogd);
267
268         r = settingmgr_view_push(data->mgr, id, (void *)&ogd);
269         if (r != 0) {
270                 _ERR("Fail to push view");
271                 return -1;
272         }
273
274         elm_object_signal_emit(obj, SUBITEMBTN_BUTTON_CLICKED,
275                         SUBITEMBTN_BUTTON_SOURCE);
276
277         return 0;
278 }
279
280 /**
281 * Entry of showing bottom sublist views.
282 *
283 * param[in]: data : the user data.
284 * param[in]: item : item data.
285 *
286 * @return: 0 - success, -1 - fail.
287 */
288 static int _push_bottom_sublist_view(struct _view_data *data,
289                 struct settingitem *item)
290 {
291         const char *id;
292         int r;
293
294         if (!data || !item) {
295                 _ERR("Invalid argument");
296                 return -1;
297         }
298
299         id = settingitem_get_id(item);
300         if (!id) {
301                 _ERR("Fail to get item id");
302                 return -1;
303         }
304
305         r = settingmgr_view_push(data->mgr, id, NULL);
306         if (r != 0) {
307                 _ERR("Fail to push view");
308                 return -1;
309         }
310
311         return 0;
312 }
313
314 /**
315 * Entry of showing bottom slider views.
316 *
317 * param[in]: data : the user data.
318 * param[in]: item : item data.
319 * param[in]: obj : object whose next view bottom slider.
320 *
321 * @return: 0 - success, -1 - fail.
322 */
323 static int _push_bottom_slider_view(struct _view_data *data,
324                 struct settingitem *item, Evas_Object *obj)
325 {
326         const char *id;
327         int r;
328         Eina_List *list;
329         Evas_Object *pb;
330
331         if (!data || !item || !obj) {
332                 _ERR("Invalid argument");
333                 return -1;
334         }
335
336         id = settingitem_get_id(item);
337         if (!id) {
338                 _ERR("Fail to get item id");
339                 return -1;
340         }
341
342         pb = evas_object_data_get(obj, PROGRESS_BAR_DATA);
343         if (pb)
344                 elm_object_signal_emit(pb,
345                                 SIG_UNCTRL_PB_UNFOCUSED, SRC_PB_PROG);
346
347         list = settingitem_get_slider_group_list(
348                         viewdata_get_parentitem(data->subsetting_view),
349                         settingmgr_get_data(data->mgr), id);
350
351         r = settingmgr_view_push(data->mgr, id, list);
352         if (r != 0) {
353                 _ERR("Fail to push view");
354                 return -1;
355         }
356
357         return 0;
358 }
359
360 /**
361 * Entry of showing passcode popup views.
362 *
363 * param[in]: data : the user data.
364 * param[in]: item : item data.
365 *
366 * @return: 0 - success, -1 - fail.
367 */
368 static int _push_passcode_popup_view(struct _view_data *data,
369                 struct settingitem *item)
370 {
371         const char *id;
372         int r;
373
374         if (!data || !item) {
375                 _ERR("Invalid argument");
376                 return -1;
377         }
378
379         id = settingitem_get_id(item);
380         if (!id) {
381                 _ERR("Fail to get item id");
382                 return -1;
383         }
384
385         r = settingmgr_view_push(data->mgr, id, NULL);
386         if (r != 0) {
387                 _ERR("Fail to push view");
388                 return -1;
389         }
390
391         return 0;
392 }
393
394 /**
395 * Entry of showing device manager view.
396 *
397 * param[in]: data : the user data.
398 * param[in]: item : item data read from json file.
399 *
400 * @return: 0 - success, -1 - fail.
401 */
402 static int _push_device_manager_view(struct _view_data *data,
403                 struct settingitem *item)
404 {
405         const char *id;
406         struct evas_obj_data param;
407         int r;
408
409         if (!data || !item) {
410                 _ERR("Invalid argument");
411                 return -1;
412         }
413
414         id = settingitem_get_id(item);
415         if (!id) {
416                 _ERR("Fail to get item id");
417                 return -1;
418         }
419
420         param.display_name = settingitem_get_display_name(item);
421         param.subitem_box = data->subitem_box;
422
423         r = settingmgr_view_push(data->mgr, id, &param);
424         if (r != 0) {
425                 _ERR("Fail to push view");
426                 return -1;
427         }
428
429         return 0;
430 }
431
432 /**
433 * Entry of showing reset popup view.
434 *
435 * param[in]: data : the user data.
436 * param[in]: item : item data read from json file.
437 *
438 * @return: 0 - success, -1 - fail.
439 */
440 static int _push_reset_popup_view(struct _view_data *data,
441                 struct settingitem *item)
442 {
443         const char *id;
444         int r;
445
446         if (!data || !item) {
447                 _ERR("Invalid argument");
448                 return -1;
449         }
450
451         id = settingitem_get_id(item);
452         if (!id) {
453                 _ERR("Fail to get item id");
454                 return -1;
455         }
456
457         r = settingmgr_view_push(data->mgr, id, NULL);
458         if (r != 0) {
459                 _ERR("Fail to push view");
460                 return -1;
461         }
462
463         return 0;
464 }
465
466 /**
467 * Entry of showing software upgrade popup view.
468 *
469 * param[in]: data : the user data.
470 * param[in]: item : item data read from json file.
471 *
472 * @return: 0 - success, -1 - fail.
473 */
474 static int _push_upgrade_popup_view(struct _view_data *data,
475                 struct settingitem *item)
476 {
477         const char *id;
478         int r;
479
480         if (!data || !item) {
481                 _ERR("Invalid argument");
482                 return -1;
483         }
484
485         id = settingitem_get_id(item);
486         if (!id) {
487                 _ERR("Fail to get item id");
488                 return -1;
489         }
490
491         r = settingmgr_view_push(data->mgr, id, NULL);
492         if (r != 0) {
493                 _ERR("Fail to push view");
494                 return -1;
495         }
496
497         return 0;
498 }
499
500 /**
501 * Entry of showing clock sublist view.
502 *
503 * param[in]: data : the user data.
504 * param[in]: item : item data read from json file.
505 * param[in]: obj : object whose next view is clock sublist view.
506 *
507 * @return: 0 - success, -1 - fail.
508 */
509 static int _push_clock_sublist_view(struct _view_data *data,
510                 struct settingitem *item, Evas_Object *obj)
511 {
512         const char *id;
513         struct evas_obj_data param;
514         struct obj_geometry_data ogd;
515         int r;
516
517         if (!data || !item || !obj) {
518                 _ERR("Invalid argument");
519                 return -1;
520         }
521
522         id = settingitem_get_id(item);
523         if (!id) {
524                 _ERR("Fail to get item id");
525                 return -1;
526         }
527
528         _get_geometry_data(obj, &ogd);
529
530         param.display_name = settingitem_get_display_name(item);
531         param.subitem_box = data->subitem_box;
532         param.cur_btn = obj;
533
534         evas_object_data_set(obj, SYSTEM_CLOCK_DATA, (void *)&ogd);
535
536         r = settingmgr_view_push(data->mgr, id, &param);
537         if (r != 0) {
538                 _ERR("Fail to push view");
539                 return -1;
540         }
541
542         elm_object_signal_emit(obj,
543                         SUBITEMBTN_BUTTON_CLICKED, SUBITEMBTN_BUTTON_SOURCE);
544
545         return 0;
546 }
547 /**
548 * Entry of showing channel lock view.
549 *
550 * param[in]: data : the user data.
551 * param[in]: item : item data read from json file.
552 * param[in]: obj : the channel lock object.
553 *
554 * @return: 0 - success, -1 - fail.
555 */
556 static int _push_need_passcode_view(struct _view_data *data,
557                 struct settingitem *item, Evas_Object *obj)
558 {
559         const char *id;
560         int r;
561         struct obj_geometry_data ogd;
562
563         if (!data || !item || !obj) {
564                 _ERR("Invalid argument");
565                 return -1;
566         }
567
568         id = settingitem_get_id(item);
569         if (!id) {
570                 _ERR("Fail to get item id");
571                 return -1;
572         }
573
574         _get_geometry_data(obj, &ogd);
575
576         r = settingmgr_view_push(data->mgr, id, &ogd);
577         if (r != 0) {
578                 _ERR("Fail to push view");
579                 return -1;
580         }
581
582         elm_object_signal_emit(obj, SUBITEMBTN_BUTTON_CLICKED,
583                         SUBITEMBTN_BUTTON_SOURCE);
584
585         return 0;
586 }
587
588 /**
589 * This function will be invoked when subitem is clicked.
590 *
591 * @param[in]: data : the user data.
592 * @param[in]: obj : the subitem object.
593 *
594 * @return: void.
595 */
596 static void _submenu_item_clicked(void *data, Evas_Object *obj)
597 {
598         struct _view_data *priv;
599         const char *style;
600         struct settingitem *item;
601
602         if (!data || !obj) {
603                 _ERR("Invalid argument");
604                 return;
605         }
606
607         priv = data;
608
609         if (priv->focus_status != FOCUS_SUB_ITEM)
610                 return;
611
612         item = evas_object_data_get(obj, SUBITEM_DATA_ID);
613         if (!item) {
614                 _ERR("Get sub item failed");
615                 return;
616         }
617
618         style = settingitem_get_settingui_style(item);
619         if (!style) {
620                 _ERR("setting-ui style is null.");
621                 return;
622         }
623
624         if (!strncmp(style, STYLE_UIGADGET, strlen(style))) {
625                 if (_push_ug_view(priv, item, obj) != 0)
626                         _ERR("Fail to push ug");
627         } else if (!strncmp(style, STYLE_CTXPOPUP,
628                         strlen(style))) {
629                 if (_push_sublist_view(priv, item, obj) != 0)
630                         _ERR("Fail to push sublist");
631         } else if (!strncmp(style, STYLE_BOTTOM_CTXPOPUP,
632                         strlen(style))) {
633                 if (_push_bottom_sublist_view(priv, item) != 0)
634                         _ERR("Fail to push bottom sublist");
635         } else if (!strncmp(style, STYLE_BOTTOMSLIDER,
636                         strlen(style)) || !strncmp(style,
637                         STYLE_BOTTOM2WAYSLIDER,
638                         strlen(style))) {
639                 if (_push_bottom_slider_view(priv,
640                                 item, obj) != 0)
641                         _ERR("Fail to push bottom slider");
642         } else if (!strncmp(style, STYLE_PASSCODE_POPUP,
643                         strlen(style))) {
644                 if (_push_passcode_popup_view(priv, item) != 0)
645                         _ERR("Fail to push passcode popup");
646         } else if (!strncmp(style, STYLE_DEVICE_MANAGER,
647                         strlen(style))) {
648                 if (_push_device_manager_view(priv, item) != 0)
649                         _ERR("Fail to push device mgr view");
650         } else if (!strncmp(style, STYLE_RESET_POPUP,
651                         strlen(style))) {
652                 if (_push_reset_popup_view(priv, item) != 0)
653                         _ERR("Fail to push reset popup");
654         } else if (!strncmp(style, STYLE_UPGRADE_POPUP,
655                         strlen(style))) {
656                 if (_push_upgrade_popup_view(priv, item) != 0)
657                         _ERR("Fail to push upgrade popup");
658         } else if (!strncmp(style, STYLE_CLOCK_CTXPOPUP,
659                         strlen(style))) {
660                 if (_push_clock_sublist_view(
661                                 priv, item, obj) != 0)
662                         _ERR("Fail to push clock sublist");
663         } else if (!strncmp(style, STYLE_NEED_PASSCODE,
664                         strlen(style))) {
665                 if (_push_need_passcode_view(
666                                 priv, item, obj) != 0)
667                         _ERR("Fail to push need passcode view");
668         }
669
670         priv->focused_sub_item_btn = obj;
671 }
672
673 /**
674 * Evas_Smart_Cb type callback for handling click event.
675 *
676 * @param[in]: data : the user data.
677 * @param[in]: obj : the corresponding object which the click event occurred.
678 * @param[in]: ev : event info.
679 *
680 * @return: void.
681 */
682 static void _subitem_btn_clicked_cb(void *data,
683                 Evas_Object *obj, void *ev)
684 {
685         struct _view_data *priv;
686         Evas_Object *icon;
687
688         if (!data || !obj) {
689                 _ERR("Invalid argument");
690                 return;
691         }
692
693         priv = data;
694
695         _submenu_item_clicked(priv, obj);
696
697         elm_object_signal_emit(priv->focused_main_item_btn,
698                         MAINICONBTN_FOCUSED_ON_SUBITEM,
699                         MAINICONBTN_MAIN_ITEM_SOURCE);
700
701         icon = elm_object_part_content_get(priv->focused_main_item_btn,
702                         MAINICONBTN_ICON_SWALLOW);
703         if (icon)
704                 elm_object_signal_emit(icon, MAIN_BTN_HIGHLIGHT, MAIN_BTN);
705 }
706
707 /**
708 * Get item value from item.
709 *
710 * @param[in]: item : the item data read from json file.
711 *
712 * @return: the value of item or null if error occurred.
713 */
714 static char *_settingitems_get_value(struct settingitem *item)
715 {
716         char *result;
717         const char *name, *style;
718
719         if (!item) {
720                 _ERR("Invalid argument");
721                 return NULL;
722         }
723
724         result = NULL;
725
726         name = settingitem_get_id(item);
727         if (name && !strncmp(name, CHANGE_PASSCODE_NAME, strlen(name))) {
728                 result = strdup(PASSCODE_MASK);
729                 return result;
730         }
731
732         style = settingitem_get_settingui_style(item);
733         if (!style) {
734                 _ERR("Fail to get setting ui style");
735                 return NULL;
736         }
737
738         if (!strncmp(style, STYLE_UIGADGET, strlen(style)))
739                 return provider_get_list_value(item);
740         else
741                 return provider_get_selected_display_name(item);
742 }
743
744 /**
745 * Get percentage value of progress from item data.
746 *
747 * @param[in]: item : item data read from json file.
748 *
749 * @return: the percentage value or -1.0 if error occurred.
750 */
751 static double _get_progress_percentage(struct settingitem *item)
752 {
753         struct slideritem *sitem;
754         double val, persent;
755
756         if (!item) {
757                 _ERR("Invalid argument");
758                 return -1.0;
759         }
760
761         sitem = settingitem_get_data_slideritem(item);
762         if (!sitem) {
763                 _ERR("Get slider item failed");
764                 return -1.0;
765         }
766
767         val = provider_get_slider_value(item);
768         persent = slideritem_find_slider_value(val, sitem);
769
770         return persent;
771 }
772
773 /**
774 * Get displaying value of item.
775 *
776 * @param[in]: item : item data read from json file.
777 * @param[in]: value : the percentage value.
778 *
779 * @return: the display value.
780 */
781 static double _get_display_value(struct settingitem *item, double value)
782 {
783         struct slideritem *sitem;
784         double disp;
785
786         if (!item) {
787                 _ERR("Invalid argument");
788                 return -1.0;
789         }
790
791         sitem = settingitem_get_data_slideritem(item);
792         if (!sitem) {
793                 _ERR("Get slider item failed");
794                 return -1.0;
795         }
796
797         disp = slideritem_find_slider_display_value(value, sitem);
798
799         return disp;
800 }
801
802 /**
803 * Create slider of subitem.
804 *
805 * @param[in]: item : the item data read from json file.
806 * @param[in]: base : the base layout of subitems.
807 * @param[in]: btn : the subitem the slider will be created on.
808 *
809 * @return: void.
810 */
811 static void _set_subitem_btn_slider(struct settingitem *item,
812                 Evas_Object *base, Evas_Object *btn)
813 {
814         Evas_Object *pb;
815         double val, percent;
816         char buf[BUF_SIZE];
817
818         if (!item || !base || !btn) {
819                 _ERR("Invalid argument");
820                 return;
821         }
822
823         elm_object_style_set(btn, SUBITEMBTN_TITLE_SLIDER_VALUE);
824
825         pb = elm_progressbar_add(base);
826         if (!pb) {
827                 _ERR("Add progress bar failed.");
828                 return;
829         }
830
831         elm_object_style_set(pb, SUBITEMBTN_TITILE_SLIDER);
832
833         percent = _get_progress_percentage(item);
834         val = _get_display_value(item, percent);
835         elm_progressbar_value_set(pb, percent);
836
837         snprintf(buf, sizeof(buf), "%d", (int)val);
838         elm_object_part_text_set(btn, SUBITEMBTN_VALUE, buf);
839         elm_object_part_content_set(btn, SUBITEMBTN_SLIDER_SWALLOW, pb);
840
841         evas_object_data_set(btn, PROGRESS_BAR_DATA, pb);
842 }
843
844 /**
845 * Get tint g-value.
846 *
847 * @param[in]: item : the item data read from json file.
848 * @param[in]: tint_r : the tint r-value.
849 *
850 * @return: the tint g-value.
851 */
852 static double _get_disp_tint_g_val(struct settingitem *item, double tint_r)
853 {
854         const char *strval;
855         struct slideritem *sitem;
856         double val;
857
858         if (!item) {
859                 _ERR("Invalid argument");
860                 return -1.0;
861         }
862
863         sitem = settingitem_get_data_slideritem(item);
864         if (!sitem) {
865                 _ERR("Get slider item failed");
866                 return -1.0;
867         }
868
869         strval = slideritem_get_max_display_value(sitem);
870         if (strval)
871                 val = atof(strval);
872         else
873                 val = 100;
874
875         return val - tint_r;
876 }
877
878 /**
879 * Create two way slider.
880 *
881 * @param[in]: item : the item data read from json file.
882 * @param[in]: base : the base layout of subitems.
883 * @param[in]: btn : the subitem which the two way slider will be created on.
884 *
885 * @return: void.
886 */
887 static void _set_subitem_btn_value_slider(struct settingitem *item,
888                 Evas_Object *base, Evas_Object *btn)
889 {
890         Evas_Object *pb;
891         double tint_r, tint_g, percent;
892         char buf[BUF_SIZE];
893
894         if (!item || !base || !btn) {
895                 _ERR("Invalid argument");
896                 return;
897         }
898
899         elm_object_style_set(btn, SUBITEMBTN_TITLE_SLIDER_VALUE);
900
901         pb = elm_progressbar_add(base);
902         if (!pb) {
903                 _ERR("Add progress bar failed.");
904                 return;
905         }
906
907         elm_object_style_set(pb, SUBITEMBTN_TITILE_SLIDER);
908         percent = _get_progress_percentage(item);
909         elm_progressbar_value_set(pb, percent);
910
911         tint_r = _get_display_value(item, percent);
912         tint_g = _get_disp_tint_g_val(item, tint_r);
913
914         snprintf(buf, sizeof(buf), "R%d", (int)tint_r);
915         elm_object_part_text_set(btn, SUBITEMBTN_VALUE,
916                         utils_get_translation_str(buf));
917         snprintf(buf, sizeof(buf), "G%d", (int)tint_g);
918         elm_object_part_text_set(btn, SUBITEMBTN_G_VALUE,
919                         utils_get_translation_str(buf));
920
921         elm_object_part_content_set(btn, SUBITEMBTN_SLIDER_SWALLOW, pb);
922
923         evas_object_data_set(btn, PROGRESS_BAR_DATA, pb);
924 }
925
926 /**
927 * Create style for subitem.
928 *
929 * @param[in]: base : the base layout of subitems.
930 * @param[in]: obj : the subitem which the style will be created on.
931 * @param[in]: style : the style read from json file.
932 * @param[in]: item : the item data read from json file.
933 *
934 * @return: void.
935 */
936 static void _draw_subitem_with_style(Evas_Object *base, Evas_Object *obj,
937                 const char *style, struct settingitem *item)
938 {
939         char *val;
940
941         if (!style || !base || !obj || !item)
942                 return;
943
944         if (!strncmp(style, STYLE_SUBBUTTON_TITLE_VALUE, strlen(style))) {
945                 val = _settingitems_get_value(item);
946                 elm_object_part_text_set(obj, SUBITEMBTN_VALUE,
947                                 utils_get_translation_str(val));
948                 free(val);
949         } else if (!strncmp(style, STYLE_SUBBUTTON_TITLE_ICON, strlen(style))) {
950                 elm_object_style_set(obj, SUBITEMBTN_TITLE_ICON);
951         } else if (!strncmp(style, STYLE_SUBBUTTON_TITLE_SLIDER_VALUE,
952                         strlen(style))) {
953                 _set_subitem_btn_slider(item, base, obj);
954         } else if (!strncmp(style, STYLE_SUBBUTTON_TITLE_2WAYSLIDER_VALUE,
955                         strlen(style))) {
956                 _set_subitem_btn_value_slider(item, base, obj);
957         }
958 }
959
960 /**
961 * Release resources of subitems.
962 *
963 * @param[in]: data : the user data.
964 *
965 * @return: void.
966 */
967 static void _release_subitems(struct _view_data *data)
968 {
969         Evas_Object *btn;
970         Eina_Array_Iterator a;
971         unsigned int i;
972
973         if (!data) {
974                 _ERR("Invalid argument");
975                 return;
976         }
977
978         if (data->sub_item_btn) {
979                 EINA_ARRAY_ITER_NEXT(data->sub_item_btn, i, btn, a)
980                         evas_object_del(btn);
981                 eina_array_free(data->sub_item_btn);
982         }
983
984         if (data->subsetting_view)
985                 viewdata_release(data->subsetting_view);
986
987         if (data->subitem_box)
988                 evas_object_del(data->subitem_box);
989 }
990
991 /**
992 * Refresh subitems when subitems are changed.
993 *
994 * @param[in]: data : the user data.
995 *
996 * @return: 0 - success, -1 - fail.
997 */
998 static int _refresh_subitems(struct _view_data *data)
999 {
1000         Evas_Object *btn;
1001         Eina_Array_Iterator a;
1002         unsigned int i;
1003         struct settingitem *item;
1004         const char *style;
1005
1006         if (!data) {
1007                 _ERR("Invalid argument");
1008                 return -1;
1009         }
1010
1011         EINA_ARRAY_ITER_NEXT(data->sub_item_btn, i, btn, a) {
1012                 item = evas_object_data_get(btn, SUBITEM_DATA_ID);
1013                 style = settingitem_get_style(item);
1014                 if (style)
1015                         _draw_subitem_with_style(data->base, btn, style, item);
1016         }
1017
1018         return 0;
1019 }
1020
1021 /**
1022 * Evas_Object_Event_Cb type callback for handling mouse out event.
1023 *
1024 * @param[in]: data : the user data.
1025 * @param[in]: e : the evas.
1026 * @param[in]: obj : the corresponding object which the mouse out event occurred.
1027 * @param[in]: ei : event info.
1028 *
1029 * @return: void.
1030 */
1031 static void _subitem_btn_mouse_out_cb(void *data, Evas *e,
1032                 Evas_Object *obj, void *ei)
1033 {
1034         /* TODO: Add necessary operations if needed. */
1035 }
1036
1037 /**
1038 * Evas_Object_Event_Cb type callback for handling mouse in event.
1039 *
1040 * @param[in]: data : the user data.
1041 * @param[in]: e : the evas.
1042 * @param[in]: obj : the corresponding object which the mouse in event occurred.
1043 * @param[in]: ei : event info.
1044 *
1045 * @return: void.
1046 */
1047 static void _subitem_btn_mouse_in_cb(void *data, Evas *e,
1048                 Evas_Object *obj, void *ei)
1049 {
1050         struct _view_data *priv;
1051         Evas_Object *icon, *pb;
1052
1053         if (!obj || !data)
1054                 return;
1055
1056         priv = data;
1057
1058         elm_object_focus_set(obj, EINA_TRUE);
1059
1060         if (priv->focus_status == FOCUS_MAIN_ITEM) {
1061                 priv->focus_status = FOCUS_SUB_ITEM;
1062                 elm_object_signal_emit(priv->focused_main_item_btn,
1063                                 MAINICONBTN_FOCUSED_ON_SUBITEM,
1064                                 MAINICONBTN_MAIN_ITEM_SOURCE);
1065
1066                 icon = elm_object_part_content_get(priv->focused_main_item_btn,
1067                                 MAINICONBTN_ICON_SWALLOW);
1068                 if (icon)
1069                         elm_object_signal_emit(icon,
1070                                         MAIN_BTN_HIGHLIGHT, MAIN_BTN);
1071         }
1072
1073         pb = evas_object_data_get(priv->focused_sub_item_btn,
1074                         PROGRESS_BAR_DATA);
1075         if (pb)
1076                 elm_object_signal_emit(pb, SIG_UNCTRL_PB_UNFOCUSED,
1077                                 SRC_PB_PROG);
1078
1079         pb = evas_object_data_get(obj, PROGRESS_BAR_DATA);
1080         if (pb)
1081                 elm_object_signal_emit(pb, SIG_UNCTRL_PB_FOCUSED, SRC_PB_PROG);
1082
1083         priv->focused_sub_item_btn = obj;
1084 }
1085
1086 /**
1087 * Create subitems of settings.
1088 *
1089 * @param[in]: data : the user data.
1090 * @param[in]: name : the name of subitem.
1091 *
1092 * @return: 0 - success, -1 - fail.
1093 */
1094 static int _draw_subitems(struct _view_data *data, const char *name)
1095 {
1096         Evas_Object *box, *btn, *tmp;
1097         struct settingview_data *view;
1098         struct settingitem *item;
1099         Eina_List *list, *l;
1100         int cnt;
1101         Eina_Array_Iterator a;
1102         unsigned int i;
1103         const char *id, *style, *status;
1104         char *passcode;
1105         Eina_Array *enabled;
1106
1107         if (!data || !name || !data->base) {
1108                 _ERR("Invalid argument");
1109                 return -1;
1110         }
1111
1112         view = settingmgr_get_view(data->mgr, name);
1113         if (!view) {
1114                 _ERR("get subview failed\n");
1115                 return -1;
1116         }
1117
1118         list = viewdata_get_childitems_list(view);
1119         if (!list) {
1120                 _ERR("childitem list is empty!");
1121                 if (view)
1122                         viewdata_release(view);
1123                 return -1;
1124         }
1125
1126         cnt = eina_list_count(list);
1127
1128         data->sub_item_btn = eina_array_new(1);
1129         enabled = eina_array_new(1);
1130         if (!data->sub_item_btn || !enabled) {
1131                 _ERR("Create Eina Array failed\n");
1132                 EINA_LIST_FREE(list, item);
1133                 if (view)
1134                         viewdata_release(view);
1135                 return -1;
1136         }
1137
1138         box = utils_add_box(data->base);
1139         if (!box) {
1140                 _ERR("Add box failed\n");
1141                 EINA_LIST_FREE(list, item);
1142                 eina_array_free(data->sub_item_btn);
1143                 if (view)
1144                         viewdata_release(view);
1145                 return -1;
1146         }
1147
1148         EINA_LIST_FOREACH(list, l, item) {
1149                 btn = utils_add_btn(data->base, SUBITEMBTN_STYLE,
1150                                 settingitem_get_display_name(item), EINA_FALSE);
1151                 if (!btn) {
1152                         _ERR("Add btn failed");
1153                         evas_object_del(box);
1154                         EINA_LIST_FREE(list, item);
1155                         EINA_ARRAY_ITER_NEXT(data->sub_item_btn, i, tmp, a)
1156                                 evas_object_del(tmp);
1157                         eina_array_free(data->sub_item_btn);
1158                         if (view)
1159                                 viewdata_release(view);
1160                         return -1;
1161                 }
1162
1163                 style = settingitem_get_style(item);
1164                 if (style)
1165                         _draw_subitem_with_style(data->base, btn, style, item);
1166
1167                 evas_object_smart_callback_add(btn, "clicked",
1168                                 _subitem_btn_clicked_cb, data);
1169                 evas_object_event_callback_add(btn, EVAS_CALLBACK_KEY_DOWN,
1170                                 _subitem_key_pressed_cb, data);
1171                 evas_object_event_callback_add(btn, EVAS_CALLBACK_MOUSE_IN,
1172                                 _subitem_btn_mouse_in_cb, data);
1173                 evas_object_event_callback_add(btn, EVAS_CALLBACK_MOUSE_OUT,
1174                                 _subitem_btn_mouse_out_cb, data);
1175
1176                 elm_box_pack_end(box, btn);
1177                 eina_array_push(data->sub_item_btn, btn);
1178
1179                 evas_object_data_set(btn, SUBITEM_DATA_ID, item);
1180
1181                 id = settingitem_get_id(item);
1182                 if (id && !strncmp(id, ITEM_CHANNEL_LOCK_ID, strlen(id))
1183                                 && (provider_get_passcode(KEY_PASSCODE, &passcode) == -1)) {
1184                         /*Disable channel lock menu if passcode has not been setup yet*/
1185                         status = DISABLED;
1186                 } else {
1187                         status = settingitem_get_status(item);
1188                 }
1189
1190                 if (status && !strncmp(status, DISABLED, strlen(status))) {
1191                         elm_object_disabled_set(btn, EINA_TRUE);
1192                         evas_object_freeze_events_set(btn, EINA_TRUE);
1193                 } else {
1194                         eina_array_push(enabled, btn);
1195                 }
1196         }
1197
1198         data->subsetting_view = view;
1199         data->sub_item_count = cnt;
1200         data->subitem_box = box;
1201
1202         elm_object_part_content_set(data->base, MAIN_VIEW_SUBITEM_SWALLOW, box);
1203
1204         utils_set_focus_directions(enabled, eina_array_count(enabled));
1205
1206         EINA_LIST_FREE(list, item);
1207         eina_array_free(enabled);
1208
1209         return 0;
1210 }
1211
1212 /**
1213 * This function will be invoked when the main item is clicked.
1214 *
1215 * @param[in]: data : the user data.
1216 * @param[in]: mainbtn : the main item which the clicked event is occurred.
1217 *
1218 * @return: void.
1219 */
1220 static void _move_from_main_item_to_subitem(struct _view_data *data,
1221                 Evas_Object *mainbtn)
1222 {
1223         Evas_Object *btn, *pb, *icon;
1224         int i;
1225
1226         if (!data || !mainbtn)
1227                 return;
1228
1229         data->focus_status = FOCUS_SUB_ITEM;
1230
1231         for (i = 0; i < data->sub_item_count; i++) {
1232                 btn = eina_array_data_get(data->sub_item_btn, i);
1233                 if (!btn) {
1234                         _ERR("Get subitem btn failed\n");
1235                         data->focus_status = FOCUS_MAIN_ITEM;
1236                         return;
1237                 }
1238
1239                 if (elm_object_disabled_get(btn) != EINA_TRUE)
1240                         break;
1241         }
1242
1243         if (i >= data->sub_item_count) {
1244                 data->focus_status = FOCUS_MAIN_ITEM;
1245                 return;
1246         }
1247
1248         pb = evas_object_data_get(btn, PROGRESS_BAR_DATA);
1249         if (pb)
1250                 elm_object_signal_emit(pb, SIG_UNCTRL_PB_FOCUSED, SRC_PB_PROG);
1251
1252         elm_object_focus_set(btn, EINA_TRUE);
1253
1254         data->focused_main_item_btn = mainbtn;
1255         elm_object_signal_emit(mainbtn, MAINICONBTN_FOCUSED_ON_SUBITEM,
1256                         MAINICONBTN_MAIN_ITEM_SOURCE);
1257
1258         icon = elm_object_part_content_get(mainbtn, MAINICONBTN_ICON_SWALLOW);
1259         if (icon)
1260                 elm_object_signal_emit(icon, MAIN_BTN_HIGHLIGHT, MAIN_BTN);
1261 }
1262
1263 /**
1264 * Evas_Object_Event_Cb type callback for handling key press event.
1265 *
1266 * @param[in]: data : the user data.
1267 * @param[in]: e : the evas.
1268 * @param[in]: obj : the corresponding object which the key press event occurred.
1269 * @param[in]: ei : event info.
1270 *
1271 * @return: void.
1272 */
1273 static void _main_setting_key_pressed_cb(void *data, Evas *e,
1274                 Evas_Object *obj, void *ei)
1275 {
1276         Evas_Event_Key_Down *ev;
1277         struct _view_data *priv;
1278         Evas_Object *next, *icon;
1279         const char *name;
1280
1281         if (!data || !ei || !obj)
1282                 return;
1283
1284         ev = ei;
1285         if (!ev->keyname)
1286                 return;
1287
1288         priv = data;
1289
1290         if (!strcmp(ev->keyname, KEY_DOWN)) {
1291                 icon = elm_object_part_content_get(obj,
1292                                 MAINICONBTN_ICON_SWALLOW);
1293                 if (!icon) {
1294                         _ERR("part %s content get failed.",
1295                                         MAINICONBTN_ICON_SWALLOW);
1296                         return;
1297                 }
1298
1299                 elm_object_signal_emit(icon, MAIN_BTN_UNFOCUSED, MAIN_BTN);
1300
1301                 next = elm_object_focus_next_object_get(obj, ELM_FOCUS_DOWN);
1302                 if (!next) {
1303                         _ERR("next object get failed.");
1304                         return;
1305                 }
1306
1307                 priv->focused_main_item_btn = next;
1308
1309                 icon = elm_object_part_content_get(next,
1310                                 MAINICONBTN_ICON_SWALLOW);
1311                 if (!icon) {
1312                         _ERR("part %s content get failed.",
1313                                         MAINICONBTN_ICON_SWALLOW);
1314                         return;
1315                 }
1316
1317                 elm_object_signal_emit(icon, MAIN_BTN_FOCUSED, MAIN_BTN);
1318
1319                 _release_subitems(priv);
1320
1321                 name = evas_object_data_get(next, SETTING_ID);
1322                 if (name)
1323                         _draw_subitems(priv, name);
1324         } else if (!strcmp(ev->keyname, KEY_UP)) {
1325                 icon = elm_object_part_content_get(obj,
1326                                 MAINICONBTN_ICON_SWALLOW);
1327                 if (!icon) {
1328                         _ERR("part %s content get failed.",
1329                                         MAINICONBTN_ICON_SWALLOW);
1330                         return;
1331                 }
1332
1333                 elm_object_signal_emit(icon, MAIN_BTN_UNFOCUSED, MAIN_BTN);
1334
1335                 next = elm_object_focus_next_object_get(obj, ELM_FOCUS_UP);
1336                 if (!next) {
1337                         _ERR("next object get failed.");
1338                         return;
1339                 }
1340
1341                 priv->focused_main_item_btn = next;
1342
1343                 icon = elm_object_part_content_get(next,
1344                                 MAINICONBTN_ICON_SWALLOW);
1345                 if (!icon) {
1346                         _ERR("part %s content get failed.",
1347                                         MAINICONBTN_ICON_SWALLOW);
1348                         return;
1349                 }
1350
1351                 elm_object_signal_emit(icon, MAIN_BTN_FOCUSED, MAIN_BTN);
1352
1353                 _release_subitems(priv);
1354
1355                 name = evas_object_data_get(next, SETTING_ID);
1356                 if (name)
1357                         _draw_subitems(priv, name);
1358         } else if (!strcmp(ev->keyname, KEY_RIGHT)) {
1359                 _move_from_main_item_to_subitem(priv, obj);
1360         } else if (!strcmp(ev->keyname, KEY_EXIT)
1361                         || !strcmp(ev->keyname, KEY_BACK)
1362                         || !strcmp(ev->keyname, KEY_BACK_REMOTE)) {
1363                 app_efl_exit();
1364         }
1365 }
1366
1367 /**
1368 * Evas_Object_Event_Cb type callback for handling mouse in event.
1369 *
1370 * @param[in]: data : the user data.
1371 * @param[in]: e : the evas.
1372 * @param[in]: obj : the corresponding object which the mouse in event occurred.
1373 * @param[in]: ei : event info.
1374 *
1375 * @return: void.
1376 */
1377 static void _mainitem_btn_mouse_in_cb(void *data, Evas *e,
1378                 Evas_Object *obj, void *ei)
1379 {
1380         struct _view_data *priv;
1381         const char *name;
1382         Evas_Object *icon;
1383
1384         if (!data || !obj) {
1385                 _ERR("Invalid argument");
1386                 return;
1387         }
1388
1389         priv = data;
1390
1391         if (priv->focus_status == FOCUS_SUB_ITEM)
1392                 _move_from_subitem_to_main_item(priv,
1393                                 priv->focused_sub_item_btn);
1394
1395         icon = elm_object_part_content_get(priv->focused_main_item_btn,
1396                         MAINICONBTN_ICON_SWALLOW);
1397         if (icon)
1398                 elm_object_signal_emit(icon, MAIN_BTN_UNFOCUSED, MAIN_BTN);
1399
1400         icon = elm_object_part_content_get(obj, MAINICONBTN_ICON_SWALLOW);
1401         if (icon)
1402                 elm_object_signal_emit(icon, MAIN_BTN_FOCUSED, MAIN_BTN);
1403
1404         _release_subitems(priv);
1405
1406         name = evas_object_data_get(obj, SETTING_ID);
1407         if (name)
1408                 _draw_subitems(priv, name);
1409
1410         elm_object_focus_set(obj, EINA_TRUE);
1411         priv->focused_main_item_btn = obj;
1412 }
1413
1414 /**
1415 * Evas_Object_Event_Cb type callback for handling mouse out event.
1416 *
1417 * @param[in]: data : the user data.
1418 * @param[in]: e : the evas.
1419 * @param[in]: obj : the corresponding object which the mouse out event occurred.
1420 * @param[in]: ei : event info.
1421 *
1422 * @return: void.
1423 */
1424 static void _mainitem_btn_mouse_out_cb(void *data, Evas *e,
1425                 Evas_Object *obj, void *ei)
1426 {
1427         /* TODO: Add necessary operations if needed. */
1428 }
1429
1430 /**
1431 * Evas_Smart_Cb type callback for handling click event.
1432 *
1433 * @param[in]: data : the user data.
1434 * @param[in]: obj : the corresponding object which the click event occurred.
1435 * @param[in]: ev : event info.
1436 *
1437 * @return: void.
1438 */
1439 static void _mainitem_btn_clicked_cb(void *data,
1440                 Evas_Object *obj, void *ev)
1441 {
1442         struct _view_data *priv;
1443
1444         if (!data || !obj) {
1445                 _ERR("Invalid argument");
1446                 return;
1447         }
1448
1449         priv = data;
1450         _move_from_main_item_to_subitem(priv, obj);
1451 }
1452
1453 /**
1454 * Create main items of settings.
1455 *
1456 * @param[in]: data : the user data.
1457 * @param[in]: list : the eina list containing data of main items.
1458 *
1459 * @return: 0 - success, -1 - fail.
1460 */
1461 static int _add_icon_btns(struct _view_data *data, Eina_List *list)
1462 {
1463         Evas_Object *btn, *icon;
1464         const char *id, *name;
1465         struct settingitem *item;
1466         char buf[BUF_SIZE];
1467         int i;
1468
1469         if (!data || !list || !data->base) {
1470                 _ERR("Invalid argument");
1471                 return -1;
1472         }
1473
1474         for (i = 0; i < data->main_item_count; i++) {
1475                 btn = utils_add_btn(data->base, MAINICONBTN_STYLE,
1476                                 NULL, EINA_FALSE);
1477                 if (!btn) {
1478                         _ERR("Add btn failed\n");
1479                         return -1;
1480                 }
1481
1482                 item = eina_list_nth(list, i);
1483                 if (item) {
1484                         name = settingitem_get_display_name(item);
1485                         elm_object_text_set(btn,
1486                                         utils_get_translation_str(name));
1487                 } else {
1488                         elm_object_text_set(btn, ICON_BUTTON_NO_DISP_NAME);
1489                 }
1490
1491                 evas_object_event_callback_add(btn, EVAS_CALLBACK_KEY_DOWN,
1492                                 _main_setting_key_pressed_cb, data);
1493                 evas_object_event_callback_add(btn, EVAS_CALLBACK_MOUSE_IN,
1494                                 _mainitem_btn_mouse_in_cb, data);
1495                 evas_object_event_callback_add(btn, EVAS_CALLBACK_MOUSE_OUT,
1496                                 _mainitem_btn_mouse_out_cb, data);
1497                 evas_object_smart_callback_add(btn, SIG_CLICKED,
1498                                 _mainitem_btn_clicked_cb, data);
1499
1500                 icon = elm_layout_add(btn);
1501                 if (icon) {
1502                         id = settingitem_get_id(item);
1503                         if (!id) {
1504                                 _ERR("get item name failed.");
1505                                 evas_object_del(btn);
1506                                 return -1;
1507                         }
1508
1509                         snprintf(buf, sizeof(buf), "%s/%s.edj",
1510                                         EDJEDIR, PACKAGE);
1511                         elm_layout_file_set(icon, buf, id);
1512                         elm_object_part_content_set(btn,
1513                                         MAINICONBTN_ICON_SWALLOW, icon);
1514                         elm_object_signal_emit(icon, MAIN_BTN_NORMAL, MAIN_BTN);
1515                         eina_array_push(data->main_icon_base, icon);
1516                 }
1517
1518                 elm_box_pack_end(data->mainitem_box, btn);
1519                 evas_object_data_set(btn, SETTING_ID, settingitem_get_id(item));
1520                 eina_array_push(data->main_item_btn, btn);
1521         }
1522
1523         return 0;
1524 }
1525
1526 /**
1527 * Create all the UI components of settings.
1528 *
1529 * @param[in]: data : the user data.
1530 *
1531 * @return: 0 - success, -1 - fail.
1532 */
1533 static int _draw_main_items(struct _view_data *data)
1534 {
1535         Evas_Object *box, *btn, *tmp, *icon;
1536         Eina_Array *btns, *icons;
1537         Eina_List *list;
1538         int cnt, i;
1539         Eina_Array_Iterator a;
1540
1541         if (!data || !data->base)
1542                 return -1;
1543
1544         box = utils_add_box(data->base);
1545         if (!box)
1546                 return -1;
1547
1548         data->mainitem_box = box;
1549
1550         cnt = 0;
1551         list = viewdata_get_childitems_list(data->main_setting_view);
1552         if (list)
1553                 cnt = eina_list_count(list);
1554
1555         if (cnt == 0) {
1556                 _ERR("There is no child item");
1557                 evas_object_del(box);
1558                 viewdata_free_childitems_list(list);
1559                 return -1;
1560         }
1561
1562         data->main_item_count = cnt;
1563
1564         btns = eina_array_new(1);
1565         if (!btns) {
1566                 _ERR("Create Eina Array failed\n");
1567                 evas_object_del(box);
1568                 viewdata_free_childitems_list(list);
1569                 return -1;
1570         }
1571
1572         data->main_item_btn = btns;
1573
1574         icons = eina_array_new(1);
1575         if (!icons) {
1576                 _ERR("new array for icon base failed.");
1577                 evas_object_del(box);
1578                 viewdata_free_childitems_list(list);
1579                 eina_array_free(btns);
1580                 return -1;
1581         }
1582
1583         data->main_icon_base = icons;
1584
1585         if (_add_icon_btns(data, list) == -1) {
1586                 _ERR("Fail to add icon buttons");
1587                 goto error;
1588         }
1589
1590         elm_object_part_content_set(data->base, MAIN_VIEW_ICON_SWALLOW, box);
1591
1592         if (!data->item_path) {
1593                 btn = eina_array_data_get(btns, 0);
1594                 if (!btn)
1595                         goto error;
1596
1597                 if (_draw_subitems(data,
1598                                 evas_object_data_get(btn, SETTING_ID)) == -1)
1599                         goto error;
1600
1601                 icon = eina_array_data_get(icons, 0);
1602                 if (!icon) {
1603                         if (data->subsetting_view)
1604                                 viewdata_release(data->subsetting_view);
1605                         goto error;
1606                 }
1607
1608                 elm_object_signal_emit(icon, MAIN_BTN_FOCUSED, MAIN_BTN);
1609
1610                 data->focus_status = FOCUS_MAIN_ITEM;
1611
1612                 elm_object_focus_set(btn, EINA_TRUE);
1613                 data->focused_main_item_btn = btn;
1614         }
1615
1616         utils_set_focus_directions(data->main_item_btn, cnt);
1617
1618         viewdata_free_childitems_list(list);
1619
1620         return 0;
1621
1622 error:
1623         evas_object_del(box);
1624         viewdata_free_childitems_list(list);
1625         EINA_ARRAY_ITER_NEXT(btns, i, tmp, a)
1626                 evas_object_del(tmp);
1627         eina_array_free(btns);
1628
1629         EINA_ARRAY_ITER_NEXT(icons, i, tmp, a)
1630                 evas_object_del(tmp);
1631         eina_array_free(icons);
1632
1633         return -1;
1634 }
1635
1636 /**
1637 * Edje_Signal_Cb type callback for handling signal.
1638 *
1639 * @param[in]: data : the user data.
1640 * @param[in]: obj : the object signal occurred on.
1641 * @param[in]: emission : the signal name.
1642 * @param[in]: source : the source name.
1643 *
1644 * @return: void.
1645 */
1646 static void _view_anim_finish(void *data, Evas_Object *obj,
1647                 const char *emission, const char *source)
1648 {
1649         struct _view_data *priv;
1650
1651         if (!data)
1652                 return;
1653
1654         priv = data;
1655
1656         _draw_main_items(priv);
1657 }
1658
1659 /**
1660 * This function moves focus from main item to subitem and
1661 * does corresponding operations.
1662 *
1663 * @param[in]: data : the user data.
1664 *
1665 * @return: void.
1666 */
1667 void _move_focus_on_subitem(struct _view_data *data)
1668 {
1669         const char *path, *id;
1670         unsigned int i;
1671         Evas_Object *icon, *subbtn, *pb;
1672         Eina_Array *subbtns;
1673         Eina_Array_Iterator a;
1674         struct settingitem *item;
1675
1676         if (!data)
1677                 return;
1678
1679         subbtns = data->sub_item_btn;
1680
1681         path = eina_array_data_get(data->item_path, 0);
1682
1683         EINA_ARRAY_ITER_NEXT(subbtns, i, subbtn, a) {
1684                 item = evas_object_data_get(subbtn, SUBITEM_DATA_ID);
1685                 id = settingitem_get_id(item);
1686                 if (!id)
1687                         return;
1688
1689                 if (!strncmp(id, path, ARRAY_SIZE)) {
1690                         icon = elm_object_part_content_get(
1691                                         data->focused_main_item_btn,
1692                                         MAINICONBTN_ICON_SWALLOW);
1693                         if (icon)
1694                                 elm_object_signal_emit(icon,
1695                                                 MAIN_BTN_HIGHLIGHT, MAIN_BTN);
1696
1697                         data->focus_status = FOCUS_SUB_ITEM;
1698                         data->focused_sub_item_btn = subbtn;
1699
1700                         elm_object_focus_set(subbtn, EINA_TRUE);
1701                         elm_object_signal_emit(data->focused_main_item_btn,
1702                                         MAINICONBTN_FOCUSED_ON_SUBITEM,
1703                                         MAINICONBTN_MAIN_ITEM_SOURCE);
1704
1705                         pb = evas_object_data_get(subbtn, PROGRESS_BAR_DATA);
1706                         if (pb)
1707                                 elm_object_signal_emit(pb,
1708                                                 SIG_UNCTRL_PB_FOCUSED,
1709                                                 SRC_PB_PROG);
1710                 }
1711         }
1712 }
1713
1714 /**
1715 * Change the language of names of buttons.
1716 *
1717 * @param[in]: list : eina list of item data.
1718 * @param[in]: btns : eina array containing buttons.
1719 * @param[in]: cnt : number of buttons.
1720 *
1721 * @return: void.
1722 */
1723 static void _change_buttons_name(Eina_List *list,
1724                 Eina_Array *btns, int cnt)
1725 {
1726         struct settingitem *item;
1727         Evas_Object *btn;
1728         const char *name;
1729         int i;
1730
1731         if (!list || !btns || !cnt) {
1732                 _ERR("Invalid argument");
1733                 return;
1734         }
1735
1736         for (i = 0; i < cnt; i++) {
1737                 item = eina_list_nth(list, i);
1738                 btn = eina_array_data_get(btns, i);
1739                 if (!item || !btn)
1740                         return;
1741
1742                 name = settingitem_get_display_name(item);
1743                 if (name)
1744                         elm_object_text_set(btn,
1745                                         utils_get_translation_str(name));
1746         }
1747 }
1748
1749 /**
1750 * Create all UI components of settings view.
1751 *
1752 * @param[in]: mgr : the view manager of settings.
1753 * @param[in]: view : the view data.
1754 * @param[in]: prev : the user data.
1755 *
1756 * @return: the base layout of settings or null if error occurred.
1757 */
1758 static Evas_Object *_create(struct setting_mgr *mgr,
1759                 struct settingview_data *view, void *prev)
1760 {
1761         Evas_Object *base, *win;
1762         struct _view_data *data;
1763
1764         if (!mgr || !view) {
1765                 _ERR("Invalid argument");
1766                 return NULL;
1767         }
1768
1769         win = settingmgr_get_win(mgr);
1770         if (!win) {
1771                 _ERR("Fail to get win");
1772                 return NULL;
1773         }
1774
1775         data = calloc(1, sizeof(*data));
1776         if (!data)
1777                 return NULL;
1778
1779         base = elm_layout_add(win);
1780         if (!base) {
1781                 free(data);
1782                 return NULL;
1783         }
1784
1785         if (!elm_layout_file_set(base, EDJ_FILE, MAIN_VIEW_PAGE))
1786                 goto error;
1787
1788         data->mgr = mgr;
1789         data->win = win;
1790         data->base = base;
1791         data->main_setting_view = view;
1792         data->subsetting_view = NULL;
1793         data->item_path = settingmgr_get_item_path(mgr);
1794
1795         evas_object_data_set(base, DATA_ID, data);
1796
1797         elm_object_signal_callback_add(base, MAIN_VIEW_ANIM_FINISH,
1798                         MAIN_VIEW_SOURCE, _view_anim_finish, data);
1799
1800         if (!data->item_path)
1801                 elm_object_signal_emit(data->base, MAIN_VIEW_LOAD, "");
1802         else
1803                 _view_anim_finish(data, NULL, NULL, NULL);
1804
1805         return base;
1806
1807 error:
1808         evas_object_del(base);
1809         free(data);
1810
1811         return NULL;
1812 }
1813
1814 /**
1815 * Show the view of settings.
1816 *
1817 * @param[in]: base : the base layout of settings.
1818 *
1819 * @return: void.
1820 */
1821 static void _show(Evas_Object *base)
1822 {
1823         struct _view_data *data;
1824         unsigned int cnt, i;
1825         const char *name, *path;
1826         Evas_Object *btn, *icon;
1827         Eina_Array *btns;
1828         Eina_Array_Iterator a;
1829
1830         if (!base) {
1831                 _ERR("Invalid argument");
1832                 return;
1833         }
1834
1835         data = evas_object_data_get(base, DATA_ID);
1836         if (!data) {
1837                 _ERR("evas object data get failed. id: %s", DATA_ID);
1838                 return;
1839         }
1840
1841         path = NULL;
1842
1843         if (data->item_path) {
1844                 btns = data->main_item_btn;
1845
1846                 cnt = eina_array_count(data->item_path);
1847                 if (cnt > 1) {
1848                         path = eina_array_data_get(data->item_path, cnt - 2);
1849                         if (!path)
1850                                 return;
1851                 }
1852
1853                 EINA_ARRAY_ITER_NEXT(btns, i, btn, a) {
1854                         name = evas_object_data_get(btn, SETTING_ID);
1855                         if (!name)
1856                                 return;
1857
1858                         if (!strncmp(name, path, ARRAY_SIZE)) {
1859                                 _draw_subitems(data, name);
1860
1861                                 icon = eina_array_data_get(
1862                                                 data->main_icon_base, i);
1863                                 if (icon)
1864                                         elm_object_signal_emit(icon,
1865                                                         MAIN_BTN_FOCUSED,
1866                                                         MAIN_BTN);
1867
1868                                 elm_object_focus_set(btn, EINA_TRUE);
1869
1870                                 data->focus_status = FOCUS_MAIN_ITEM;
1871                                 data->focused_main_item_btn = btn;
1872
1873                                 _move_focus_on_subitem(data);
1874                         }
1875                 }
1876         }
1877
1878         evas_object_show(base);
1879 }
1880
1881 /**
1882 * Hide the view of settings.
1883 *
1884 * @param[in]: base : the base layout of settings.
1885 *
1886 * @return: void.
1887 */
1888 static void _hide(Evas_Object *base)
1889 {
1890         if (!base) {
1891                 _ERR("Invalid argument");
1892                 return;
1893         }
1894
1895         evas_object_hide(base);
1896 }
1897
1898 /**
1899 * Refresh the view of settings.
1900 *
1901 * @param[in]: base : the base layout of settings.
1902 *
1903 * @return: void.
1904 */
1905 static void _refresh(Evas_Object *base)
1906 {
1907         struct _view_data *data;
1908         char *sld;
1909         const char *id;
1910         int i;
1911         struct settingitem *item;
1912         Eina_Array_Iterator a;
1913         Evas_Object *btn, *pb, *icon;
1914
1915         if (!base)
1916                 return;
1917
1918         data = evas_object_data_get(base, DATA_ID);
1919         if (!data)
1920                 return;
1921
1922         sld = evas_object_data_del(base, SELECTED_ITEM_ID);
1923         if (sld) {
1924                 EINA_ARRAY_ITER_NEXT(data->sub_item_btn, i, btn, a) {
1925                         item = evas_object_data_get(btn, SUBITEM_DATA_ID);
1926                         id = settingitem_get_id(item);
1927                         if (!id)
1928                                 continue;
1929
1930                         if (item && !strncmp(sld, id, strlen(sld))) {
1931                                 data->focused_sub_item_btn = btn;
1932                                 break;
1933                         }
1934                 }
1935         }
1936
1937         if (data->focus_status == FOCUS_SUB_ITEM) {
1938                 elm_object_focus_set(data->focused_sub_item_btn, EINA_TRUE);
1939
1940                 elm_object_signal_emit(data->focused_main_item_btn,
1941                                 MAINICONBTN_FOCUSED_ON_SUBITEM,
1942                                 MAINICONBTN_MAIN_ITEM_SOURCE);
1943
1944                 icon = elm_object_part_content_get(data->focused_main_item_btn,
1945                                 MAINICONBTN_ICON_SWALLOW);
1946                 if (icon)
1947                         elm_object_signal_emit(icon,
1948                                         MAIN_BTN_HIGHLIGHT, MAIN_BTN);
1949
1950                 if (_refresh_subitems(data) == -1)
1951                         _ERR("Refresh subitems failed");
1952
1953                 pb = evas_object_data_get(data->focused_sub_item_btn,
1954                                 PROGRESS_BAR_DATA);
1955                 if (pb)
1956                         elm_object_signal_emit(pb,
1957                                         SIG_UNCTRL_PB_FOCUSED, SRC_PB_PROG);
1958         }
1959
1960         if (settingmgr_get_timeout_freeze_state(data->mgr) == EINA_TRUE)
1961                 settingmgr_thaw_timeout(data->mgr);
1962 }
1963
1964 /**
1965 * Destroy the view of settings.
1966 *
1967 * @param[in]: base : the base layout of settings.
1968 *
1969 * @return: void.
1970 */
1971 static void _destroy(Evas_Object *base)
1972 {
1973         struct _view_data *data;
1974         Eina_Array_Iterator a;
1975         Evas_Object *tmp;
1976         unsigned int i;
1977
1978         if (!base) {
1979                 _ERR("Parameter error!");
1980                 return;
1981         }
1982
1983         data = evas_object_data_get(base, DATA_ID);
1984
1985         if (data->sub_item_btn) {
1986                 EINA_ARRAY_ITER_NEXT(data->sub_item_btn, i, tmp, a)
1987                         evas_object_del(tmp);
1988                 eina_array_free(data->sub_item_btn);
1989         }
1990
1991         if (data->main_item_btn) {
1992                 EINA_ARRAY_ITER_NEXT(data->main_item_btn, i, tmp, a)
1993                         evas_object_del(tmp);
1994                 eina_array_free(data->main_item_btn);
1995         }
1996
1997         if (data->main_icon_base) {
1998                 EINA_ARRAY_ITER_NEXT(data->main_icon_base, i, tmp, a)
1999                         evas_object_del(tmp);
2000                 eina_array_free(data->main_icon_base);
2001         }
2002
2003         if (data->main_setting_view)
2004                 viewdata_release(data->main_setting_view);
2005
2006         if (data->subsetting_view)
2007                 viewdata_release(data->subsetting_view);
2008
2009         free(data);
2010         evas_object_del(base);
2011 }
2012
2013 /**
2014 * Change the language of view of settings.
2015 *
2016 * @param[in]: base : the base layout of settings.
2017 *
2018 * @return: void.
2019 */
2020 static void _lang_changed(Evas_Object *base)
2021 {
2022         struct _view_data *data;
2023         Eina_List *l;
2024         int cnt;
2025
2026         if (!base) {
2027                 _ERR("Invalid argument");
2028                 return;
2029         }
2030
2031         data = evas_object_data_get(base, DATA_ID);
2032         if (!data)
2033                 return;
2034
2035         cnt = 0;
2036         l = viewdata_get_childitems_list(data->main_setting_view);
2037         if (l)
2038                 cnt = eina_list_count(l);
2039
2040         _change_buttons_name(l, data->main_item_btn, cnt);
2041
2042         cnt = 0;
2043         l = viewdata_get_childitems_list(data->subsetting_view);
2044         if (l)
2045                 cnt = eina_list_count(l);
2046
2047         _change_buttons_name(l, data->sub_item_btn, cnt);
2048 }
2049
2050 /**
2051 * Froze the view of settings.
2052 *
2053 * @param[in]: base : the base layout of settings.
2054 *
2055 * @return: void.
2056 */
2057 static void _frozen(Evas_Object *base)
2058 {
2059         struct _view_data *data;
2060
2061         if (!base) {
2062                 _ERR("Invalid argument");
2063                 return;
2064         }
2065
2066         data = evas_object_data_get(base, DATA_ID);
2067         if (!data) {
2068                 _ERR("Fail to get mainview data");
2069                 return;
2070         }
2071
2072         evas_object_freeze_events_set(data->mainitem_box, EINA_TRUE);
2073         evas_object_freeze_events_set(data->subitem_box, EINA_TRUE);
2074 }
2075
2076 /**
2077 * Activate the view of settings.
2078 *
2079 * @param[in]: base : the base layout of settings.
2080 *
2081 * @return: void.
2082 */
2083 static void _active(Evas_Object *base)
2084 {
2085         struct _view_data *data;
2086
2087         if (!base) {
2088                 _ERR("Invalid argument");
2089                 return;
2090         }
2091
2092         data = evas_object_data_get(base, DATA_ID);
2093         if (!data) {
2094                 _ERR("Fail to get mainview data");
2095                 return;
2096         }
2097
2098         evas_object_freeze_events_set(data->mainitem_box, EINA_FALSE);
2099         evas_object_freeze_events_set(data->subitem_box, EINA_FALSE);
2100 }
2101
2102 static struct setting_class _vclass = {
2103         .title = VCLASS_TITLE_MAIN_VIEW,
2104         .create = _create,
2105         .show = _show,
2106         .destroy = _destroy,
2107         .hide = _hide,
2108         .refresh = _refresh,
2109         .frozen = _frozen,
2110         .active = _active,
2111         .lang_changed = _lang_changed,
2112         .hide_view = 0
2113 };
2114
2115 /**
2116 * Return view class of settings view.
2117 *
2118 * @param: void.
2119 *
2120 * @return: the view class of settings view.
2121 */
2122 struct setting_class *view_maincatalog_get_vclass(void)
2123 {
2124         return &_vclass;
2125 }