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