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