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