Base code / protex done / build check done (32/64bit)
[profile/tv/apps/native/settings.git] / src / data_wrapper.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 <Eina.h>
18 #include <glib-object.h>
19 #include <json-glib/json-glib.h>
20 #include "data_wrapper.h"
21 #include "dbg.h"
22
23 struct settingui_args {
24         char *keyname;
25         char *value;
26 };
27
28 struct setting_ui {
29         char *style;
30         char *name;
31         Eina_List *args;
32 };
33
34 struct listitem {
35         char *display_name;
36         char *value;
37 };
38
39 struct slideritem {
40         char *min_value;
41         char *min_disp_value;
42         char *max_value;
43         char *max_disp_value;
44         char *step_value;
45         char *step_disp_value;
46 };
47
48 struct uidata {
49         char *key;
50         char *type;
51         Eina_List *item;
52         struct slideritem *slider_item;
53 };
54
55 struct settingitem {
56         char item_name[ARRAY_SIZE];
57         char *display_name;
58         char *style;
59         char *status;
60         struct setting_ui *setting_ui;
61         struct uidata *data;
62         Eina_List *sub_settingitems;
63         Eina_List *group_list;
64         char *parent_item;
65 };
66
67 struct settingmgr_data {
68         Eina_Hash *jsonhash;
69         Eina_List *parsed_json_file;
70 };
71
72 struct settingview_data {
73         struct settingitem *parentitem;
74         Eina_Array *childitems;
75 };
76
77 /**
78 *  This function is invoked to release slider item data.
79 *
80 *  @param item [in] The slideritem data pointer.
81 *  @return void.
82 */
83 static void _free_slider_item(struct slideritem *item)
84 {
85         if (!item) {
86                 _ERR("Invalid argument");
87                 return;
88         }
89
90         free(item->min_value);
91         free(item->min_disp_value);
92         free(item->max_value);
93         free(item->max_disp_value);
94         free(item->step_value);
95         free(item->step_disp_value);
96         free(item);
97 }
98
99 /**
100 *  This function is invoked to release item list data.
101 *
102 *  @param list [in] The Eina_List data pointer.
103 *  @return void.
104 */
105 static void _free_list_item(Eina_List *list)
106 {
107         struct listitem *litem;
108
109         if (!list) {
110                 _ERR("Invalid argument");
111                 return;
112         }
113
114         EINA_LIST_FREE(list, litem) {
115                 free(litem->display_name);
116                 free(litem->value);
117                 free(litem);
118         }
119 }
120
121 /**
122 *  This function is invoked to release item UI data.
123 *
124 *  @param data [in] The uidata data pointer.
125 *  @return void.
126 */
127 static void _free_uidata(struct uidata *data)
128 {
129         if (!data) {
130                 _ERR("Invalid argument");
131                 return;
132         }
133
134         free(data->key);
135         free(data->type);
136         _free_slider_item(data->slider_item);
137         _free_list_item(data->item);
138         free(data);
139 }
140
141 /**
142 *  This function is invoked to release UI arguments list.
143 *
144 *  @param list [in] The Eina_List data pointer.
145 *  @return void.
146 */
147 static void _free_ui_args(Eina_List *list)
148 {
149         struct settingui_args *args;
150
151         if (!list) {
152                 _ERR("Invalid argument");
153                 return;
154         }
155
156         EINA_LIST_FREE(list, args) {
157                 free(args->keyname);
158                 free(args->value);
159                 free(args);
160         }
161 }
162
163 /**
164 *  This function is invoked to release setting UI data.
165 *
166 *  @param data [in] The setting_ui data pointer.
167 *  @return void.
168 */
169 static void _free_setting_ui(struct setting_ui *data)
170 {
171         if (!data) {
172                 _ERR("Invalid argument");
173                 return;
174         }
175
176         free(data->style);
177         free(data->name);
178         _free_ui_args(data->args);
179         free(data);
180 }
181
182 /**
183 *  This function is invoked to release string list.
184 *
185 *  @param list [in] The Eina_List data pointer.
186 *  @return void.
187 */
188 static void _free_str_list(Eina_List *list)
189 {
190         char *item;
191
192         if (!list) {
193                 _ERR("Invalid argument");
194                 return;
195         }
196
197         EINA_LIST_FREE(list, item)
198                 free(item);
199 }
200
201 /**
202 *  This function is @Eina_Free_Cb type callback to release every
203 *  setting item data stored in eina hash.
204 *
205 *  @param data [in] The function specific data which hold settingitem pointer.
206 *  @return void.
207 */
208 static void _free_settingitem_cb(void *data)
209 {
210         struct settingitem *item;
211
212         if (!data) {
213                 _ERR("Invalid argument");
214                 return;
215         }
216
217         item = data;
218
219         free(item->display_name);
220         free(item->style);
221         free(item->status);
222         _free_str_list(item->sub_settingitems);
223         _free_uidata(item->data);
224         _free_setting_ui(item->setting_ui);
225         free(item->parent_item);
226         _free_str_list(item->group_list);
227         free(item);
228 }
229
230 /**
231 *  This function is invoked to initialize eina hash.
232 *
233 *  @param void.
234 *  @return The Eina_Hash data pointer, NULL on error.
235 */
236 static Eina_Hash *_hash_init(void)
237 {
238         Eina_Hash *hash;
239
240         hash = eina_hash_string_superfast_new(_free_settingitem_cb);
241
242         return hash;
243 }
244
245 /**
246 *  This function is invoked to destroy eina hash and release every element.
247 *
248 *  @param hash [in] The Eina_Hash data pointer.
249 *  @return void.
250 */
251 static void _hash_fini(Eina_Hash *hash)
252 {
253         if (!hash)
254                 return;
255
256         eina_hash_free(hash);
257 }
258
259 /**
260 *  This function is invoked to read slider item data from json file.
261 *
262 *  @param jparser [in] The json_parser data pointer.
263 *  @param name [in] The item name to be read.
264 *  @return The slideritem data pointer, NULL on error.
265 */
266 static struct slideritem *_read_slider_data_from_json(
267                 struct json_parser *jparser, const char *name)
268 {
269         char buf[BUF_SIZE];
270         struct slideritem *item;
271
272         if (!jparser || !name) {
273                 _ERR("Invalid argument");
274                 return NULL;
275         }
276
277         item = calloc(1, sizeof(struct slideritem));
278         if (!item)
279                 return NULL;
280
281         snprintf(buf, sizeof(buf), "$.settingitems.%s.%s.%s.%s",
282                         name, JSONSTR_DATA, JSONSTR_DATA_SLIDER,
283                         JSONSTR_SLIDER_MIN_DISPLAYVALUE);
284         item->min_disp_value = parser_get_string_value_from_json(jparser, buf);
285
286         snprintf(buf, sizeof(buf), "$.settingitems.%s.%s.%s.%s",
287                         name, JSONSTR_DATA, JSONSTR_DATA_SLIDER,
288                         JSONSTR_SLIDER_MIN_VALUE);
289         item->min_value = parser_get_string_value_from_json(jparser, buf);
290
291         snprintf(buf, sizeof(buf), "$.settingitems.%s.%s.%s.%s",
292                         name, JSONSTR_DATA, JSONSTR_DATA_SLIDER,
293                         JSONSTR_SLIDER_MAX_DISPLAYVALUE);
294         item->max_disp_value = parser_get_string_value_from_json(jparser, buf);
295
296         snprintf(buf, sizeof(buf), "$.settingitems.%s.%s.%s.%s",
297                         name, JSONSTR_DATA, JSONSTR_DATA_SLIDER,
298                         JSONSTR_SLIDER_MAX_VALUE);
299         item->max_value = parser_get_string_value_from_json(jparser, buf);
300
301         snprintf(buf, sizeof(buf), "$.settingitems.%s.%s.%s.%s",
302                         name, JSONSTR_DATA, JSONSTR_DATA_SLIDER,
303                         JSONSTR_SLIDER_STEP_DISPLAYVALUE);
304         item->step_disp_value = parser_get_string_value_from_json(jparser, buf);
305
306         snprintf(buf, sizeof(buf), "$.settingitems.%s.%s.%s.%s",
307                         name, JSONSTR_DATA, JSONSTR_DATA_SLIDER,
308                         JSONSTR_SLIDER_STEP_VALUE);
309         item->step_value = parser_get_string_value_from_json(jparser, buf);
310
311         return item;
312 }
313
314 /**
315 *  This function is invoked to read list item data from json file and store them into eina list.
316 *
317 *  @param jparser [in] The json_parser data pointer.
318 *  @param name [in] The item name to be read.
319 *  @return The Eina_List data pointer, NULL on error.
320 */
321 static Eina_List *_read_list_data_from_json(
322                 struct json_parser *jparser, const char *name)
323 {
324         char buf[BUF_SIZE];
325         struct listitem *item;
326         int i, length;
327         Eina_List *list;
328
329         if (!jparser || !name) {
330                 _ERR("Invalid argument");
331                 return NULL;
332         }
333
334         snprintf(buf, sizeof(buf), "$.settingitems.%s.%s.%s", name,
335                         JSONSTR_DATA, JSONSTR_DATA_LIST);
336         length = parser_get_array_length_from_json(jparser, buf);
337
338         list = NULL;
339
340         for (i = 0; i < length; i++) {
341                 item = calloc(1, sizeof(struct listitem));
342                 if (!item) {
343                         _free_list_item(list);
344                         return NULL;
345                 }
346
347                 snprintf(buf, sizeof(buf), "$.settingitems.%s.%s.%s[%d].%s",
348                                 name, JSONSTR_DATA, JSONSTR_DATA_LIST,
349                                 i, JSONSTR_LIST_DISPLAYVALUE);
350                 item->display_name = parser_get_string_value_from_json(
351                                 jparser, buf);
352
353                 snprintf(buf, sizeof(buf), "$.settingitems.%s.%s.%s[%d].%s",
354                                 name, JSONSTR_DATA, JSONSTR_DATA_LIST,
355                                 i, JSONSTR_LIST_VALUE);
356                 item->value = parser_get_string_value_from_json(jparser, buf);
357
358                 list = eina_list_append(list, item);
359         }
360
361         return list;
362 }
363
364 /**
365 *  This function is invoked to read setting UI property's arguments list from json file.
366 *
367 *  @param jparser [in] The json_parser data pointer.
368 *  @param name [in] The item name to be read.
369 *  @return The Eina_List data pointer, NULL on error.
370 */
371 static Eina_List *_get_settingui_args_list(
372                 struct json_parser *jparser, const char *name)
373 {
374         int i, cnt;
375         char **args;
376         struct settingui_args *data;
377         Eina_List *list;
378         char buf[BUF_SIZE];
379
380         if (!jparser || !name) {
381                 _ERR("Invalid argument");
382                 return NULL;
383         }
384
385         cnt = 0;
386         args = parser_get_settingui_args_from_json(jparser,
387                         name, JSONSTR_SETTINGUI, &cnt);
388         if (!args)
389                 return NULL;
390
391         list = NULL;
392
393         for (i = 0; i < cnt; i++) {
394                 if (!args[i]) {
395                         _ERR("Memory error");
396                         goto error;
397                 }
398
399                 data = calloc(1, sizeof(*data));
400                 if (!data) {
401                         _ERR("Allocate memory failed");
402                         goto error;
403                 }
404
405                 data->keyname = calloc(1, sizeof(char) * ARRAY_SIZE);
406                 if (!data->keyname) {
407                         _ERR("Allocate memory failed");
408                         free(data);
409                         goto error;
410                 }
411
412                 strncpy((char *)data->keyname, args[i], ARRAY_SIZE - 1);
413
414                 snprintf(buf, sizeof(buf), "$.menuitems.%s.%s.%s.%s",
415                                 name, JSONSTR_SETTINGUI,
416                                 JSONSTR_SETTINGUI_ARGS, args[i]);
417                 data->value = parser_get_string_value_from_json(jparser, buf);
418
419                 list = eina_list_append(list, data);
420         }
421
422         parser_release_member_list(args);
423
424         return list;
425
426 error:
427         parser_release_member_list(args);
428         _free_ui_args(list);
429
430         return NULL;
431 }
432
433 /**
434 *  This function is invoked to read setting item's "data" property infomation from json file.
435 *
436 *  @param jparser [in] The json_parser data pointer.
437 *  @param name [in] The item name to be read.
438 *  @return The uidata data pointer, NULL on error.
439 */
440 static struct uidata *_get_datainfo_from_json(
441                 struct json_parser *jparser, const char *name)
442 {
443         char **list;
444         int cnt, i;
445         char buf[BUF_SIZE];
446         struct uidata *data;
447
448         if (!jparser || !name) {
449                 _ERR("Invalid argument");
450                 return NULL;
451         }
452
453         data = calloc(1, sizeof(struct uidata));
454         if (!data)
455                 return NULL;
456
457         cnt = 0;
458         list = parser_get_data_list_from_json(jparser, name, &cnt);
459         if (!list) {
460                 _free_uidata(data);
461                 return NULL;
462         }
463
464         for (i = 0; i < cnt; i++) {
465                 if (!list[i]) {
466                         _ERR("Memory error");
467                         parser_release_member_list(list);
468                         _free_uidata(data);
469                         return NULL;
470                 }
471
472                 if (!strncmp(list[i], JSONSTR_DATA_KEY, strlen(list[i]))) {
473                         snprintf(buf, sizeof(buf), "$.settingitems.%s.%s.%s",
474                                         name, JSONSTR_DATA, JSONSTR_DATA_KEY);
475                         data->key = parser_get_string_value_from_json(
476                                         jparser, buf);
477                 } else if (!strncmp(list[i], JSONSTR_DATA_TYPE,
478                                 strlen(list[i]))) {
479                         snprintf(buf, sizeof(buf), "$.settingitems.%s.%s.%s",
480                                         name, JSONSTR_DATA, JSONSTR_DATA_TYPE);
481                         data->type = parser_get_string_value_from_json(
482                                         jparser, buf);
483                 } else if (!strncmp(list[i], JSONSTR_DATA_SLIDER,
484                                 strlen(list[i]))) {
485                         data->slider_item = _read_slider_data_from_json(
486                                         jparser, name);
487                 } else if (!strncmp(list[i], JSONSTR_DATA_LIST,
488                                 strlen(list[i]))) {
489                         data->item = _read_list_data_from_json(jparser, name);
490                 }
491         }
492
493         parser_release_member_list(list);
494
495         return data;
496 }
497
498 /**
499 *  This function is invoked to read setting item's infomation from json file.
500 *
501 *  @param jparser [in] The json_parser data pointer.
502 *  @param data [in] The settingitem data pointer which stored infomation read from json file.
503 *  @param name [in] The item name to be read.
504 *  @return void.
505 */
506 static void _get_iteminfo_from_json(struct json_parser *jparser,
507                 struct settingitem *data, const char *name)
508 {
509         struct settingitem *item;
510         char **list;
511         int cnt, i;
512         char buf[BUF_SIZE];
513
514         if (!jparser || !data || !name) {
515                 _ERR("Invalid argument");
516                 return;
517         }
518
519         item = data;
520
521         cnt = 0;
522         list = parser_get_itemlist_from_json(jparser, name, &cnt, DRAWING_INFO);
523         if (!list)
524                 return;
525
526         for (i = 0; i < cnt; i++) {
527                 if (!list[i]) {
528                         _ERR("Memory error");
529                         parser_release_member_list(list);
530                         return;
531                 }
532
533                 if (!strncmp(list[i], JSONSTR_DISPLAY_NAME, strlen(list[i]))) {
534                         snprintf(buf, sizeof(buf), "$.settingitems.%s.%s",
535                                         name, JSONSTR_DISPLAY_NAME);
536                         item->display_name = parser_get_string_value_from_json(
537                                         jparser, buf);
538                 } else if (!strncmp(list[i], JSONSTR_STYLE, strlen(list[i]))) {
539                         snprintf(buf, sizeof(buf), "$.settingitems.%s.%s",
540                                         name, JSONSTR_STYLE);
541                         item->style = parser_get_string_value_from_json(
542                                         jparser, buf);
543                 } else if (!strncmp(list[i], JSONSTR_STATUS, strlen(list[i]))) {
544                         snprintf(buf, sizeof(buf), "$.settingitems.%s.%s",
545                                         name, JSONSTR_STATUS);
546                         item->status = parser_get_string_value_from_json(
547                                         jparser, buf);
548                 } else if (!strncmp(list[i], JSONSTR_SETTINGUI,
549                                 strlen(list[i]))) {
550                         item->setting_ui = calloc(1, sizeof(struct setting_ui));
551                         if (!item->setting_ui)
552                                 continue;
553
554                         snprintf(buf, sizeof(buf), "$.settingitems.%s.%s", name,
555                                         JSONSTR_SETTINGUI_STYLE);
556                         item->setting_ui->style =
557                                         parser_get_string_value_from_json(
558                                         jparser, buf);
559
560                         snprintf(buf, sizeof(buf), "$.settingitems.%s.%s", name,
561                                         JSONSTR_SETTINGUI_NAME);
562                         item->setting_ui->name =
563                                         parser_get_string_value_from_json(
564                                         jparser, buf);
565                         item->setting_ui->args = _get_settingui_args_list(
566                                         jparser, name);
567                 } else if (!strncmp(list[i], JSONSTR_DATA, strlen(list[i]))) {
568                         item->data = _get_datainfo_from_json(jparser, name);
569                         if (!item->data)
570                                 continue;
571                 }
572         }
573
574         parser_release_member_list(list);
575 }
576
577 /**
578 *  This function is invoked to read setting tree's infomation from json file.
579 *
580 *  @param jparser [in] The json_parser data pointer.
581 *  @param data [in] The settingitem data pointer which stored infomation read from json file.
582 *  @param name [in] The item name to be read.
583 *  @return void.
584 */
585 static void _get_treeinfo_from_json(struct json_parser *jparser,
586                 struct settingitem *data, const char *name)
587 {
588         struct settingitem *item;
589         char **list;
590         int cnt, i;
591         char buf[BUF_SIZE];
592
593         if (!jparser || !data || !name) {
594                 _ERR("Invalid argument");
595                 return;
596         }
597
598         item = data;
599         cnt = 0;
600
601         list = parser_get_itemlist_from_json(jparser, name, &cnt, SUBMENU_INFO);
602         if (!list)
603                 return;
604
605         for (i = 0; i < cnt; i++) {
606                 if (!list[i]) {
607                         _ERR("Memory error");
608                         parser_release_member_list(list);
609                         return;
610                 }
611
612                 if (!strncmp(list[i], JSONSTR_SUBSETTING_SUBITEMS,
613                                 strlen(list[i]))) {
614                         snprintf(buf, sizeof(buf), "$.settingtree.%s.%s",
615                                         name, JSONSTR_SUBSETTING_SUBITEMS);
616                         item->sub_settingitems =
617                                         parser_get_string_list_from_json(
618                                         jparser, buf);
619                 } else if (!strncmp(list[i], JSONSTR_SUBSETTING_PARENTITEM,
620                                 strlen(list[i]))) {
621                         snprintf(buf, sizeof(buf), "$.settingtree.%s.%s",
622                                         name, JSONSTR_SUBSETTING_PARENTITEM);
623                         item->parent_item = parser_get_string_value_from_json(
624                                         jparser, buf);
625                 } else if (!strncmp(list[i], JSONSTR_GROUP, strlen(list[i]))) {
626                         snprintf(buf, sizeof(buf), "$.settingtree.%s.%s",
627                                         name, JSONSTR_GROUP);
628                         item->group_list = parser_get_string_list_from_json(
629                                         jparser, buf);
630                 }
631         }
632
633         parser_release_member_list(list);
634 }
635
636 /**
637 *  This function is invoked to read item infomation from json file.
638 *
639 *  @param jparser [in] The json_parser data pointer.
640 *  @param name [in] The item name to be read.
641 *  @return The settingitem data pointer, NULL on error.
642 */
643 static struct settingitem *_get_settingitem_from_json(
644                 struct json_parser *jparser, const char *name)
645 {
646         struct settingitem *item;
647
648         if (!jparser || !name) {
649                 _ERR("Parameter error!");
650                 return NULL;
651         }
652
653         item = calloc(1, sizeof(*item));
654         if (!item)
655                 return NULL;
656
657         item->parent_item = NULL;
658         item->sub_settingitems = NULL;
659
660         strncpy(item->item_name, name, ARRAY_SIZE - 1);
661
662         _get_iteminfo_from_json(jparser, item, name);
663         _get_treeinfo_from_json(jparser, item, name);
664
665         return item;
666 }
667
668 /**
669 *  This function is invoked to merge item infomation between existed and new item.
670 *
671 *  @param existed [in] The existed settingitem data pointer.
672 *  @param newer [in] The new settingitem data pointer.
673 *  @return void.
674 */
675 static void _merge_settingitems(struct settingitem *existed,
676                 struct settingitem *newer)
677 {
678         if (!existed || !newer) {
679                 _ERR("Invalid argument");
680                 return;
681         }
682
683         if (newer->sub_settingitems) {
684                 _free_str_list(existed->sub_settingitems);
685                 existed->sub_settingitems = newer->sub_settingitems;
686         }
687
688         if (newer->parent_item) {
689                 free(existed->parent_item);
690                 existed->parent_item = newer->parent_item;
691         }
692
693         if (newer->display_name) {
694                 free(existed->display_name);
695                 existed->display_name = newer->display_name;
696         }
697
698         if (newer->setting_ui) {
699                 _free_setting_ui(existed->setting_ui);
700                 existed->setting_ui = newer->setting_ui;
701         }
702
703         if (newer->style) {
704                 free(existed->style);
705                 existed->style = newer->style;
706         }
707
708         if (newer->data) {
709                 _free_uidata(existed->data);
710                 existed->data = newer->data;
711         }
712
713         if (newer->group_list) {
714                 _free_str_list(existed->group_list);
715                 existed->group_list = newer->group_list;
716         }
717 }
718
719 /**
720 *  This function is invoked to read a json file and store item infomation to eina hash.
721 *
722 *  @param hash [in] The Eina_Hash data pointer.
723 *  @param conf [in] The absolute json file path.
724 *  @param name [in] The json file name.
725 *  @return 0 if success, -1 if fail.
726 */
727 static int _write_settingitems_to_hash(Eina_Hash *hash,
728                 const char *conf, const char *name)
729 {
730         struct json_parser *jparser;
731         char **list;
732         struct settingitem *newer;
733         struct settingitem *existed;
734         JsonReader *reader;
735         char path[ARRAY_SIZE];
736         int cnt, i;
737
738         if (!hash || !name) {
739                 _ERR("Parameter error!");
740                 return -1;
741         }
742
743         if (!conf)
744                 snprintf(path, sizeof(path), "%s/%s.json",
745                                 JSON_OUTPUT_DIR, name);
746         else
747                 snprintf(path, sizeof(path), "%s", conf);
748
749         jparser = parser_init(path);
750         if (!jparser) {
751                 _ERR("parser_init failed!\n");
752                 return -1;
753         }
754
755         reader = parser_get_json_reader(jparser);
756         if (!reader) {
757                 _ERR("parser_get_json_reader failed!\n");
758                 parser_fini(jparser);
759                 return -1;
760         }
761
762         json_reader_read_member(reader, JSONSTR_SETTING_ITEMS);
763         cnt = json_reader_count_members(reader);
764         list = json_reader_list_members(reader);
765         json_reader_end_member(reader);
766
767         for (i = 0; i < cnt; i++) {
768                 newer = _get_settingitem_from_json(jparser, list[i]);
769                 if (!newer)
770                         continue;
771
772                 existed = eina_hash_find(hash, list[i]);
773                 if (!existed)
774                         eina_hash_add(hash, list[i], newer);
775                 else
776                         _merge_settingitems(existed, newer);
777         }
778
779         newer = _get_settingitem_from_json(jparser, name);
780         existed = eina_hash_find(hash, name);
781         if (!existed)
782                 eina_hash_add(hash, name, newer);
783         else
784                 _merge_settingitems(existed, newer);
785
786         parser_release_member_list(list);
787         parser_fini(jparser);
788
789         return 0;
790 }
791
792 /**
793 *  This function is invoked to check slider item style.
794 *
795 *  @param hash [in] The settingitem data pointer.
796 *  @return true if style is bottom slider or bottom 2-way slider
797 *              false if style is other kind of view.
798 */
799 static bool _check_slider_item(struct settingitem *item)
800 {
801         const char *style;
802
803         if (!item) {
804                 _ERR("Invalid argument");
805                 return false;
806         }
807
808         style = settingitem_get_settingui_style(item);
809         if (!style)
810                 return false;
811
812         if (!strncmp(style, STYLE_BOTTOMSLIDER, strlen(style)) ||
813                         !strncmp(style, STYLE_BOTTOM2WAYSLIDER, strlen(style)))
814                 return true;
815
816         return false;
817 }
818
819 /**
820 *  This function is invoked to tranform string type value to float.
821 *
822 *  @param str [in] The string value.
823 *  @param val [out] The float value.
824 *  @return 0 if success, -1 if fail.
825 */
826 static int _get_slider_value(const char *str, double *val)
827 {
828         if (!str || !strlen(str) || !val) {
829                 _ERR("Invalid argument");
830                 return -1;
831         }
832
833         *val = atof(str);
834
835         return 0;
836 }
837
838 /**
839 *  This function is invoked to create and initialize setting manager data structure.
840 *
841 *  @param void.
842 *  @return The settingmgr_data data pointer, NULL on error.
843 */
844 struct settingmgr_data *viewmgr_data_init(void)
845 {
846         struct settingmgr_data *data;
847
848         data = calloc(1, sizeof(struct settingmgr_data));
849         if (!data) {
850                 _ERR("calloc data failed\n");
851                 return NULL;
852         }
853
854         data->jsonhash = _hash_init();
855         if (!data->jsonhash) {
856                 free(data);
857                 return NULL;
858         }
859
860         data->parsed_json_file = NULL;
861
862         return data;
863 }
864
865 /**
866 *  This function is invoked to destroy and release setting manager data structure.
867 *
868 *  @param data [in] The settingmgr_data data pointer.
869 *  @return void.
870 */
871 void viewmgr_data_fini(struct settingmgr_data *data)
872 {
873         char *node;
874
875         if (!data) {
876                 _ERR("Parameter error!");
877                 return;
878         }
879
880         _hash_fini(data->jsonhash);
881
882         if (data->parsed_json_file) {
883                 EINA_LIST_FREE(data->parsed_json_file, node)
884                         free(node);
885         }
886
887         free(data);
888 }
889
890 /**
891 *  This function is invoked to get setting item data with specific name.
892 *
893 *  @param data [in] The settingmgr_data data pointer.
894 *  @param name [in] The item name want to get.
895 *  @return The settingitem data pointer, NULL on error.
896 */
897 struct settingitem *viewmgr_data_get_settingitem(
898                 struct settingmgr_data *data, const char *name)
899 {
900         struct settingitem *item;
901
902         if (!name || !data)
903                 return NULL;
904
905         item = eina_hash_find(data->jsonhash, name);
906
907         return item;
908 }
909
910 /**
911 *  This function is invoked to parse specific json file and store data into eina hash.
912 *
913 *  @param data [in] The settingmgr_data data pointer.
914 *  @param name [in] The item name want to read.
915 *  @return 0 if success, -1 if fail.
916 */
917 int viewmgr_data_read_jsonfile_into_hash(
918                 struct settingmgr_data *data, const char *name)
919 {
920         char *tmp;
921         const char *style, *ui_name;
922         struct settingitem *item;
923         Eina_Hash *hash;
924         Eina_List *list, *l;
925         int r, flag;
926
927         if (!data || !name) {
928                 _ERR("Parameter error!");
929                 return -1;
930         }
931
932         hash = data->jsonhash;
933         list = data->parsed_json_file;
934         flag = 1;
935
936         item = viewmgr_data_get_settingitem(data, name);
937         style = settingitem_get_settingui_style(item);
938         ui_name = settingitem_get_settingui_name(item);
939
940         if (style && !ui_name && strncmp(style,
941                         STYLE_NEED_PASSCODE, strlen(style)))
942                 return 0;
943
944         if (style && ui_name && !strncmp(style, STYLE_UIGADGET, strlen(style)))
945                 return 0;
946
947         EINA_LIST_FOREACH(list, l, tmp) {
948                 if (!strncmp(tmp, name, BUF_SIZE))
949                         flag = 0;
950         }
951
952         if (flag) {
953                 r = _write_settingitems_to_hash(hash, NULL, name);
954                 if (r == -1) {
955                         _ERR("_write_settingitems_to_hash failed!\n");
956                         return -1;
957                 }
958
959                 tmp = strdup(name);
960                 data->parsed_json_file = eina_list_prepend(
961                                 data->parsed_json_file, tmp);
962         }
963
964         return 0;
965 }
966
967 /**
968 *  This function is invoked to build setting manager data structure with specific name.
969 *
970 *  @param sdata [in] The settingmgr_data data pointer.
971 *  @param name [in] The item name.
972 *  @return The settingview_data data pointer, NULL on error.
973 */
974 struct settingview_data *viewmgr_data_build_view(
975                 struct settingmgr_data *sdata, const char *name)
976 {
977         Eina_List *list, *l;
978         struct settingitem *item;
979         const char *node;
980         struct settingview_data *vdata;
981
982         if (!sdata || !name) {
983                 _ERR("Parameter error!");
984                 return NULL;
985         }
986
987         vdata = viewdata_allocate();
988         if (!vdata) {
989                 _ERR("Allocate memory failed");
990                 return NULL;
991         }
992
993         item = NULL;
994         l = NULL;
995
996         vdata->parentitem = viewmgr_data_get_settingitem(sdata, name);
997         list = settingitem_get_subitems(vdata->parentitem);
998         if (list) {
999                 vdata->childitems = eina_array_new(1);
1000                 EINA_LIST_FOREACH(list, l, node) {
1001                         item = viewmgr_data_get_settingitem(sdata, node);
1002                         if (!item) {
1003                                 _ERR("childitem not found, continuing");
1004                                 continue;
1005                         }
1006
1007                         eina_array_push(vdata->childitems, item);
1008                 }
1009         }
1010
1011         return vdata;
1012 }
1013
1014 /**
1015 *  This function is invoked to get sub item list from setting item data structure.
1016 *
1017 *  @param sitem [in] The settingitem data pointer.
1018 *  @return The Eina_List data pointer, NULL on error.
1019 */
1020 Eina_List *settingitem_get_subitems(struct settingitem *sitem)
1021 {
1022         if (!sitem)
1023                 return NULL;
1024
1025         return sitem->sub_settingitems;
1026 }
1027
1028 /**
1029 *  This function is invoked to get item group list from setting item data structure.
1030 *
1031 *  @param sitem [in] The settingitem data pointer.
1032 *  @return The Eina_List data pointer, NULL on error.
1033 */
1034 Eina_List *settingitem_get_group_list(struct settingitem *sitem)
1035 {
1036         if (!sitem)
1037                 return NULL;
1038
1039         return sitem->group_list;
1040 }
1041
1042 /**
1043 *  This function is invoked to get parent item name from setting item data structure.
1044 *
1045 *  @param item [in] The settingitem data pointer.
1046 *  @return The string value, NULL on error.
1047 */
1048 const char *settingitem_get_parentitem(struct settingitem *item)
1049 {
1050         if (!item)
1051                 return NULL;
1052
1053         return item->parent_item;
1054 }
1055
1056 /**
1057 *  This function is invoked to get item display name from setting item data structure.
1058 *
1059 *  @param item [in] The settingitem data pointer.
1060 *  @return The string value, NULL on error.
1061 */
1062 const char *settingitem_get_display_name(struct settingitem *item)
1063 {
1064         if (!item)
1065                 return NULL;
1066
1067         return item->display_name;
1068 }
1069
1070 /**
1071 *  This function is invoked to get item id from setting item data structure.
1072 *
1073 *  @param item [in] The settingitem data pointer.
1074 *  @return The string value, NULL on error.
1075 */
1076 const char *settingitem_get_id(struct settingitem *item)
1077 {
1078         if (!item)
1079                 return NULL;
1080
1081         return item->item_name;
1082 }
1083
1084 /**
1085 *  This function is invoked to get item style from setting item data structure.
1086 *
1087 *  @param item [in] The settingitem data pointer.
1088 *  @return The string value, NULL on error.
1089 */
1090 const char *settingitem_get_style(struct settingitem *item)
1091 {
1092         if (!item)
1093                 return NULL;
1094
1095         return item->style;
1096 }
1097
1098 /**
1099 *  This function is invoked to get item status from setting item data structure.
1100 *
1101 *  @param item [in] The settingitem data pointer.
1102 *  @return The string value, NULL on error.
1103 */
1104 const char *settingitem_get_status(struct settingitem *item)
1105 {
1106         if (!item)
1107                 return NULL;
1108
1109         return item->status;
1110 }
1111
1112 /**
1113 *  This function is invoked to get item's setting UI style from setting item data structure.
1114 *
1115 *  @param item [in] The settingitem data pointer.
1116 *  @return The string value, NULL on error.
1117 */
1118 const char *settingitem_get_settingui_style(struct settingitem *item)
1119 {
1120         if (!item || !item->setting_ui)
1121                 return NULL;
1122
1123         return item->setting_ui->style;
1124 }
1125
1126 /**
1127 *  This function is invoked to get item's setting UI name from setting item data structure.
1128 *
1129 *  @param item [in] The settingitem data pointer.
1130 *  @return The string value, NULL on error.
1131 */
1132 const char *settingitem_get_settingui_name(struct settingitem *item)
1133 {
1134         if (!item || !item->setting_ui)
1135                 return NULL;
1136
1137         return item->setting_ui->name;
1138 }
1139
1140 /**
1141 *  This function is invoked to get item's setting UI arguments from setting item data structure.
1142 *
1143 *  @param item [in] The settingitem data pointer.
1144 *  @return The Eina_List data pointer, NULL on error.
1145 */
1146 Eina_List *settingitem_get_settingui_args(struct settingitem *item)
1147 {
1148         if (!item || !item->setting_ui)
1149                 return NULL;
1150
1151         return item->setting_ui->args;
1152 }
1153
1154 /**
1155 *  This function is invoked to get item's data key value from setting item data structure.
1156 *
1157 *  @param item [in] The settingitem data pointer.
1158 *  @return The string value, NULL on error.
1159 */
1160 const char *settingitem_get_data_key(struct settingitem *item)
1161 {
1162         if (!item || !item->data)
1163                 return NULL;
1164
1165         return item->data->key;
1166 }
1167
1168 /**
1169 *  This function is invoked to get item's data type value from setting item data structure.
1170 *
1171 *  @param item [in] The settingitem data pointer.
1172 *  @return The string value, NULL on error.
1173 */
1174 const char *settingitem_get_data_type(struct settingitem *item)
1175 {
1176         if (!item || !item->data)
1177                 return NULL;
1178
1179         return item->data->type;
1180 }
1181
1182 /**
1183 *  This function is invoked to get item's data list from setting item data structure.
1184 *
1185 *  @param item [in] The settingitem data pointer.
1186 *  @return The Eina_List data pointer, NULL on error.
1187 */
1188 Eina_List *settingitem_get_data_list(struct settingitem *item)
1189 {
1190         if (!item || !item->data)
1191                 return NULL;
1192
1193         return item->data->item;
1194 }
1195
1196 /**
1197 *  This function is invoked to get item's slider data from setting item data structure.
1198 *
1199 *  @param item [in] The settingitem data pointer.
1200 *  @return The slideritem data pointer, NULL on error.
1201 */
1202 struct slideritem *settingitem_get_data_slideritem(struct settingitem *item)
1203 {
1204         if (!item || !item->data)
1205                 return NULL;
1206
1207         return item->data->slider_item;
1208 }
1209
1210 /**
1211 *  This function is invoked to get item's list data display name from listitem data structure.
1212 *
1213 *  @param litem [in] The listitem data pointer.
1214 *  @return The string value, NULL on error.
1215 */
1216 const char *listitem_get_display_name(struct listitem *litem)
1217 {
1218         if (!litem)
1219                 return NULL;
1220
1221         return litem->display_name;
1222 }
1223
1224 /**
1225 *  This function is invoked to get item's list data value from listitem data structure.
1226 *
1227 *  @param litem [in] The listitem data pointer.
1228 *  @return The string value, NULL on error.
1229 */
1230 const char *listitem_get_value(struct listitem *litem)
1231 {
1232         if (!litem)
1233                 return NULL;
1234
1235         return litem->value;
1236 }
1237
1238 /**
1239 *  This function is invoked to get item's slider minimum value from slideritem data structure.
1240 *
1241 *  @param sitem [in] The slideritem data pointer.
1242 *  @return The string value, NULL on error.
1243 */
1244 const char *slideritem_get_min_value(struct slideritem *sitem)
1245 {
1246         if (!sitem)
1247                 return NULL;
1248
1249         return sitem->min_value;
1250 }
1251
1252 /**
1253 *  This function is invoked to get item's slider step value from slideritem data structure.
1254 *
1255 *  @param sitem [in] The slideritem data pointer.
1256 *  @return The string value, NULL on error.
1257 */
1258 const char *slideritem_get_step_value(struct slideritem *sitem)
1259 {
1260         if (!sitem)
1261                 return NULL;
1262
1263         return sitem->step_value;
1264 }
1265
1266 /**
1267 *  This function is invoked to get item's slider maximum value from slideritem data structure.
1268 *
1269 *  @param sitem [in] The slideritem data pointer.
1270 *  @return The string value, NULL on error.
1271 */
1272 const char *slideritem_get_max_value(struct slideritem *sitem)
1273 {
1274         if (!sitem)
1275                 return NULL;
1276
1277         return sitem->max_value;
1278 }
1279
1280 /**
1281 *  This function is invoked to get item's slider minimum display value
1282 *  from slideritem data structure.
1283 *
1284 *  @param sitem [in] The slideritem data pointer.
1285 *  @return The string value, NULL on error.
1286 */
1287 const char *slideritem_get_min_display_value(struct slideritem *sitem)
1288 {
1289         if (!sitem)
1290                 return NULL;
1291
1292         return sitem->min_disp_value;
1293 }
1294
1295 /**
1296 *  This function is invoked to get item's slider step display value
1297 *  from slideritem data structure.
1298 *
1299 *  @param sitem [in] The slideritem data pointer.
1300 *  @return The string value, NULL on error.
1301 */
1302 const char *slideritem_get_step_display_value(struct slideritem *sitem)
1303 {
1304         if (!sitem)
1305                 return NULL;
1306
1307         return sitem->step_disp_value;
1308 }
1309
1310 /**
1311 *  This function is invoked to get item's slider maximum display value
1312 *  from slideritem data structure.
1313 *
1314 *  @param sitem [in] The slideritem data pointer.
1315 *  @return The string value, NULL on error.
1316 */
1317 const char *slideritem_get_max_display_value(struct slideritem *sitem)
1318 {
1319         if (!sitem)
1320                 return NULL;
1321
1322         return sitem->max_disp_value;
1323 }
1324
1325 /**
1326 *  This function is invoked to calculate slider real value with specific original value.
1327 *
1328 *  @param val [in] The original value.
1329 *  @param data [in] The slideritem data pointer.
1330 *  @return The float slider value, 0.0 on error.
1331 */
1332 double slideritem_find_slider_value(double val, struct slideritem *data)
1333 {
1334         double sval, min, max;
1335         int r;
1336
1337         if (!data) {
1338                 _ERR("Invalid arguments");
1339                 return 0.0;
1340         }
1341
1342         min = 0.0;
1343         max = 0.0;
1344
1345         r = _get_slider_value(slideritem_get_min_value(data), &min);
1346         if (r == -1)
1347                 return 0.0;
1348
1349         r = _get_slider_value(slideritem_get_max_value(data), &max);
1350         if (r == -1)
1351                 return 0.0;
1352
1353         if (max - min == 0.0)
1354                 return 0.0;
1355
1356         sval = (val - min) / (max - min);
1357
1358         return sval;
1359 }
1360
1361 /**
1362 *  This function is invoked to calculate slider display value with specific real value.
1363 *
1364 *  @param val [in] The real value.
1365 *  @param data [in] The slideritem data pointer.
1366 *  @return The float slider display value, 0.0 on error.
1367 */
1368 double slideritem_find_slider_display_value(double val,
1369                 struct slideritem *data)
1370 {
1371         double sval, min, max;
1372         int r;
1373
1374         if (!data) {
1375                 _ERR("Invalid arguments");
1376                 return 0.0;
1377         }
1378
1379         min = 0.0;
1380         max = 0.0;
1381
1382         r = _get_slider_value(slideritem_get_min_display_value(data), &min);
1383         if (r == -1)
1384                 return 0.0;
1385
1386         r = _get_slider_value(slideritem_get_max_display_value(data), &max);
1387         if (r == -1)
1388                 return 0.0;
1389
1390         sval = min + (val * (max - min));
1391
1392         return sval;
1393 }
1394
1395 /**
1396 *  This function is invoked to get parent item from setting view data.
1397 *
1398 *  @param data [in] The settingview_data data pointer.
1399 *  @return The settingitem data pointer, NULL on error.
1400 */
1401 struct settingitem *viewdata_get_parentitem(struct settingview_data *data)
1402 {
1403         if (!data) {
1404                 _ERR("Parameter error!");
1405                 return NULL;
1406         }
1407
1408         return data->parentitem;
1409 }
1410
1411 /**
1412 *  This function is invoked to get child items array from setting view data.
1413 *
1414 *  @param data [in] The settingview_data data pointer.
1415 *  @return The Eina_Array data pointer, NULL on error.
1416 */
1417 Eina_Array *viewdata_get_childitems(struct settingview_data *data)
1418 {
1419         if (!data) {
1420                 _ERR("Parameter error!");
1421                 return NULL;
1422         }
1423
1424         return data->childitems;
1425 }
1426
1427 /**
1428 *  This function is invoked to build child items list.
1429 *
1430 *  @param view [in] The settingview_data data pointer.
1431 *  @return The Eina_List data pointer, NULL on error.
1432 */
1433 Eina_List *viewdata_get_childitems_list(struct settingview_data *view)
1434 {
1435         int i, cnt;
1436         Eina_List *subitems, *list;
1437         struct settingitem *subitem;
1438
1439         subitems = settingitem_get_subitems(view->parentitem);
1440         if (!subitems)
1441                 return NULL;
1442
1443         list = NULL;
1444         cnt = eina_list_count(subitems);
1445         for (i = 0; i < cnt; i++) {
1446                 subitem = eina_array_data_get(view->childitems, i);
1447                 list = eina_list_append(list, subitem);
1448         }
1449
1450         return list;
1451 }
1452
1453 /**
1454 *  This function is invoked to free child items list.
1455 *
1456 *  @param list [in] The Eina_List data pointer.
1457 *  @return void.
1458 */
1459 void viewdata_free_childitems_list(Eina_List *list)
1460 {
1461         if (!list) {
1462                 _ERR("the list is null.");
1463                 return;
1464         }
1465
1466         eina_list_free(list);
1467 }
1468
1469 /**
1470 *  This function is invoked to allocate setting view data.
1471 *
1472 *  @param void.
1473 *  @return The settingview_data data pointer, NULL on error.
1474 */
1475 struct settingview_data *viewdata_allocate(void)
1476 {
1477         struct settingview_data *vdata;
1478
1479         vdata = calloc(1, sizeof(*vdata));
1480         if (!vdata) {
1481                 _ERR("Allocate memory failed\n");
1482                 return NULL;
1483         }
1484
1485         return vdata;
1486 }
1487
1488 /**
1489 *  This function is invoked to release setting view data.
1490 *
1491 *  @param data [in] The settingview_data data pointer.
1492 *  @return void.
1493 */
1494 void viewdata_release(struct settingview_data *data)
1495 {
1496         if (!data) {
1497                 _ERR("Invalid argument");
1498                 return;
1499         }
1500
1501         if (data->childitems)
1502                 eina_array_free(data->childitems);
1503
1504         free(data);
1505 }
1506
1507 /**
1508 *  This function is invoked to get item group list, these items are slider setting UI style
1509 *  and contained specific item.
1510 *
1511 *  @param item [in] The settingitem data pointer.
1512 *  @param sdata [in] The settingmgr_data data pointer.
1513 *  @param name [in] The item name.
1514 *  @return The Eina_List data pointer, NULL on error.
1515 */
1516 Eina_List *settingitem_get_slider_group_list(struct settingitem *item,
1517                 struct settingmgr_data *sdata, const char *name)
1518 {
1519         Eina_List *l, *group, *result;
1520         struct settingitem *sitem;
1521         const char *node;
1522         int found;
1523
1524         if (!item || !sdata || !name) {
1525                 _ERR("Invalid argument");
1526                 return NULL;
1527         }
1528
1529         group = settingitem_get_group_list(item);
1530         if (!group)
1531                 return NULL;
1532
1533         found = 0;
1534
1535         EINA_LIST_FOREACH(group, l, node) {
1536                 if (!strncmp(name, node, strlen(name))) {
1537                         found = 1;
1538                         break;
1539                 }
1540         }
1541
1542         if (!found)
1543                 return NULL;
1544
1545         result = NULL;
1546
1547         EINA_LIST_FOREACH(group, l, node) {
1548                 sitem = viewmgr_data_get_settingitem(sdata, node);
1549                 if (_check_slider_item(sitem))
1550                         result = eina_list_append(result, node);
1551         }
1552
1553         return result;
1554 }