f21ca3e6533aa6036c39a14861ece508a5eb318c
[apps/core/preloaded/settings.git] / src / setting-plugin.c
1 /*
2  * setting
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
5  *
6  * Contact: MyoungJune Park <mj2004.park@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <unistd.h>
23 #include <eina_list.h>
24 #include <glib.h>
25
26
27 #include <setting-debug.h>
28 #include <setting-common-general-func.h>
29 #include <setting-common-draw-widget.h>
30
31 #include <setting-plugin.h>
32
33
34
35 static Setting_GenGroupItem_Data *g_list_item;  /*TEST*/
36
37
38
39 /*
40  * UI draw handler table : _g_draw_list
41  *  - contains Object_Drawer typed object.
42  */
43 Eina_List *_g_drawer_list = NULL;
44
45 /**
46  * @return Evas_Object * obj
47  */
48 static void* navigationbar_func(void *data, xmlNode *xmlObj);
49
50
51 /*
52  * @return void
53  */
54 static void* group_func(void *data, xmlNode *xmlObj);
55
56 /*
57  * @return Setting_GenGroupItem_Data* ptr
58  */
59 static void* link_func(void *data, xmlNode *xmlObj);
60
61 /*
62  * @return Setting_GenGroupItem_Data* ptr
63  */
64 static void* slider_func(void *data, xmlNode *xmlObj);
65
66 /*
67  * @return Setting_GenGroupItem_Data* ptr
68  */
69 static void* label_func(void *data, xmlNode *xmlObj);
70
71 /*
72  * @return Setting_GenGroupItem_Data* ptr
73  */
74 static void* checkbox_func(void *data, xmlNode *xmlObj);
75
76 /*
77  * @return Setting_GenGroupItem_Data* ptr
78  */
79 static void* editbox_func(void *data, xmlNode *xmlObj);
80
81 /*
82  * @return Setting_GenGroupItem_Data* ptr
83  */
84 static void* expandlist_func(void *data, xmlNode *xmlObj);
85
86 /**
87  * @return nothing
88  */
89 static void* expanditem_func(void *data, xmlNode *xmlObj);
90
91 /**
92  * do nothing
93  */
94 static void* settings_func(void *data, xmlNode *xmlObj);
95
96
97 static void* launch_func(void *data, xmlNode *xmlObj);
98
99 /**
100  * do nothing
101  */
102 static void* setting_func(void *data, xmlNode *xmlObj);
103
104 static int __node_walker(PluginNode* context, xmlNode* cur);
105
106 static int __node_finder(PluginNode* context, xmlNode* cur, char* id_str, char* value, bool* is_end);
107
108
109 static void __drawer_add(const char *type, drawer_fp draw)
110 {
111         Object_Drawer *node = calloc(1, sizeof(Object_Drawer));
112         if (node && type && draw)
113         {
114                 node->type = type;
115                 node->draw = draw;
116
117                 _g_drawer_list = eina_list_append(_g_drawer_list, node);
118         }
119 }
120
121
122 static drawer_fp __drawer_find(char* type)
123 {
124         SETTING_TRACE_BEGIN;
125         SETTING_TRACE("node type:%s", type);
126         Eina_List *check_list = _g_drawer_list;
127         Object_Drawer *list_item = NULL;
128
129         while (check_list) {
130                 list_item = (Object_Drawer *) eina_list_data_get(check_list);
131                 if (NULL == list_item)
132                         continue;
133
134                 if (0 == safeStrCmp(list_item->type, type))
135                 {
136                         //SETTING_TRACE("list_item->type:%s", list_item->type);
137                         break;
138                 }
139                 //if not matched,to check next node.
140                 check_list = eina_list_next(check_list);
141                 list_item = NULL;
142         }
143         //SETTING_TRACE("list_item:%p", list_item);
144         return list_item ? list_item->draw : NULL;
145 }
146 void setting_drawer_list_init()
147 {
148         SETTING_TRACE_BEGIN;
149 #if 0
150         /* <navigationbar> */__drawer_add("navigationbar", navigationbar_func);
151 #endif
152         /* <bool>          */__drawer_add("bool", checkbox_func);
153         /* <string>        */__drawer_add("string", editbox_func);
154         /* <group>         */__drawer_add("group", group_func);
155         /* <integer>       */__drawer_add("integer", slider_func);
156         /* <label>         */__drawer_add("label", label_func);
157         /* <link>          */__drawer_add("link", link_func);
158         /* <launch>        */__drawer_add("launch", launch_func);
159         /* <extendlist>    */__drawer_add("expandlist", expandlist_func);
160         /* <extenditem>    */__drawer_add("expanditem", expanditem_func);
161         /* <settings>      */__drawer_add("settings", settings_func);
162         /* <setting>       */__drawer_add("setting", setting_func);
163 }
164
165 void setting_drawer_list_fini()
166 {
167         if (_g_drawer_list)
168         {
169                 Object_Drawer *node = NULL;
170                 Eina_List *li = _g_drawer_list;
171                 while (li) {
172                         node = (Object_Drawer *) eina_list_data_get(li);
173                         if (node)
174                         {
175                                 //SETTING_TRACE("Deregister %s", node->type);
176                                 FREE(node);
177                         }
178                         li = eina_list_next(li);
179                 }
180                 _g_drawer_list = eina_list_free(_g_drawer_list);
181                 _g_drawer_list = NULL;
182         }
183 }
184
185 /////////////////////////
186 /////////////////////////
187 /////////////////////////
188
189 #define MAX_CONTENT_LEN 512
190 #define MAX_LOCAL_BUFSIZE 128
191 #define DBUS_PATH "/setting/dbus_handler"
192 #define DBUS_SIGNAL_INTERFACE "org.tizen.setting.signal"
193
194 static char* s_pkg_name;
195
196 static char* substring(const char* str, size_t begin, size_t len)
197 {
198   if (str == 0 || strlen(str) == 0 || strlen(str) < begin || strlen(str) < (begin+len))
199     return 0;
200
201   return strndup(str + begin, len);
202 }
203
204 /**
205  * package ID
206  *
207  * ncbyusjryr.AppSetting --> package ID is ncbyusjryr
208  */
209 static char* get_app_string(char* path)
210 {
211         SETTING_TRACE_BEGIN;
212         char* temp = substring(path, 10, 10/*string size*/);
213         SETTING_TRACE("package ID : >>> %s ",temp );
214         return temp;
215 }
216
217 //------------------------------------------------------
218 // for client - bus
219 static DBusConnection *bus;
220 //------------------------------------------------------
221 static DBusHandlerResult __signal_filter(DBusConnection* conn, DBusMessage* message, void* user_data)
222 {
223     int my_pid = getpid();
224     int sender_pid = 0;
225     char* key = NULL;
226     char* value = NULL;
227
228     DBusError error;
229     dbus_error_init(&error);
230
231         setting_main_appdata *ad = user_data;
232
233         char* pkg_name = get_app_string(ad->plugin_path);
234         s_pkg_name = pkg_name;
235
236     if (dbus_message_is_signal(message, DBUS_SIGNAL_INTERFACE, pkg_name))
237     {
238         if (dbus_message_get_args(message, &error,
239                 DBUS_TYPE_UINT32, &sender_pid,
240                 DBUS_TYPE_STRING, &key,
241                 DBUS_TYPE_STRING, &value,
242                 DBUS_TYPE_INVALID) == FALSE)
243         {
244             SETTING_TRACE_ERROR("Fail to get data : %s", error.message);
245             dbus_error_free(&error);
246             return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
247         }
248     }
249
250     if (sender_pid != 0 && my_pid != sender_pid)
251     {
252         SETTING_TRACE("received key : %s , value : %s", key, value);
253                 //-------------------------------------------------------------
254                 // received key : checkbox1|N/A , value : INT|1
255                 //-------------------------------------------------------------
256                 //char* key = "checkbox1|N/A";
257                 char* ptr = strchr(key, '|');
258
259                 xmlDocPtr doc = NULL;
260                 if (ptr && key)
261                 {
262                         //parsing for : checkbox1|N/A  -> checkbox1
263                         char* key_name = substring(key, 0, strlen(key)-strlen(ptr));
264                         char* val_name = strchr(value, '|');
265                         val_name++;
266
267                         // ad->plugin_path
268                         // access xml file
269                         doc = xmlParseFile(ad->plugin_path);
270                         // generate xml tree
271                         xmlNode *root = xmlDocGetRootElement(doc);
272                         // find a node
273                         bool is_end = false;
274                         __node_finder((PluginNode*)ad->plugin_node, root, key_name ,val_name, &is_end);
275                 }
276                 // update the node
277                 GError *error = NULL;
278
279 #if 0
280                 if(doc != NULL)
281                 {
282                         xmlSaveFormatFile(ad->plugin_path, doc, 1);
283                         // TODO: make sure this is right
284                         xmlFreeDoc(doc);
285                         doc = NULL;
286                         SETTING_TRACE("__cfg_file_write successful");
287                 }
288 #endif
289
290                 // update UI
291     }
292
293     return DBUS_HANDLER_RESULT_HANDLED;
294 }
295
296 static int __send_msg(char* key, char* value)
297 {
298         DBusMessage* message;
299
300         int sender_pid = getpid();
301
302         if (bus == NULL)
303                 return -1;
304
305         if (s_pkg_name == NULL) return -1;
306
307         message = dbus_message_new_signal(DBUS_PATH, DBUS_SIGNAL_INTERFACE, s_pkg_name);
308
309         SETTING_TRACE("Sending message[%s:%s] via dbus", key ,value);
310         if (dbus_message_append_args(message,
311                                 DBUS_TYPE_UINT32, &sender_pid,
312                                 DBUS_TYPE_STRING, &key,
313                                 DBUS_TYPE_STRING, &value,
314                                 DBUS_TYPE_INVALID) == FALSE)
315         {
316                 SETTING_TRACE("Fail to load data error");
317                 return -1;
318         }
319
320         if (dbus_connection_send(bus, message, NULL) == FALSE)
321         {
322                 SETTING_TRACE("Fail to send message");
323                 return -1;
324         }
325
326         dbus_connection_flush(bus);
327         dbus_message_unref(message);
328
329         SETTING_TRACE("[CLIENT] send data signal done");
330
331     return 0;
332 }
333
334
335 static void __send_int_msg(xmlNode* xmlObj, int val)
336 {
337         const char *id = (char*)xmlGetProp(xmlObj, "id");
338         const char *title = (char*)xmlGetProp(xmlObj, "title");
339         char key[MAX_CONTENT_LEN] = {0,};
340         snprintf(key, sizeof(key), "%s|%s", id, title);
341
342         char value[MAX_CONTENT_LEN] = {0,};
343         snprintf(value, sizeof(value), "INT|%d", val);
344         __send_msg(key, value);
345 }
346
347
348 static void __send_string_msg(xmlNode* xmlObj, char *string)
349 {
350         const char *id = (char*)xmlGetProp(xmlObj, "id");
351         const char *title = (char*)xmlGetProp(xmlObj, "title");
352         char key[MAX_CONTENT_LEN] = {0,};
353         snprintf(key, sizeof(key), "%s|%s", id, title);
354
355         char value[MAX_CONTENT_LEN] = {0,};
356         snprintf(value, sizeof(value), "STRING|%s", string);
357         __send_msg(key, value);
358 }
359
360
361 int setting_dbus_handler_init(void* user_data)
362 {
363         SETTING_TRACE_BEGIN;
364         if (bus)
365         {
366                 SETTING_TRACE("already get a bus, need release first.");
367                 setting_dbus_handler_fini();
368         }
369         DBusError error;
370         memset(&error, 0, sizeof(DBusError));
371         char rule[MAX_LOCAL_BUFSIZE + 1] = {0,};
372         dbus_error_init(&error);
373         bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
374         if (!bus)
375         {
376                 SETTING_TRACE("Fail to connect to the D-BUS daemon: %s", error.message);
377                 dbus_error_free(&error);
378                 return -1;
379         }
380
381         dbus_connection_setup_with_g_main(bus, NULL);
382         snprintf(rule, MAX_LOCAL_BUFSIZE, "path='%s',type='signal',interface='%s'", DBUS_PATH, DBUS_SIGNAL_INTERFACE);
383
384         dbus_bus_add_match(bus, rule, &error);
385         if (dbus_error_is_set(&error))
386         {
387                 SETTING_TRACE("Fail to rule set; %s", error.message);
388                 dbus_bus_remove_match(bus, rule, &error);
389                 dbus_error_free(&error);
390                 dbus_connection_close(bus);
391                 bus = NULL;
392                 return -1;
393         }
394
395         if (dbus_connection_add_filter(bus, __signal_filter, user_data, NULL) == FALSE)
396         {
397                 dbus_bus_remove_match(bus, rule, &error);
398                 dbus_error_free(&error);
399                 dbus_connection_close(bus);
400                 bus = NULL;
401                 return -1;
402         }
403
404         SETTING_TRACE("app signal initialized");
405         return 0;
406 }
407
408 int setting_dbus_handler_fini(void)
409 {
410         //do safty checking first.
411         setting_retvm_if(!bus, 0, "!bus");
412         DBusError error;
413         memset(&error, 0, sizeof(DBusError));
414         char rule[MAX_LOCAL_BUFSIZE + 1] = {0, };
415
416         dbus_error_init(&error);
417         //dbus_connection_remove_filter(bus, __signal_filter, NULL);
418         snprintf(rule, MAX_LOCAL_BUFSIZE, "path='%s',type='signal',interface='%s'", DBUS_PATH, DBUS_SIGNAL_INTERFACE);
419         dbus_bus_remove_match(bus, rule, &error);
420
421         if (dbus_error_is_set(&error))
422         {
423                 SETTING_TRACE("Fail to rule unset: %s", error.message);
424                 dbus_error_free(&error);
425                 //return -1;
426         }
427
428         dbus_connection_close(bus);
429         bus = NULL;
430         SETTING_TRACE("app signal finalized");
431         return 0;
432 }
433
434 /////////////////////////////
435 /////////////////////////////
436 /////////////////////////////
437
438 Elm_Genlist_Item_Class itc_layout;
439
440 // write -> update
441 static int __cfg_file_write(Draw_Data *pd)
442 {
443         SETTING_TRACE_BEGIN;
444
445         GError *error = NULL;
446         if(pd->doc != NULL)
447         {
448                 xmlSaveFormatFile(pd->cfg_file, pd->doc, 1);
449                 //xmlFreeDoc(pd->doc);
450                 //pd->doc = NULL;
451                 SETTING_TRACE("__cfg_file_write successful");
452         }
453
454         return TRUE;
455 }
456
457
458 static void ___click_softkey_back_cb(void *data, Evas_Object *obj,
459                                           void *event_info)
460 {
461         SETTING_TRACE_BEGIN;
462         ret_if(!data);
463
464         PluginNode* node = (PluginNode*)data;
465         Draw_Data *pd = node->pd;
466         if (pd->ly_main) {
467                 evas_object_del(pd->ly_main);
468                 pd->ly_main = NULL;
469         }
470
471         setting_plugin_destroy(node);
472
473         pd->scroller = NULL;
474         pd->navi_bar = NULL;
475         pd->cfg_file = NULL;
476
477         pd->root = NULL;
478 }
479
480
481 static void* group_func(void *data, xmlNode *xmlObj)
482 {
483         SETTING_TRACE_BEGIN;
484         ret_if(!data || !xmlObj);
485
486         PluginNode* node = (PluginNode*)data;
487         Draw_Data *pd = node->pd;
488
489         // original code is non-recursive
490 #if 0
491         const char *title = (char*)json_object_get_string_member(jsonObj, "title");
492         (void)setting_create_Gendial_field_titleItem(pd->scroller,
493                                                      &(itc_group_item),
494                                                      title, NULL);
495
496         // non recursive method
497         if (json_object_has_member(jsonObj, "elements"))
498         {
499                 JsonNode* elements_node = json_object_get_member(jsonObj, "elements");
500                 int i;
501                 JsonObject* tempobj;
502                 char* type;
503                 for (i=0; i < json_array_get_length(json_node_get_array(elements_node)); i++)
504                 {
505                         tempobj  = json_array_get_object_element(json_node_get_array(elements_node), i);
506                         type = (char*)json_object_get_string_member(tempobj, "type");
507                         drawer_fp  fp = __drawer_find(type);
508                         if (fp) fp(pd, tempobj); // draw it
509                 }
510         }
511 #else
512         // new code is recursive
513         const char *title = (char*)xmlGetProp(xmlObj, "title");
514         SETTING_TRACE (" >>> GROUP NAME : %s \n", title);
515         (void)setting_create_Gendial_field_titleItem(pd->scroller, &(itc_group_item), title, NULL);
516 #endif
517
518         return NULL;
519 };
520
521
522 static void* __link_list_cb(void *data, Evas_Object *obj, void *event_info)
523 {
524         SETTING_TRACE_BEGIN;
525         ret_if(data == NULL);
526         retm_if(event_info == NULL, "Invalid argument: event info is NULL");
527         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
528         elm_genlist_item_selected_set(item, 0);
529         Setting_GenGroupItem_Data *list_item =
530             (Setting_GenGroupItem_Data *) elm_object_item_data_get(item);
531
532         xmlNode* xmlObj = data;
533         ret_if(!xmlObj);
534         const char *link_file = (char*)xmlGetProp(xmlObj, "value");
535
536         if(!link_file)
537         {
538                 SETTING_TRACE_ERROR("Invalidate liked file");
539                 return;
540         }
541         char file[1024] = {0,};
542         snprintf(file, sizeof(file), "%s/%s", PLUGIN_CFG_DIR, link_file);
543         SETTING_TRACE("file:%s", file);
544
545         PluginNode* plugin_node = setting_plugin_create();
546         setting_plugin_load(plugin_node, (const char *)file);
547
548         //setting_plugin_load(NULL, file);
549
550         return NULL;
551 }
552
553 static void* __launch_list_cb(void *data, Evas_Object *obj, void *event_info)
554 {
555         SETTING_TRACE_BEGIN;
556         ret_if(data == NULL);
557         retm_if(event_info == NULL, "Invalid argument: event info is NULL");
558         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
559         elm_genlist_item_selected_set(item, 0);
560         Setting_GenGroupItem_Data *list_item =
561             (Setting_GenGroupItem_Data *) elm_object_item_data_get(item);
562
563         xmlNode* xmlObj = data;
564         ret_if(!xmlObj);
565         const char *key_str = (char*)xmlGetProp(xmlObj, "id");
566         const char *title_str = (char*)xmlGetProp(xmlObj, "title");
567         const char *appid_str = (char*)xmlGetProp(xmlObj, "appid");
568         const char *operation_str = (char*)xmlGetProp(xmlObj, "operation");
569
570
571         service_h svc = NULL;
572         service_create(&svc);
573         service_set_app_id(svc, appid_str);                                                     // xml property â€“ appid
574         service_set_operation(svc, operation_str);                                              // property : operation
575         service_send_launch_request(svc, NULL, NULL);
576         service_destroy(svc);
577
578         return NULL;
579 }
580
581 static void* label_func(void *data, xmlNode *xmlObj)
582 {
583         SETTING_TRACE_BEGIN;
584         ret_if(!data || !xmlObj);
585         PluginNode* node = (PluginNode*)data;
586         Draw_Data *pd = node->pd;
587
588         const char *title = (char*)xmlGetProp(xmlObj, "title");
589
590         Setting_GenGroupItem_Data *obj =
591                 setting_create_Gendial_field_def(pd->scroller, &(itc_1text),
592                                                  NULL,
593                                                  xmlObj, SWALLOW_Type_INVALID, NULL, NULL,
594                                                  0, title, NULL, NULL);
595
596         return obj;
597 }
598
599 static void* link_func(void *data, xmlNode *xmlObj)
600 {
601         SETTING_TRACE_BEGIN;
602         ret_if(!data || !xmlObj);
603         PluginNode* node = (PluginNode*)data;
604         Draw_Data *pd = node->pd;
605
606         const char *key_str = (char*)xmlGetProp(xmlObj, "id");
607         Setting_GenGroupItem_Data * obj =
608                 setting_create_Gendial_field_def(pd->scroller, &(itc_1text),
609                                                  __link_list_cb,
610                                                  xmlObj, SWALLOW_Type_INVALID, NULL, NULL,
611                                                  0, key_str, NULL, NULL);
612
613         return (void*)obj;
614 };
615
616 static void* launch_func(void *data, xmlNode *xmlObj)
617 {
618         SETTING_TRACE_BEGIN;
619         ret_if(!data || !xmlObj);
620         PluginNode* node = (PluginNode*)data;
621         Draw_Data *pd = node->pd;
622
623         const char *title_str = (char*)xmlGetProp(xmlObj, "title");
624
625         Setting_GenGroupItem_Data * obj =
626                 setting_create_Gendial_field_def(pd->scroller, &(itc_1text),
627                                                  __launch_list_cb,
628                                                  xmlObj, SWALLOW_Type_INVALID, NULL, NULL,
629                                                  0, title_str, NULL, NULL);
630
631         return (void*)obj;
632 };
633
634 static void __slider_stop_cb(void *data, Evas_Object *obj,
635                                     void *event_info)
636 {
637         ret_if(data == NULL || obj == NULL);
638         double val = elm_slider_value_get(obj);
639         SETTING_TRACE("val = %f", val);
640         Setting_GenGroupItem_Data *list_item = data;
641         ret_if(list_item->userdata == NULL);
642
643         xmlNode* xmlObj = list_item->userdata;
644         ret_if(!xmlObj);
645
646         //apply the vconf changes after stopping moving slider..
647         list_item->chk_status = (int)(val + 0.5);
648         elm_slider_value_set(obj, list_item->chk_status);
649
650         SETTING_TRACE(" slider after ---> val = %d", (int) list_item->chk_status);
651
652         // int -> double -> xmlChar*
653         xmlAttrPtr newattr;
654         char buf[10];
655         sprintf(buf, "%d", (int) list_item->chk_status);
656         newattr = xmlSetProp(xmlObj, "value", buf);
657
658         __send_int_msg(xmlObj, list_item->chk_status);
659         __cfg_file_write((Draw_Data *)list_item->belongs_to);
660 }
661
662
663 static void* slider_func(void *data, xmlNode *xmlObj)
664 {
665         SETTING_TRACE_BEGIN;
666         ret_if(!data || !xmlObj);
667         PluginNode* node = (PluginNode*)data;
668         Draw_Data *pd = node->pd;
669
670         // type casting
671         const char *title = (char*)xmlGetProp(xmlObj, "title");
672
673         SETTING_TRACE (" >>> [slider input] min=%s max=%s value=%s ",(char*)xmlGetProp(xmlObj, "min"), (char*)xmlGetProp(xmlObj, "max"), (char*)xmlGetProp(xmlObj, "value"));
674
675         int value = atoi((char*)xmlGetProp(xmlObj, "value"));
676         int min = atoi((char*)xmlGetProp(xmlObj, "min"));
677         int max = atoi((char*)xmlGetProp(xmlObj, "max"));
678
679         SETTING_TRACE ("[slider input] min=%d max=%d value=%d ", min, max, value);
680
681         setting_create_Gendial_itc("dialogue/1text.1icon.5", &(itc_layout));
682         Setting_GenGroupItem_Data *list_item =
683             setting_create_Gendial_field_def(pd->scroller, &(itc_layout), NULL,
684                                              NULL,
685                                              SWALLOW_Type_LAYOUT_SLIDER,
686                                              IMG_SENSITIVITY_ICON_01,
687                                              IMG_SENSITIVITY_ICON_02, value,
688                                              title, NULL, NULL);
689         if (list_item) {
690                 list_item->win_main = NULL;
691                 list_item->evas = NULL;
692                 list_item->isIndicatorVisible = true;
693                 list_item->slider_min = min;
694                 list_item->slider_max = max;
695                 list_item->userdata = xmlObj;
696                 list_item->stop_change_cb = __slider_stop_cb;
697                 list_item->belongs_to = (int)pd;
698         }
699
700         g_list_item = list_item;
701
702         return (void*)list_item;
703 };
704
705 /*
706   elm_object_item_data_set(item_to_update->item, item_to_update);
707   elm_genlist_item_update(item_to_update->item);
708 */
709 static void* navigationbar_func(void *data, xmlNode *xmlObj)
710 {
711 #if 1
712         SETTING_TRACE_BEGIN;
713         ret_if(!data || !xmlObj);
714
715         PluginNode* node = (PluginNode*)data;
716         Draw_Data *pd = node->pd;
717
718         //----------------------------------------------------------------
719         // [DATA] title, btn[0], btn[1]
720         const char *title = (char*)xmlGetProp(xmlObj, "title");
721         char *btn[2] = {0, };
722
723         // find child nodes named 'elements'
724         if (xmlObj->children) {
725                 xmlNode* cur = xmlObj->children;
726                 int i =0;
727                 while (cur != NULL)
728                 {
729                         if (!xmlStrcmp(cur->name, (const xmlChar*)"button")) {
730                                 btn[i] = xmlGetProp(cur, "title");
731                                 SETTING_TRACE("------>>> node type : Element, name=%s id=%s / btn[%d] = %s ",
732                                                                 cur->name,xmlGetProp(cur, "id"),
733                                                                 i,
734                                                                 btn[i]);
735                                 i++;
736                         }
737                         cur = cur->next;
738                 }
739         }
740         //----------------------------------------------------------------
741         // [UI] with DATA
742         pd->ly_main = setting_create_layout_navi_bar_genlist(pd->win_get,
743                                                    pd->win_get,
744                                                    _(title),
745                                                    _(btn[1]), _(btn[0]),
746                                                    ___click_softkey_back_cb,
747                                                    ___click_softkey_back_cb, data, &pd->scroller,
748                                                    &(pd->navi_bar));
749
750 #endif
751         return NULL;
752 };
753
754
755 static void __check_mouse_up_cb(void *data, Evas_Object *obj,
756                                              void *event_info)
757 {
758         /* error check */
759         SETTING_TRACE_BEGIN;
760         setting_retm_if(data == NULL, "Data parameter is NULL");
761
762         retm_if(event_info == NULL, "Invalid argument: event info is NULL");
763         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
764         elm_genlist_item_selected_set(item, 0);
765         Setting_GenGroupItem_Data *list_item =
766             (Setting_GenGroupItem_Data *) elm_object_item_data_get(item);
767
768         SETTING_TRACE("clicking item[%s]", _(list_item->keyStr));
769
770         int old_status = elm_check_state_get(list_item->eo_check);
771         list_item->chk_status = !old_status;
772         elm_check_state_set(list_item->eo_check, list_item->chk_status);
773
774         xmlNode *xmlObj = data;
775         xmlAttrPtr newattr;
776         newattr = xmlSetProp(xmlObj, "state", xmlXPathCastNumberToString(list_item->chk_status));
777
778         __send_int_msg(xmlObj, list_item->chk_status);
779         __cfg_file_write((Draw_Data *)list_item->belongs_to);
780 }
781
782
783 static void __chk_btn_cb(void *data, Evas_Object *obj,
784                                              void *event_info)
785 {
786         SETTING_TRACE_BEGIN;
787         /* error check */
788         retm_if(data == NULL, "Data parameter is NULL");
789         Setting_GenGroupItem_Data *list_item = (Setting_GenGroupItem_Data *) data;
790
791         xmlNode* xmlObj = list_item->userdata;
792         ret_if(!xmlObj);
793         list_item->chk_status = elm_check_state_get(obj);       /*  for genlist update status */
794
795         xmlAttrPtr newattr;
796         if (list_item->chk_status == 1) {
797                 newattr = xmlSetProp(xmlObj, "value", "true");
798         } else if (list_item->chk_status == 0) {
799                 newattr = xmlSetProp(xmlObj, "value", "false");
800         } else {
801                 newattr = xmlSetProp(xmlObj, "value", "false");
802         }
803
804         const char *id = (char*)xmlGetProp(xmlObj, "id");
805         const char *title = (char*)xmlGetProp(xmlObj, "title");
806         //SETTING_TRACE(" >>>> id:%s , title:%s", id, title);
807         __send_int_msg(xmlObj, list_item->chk_status);
808         __cfg_file_write((Draw_Data *)list_item->belongs_to);
809         return;
810 }
811
812
813 static void* checkbox_func(void *data, xmlNode *xmlObj)
814 {
815         SETTING_TRACE_BEGIN;
816         ret_if(!data || !xmlObj);
817
818         PluginNode* node = (PluginNode*)data;
819         Draw_Data *pd = node->pd;
820
821         // [DATA] title, value
822         const char *title = (char*)xmlGetProp(xmlObj, "title");
823
824         // true / false
825         char* value = (char*)xmlGetProp(xmlObj, "value");
826
827         int ival = -1;
828
829         if ( 0 == safeStrCmp(value, "true")) {
830                 ival = 1;
831         } else if ( 0 == safeStrCmp(value, "false"))  {
832                 ival = 0;
833         } else {
834                 ival = 0;       // default : false (0)
835         }
836
837         // title, value, xmlObj
838         Setting_GenGroupItem_Data *list_item =
839                 setting_create_Gendial_field_def(pd->scroller,
840                                           &(itc_1text_1icon),
841                                           __check_mouse_up_cb,
842                                           xmlObj,
843                                           SWALLOW_Type_1TOGGLE,
844                                           NULL, NULL,
845                                           ival,
846                                           title,
847                                           NULL,
848                                           __chk_btn_cb);
849         if(list_item) {
850                 list_item->userdata = xmlObj;
851                 list_item->belongs_to = (int) pd;
852                 SETTING_TRACE("pd:%p,list_item->belongs_to:%d", pd, list_item->belongs_to);
853         }
854
855         return list_item;
856 }
857
858
859 static void __entry_unfocus_cb(void *data, Evas_Object *obj, void *event_info)
860 {
861         SETTING_TRACE_BEGIN;
862         retm_if(!data || !obj, "Data parameter is NULL");
863
864         setting_hide_input_pannel_cb(obj);
865         const char *entry_str = elm_entry_entry_get(obj);
866         char *entry_str_utf8 = NULL;
867         entry_str_utf8 = elm_entry_markup_to_utf8(entry_str);
868
869         Setting_GenGroupItem_Data *list_item = data;
870
871         xmlNode* xmlObj = list_item->userdata;
872         ret_if(!xmlObj);
873         xmlAttrPtr newattr;
874         const char *title = (char*)xmlSetProp(xmlObj, "value",entry_str_utf8);
875
876         __send_string_msg(xmlObj, entry_str_utf8);
877         __cfg_file_write((Draw_Data *)list_item->belongs_to);
878
879         FREE(entry_str_utf8);
880 }
881
882
883 static void __editbox_list_cb(void *data, Evas_Object *obj,
884                                             void *event_info)
885 {
886         SETTING_TRACE_BEGIN;
887         /* error check */
888
889         retm_if(event_info == NULL, "Invalid argument: event info is NULL");
890         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
891         elm_genlist_item_selected_set(item, 0);
892         Setting_GenGroupItem_Data *list_item = (Setting_GenGroupItem_Data *) elm_object_item_data_get(item);
893
894         SETTING_TRACE("clicking item[%s]", _(list_item->keyStr));
895         if (!elm_object_focus_get(list_item->eo_check)) {
896                 elm_object_focus_set(list_item->eo_check, EINA_TRUE);
897         }
898
899         Ecore_IMF_Context *imf_context = (Ecore_IMF_Context *)elm_entry_imf_context_get(list_item->eo_check);
900         setting_retm_if(imf_context == NULL, "imf_context is NULL");
901         ecore_imf_context_input_panel_show(imf_context);
902 }
903
904
905 static void __editbox_changed_cb(void *data, Evas_Object *obj,
906                                        void *event_info)
907 {
908         SETTING_TRACE_BEGIN;
909         retm_if(!data || !obj, "Data parameter is NULL");
910         retm_if(!elm_object_focus_get(obj), "Entry is not focused");
911
912         Setting_GenGroupItem_Data *list_item =
913             (Setting_GenGroupItem_Data *) data;
914
915         const char *entry_str = elm_entry_entry_get(obj);
916         int entry_len = safeStrLen(entry_str);
917         SETTING_TRACE("entry_str:[%s], lenght:%d", entry_str, entry_len);
918
919         G_FREE(list_item->sub_desc);//release first
920         list_item->sub_desc = (char *)g_strdup(entry_str);
921 }
922
923
924 static void* editbox_func(void *data, xmlNode *xmlObj)
925 {
926         SETTING_TRACE_BEGIN;
927         ret_if(!data || !xmlObj);
928
929         PluginNode* node = (PluginNode*)data;
930         Draw_Data *pd = node->pd;
931
932         const char *title = (char*)xmlGetProp(xmlObj, "title");
933         const char *key_str= (char*)xmlGetProp(xmlObj, "value");
934
935         // TODO: minlength
936         // TODO: maxlength
937         Setting_GenGroupItem_Data *list_item =
938             setting_create_Gendial_field_def(pd->scroller, &(itc_1icon),
939                                              __editbox_list_cb,
940                                              pd, SWALLOW_Type_LAYOUT_ENTRY,
941                                              NULL, NULL, 0, title, key_str,
942                                              __editbox_changed_cb);
943         if (list_item) {
944                 list_item->userdata = xmlObj;
945                 list_item->stop_change_cb = __entry_unfocus_cb;
946                 list_item->belongs_to = (int)pd;
947         }
948
949         return list_item;
950 };
951
952
953 static void __expanditem_func_sel_cb(void *data, Evas_Object *obj, void *event_info)
954 {
955         SETTING_TRACE_BEGIN;
956         /* error check */
957         retm_if(event_info == NULL, "Invalid argument: event info is NULL");
958         Elm_Object_Item *subitem = (Elm_Object_Item *) event_info;
959         Elm_Object_Item *parentItem = elm_genlist_item_parent_get(subitem);
960         elm_genlist_item_selected_set(subitem, 0);
961         Setting_GenGroupItem_Data *data_subItem = elm_object_item_data_get(subitem);
962         Setting_GenGroupItem_Data *data_parentItem = elm_object_item_data_get(parentItem);      /* parent data */
963         ret_if(NULL == data_subItem || NULL == data_parentItem);
964
965         elm_radio_value_set(data_subItem->rgd, data_subItem->chk_status);
966
967         data_parentItem->sub_desc = (char *)g_strdup(_(data_subItem->keyStr));
968         elm_object_item_data_set(data_parentItem->item, data_parentItem);
969         elm_genlist_item_update(data_parentItem->item);
970
971         xmlNode* xmlObj = data_parentItem->userdata;
972         ret_if(!xmlObj);
973
974         xmlAttrPtr newattr;
975         //newattr = xmlSetProp(xmlObj, "string", data_parentItem->sub_desc);
976         newattr = xmlSetProp(xmlObj, "value", data_parentItem->sub_desc);
977
978         __send_string_msg(xmlObj, data_parentItem->sub_desc);
979         __cfg_file_write((Draw_Data *)data_parentItem->belongs_to);
980 }
981
982
983 static void __expanditem_func_exp_cb(void *data, Evas_Object *obj, void *event_info)
984 {
985         ret_if(NULL == data || NULL == event_info);
986         SETTING_TRACE_BEGIN;
987
988         PluginNode* node = (PluginNode*)data;
989         Draw_Data *pd = node->pd;
990
991         Elm_Object_Item *parentItem = event_info;       /* parent item */
992         Setting_GenGroupItem_Data *data_parentItem = elm_object_item_data_get(parentItem);      /* parent data */
993         Evas_Object *scroller = elm_object_item_widget_get(parentItem);
994
995
996         xmlNode *xmlObj = data_parentItem->userdata;
997         //char *value = (char*)xmlGetProp(xmlObj, "string");
998         char *value = (char*)xmlGetProp(xmlObj, "value");
999         SETTING_TRACE(">>> value = %s", value);
1000         int i=0;
1001         Evas_Object *rgd = NULL;
1002
1003         if (xmlObj->children && !data_parentItem->rgd) {//to protect from entering repeatly
1004                 xmlNode* cur = xmlObj->children;
1005
1006                 rgd = elm_radio_add(scroller);
1007                 elm_radio_value_set(rgd, -1);
1008
1009                 int i;
1010                 char *type;
1011                 char *subitem_title = NULL;
1012                 int subitem_index = 0;
1013                 int sel_idx = -1;
1014
1015                 while (cur != NULL) {
1016                         if (!xmlStrcmp(cur->name, (const xmlChar*)"expanditem")) {
1017                                 type = (char*)xmlGetProp(cur, "type");
1018                                 if (0 == safeStrCmp(type, "radio")) {
1019                                         subitem_title = (char*)xmlGetProp(cur, "title");
1020                                         Setting_GenGroupItem_Data *list_item =
1021                                                                                         setting_create_Gendial_exp_sub_field(scroller,
1022                                                                                                         &(itc_1icon_1text_sub),
1023                                                                                                         __expanditem_func_sel_cb, NULL, parentItem,
1024                                                                                                         SWALLOW_Type_1RADIO, rgd,
1025                                                                                                         subitem_index,
1026                                                                                                         subitem_title, NULL);
1027
1028                                         // SETTING_TRACE(">>> value = %s, subitem_title = %s ", value, subitem_title);
1029
1030                                         if (0 == safeStrCmp(value, subitem_title)) {
1031                                                 sel_idx = subitem_index;
1032                                                 SETTING_TRACE("%d is selected in Radio Group", sel_idx);
1033                                         }
1034                                         data_parentItem->childs = eina_list_append(data_parentItem->childs, list_item);
1035                                         subitem_index++;
1036
1037                                 } else {
1038                                         SETTING_TRACE("invalid type[:%s]", type);
1039                                 }
1040
1041                                 i++;
1042                         }
1043                         cur = cur->next;
1044                 }
1045
1046                 // value set
1047                 elm_radio_value_set(rgd, sel_idx);
1048                 data_parentItem->rgd = rgd;//protecting condition
1049         }
1050 }
1051
1052
1053 static void __expanditem_func_smart_cb(void *data, Evas_Object *obj, void *event_info)
1054 {
1055         ret_if(data == NULL || event_info == NULL);
1056         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
1057         Setting_GenGroupItem_Data *data_item = elm_object_item_data_get(item);
1058         char *cb_type = data;
1059
1060         if (0 == safeStrCmp(cb_type, "contracted")) {
1061                 data_item->rgd = NULL;
1062                 elm_genlist_item_subitems_clear(item);
1063         }
1064 }
1065
1066
1067 static void* settings_func(void *data, xmlNode *xmlObj)
1068 {
1069         return NULL;
1070 }
1071
1072 // <setting>
1073 static void* setting_func(void *data, xmlNode *xmlObj)
1074 {
1075         SETTING_TRACE_BEGIN;
1076         ret_if(!data || !xmlObj);
1077
1078 #if 1/*{{{*/
1079         //Draw_Data *pd = node->pd;
1080         PluginNode* node = (PluginNode*)data;
1081         Draw_Data *pd = node->pd;
1082
1083         //----------------------------------------------------------------
1084         // [DATA] title, btn[0], btn[1]
1085         const char *title = (char*)xmlGetProp(xmlObj, "title");
1086         char *btn[2] = {/* 0 */"OK", /* 1 */"NO"};
1087
1088         // find child nodes named 'elements'
1089         #if 0
1090         if (xmlObj->children) {
1091                 xmlNode* cur = xmlObj->children;
1092                 int i =0;
1093                 while (cur != NULL)
1094                 {
1095                         if (!xmlStrcmp(cur->name, (const xmlChar*)"button")) {
1096                                 btn[i] = xmlGetProp(cur, "title");
1097                                 SETTING_TRACE("------>>> node type : Element, name=%s id=%s / btn[%d] = %s ",
1098                                                                 cur->name,xmlGetProp(cur, "id"),
1099                                                                 i,
1100                                                                 btn[i]);
1101                                 i++;
1102                         }
1103                         cur = cur->next;
1104                 }
1105         }
1106         #endif
1107         //----------------------------------------------------------------
1108         SETTING_TRACE("before setting_create_layout_navi_bar_genlist");
1109         // [UI] with DATA
1110         pd->scroller = elm_genlist_add(pd->win_get);
1111         retvm_if(pd->scroller == NULL, NULL,
1112                  "Cannot set scroller object  as contento of layout");
1113         elm_object_style_set(pd->scroller, "dialogue");
1114         elm_genlist_clear(pd->scroller);        /* first to clear list */
1115
1116         /*  Enabling illume notification property for window */
1117         elm_win_conformant_set(pd->win_get, 1);
1118         Evas_Object *conformant = elm_conformant_add(pd->win_get);
1119         elm_object_style_set(conformant, "internal_layout");    /*  By Kollus. 2011-01-04 */
1120         evas_object_show(conformant);
1121         elm_object_content_set(conformant, pd->scroller);
1122
1123         SETTING_TRACE("_(title):%s", _(title));
1124         pd->ly_main =
1125             setting_create_layout_navi_bar(pd->win_get, pd->win_get,
1126                                            _(title),
1127                                            _("IDS_COM_BODY_BACK"), NULL, NULL,
1128                                            ___click_softkey_back_cb,
1129                                            NULL, NULL,
1130                                            data, conformant,
1131                                            &(pd->navi_bar), NULL);
1132         SETTING_TRACE("after setting_create_layout_navi_bar_genlist");
1133
1134 #endif/*}}}*/
1135         return NULL;
1136 }
1137
1138
1139 static void* expanditem_func(void *data, xmlNode *xmlObj)
1140 {
1141         // DO NOTHING - expandlist draws this area
1142         return NULL;
1143 }
1144
1145 static void* expandlist_func(void *data, xmlNode *xmlObj)
1146 {
1147         SETTING_TRACE_BEGIN;
1148         ret_if(!data || !xmlObj);
1149
1150         PluginNode* node = (PluginNode*)data;
1151         Draw_Data *pd = node->pd;
1152
1153         const char *key_str = (char*)xmlGetProp(xmlObj, "title");
1154         const char *value = (char*)xmlGetProp(xmlObj, "value"); // string -> value
1155
1156         setting_enable_expandable_genlist(pd->scroller, data, __expanditem_func_exp_cb, __expanditem_func_smart_cb);
1157         Setting_GenGroupItem_Data *list_item =
1158             setting_create_Gendial_exp_parent_field(pd->scroller,
1159                                                     &(itc_2text_3_parent),
1160                                                     NULL, NULL,
1161                                                     SWALLOW_Type_INVALID,
1162                                                     key_str,
1163                                                     value);
1164         if (list_item) {
1165                 list_item->userdata = xmlObj;
1166                 list_item->belongs_to = (int)pd;
1167         }
1168
1169         return list_item;
1170 }
1171
1172
1173
1174 static int __node_walker(PluginNode* context, xmlNode* cur)
1175 {
1176         //SETTING_TRACE_BEGIN;
1177         Draw_Data *pd = context->pd;
1178
1179         retv_if(!pd, -1);
1180         xmlNode *cur_node = NULL;
1181         for (cur_node = cur; cur_node;cur_node = cur_node->next) {
1182                 if (cur_node->type == XML_ELEMENT_NODE) {
1183                         SETTING_TRACE("node type : %s id= %s", cur_node->name,xmlGetProp(cur_node, "id"));
1184
1185                         drawer_fp  fp = __drawer_find(cur_node->name);
1186                         if (fp)
1187                         {
1188                                 // type check
1189                                 void* vret = fp(context, cur_node); // draw it
1190
1191                                 if (vret)
1192                                 {
1193                                         Setting_GenGroupItem_Data* genlist_node = (Setting_GenGroupItem_Data* )vret;
1194                                         //SETTING_TRACE("add node to Eina List name : %s, id : ", cur_node->name, xmlGetProp(cur_node, "id"));
1195                                         // add it to the hash table create before.
1196                                         // id, object
1197                                         // add list
1198                                         char* key_name = xmlGetProp(cur_node, "id");
1199                                         eina_hash_add(context->ui_list, strdup(key_name),(void*)genlist_node);
1200                                 }
1201                         }
1202                 }
1203                 __node_walker(context, cur_node->children);     /* RECURSIVE */
1204         }
1205         return 0;
1206 }
1207
1208 /**
1209  * @param id_str [in] "id"
1210  * @param value [in] value to be udpated
1211  * @see __expanditem_func_sel_cb
1212  */
1213 static int __node_finder(PluginNode* context, xmlNode* cur, char* id_str, char* value, bool* is_end)
1214 {
1215         SETTING_TRACE_BEGIN;
1216         xmlNode *cur_node = NULL;
1217
1218         if (*is_end == true) return 0;
1219
1220         for (cur_node = cur; cur_node;cur_node = cur_node->next) {
1221                 if (cur_node->type == XML_ELEMENT_NODE) {
1222
1223                         char* id_name = (char*)xmlGetProp(cur_node, "id");
1224                         if ( id_name && 0 == strcmp(id_str, id_name))
1225                         {
1226                                 SETTING_TRACE("FOUND >>>> %s", id_name);
1227                                 // cur_node     - update xml code
1228                                 xmlAttrPtr newattr = xmlSetProp(cur_node, "value", value);
1229
1230                                 //-----------------------------------------------------------
1231                                 // UI UPDATE
1232                                 // case : slider
1233                                 if ( 0 == strcmp (cur_node->name, "integer"))
1234                                 {
1235                                         SETTING_TRACE(">>>>> UPDATE SLIDER CONTROL %x --- %s ",context->ui_list, id_name);
1236                                         Setting_GenGroupItem_Data* item_to_update = (Setting_GenGroupItem_Data*)eina_hash_find(context->ui_list, id_name);
1237                                         if      (item_to_update)
1238                                         {
1239                                                 item_to_update->chk_status = atoi(value);
1240                                                 SETTING_TRACE(">>>   o-------------0 SLIDER VALUE = %d ", item_to_update->chk_status);
1241
1242                                                 elm_object_item_data_set(item_to_update->item, item_to_update);
1243                                                 elm_genlist_item_update(item_to_update->item);
1244                                         } else {
1245                                                 SETTING_TRACE("item_to_update is NULL");
1246                                         }
1247                                 }
1248                                 // case : toggle
1249                                 if ( 0 == strcmp (cur_node->name, "bool"))
1250                                 {
1251                                         SETTING_TRACE(">>>>> UPDATE TOGGLE CONTROL %x --- %s ",context->ui_list, id_name);
1252                                         Setting_GenGroupItem_Data* item_to_update = (Setting_GenGroupItem_Data*)eina_hash_find(context->ui_list, id_name);
1253                                         if      (item_to_update)
1254                                         {
1255                                                 item_to_update->chk_status = atoi(value);
1256                                                 SETTING_TRACE(">>>   o-------------0 TOGGLE VALUE = %d ", item_to_update->chk_status);
1257
1258                                                 elm_object_item_data_set(item_to_update->item, item_to_update);
1259                                                 elm_genlist_item_update(item_to_update->item);
1260                                         } else {
1261                                                 SETTING_TRACE("item_to_update is NULL");
1262                                         }
1263                                 }
1264                                 // case : edit control
1265                                 if ( 0 == strcmp (cur_node->name, "string"))
1266                                 {
1267                                         SETTING_TRACE(">>>>> UPDATE EDIT CONTROL CONTROL %x --- %s ",context->ui_list, id_name);
1268                                         Setting_GenGroupItem_Data* item_to_update = (Setting_GenGroupItem_Data*)eina_hash_find(context->ui_list, id_name);
1269                                         if      (item_to_update)
1270                                         {
1271                                                 char* old_string = item_to_update->sub_desc;
1272                                                 item_to_update->sub_desc = strdup(value);
1273                                                 SETTING_TRACE(">>>   o-------------0 STRING VALUE = %s ", value);
1274
1275                                                 // free old string
1276
1277                                                 elm_object_item_data_set(item_to_update->item, item_to_update);
1278                                                 elm_genlist_item_update(item_to_update->item);
1279
1280                                         } else {
1281                                                 SETTING_TRACE("item_to_update is NULL");
1282                                         }
1283                                 }
1284                                 // case : expand list
1285                                 // parent
1286                                 //    child1
1287                                 //    child2
1288                                 //    child3
1289                                 //    child4
1290                                 //-----------------------------------------------------------
1291                                 if ( 0 == strcmp (cur_node->name, "expandlist"))
1292                                 {
1293                                         SETTING_TRACE(">>>>> UPDATE EXPAND LIST CONTROL %x --- %s ",context->ui_list, id_name);
1294                                         Setting_GenGroupItem_Data* item_to_update = (Setting_GenGroupItem_Data*)eina_hash_find(context->ui_list, id_name);
1295                                         if      (item_to_update)
1296                                         {
1297                                                 char* old_string = item_to_update->sub_desc;
1298                                                 item_to_update->sub_desc = strdup(value);
1299                                                 SETTING_TRACE(">>>   o-------------0 EXPAND LIST VALUE = %s ", value);
1300
1301                                                 // free old string
1302                                                 // string update
1303                                                 elm_object_item_data_set(item_to_update->item, item_to_update);
1304                                                 elm_genlist_item_update(item_to_update->item);
1305
1306                                                 // TODO: need to update child elements
1307                                                 // item_to_update->childs ---> expanded list
1308                                                 if (item_to_update->childs)
1309                                                 {
1310                                                         Eina_List *li = item_to_update->childs;
1311                                                         int radio_index = 0;
1312                                                         while(li)
1313                                                         {
1314                                                                 Setting_GenGroupItem_Data* node = eina_list_data_get(li);
1315                                                                 // do something more
1316                                                                 // SETTING_TRACE(">>> RADIO LIST STRING VALUE = %s ", node->keyStr);
1317                                                                 // set position of radio button
1318                                                                 if (strcmp(node->keyStr, value) == 0)
1319                                                                 {
1320                                                                         elm_radio_value_set(node->rgd, radio_index);
1321                                                                 }
1322                                                                 elm_object_item_data_set(item_to_update->item, item_to_update);
1323                                                                 elm_genlist_item_update(item_to_update->item);
1324
1325                                                                 // go next
1326                                                                 li = eina_list_next(li);
1327                                                                 radio_index++;
1328                                                         }
1329
1330                                                 }
1331                                         } else {
1332                                                 SETTING_TRACE("item_to_update is NULL");
1333                                         }
1334                                 }
1335
1336                                 *is_end = true;
1337                         }
1338                 }
1339                 __node_finder(context, cur_node->children, id_str, value, is_end);      /* RECURSIVE */
1340         }
1341         return 0;
1342 }
1343
1344 static unsigned int _plugin_string_key_length(const char*key)
1345 {
1346         if (!key)
1347                 return 0;
1348
1349         return (int)strlen(key) + 1;
1350 }
1351
1352 static int _plugin_string_key_cmp(const char* key1, int key1_length,
1353                                                                         const char* key2, int key2_length)
1354 {
1355         return strcmp(key1, key2);
1356 }
1357
1358 static void _plugin_entry_free_cb(void* data)
1359 {
1360     Setting_GenGroupItem_Data* node = (Setting_GenGroupItem_Data*) data;
1361         if (node->childs)
1362         {
1363                 eina_list_free(node->childs);
1364                 node->childs = NULL;
1365         }
1366 }
1367
1368 //static PluginNode* g_context;
1369
1370 PluginNode* setting_plugin_create()
1371 {
1372         PluginNode *node = calloc(1, sizeof(PluginNode));
1373
1374         Draw_Data *pd = calloc(1, sizeof(Draw_Data));
1375         setting_retvm_if(!pd, -1, "Create Draw_Data obj failed");
1376         //eina_init();
1377
1378         node->pd = pd;
1379         node->ui_list = eina_hash_new(EINA_KEY_LENGTH(_plugin_string_key_length),
1380                                                                   EINA_KEY_CMP(_plugin_string_key_cmp),
1381                                                                   EINA_KEY_HASH(eina_hash_superfast),
1382                                                                   _plugin_entry_free_cb,
1383                                                                   5); // 2^5
1384
1385         return node;
1386 }
1387
1388 void setting_plugin_destroy(PluginNode* node)
1389 {
1390         SETTING_TRACE_BEGIN;
1391         if (node) {
1392                 SETTING_TRACE("node is NOT NULL")
1393                 if (node->pd) {
1394                         SETTING_TRACE("node->pd is NOT NULL")
1395                         if(node->pd->doc != NULL) {
1396                                 xmlSaveFormatFile(node->plugin_path, node->pd->doc, 1);
1397                                 xmlFreeDoc(node->pd->doc);
1398                                 node->pd->doc = NULL;
1399                                 SETTING_TRACE("__cfg_file_write successful");
1400                         }
1401
1402                         free(node->pd);
1403                         node->pd = NULL;
1404                 }
1405
1406                 if (node->ui_list) {
1407                         eina_hash_free(node->ui_list);
1408                         node->ui_list = NULL;
1409                 }
1410                 free(node);
1411                 node = NULL;
1412         }
1413 }
1414
1415
1416 static Eina_Bool _plugin_foreach_cb(const Eina_Hash *hash, const void*key, void* data, void* fdata)
1417 {
1418     Setting_GenGroupItem_Data* node = (Setting_GenGroupItem_Data*) data;
1419         SETTING_TRACE("%s --- %s ", (char*)key, node->keyStr);
1420         return EINA_TRUE;
1421 }
1422
1423
1424 void setting_plugin_debug(PluginNode* context)
1425 {
1426 //      SETTING_TRACE("HASH TABLE -------------------------------------");
1427         eina_hash_foreach(context->ui_list,_plugin_foreach_cb, NULL);
1428 //      SETTING_TRACE("HASH TABLE -------------------------------------");
1429
1430 }
1431
1432 void setting_plugin_update(PluginNode* context)
1433 {
1434     Eina_List *li = context->ui_list;
1435
1436     while (li) {
1437         Setting_GenGroupItem_Data* node = (Setting_GenGroupItem_Data*) eina_list_data_get(li);
1438         if (node) {
1439             // SETTING_TRACE(" ---> keyStr : %s , swallow type : %d  ", node->keyStr, node->swallow_type);
1440                         Setting_GenGroupItem_Data* item_to_update = NULL;
1441                         item_to_update = node;
1442                         elm_object_item_data_set(item_to_update->item, item_to_update);
1443                         elm_genlist_item_update(item_to_update->item);
1444         }
1445         li = eina_list_next(li);
1446         }
1447 }
1448
1449
1450 bool setting_plugin_load(PluginNode* context, const char *cfg_file)
1451 {
1452         SETTING_TRACE("cfg_file:%s", cfg_file)
1453         if (isEmptyStr(cfg_file) || 0 != access(cfg_file, R_OK|W_OK|F_OK ))
1454         {
1455                 SETTING_TRACE_ERROR(" error occured : access \n");
1456                 return FALSE;
1457         }
1458         context->pd->cfg_file = cfg_file;
1459         context->pd->win_get = (Evas_Object *) ug_get_window();
1460
1461         GError *error = NULL;
1462
1463         context->pd->doc = xmlParseFile(cfg_file);
1464         context->pd->root = xmlDocGetRootElement(context->pd->doc);
1465
1466         // TODO: error handler here
1467         __node_walker(context, context->pd->root);
1468
1469         // debug message
1470         setting_plugin_debug(context);
1471         return true;
1472 }
1473
1474