new release for RSA
[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 #include <libxml/xmlmemory.h>
27 #include <libxml/parser.h>
28
29 #include <setting-debug.h>
30 #include <setting-common-general-func.h>
31 #include <setting-common-draw-widget.h>
32
33 #include <setting-plugin.h>
34
35 /*
36  * UI draw handler table : _g_draw_list
37  *  - contains Object_Drawer typed object.
38  */
39 Eina_List *_g_drawer_list = NULL;
40
41 typedef void (*drawer_fp)(void *data, xmlNode *xmlObj);
42 static void group_func(void *data, xmlNode *xmlObj);
43 static void link_func(void *data, xmlNode *xmlObj);
44 static void slider_func(void *data, xmlNode *xmlObj);
45 static void navigationbar_func(void *data, xmlNode *xmlObj);
46 static void checkbox_func(void *data, xmlNode *xmlObj);
47 static void editbox_func(void *data, xmlNode *xmlObj);
48 static void expanditem_func(void *data, xmlNode *xmlObj);
49 static void expandlist_func(void *data, xmlNode *xmlObj);
50 static void settings_func(void *data, xmlNode *xmlObj);
51 static void setting_func(void *data, xmlNode *xmlObj);
52
53 // draw handler
54 typedef struct
55 {
56         const char* type;                       // ui type
57         drawer_fp draw;
58 } Object_Drawer;
59
60 static void __drawer_add(const char *type, drawer_fp draw)
61 {
62         Object_Drawer *node = calloc(1, sizeof(Object_Drawer));
63         if (node && type && draw)
64         {
65                 node->type = type;
66                 node->draw = draw;
67
68                 _g_drawer_list = eina_list_append(_g_drawer_list, node);
69         }
70 }
71
72
73 static drawer_fp __drawer_find(char* type)
74 {
75         SETTING_TRACE_BEGIN;
76         Eina_List *check_list = _g_drawer_list;
77         Object_Drawer *list_item = NULL;
78
79         while (check_list) {
80
81                 list_item = NULL;
82                 list_item = (Object_Drawer *) eina_list_data_get(check_list);
83                 if (NULL == list_item)
84                         continue;
85
86                 if (0 == safeStrCmp(list_item->type, type))
87                 {
88                         //SETTING_TRACE("list_item->type:%s", list_item->type);
89                         break;
90                 }
91
92                 check_list = eina_list_next(check_list);
93         }
94         //SETTING_TRACE("list_item:%p", list_item);
95         return list_item ? list_item->draw : NULL;
96 }
97 void setting_drawer_list_init()
98 {SETTING_TRACE_BEGIN;
99         /* <navigationbar> */__drawer_add("navigationbar", navigationbar_func);
100         /* <bool>          */__drawer_add("bool", checkbox_func);
101         /* <string>        */__drawer_add("string", editbox_func);
102         /* <group>         */__drawer_add("group", group_func);
103         /* <integer>       */__drawer_add("integer", slider_func);
104         /* <link           */__drawer_add("link", link_func);
105         /* <extendlist>    */__drawer_add("expandlist", expandlist_func);
106         /* <extenditem>    */__drawer_add("expanditem", expanditem_func);
107         /* <settings>      */__drawer_add("settings", settings_func);
108         /* <setting>       */__drawer_add("setting", setting_func);
109 }
110
111 void setting_drawer_list_fini()
112 {
113         if (_g_drawer_list)
114         {
115                 Object_Drawer *node = NULL;
116                 Eina_List *li = _g_drawer_list;
117                 while (li) {
118                         node = (Object_Drawer *) eina_list_data_get(li);
119                         if (node)
120                         {
121                                 SETTING_TRACE("Deregister %s", node->type);
122                                 FREE(node);
123                         }
124                         li = eina_list_next(li);
125                 }
126                 _g_drawer_list = eina_list_free(_g_drawer_list);
127                 _g_drawer_list = NULL;
128         }
129 }
130
131 /////////////////////////
132 /////////////////////////
133 /////////////////////////
134
135 #define MAX_CONTENT_LEN 512
136 #define MAX_LOCAL_BUFSIZE 128
137 #define DBUS_PATH "/setting/dbus_handler"
138 #define DBUS_SIGNAL_INTERFACE "org.tizen.setting.signal"
139 #define DBUS_SIGNAL "test"
140
141
142 //------------------------------------------------------
143 // for client - bus
144 static DBusConnection *bus;
145 //------------------------------------------------------
146 static DBusHandlerResult __signal_filter(DBusConnection* conn, DBusMessage* message, void* user_data)
147 {
148     int my_pid = getpid();
149     int sender_pid = 0;
150     char* key = NULL;
151     char* value = NULL;
152
153     DBusError error;
154     dbus_error_init(&error);
155
156     if (dbus_message_is_signal(message, DBUS_SIGNAL_INTERFACE, DBUS_SIGNAL))
157     {
158         if (dbus_message_get_args(message, &error,
159                 DBUS_TYPE_UINT32, &sender_pid,
160                 DBUS_TYPE_STRING, &key,
161                 DBUS_TYPE_STRING, &value,
162                 DBUS_TYPE_INVALID) == FALSE)
163         {
164             SETTING_TRACE_ERROR("Fail to get data : %s", error.message);
165             dbus_error_free(&error);
166             return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
167         }
168     }
169
170     if (sender_pid != 0 && my_pid != sender_pid)
171     {
172         SETTING_TRACE("received key : %s , value : %s", key, value);
173     }
174
175     return DBUS_HANDLER_RESULT_HANDLED;
176 }
177
178 static int __send_msg(char* key, char* value)
179 {
180         DBusMessage* message;
181         int sender_pid = getpid();
182
183         if (bus == NULL)
184                 return -1;
185
186         message = dbus_message_new_signal(DBUS_PATH, DBUS_SIGNAL_INTERFACE, DBUS_SIGNAL);
187
188         SETTING_TRACE("Sending message[%s:%s] via dbus", key ,value);
189         if (dbus_message_append_args(message,
190                                 DBUS_TYPE_UINT32, &sender_pid,
191                                 DBUS_TYPE_STRING, &key,
192                                 DBUS_TYPE_STRING, &value,
193                                 DBUS_TYPE_INVALID) == FALSE)
194         {
195                 SETTING_TRACE("Fail to load data error");
196                 return -1;
197         }
198
199         if (dbus_connection_send(bus, message, NULL) == FALSE)
200         {
201                 SETTING_TRACE("Fail to send message");
202                 return -1;
203         }
204
205         dbus_connection_flush(bus);
206         dbus_message_unref(message);
207
208         SETTING_TRACE("[CLIENT] send data signal done");
209
210     return 0;
211 }
212
213
214 static void __send_int_msg(xmlNode* xmlObj, int val)
215 {
216         const char *id = (char*)xmlGetProp(xmlObj, "id");
217         const char *title = (char*)xmlGetProp(xmlObj, "title");
218         char key[MAX_CONTENT_LEN] = {0,};
219         snprintf(key, sizeof(key), "%s|%s", id, title);
220
221         char value[MAX_CONTENT_LEN] = {0,};
222         snprintf(value, sizeof(value), "INT|%d", val);
223         __send_msg(key, value);
224 }
225
226
227 static void __send_string_msg(xmlNode* xmlObj, char *string)
228 {
229         const char *id = (char*)xmlGetProp(xmlObj, "id");
230         const char *title = (char*)xmlGetProp(xmlObj, "title");
231         char key[MAX_CONTENT_LEN] = {0,};
232         snprintf(key, sizeof(key), "%s|%s", id, title);
233
234         char value[MAX_CONTENT_LEN] = {0,};
235         snprintf(value, sizeof(value), "STRING|%s", string);
236         __send_msg(key, value);
237 }
238
239
240 int setting_dbus_handler_init(void)
241 {
242         SETTING_TRACE_BEGIN;
243     DBusError error;
244     char rule[MAX_LOCAL_BUFSIZE];
245
246     dbus_error_init(&error);
247     bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
248     if (!bus)
249     {
250         SETTING_TRACE("Fail to connect to the D-BUS daemon: %s", error.message);
251         dbus_error_free(&error);
252         return -1;
253     }
254
255     dbus_connection_setup_with_g_main(bus, NULL);
256     snprintf(rule, MAX_LOCAL_BUFSIZE, "path='%s',type='signal',interface='%s'", DBUS_PATH, DBUS_SIGNAL_INTERFACE);
257
258     dbus_bus_add_match(bus, rule, &error);
259     if (dbus_error_is_set(&error))
260     {
261         SETTING_TRACE("Fail to rule set; %s", error.message);
262         dbus_error_free(&error);
263         return -1;
264     }
265
266     if (dbus_connection_add_filter(bus, __signal_filter, NULL, NULL) == FALSE)
267     {
268         return -1;
269     }
270
271     SETTING_TRACE("app signal initialized");
272
273     return 0;
274 }
275
276
277 int setting_dbus_handler_fini(void)
278 {
279     DBusError error;
280     char rule[MAX_LOCAL_BUFSIZE];
281
282     dbus_error_init(&error);
283     dbus_connection_remove_filter(bus, __signal_filter, NULL);
284     snprintf(rule, MAX_LOCAL_BUFSIZE, "path='%s',type='signal',interface='%s'", DBUS_PATH, DBUS_SIGNAL_INTERFACE);
285     dbus_bus_remove_match(bus, rule, &error);
286
287     if (dbus_error_is_set(&error))
288     {
289         SETTING_TRACE("Fail to rule unset: %s", error.message);
290         dbus_error_free(&error);
291         return -1;
292     }
293
294     dbus_connection_close(bus);
295     SETTING_TRACE("app signal finalized");
296     return 0;
297 }
298
299 /////////////////////////////
300 /////////////////////////////
301 /////////////////////////////
302
303 Elm_Genlist_Item_Class itc_layout;
304
305 // draw handler
306 typedef struct
307 {
308         xmlDocPtr doc;
309         xmlNode *root;
310
311         const char *cfg_file;
312         Evas_Object *win_get;
313         Evas_Object *ly_main;
314         Evas_Object *scroller;
315         Evas_Object *navi_bar;
316 } Draw_Data;
317
318
319 // write -> update
320 static int __cfg_file_write(Draw_Data *pd)
321 {
322         SETTING_TRACE_BEGIN;
323
324         GError *error = NULL;
325         if(pd->doc != NULL)
326         {
327                 xmlSaveFormatFile(pd->cfg_file, pd->doc, 1);
328                 // TODO: make sure this is right
329                 //xmlFreeDoc(pd->doc);
330                 //pd->doc = NULL;
331                 SETTING_TRACE("__cfg_file_write successful");
332         }
333
334         return TRUE;
335 }
336
337
338 static void ___click_softkey_back_cb(void *data, Evas_Object *obj,
339                                           void *event_info)
340 {
341         SETTING_TRACE_BEGIN;
342         ret_if(!data);
343         Draw_Data *pd = data;
344         if (pd->ly_main) {
345                 evas_object_del(pd->ly_main);
346                 pd->ly_main = NULL;
347         }
348
349         pd->scroller = NULL;
350         pd->navi_bar = NULL;
351         pd->cfg_file = NULL;
352
353         pd->root = NULL;
354 }
355
356
357 static void group_func(void *data, xmlNode *xmlObj)
358 {
359         SETTING_TRACE_BEGIN;
360         ret_if(!data || !xmlObj);
361         Draw_Data *pd = data;
362
363         // original code is non-recursive
364 #if 0
365         const char *title = (char*)json_object_get_string_member(jsonObj, "title");
366         (void)setting_create_Gendial_field_titleItem(pd->scroller,
367                                                      &(itc_group_item),
368                                                      title, NULL);
369
370         // non recursive method
371         if (json_object_has_member(jsonObj, "elements"))
372         {
373                 JsonNode* elements_node = json_object_get_member(jsonObj, "elements");
374                 int i;
375                 JsonObject* tempobj;
376                 char* type;
377                 for (i=0; i < json_array_get_length(json_node_get_array(elements_node)); i++)
378                 {
379                         tempobj  = json_array_get_object_element(json_node_get_array(elements_node), i);
380                         type = (char*)json_object_get_string_member(tempobj, "type");
381                         drawer_fp  fp = __drawer_find(type);
382                         if (fp) fp(pd, tempobj); // draw it
383                 }
384         }
385 #else
386         // new code is recursive
387         const char *title = (char*)xmlGetProp(xmlObj, "title");
388         SETTING_TRACE (" >>> GROUP NAME : %s \n", title);
389         (void)setting_create_Gendial_field_titleItem(pd->scroller, &(itc_group_item), title, NULL);
390 #endif
391 };
392
393
394 static void __link_list_cb(void *data, Evas_Object *obj, void *event_info)
395 {
396         ret_if(data == NULL);
397         retm_if(event_info == NULL, "Invalid argument: event info is NULL");
398         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
399         elm_genlist_item_selected_set(item, 0);
400         Setting_GenGroupItem_Data *list_item =
401             (Setting_GenGroupItem_Data *) elm_object_item_data_get(item);
402
403         xmlNode* xmlObj = data;
404         ret_if(!xmlObj);
405         const char *link_file = (char*)xmlGetProp(xmlObj, "value");
406
407         if(!link_file)
408         {
409                 SETTING_TRACE_ERROR("Invalidate liked file");
410                 return;
411         }
412         char file[1024] = {0,};
413         snprintf(file, sizeof(file), "%s/%s", PLUGIN_CFG_DIR, link_file);
414         SETTING_TRACE("file:%s", file);
415
416         setting_plugin_load(file);
417 }
418
419
420 static void link_func(void *data, xmlNode *xmlObj)
421 {
422         SETTING_TRACE_BEGIN;
423         ret_if(!data || !xmlObj);
424         Draw_Data *pd = data;
425         const char *key_str = (char*)xmlGetProp(xmlObj, "id");
426
427         setting_create_Gendial_field_def(pd->scroller, &(itc_1text),
428                                          __link_list_cb,
429                                          xmlObj, SWALLOW_Type_INVALID, NULL, NULL,
430                                          0, key_str, NULL, NULL);
431 };
432
433
434 static void __slider_stop_cb(void *data, Evas_Object *obj,
435                                     void *event_info)
436 {
437         ret_if(data == NULL || obj == NULL);
438         double val = elm_slider_value_get(obj);
439         SETTING_TRACE("val = %f", val);
440         Setting_GenGroupItem_Data *list_item = data;
441         ret_if(list_item->userdata == NULL);
442
443         xmlNode* xmlObj = list_item->userdata;
444         ret_if(!xmlObj);
445
446         //apply the vconf changes after stopping moving slider..
447         list_item->chk_status = (int)(val + 0.5);
448         elm_slider_value_set(obj, list_item->chk_status);
449
450         SETTING_TRACE(" slider after ---> val = %d", (int) list_item->chk_status);
451
452         // int -> double -> xmlChar*
453         xmlAttrPtr newattr;
454         char buf[10];
455         sprintf(buf, "%d", (int) list_item->chk_status);
456         newattr = xmlSetProp(xmlObj, "value", buf);
457
458         __send_int_msg(xmlObj, list_item->chk_status);
459         __cfg_file_write((Draw_Data *)list_item->belongs_to);
460 }
461
462
463 static void slider_func(void *data, xmlNode *xmlObj)
464 {
465         SETTING_TRACE_BEGIN;
466         ret_if(!data || !xmlObj);
467         Draw_Data *pd = data;
468
469         // type casting
470         const char *title = (char*)xmlGetProp(xmlObj, "title");
471
472         SETTING_TRACE (" >>> [slider input] min=%s max=%s value=%s ",(char*)xmlGetProp(xmlObj, "min"), (char*)xmlGetProp(xmlObj, "max"), (char*)xmlGetProp(xmlObj, "value"));
473
474         int value = atoi((char*)xmlGetProp(xmlObj, "value"));
475         int min = atoi((char*)xmlGetProp(xmlObj, "min"));
476         int max = atoi((char*)xmlGetProp(xmlObj, "max"));
477
478         SETTING_TRACE ("[slider input] min=%d max=%d value=%d ", min, max, value);
479
480         setting_create_Gendial_itc("dialogue/1text.1icon.5", &(itc_layout));
481         Setting_GenGroupItem_Data *list_item =
482             setting_create_Gendial_field_def(pd->scroller, &(itc_layout), NULL,
483                                              NULL,
484                                              SWALLOW_Type_LAYOUT_SLIDER,
485                                              IMG_SENSITIVITY_ICON_01,
486                                              IMG_SENSITIVITY_ICON_02, value,
487                                              title, NULL, NULL);
488         if (list_item) {
489                 list_item->win_main = NULL;
490                 list_item->evas = NULL;
491                 list_item->isIndicatorVisible = true;
492                 list_item->slider_min = min;
493                 list_item->slider_max = max;
494                 list_item->userdata = xmlObj;
495                 list_item->stop_change_cb = __slider_stop_cb;
496                 list_item->belongs_to = (int)pd;
497         }
498 };
499
500
501 static void navigationbar_func(void *data, xmlNode *xmlObj)
502 {
503         SETTING_TRACE_BEGIN;
504         ret_if(!data || !xmlObj);
505         Draw_Data *pd = data;
506
507         //----------------------------------------------------------------
508         // [DATA] title, btn[0], btn[1]
509         const char *title = (char*)xmlGetProp(xmlObj, "title");
510         char *btn[2] = {0, };
511
512         // find child nodes named 'elements'
513         if (xmlObj->children) {
514                 xmlNode* cur = xmlObj->children;
515                 int i =0;
516                 while (cur != NULL)
517                 {
518                         if (!xmlStrcmp(cur->name, (const xmlChar*)"button")) {
519                                 btn[i] = xmlGetProp(cur, "title");
520                                 SETTING_TRACE("------>>> node type : Element, name=%s id=%s / btn[%d] = %s ", cur->name,xmlGetProp(cur, "id"), i, btn[i]);
521                                 i++;
522                         }
523                         cur = cur->next;
524                 }
525         }
526         //----------------------------------------------------------------
527         // [UI] with DATA
528         pd->ly_main = setting_create_layout_navi_bar_genlist(pd->win_get,
529                                                    pd->win_get,
530                                                    _(title),
531                                                    _(btn[1]), _(btn[0]),
532                                                    ___click_softkey_back_cb,
533                                                    ___click_softkey_back_cb, pd, &pd->scroller,
534                                                    &(pd->navi_bar));
535 };
536
537
538 static void __check_mouse_up_cb(void *data, Evas_Object *obj,
539                                              void *event_info)
540 {
541         /* error check */
542         SETTING_TRACE_BEGIN;
543         setting_retm_if(data == NULL, "Data parameter is NULL");
544
545         retm_if(event_info == NULL, "Invalid argument: event info is NULL");
546         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
547         elm_genlist_item_selected_set(item, 0);
548         Setting_GenGroupItem_Data *list_item =
549             (Setting_GenGroupItem_Data *) elm_object_item_data_get(item);
550
551         SETTING_TRACE("clicking item[%s]", _(list_item->keyStr));
552
553         int old_status = elm_check_state_get(list_item->eo_check);
554         list_item->chk_status = !old_status;
555         elm_check_state_set(list_item->eo_check, list_item->chk_status);
556
557         xmlNode *xmlObj = data;
558         xmlAttrPtr newattr;
559         newattr = xmlSetProp(xmlObj, "state", xmlXPathCastNumberToString(list_item->chk_status));
560
561         __send_int_msg(xmlObj, list_item->chk_status);
562         __cfg_file_write((Draw_Data *)list_item->belongs_to);
563 }
564
565
566 static void __chk_btn_cb(void *data, Evas_Object *obj,
567                                              void *event_info)
568 {
569         SETTING_TRACE_BEGIN;
570         /* error check */
571         retm_if(data == NULL, "Data parameter is NULL");
572         Setting_GenGroupItem_Data *list_item = (Setting_GenGroupItem_Data *) data;
573
574         xmlNode* xmlObj = list_item->userdata;
575         ret_if(!xmlObj);
576         list_item->chk_status = elm_check_state_get(obj);       /*  for genlist update status */
577
578         xmlAttrPtr newattr;
579         if (list_item->chk_status == 1) {
580                 newattr = xmlSetProp(xmlObj, "value", "true");
581         } else if (list_item->chk_status == 0) {
582                 newattr = xmlSetProp(xmlObj, "value", "false");
583         } else {
584                 newattr = xmlSetProp(xmlObj, "value", "false");
585         }
586
587         const char *id = (char*)xmlGetProp(xmlObj, "id");
588         const char *title = (char*)xmlGetProp(xmlObj, "title");
589         SETTING_TRACE(" >>>> id:%s , title:%s", id, title);
590         __send_int_msg(xmlObj, list_item->chk_status);
591         __cfg_file_write((Draw_Data *)list_item->belongs_to);
592         return;
593 }
594
595
596 static void checkbox_func(void *data, xmlNode *xmlObj)
597 {
598         SETTING_TRACE_BEGIN;
599         ret_if(!data || !xmlObj);
600         Draw_Data *pd = data;
601
602         // [DATA] title, value
603         const char *title = (char*)xmlGetProp(xmlObj, "title");
604
605         // true / false
606         char* value = (char*)xmlGetProp(xmlObj, "value");
607
608         int ival = -1;
609
610         if ( 0 == safeStrCmp(value, "true")) {
611                 ival = 1;
612         } else if ( 0 == safeStrCmp(value, "false"))  {
613                 ival = 0;
614         } else {
615                 ival = 0;       // default : false (0)
616         }
617
618         // title, value, xmlObj
619         Setting_GenGroupItem_Data *list_item =
620                 setting_create_Gendial_field_def(pd->scroller,
621                                           &(itc_1text_1icon),
622                                           __check_mouse_up_cb,
623                                           xmlObj,
624                                           SWALLOW_Type_1TOGGLE,
625                                           NULL, NULL,
626                                           ival,
627                                           title,
628                                           NULL,
629                                           __chk_btn_cb);
630         if(list_item) {
631                 list_item->userdata = xmlObj;
632                 list_item->belongs_to = (int) pd;
633                 SETTING_TRACE("pd:%p,list_item->belongs_to:%d", pd, list_item->belongs_to);
634         }
635 };
636
637
638 static void __entry_unfocus_cb(void *data, Evas_Object *obj, void *event_info)
639 {
640         SETTING_TRACE_BEGIN;
641         retm_if(!data || !obj, "Data parameter is NULL");
642
643         setting_hide_input_pannel_cb(obj);
644         const char *entry_str = elm_entry_entry_get(obj);
645         char *entry_str_utf8 = NULL;
646         entry_str_utf8 = elm_entry_markup_to_utf8(entry_str);
647
648         Setting_GenGroupItem_Data *list_item = data;
649
650         xmlNode* xmlObj = list_item->userdata;
651         ret_if(!xmlObj);
652         xmlAttrPtr newattr;
653         const char *title = (char*)xmlSetProp(xmlObj, "string",entry_str_utf8);
654
655         __send_string_msg(xmlObj, entry_str_utf8);
656         __cfg_file_write((Draw_Data *)list_item->belongs_to);
657
658         FREE(entry_str_utf8);
659 }
660
661
662 static void __editbox_list_cb(void *data, Evas_Object *obj,
663                                             void *event_info)
664 {
665         SETTING_TRACE_BEGIN;
666         /* error check */
667
668         retm_if(event_info == NULL, "Invalid argument: event info is NULL");
669         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
670         elm_genlist_item_selected_set(item, 0);
671         Setting_GenGroupItem_Data *list_item = (Setting_GenGroupItem_Data *) elm_object_item_data_get(item);
672
673         SETTING_TRACE("clicking item[%s]", _(list_item->keyStr));
674         if (!elm_object_focus_get(list_item->eo_check)) {
675                 elm_object_focus_set(list_item->eo_check, EINA_TRUE);
676         }
677
678         Ecore_IMF_Context *imf_context = (Ecore_IMF_Context *)elm_entry_imf_context_get(list_item->eo_check);
679         setting_retm_if(imf_context == NULL, "imf_context is NULL");
680         ecore_imf_context_input_panel_show(imf_context);
681 }
682
683
684 static void __editbox_changed_cb(void *data, Evas_Object *obj,
685                                        void *event_info)
686 {
687         SETTING_TRACE_BEGIN;
688         retm_if(!data || !obj, "Data parameter is NULL");
689         retm_if(!elm_object_focus_get(obj), "Entry is not focused");
690
691         Setting_GenGroupItem_Data *list_item =
692             (Setting_GenGroupItem_Data *) data;
693
694         const char *entry_str = elm_entry_entry_get(obj);
695         int entry_len = safeStrLen(entry_str);
696         SETTING_TRACE("entry_str:[%s], lenght:%d", entry_str, entry_len);
697
698         G_FREE(list_item->sub_desc);//release first
699         list_item->sub_desc = (char *)g_strdup(entry_str);
700 }
701
702
703 static void editbox_func(void *data, xmlNode *xmlObj)
704 {
705         SETTING_TRACE_BEGIN;
706         ret_if(!data || !xmlObj);
707         Draw_Data *pd = data;
708
709         const char *title = (char*)xmlGetProp(xmlObj, "title");
710         const char *key_str= (char*)xmlGetProp(xmlObj, "string");
711
712         Setting_GenGroupItem_Data *list_item =
713             setting_create_Gendial_field_def(pd->scroller, &(itc_1icon),
714                                              __editbox_list_cb,
715                                              pd, SWALLOW_Type_LAYOUT_ENTRY,
716                                              NULL, NULL, 0, title, key_str,
717                                              __editbox_changed_cb);
718         if (list_item) {
719                 list_item->userdata = xmlObj;
720                 list_item->stop_change_cb = __entry_unfocus_cb;
721                 list_item->belongs_to = (int)pd;
722         }
723 };
724
725
726 static void __expanditem_func_sel_cb(void *data, Evas_Object *obj, void *event_info)
727 {
728         SETTING_TRACE_BEGIN;
729         /* error check */
730         retm_if(event_info == NULL, "Invalid argument: event info is NULL");
731         Elm_Object_Item *subitem = (Elm_Object_Item *) event_info;
732         Elm_Object_Item *parentItem = elm_genlist_item_parent_get(subitem);
733         elm_genlist_item_selected_set(subitem, 0);
734         Setting_GenGroupItem_Data *data_subItem = elm_object_item_data_get(subitem);
735         Setting_GenGroupItem_Data *data_parentItem = elm_object_item_data_get(parentItem);      /* parent data */
736         ret_if(NULL == data_subItem || NULL == data_parentItem);
737
738         elm_radio_value_set(data_subItem->rgd, data_subItem->chk_status);
739
740         data_parentItem->sub_desc = (char *)g_strdup(_(data_subItem->keyStr));
741         elm_object_item_data_set(data_parentItem->item, data_parentItem);
742         elm_genlist_item_update(data_parentItem->item);
743
744         xmlNode* xmlObj = data_parentItem->userdata;
745         ret_if(!xmlObj);
746
747         xmlAttrPtr newattr;
748         newattr = xmlSetProp(xmlObj, "string", data_parentItem->sub_desc);
749
750         __send_string_msg(xmlObj, data_parentItem->sub_desc);
751         __cfg_file_write((Draw_Data *)data_parentItem->belongs_to);
752 }
753
754
755 static void __expanditem_func_exp_cb(void *data, Evas_Object *obj, void *event_info)
756 {
757         ret_if(NULL == data || NULL == event_info);
758         SETTING_TRACE_BEGIN;
759         Draw_Data *pd = data;
760         Elm_Object_Item *parentItem = event_info;       /* parent item */
761         Setting_GenGroupItem_Data *data_parentItem = elm_object_item_data_get(parentItem);      /* parent data */
762         Evas_Object *scroller = elm_object_item_widget_get(parentItem);
763
764         xmlNode *xmlObj = data_parentItem->userdata;
765         char *value = (char*)xmlGetProp(xmlObj, "string");
766         int i=0;
767         Evas_Object *rgd = NULL;
768
769         if (xmlObj->children && !data_parentItem->rgd) {//to protect from entering repeatly
770                 xmlNode* cur = xmlObj->children;
771
772                 rgd = elm_radio_add(scroller);
773                 elm_radio_value_set(rgd, -1);
774
775                 int i;
776                 char *type;
777                 char *subitem_title = NULL;
778                 int subitem_index = 0;
779                 int sel_idx = -1;
780
781                 while (cur != NULL) {
782                         if (!xmlStrcmp(cur->name, (const xmlChar*)"expanditem")) {
783                                 type = (char*)xmlGetProp(cur, "type");
784                                 if (0 == safeStrCmp(type, "radio")) {
785                                         subitem_title = (char*)xmlGetProp(cur, "title");
786                                         setting_create_Gendial_exp_sub_field(scroller,
787                                                                                  &(itc_1icon_1text_sub),
788                                                                                  __expanditem_func_sel_cb, NULL, parentItem,
789                                                                                  SWALLOW_Type_1RADIO, rgd,
790                                                                                  subitem_index,
791                                                                                  subitem_title, NULL);
792                                         if (0 == safeStrCmp(value, subitem_title)) {
793                                                 sel_idx = subitem_index;
794                                         }
795                                         subitem_index++;
796                                 } else {
797                                         SETTING_TRACE("invalid type[:%s]", type);
798                                 }
799
800                                 i++;
801                         }
802                         cur = cur->next;
803                 }
804
805                 // value set
806                 elm_radio_value_set(rgd, sel_idx);
807                 data_parentItem->rgd = rgd;//protecting condition
808         }
809 }
810
811
812 static void __expanditem_func_smart_cb(void *data, Evas_Object *obj, void *event_info)
813 {
814         ret_if(data == NULL || event_info == NULL);
815         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
816         Setting_GenGroupItem_Data *data_item = elm_object_item_data_get(item);
817         char *cb_type = data;
818
819         if (0 == safeStrCmp(cb_type, "contracted")) {
820                 data_item->rgd = NULL;
821                 elm_genlist_item_subitems_clear(item);
822         }
823 }
824
825
826 static void settings_func(void *data, xmlNode *xmlObj)
827 {
828         // DO NOTHING
829 }
830
831 // <setting>
832 static void setting_func(void *data, xmlNode *xmlObj)
833 {
834         // DO NOTHING
835 }
836
837
838 static void expanditem_func(void *data, xmlNode *xmlObj)
839 {
840         // DO NOTHING - expandlist draws this area
841 };
842
843
844 static void expandlist_func(void *data, xmlNode *xmlObj)
845 {
846         SETTING_TRACE_BEGIN;
847         ret_if(!data || !xmlObj);
848         Draw_Data *pd = data;
849         const char *key_str = (char*)xmlGetProp(xmlObj, "title");
850         const char *value = (char*)xmlGetProp(xmlObj, "value"); // string -> value
851
852         setting_enable_expandable_genlist(pd->scroller, pd, __expanditem_func_exp_cb, __expanditem_func_smart_cb);
853         Setting_GenGroupItem_Data *list_item =
854             setting_create_Gendial_exp_parent_field(pd->scroller,
855                                                     &(itc_2text_3_parent),
856                                                     NULL, NULL,
857                                                     SWALLOW_Type_INVALID,
858                                                     key_str,
859                                                     value);
860         if (list_item) {
861                 list_item->userdata = xmlObj;
862                 list_item->belongs_to = (int)pd;
863         }
864 };
865
866
867 /////////////
868 static int __node_walker(Draw_Data *pd, xmlNode* cur)
869 {
870         //SETTING_TRACE_BEGIN;
871         retv_if(!pd, -1);
872         xmlNode *cur_node = NULL;
873         for (cur_node = cur; cur_node;cur_node = cur_node->next) {
874                 if (cur_node->type == XML_ELEMENT_NODE) {
875                         SETTING_TRACE("node type : Element, name=%s id=%s", cur_node->name,xmlGetProp(cur_node, "id"));
876
877                         drawer_fp  fp = __drawer_find(cur_node->name);
878                         if (fp)
879                                 fp(pd, cur_node); // draw it
880                 }
881                 __node_walker(pd, cur_node->children);  /* RECURSIVE */
882         }
883         return 0;
884 }
885
886
887 bool setting_plugin_load(const char *cfg_file)
888 {
889         SETTING_TRACE("cfg_file:%s", cfg_file)
890         if (isEmptyStr(cfg_file) || 0 != access(cfg_file, R_OK|W_OK|F_OK ))
891         {
892                 SETTING_TRACE_ERROR(" error occured : access \n");
893                 return FALSE;
894         }
895
896         Draw_Data *pd = calloc(1, sizeof(Draw_Data));
897         setting_retvm_if(!pd, -1, "Create Draw_Data obj failed");
898
899         pd->cfg_file = cfg_file;
900         pd->win_get = (Evas_Object *) ug_get_window();
901         GError *error = NULL;
902
903         pd->doc = xmlParseFile(cfg_file);
904         pd->root = xmlDocGetRootElement(pd->doc);
905         // TODO: error handler here
906         __node_walker(pd, pd->root);
907
908         return TRUE;
909 }
910
911