GetValue() API is not working after changing the setting value in IME Setting UG
[apps/home/settings.git] / setting-common / src / setting-common-plugin.c
1 /*
2  * setting
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Flora License, Version 1.1 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://floralicense.org/license/
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an AS IS BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18
19 #include <setting-common-plugin.h>
20 #include <unistd.h>
21 #include <eina_list.h>
22 #include <errno.h>
23 #include <glib.h>
24
25 //#include <libxml/xmlmemory.h>
26 //#include <libxml/parser.h>
27
28 #include <setting-debug.h>
29 #include <setting-common-general-func.h>
30 #include <setting-common-draw-widget.h>
31
32 //extern setting_main_appdata *g_main_ad;
33
34 static Setting_GenGroupItem_Data *g_list_item;  /*TEST*/
35
36 /*
37  * UI draw handler table : _g_draw_list
38  *  - contains Object_Drawer typed object.
39  */
40 static Eina_List *_g_drawer_list = NULL;
41
42 #if 0
43 /**
44  * @return Evas_Object * obj
45  */
46 static void* navigationbar_func(void *data, xmlNode *xmlObj);
47 #endif
48
49 /*
50  * @return void
51  */
52 static void* group_func(void *data, xmlNode *xmlObj);
53
54 /*
55  * @return Setting_GenGroupItem_Data* ptr
56  */
57 static void* link_func(void *data, xmlNode *xmlObj);
58
59 /*
60  * @return Setting_GenGroupItem_Data* ptr
61  */
62 static void* slider_func(void *data, xmlNode *xmlObj);
63
64 /*
65  * @return Setting_GenGroupItem_Data* ptr
66  */
67 static void* label_func(void *data, xmlNode *xmlObj);
68
69 /*
70  * @return Setting_GenGroupItem_Data* ptr
71  */
72 static void* checkbox_func(void *data, xmlNode *xmlObj);
73
74 /*
75  * @return Setting_GenGroupItem_Data* ptr
76  */
77 static void* editbox_func(void *data, xmlNode *xmlObj);
78
79 /*
80  * @return Setting_GenGroupItem_Data* ptr
81  */
82 static void* expandlist_func(void *data, xmlNode *xmlObj);
83
84 /**
85  * @return nothing
86  */
87 static void* expanditem_func(void *data, xmlNode *xmlObj);
88
89 /**
90  * do nothing
91  */
92 static void* settings_func(void *data, xmlNode *xmlObj);
93
94
95 static void* launch_func(void *data, xmlNode *xmlObj);
96
97 /**
98  * do nothing
99  */
100 static void* setting_func(void *data, xmlNode *xmlObj);
101
102 static int __node_walker(PluginNode* context, xmlNode* cur);
103
104 static int __node_finder(PluginNode* context, xmlNode* cur, char* id_str, char* value, bool* is_end);
105
106
107 static void __drawer_add(const char *type, drawer_fp draw)
108 {
109         Object_Drawer *node = calloc(1, sizeof(Object_Drawer));
110         if (node && type && draw)
111         {
112                 node->type = type;
113                 node->draw = draw;
114
115                 _g_drawer_list = eina_list_append(_g_drawer_list, node);
116         }
117         // FREE(node);
118 }
119
120
121 static drawer_fp __drawer_find(char* type)
122 {
123         SETTING_TRACE_BEGIN;
124         SETTING_TRACE("node type:%s", type);
125         Eina_List *check_list = _g_drawer_list;
126         Object_Drawer *list_item = NULL;
127
128         while (check_list) {
129                 list_item = (Object_Drawer *) eina_list_data_get(check_list);
130                 if (NULL == list_item)
131                         continue;
132
133                 if (0 == safeStrCmp(list_item->type, type))
134                 {
135                         //SETTING_TRACE("list_item->type:%s", list_item->type);
136                         break;
137                 }
138                 //if not matched,to check next node.
139                 check_list = eina_list_next(check_list);
140                 list_item = NULL;
141         }
142         //SETTING_TRACE("list_item:%p", list_item);
143         return list_item ? list_item->draw : NULL;
144 }
145
146 void setting_drawer_list_init()
147 {
148         SETTING_TRACE_BEGIN;
149 #if 0
150         /* <navigationbar> */__drawer_add("navigationbar", navigationbar_func);
151 #endif
152         /* <bool>          */__drawer_add("bool", checkbox_func);
153         /* <string>        */__drawer_add("string", editbox_func);
154         /* <group>         */__drawer_add("group", group_func);
155         /* <integer>       */__drawer_add("integer", slider_func);
156         /* <label>         */__drawer_add("label", label_func);
157         /* <link>          */__drawer_add("link", link_func);
158         /* <launch>        */__drawer_add("launch", launch_func);
159         /* <extendlist>    */__drawer_add("expandlist", expandlist_func);
160         /* <extenditem>    */__drawer_add("expanditem", expanditem_func);
161         /* <settings>      */__drawer_add("settings", settings_func);
162         /* <setting>       */__drawer_add("setting", setting_func);
163 }
164
165 void setting_drawer_list_fini()
166 {
167         if (_g_drawer_list)
168         {
169                 Object_Drawer *node = NULL;
170                 Eina_List *li = _g_drawer_list;
171                 while (li) {
172                         node = (Object_Drawer *) eina_list_data_get(li);
173                         if (node)
174                         {
175                                 //SETTING_TRACE("Deregister %s", node->type);
176                                 FREE(node);
177                         }
178                         li = eina_list_next(li);
179                 }
180                 _g_drawer_list = eina_list_free(_g_drawer_list);
181                 _g_drawer_list = NULL;
182         }
183 }
184
185 /////////////////////////
186 /////////////////////////
187 /////////////////////////
188
189 #define MAX_CONTENT_LEN 512
190 #define MAX_LOCAL_BUFSIZE 128
191 #define DBUS_PATH "/setting/dbus_handler"
192 #define DBUS_SIGNAL_INTERFACE "org.tizen.setting.signal"
193
194 #define APPID_LENGTH 10
195 #define APPID_POS_FROM_PATH 10
196
197 static char* s_pkg_name;
198 static char* s_plugin_path;
199
200 /**
201  * package ID
202  *
203  * ncbyusjryr.AppSetting --> package ID is ncbyusjryr
204  * "Update_" "ncbyusjryr"
205  */
206 static char* get_app_string(char* path)
207 {
208         SETTING_TRACE_BEGIN;
209         //SETTING_TRACE("package path : >>> %s ",path );
210         char* temp = substring(path, APPID_POS_FROM_PATH, APPID_LENGTH/*string size*/);
211         SETTING_TRACE("package ID : >>> %s ",temp );
212         return temp;
213 }
214
215 //------------------------------------------------------
216 // for client - bus
217 static DBusConnection *bus;
218 //------------------------------------------------------
219 static DBusHandlerResult __signal_filter(DBusConnection* conn, DBusMessage* message, void* user_data)
220 {
221     int my_pid = getpid();
222     int sender_pid = 0;
223     char* key = NULL;
224     char* value = NULL;
225
226         if (message == NULL)
227                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
228
229     DBusError error;
230     dbus_error_init(&error);
231
232         PluginNode* ad = (PluginNode*)user_data;
233
234         char* plugin_path = ad->plugin_path;
235         char* pkg_name = get_app_string(plugin_path);
236
237         if (pkg_name == NULL)
238         {
239                 SETTING_TRACE("pkg_name is NULL - it's abnormal operation");
240                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
241         }
242
243         char str_buf[MAX_COMMON_BUFFER_LEN];
244         snprintf(str_buf, MAX_COMMON_BUFFER_LEN, "Update_%s", pkg_name);
245         s_pkg_name = strdup(str_buf);
246
247         if (pkg_name)
248         {
249                 free(pkg_name);
250                 pkg_name = NULL;
251         }
252
253         if (s_pkg_name == NULL)
254         {
255                 SETTING_TRACE("s_pkg_name is NULL - it's abnormal operation");
256                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
257         }
258         SETTING_TRACE("s_pkg_name : %s ", s_pkg_name);
259     if (dbus_message_is_signal(message, DBUS_SIGNAL_INTERFACE, s_pkg_name))
260     {
261         if (dbus_message_get_args(message, &error,
262                 DBUS_TYPE_UINT32, &sender_pid,
263                 DBUS_TYPE_STRING, &key,
264                 DBUS_TYPE_STRING, &value,
265                 DBUS_TYPE_INVALID) == FALSE)
266         {
267             SETTING_TRACE_ERROR("Fail to get data : %s", error.message);
268             dbus_error_free(&error);
269             return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
270         }
271     }
272
273     if (sender_pid != 0 && my_pid != sender_pid)
274     {
275         SETTING_TRACE("received key : %s , value : %s", key, value);
276                 //-------------------------------------------------------------
277                 // received key : checkbox1|N/A , value : INT|1
278                 //-------------------------------------------------------------
279                 //char* key = "checkbox1|N/A";
280                 char* ptr = NULL;
281
282                 if (key) {
283                         ptr = strchr(key, '|');
284                 }
285
286                 xmlDocPtr doc = NULL;
287                 if (ptr && key)
288                 {
289                         //parsing for : checkbox1|N/A  -> checkbox1
290                         char* key_name = substring(key, 0, strlen(key)-strlen(ptr));
291                         char* val_name = strchr(value, '|');
292                         val_name++;
293
294                         if (key_name == NULL)
295                                 goto final;
296
297                         // access xml file
298                         doc = xmlParseFile(plugin_path);
299                         if (doc == NULL)
300                         {
301                                 SETTING_TRACE("unable to parse file : %s", plugin_path);
302                                 FREE(key_name);
303                                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;     /* xml parsing error */
304                         }
305                         // generate xml tree
306                         xmlNode *root = xmlDocGetRootElement(doc);
307                         // find a node
308                         bool is_end = false;
309
310                         // TODO : message queing
311                         // get key/value from d-bus and parse xml and search xml data with key
312                         static int count = 0;
313                         SETTING_TRACE(" BEGIN ---------------------------- dbus--> before __node_finder : %d", count);
314                         __node_finder((PluginNode*)ad, root, key_name ,val_name, &is_end);
315                         SETTING_TRACE(" END  ----------------------------- dbus--> after __node_finder : %d", count);
316                         count += 1;
317                 }
318                 // update the node
319                 GError *error = NULL;
320 #if 0
321                 if(doc != NULL)
322                 {
323                         xmlSaveFormatFile(ad->plugin_path, doc, 1);
324                         // TODO: make sure this is right
325                         xmlFreeDoc(doc);
326                         doc = NULL;
327                         SETTING_TRACE("__cfg_file_write successful");
328                 }
329 #endif
330                 // update UI
331     }
332
333 final:
334     return DBUS_HANDLER_RESULT_HANDLED;
335 }
336
337 static int __send_msg(char* key, char* value)
338 {
339         DBusMessage* message;
340
341         int sender_pid = getpid();
342
343         if (bus == NULL)
344                 return -1;
345
346         // ex) in gdb --> $15 = 0x43b6eb78 "Update_(null)" -> error codintion
347         if (s_pkg_name == NULL)
348         {
349                 SETTING_TRACE("s_pkg_name is NULL - it's abnormal operation");
350                 return -1;
351         }
352
353         message = dbus_message_new_signal(DBUS_PATH, DBUS_SIGNAL_INTERFACE, s_pkg_name);
354
355         SETTING_TRACE("Sending message[%s:%s] via dbus", key ,value);
356         if (dbus_message_append_args(message,
357                                 DBUS_TYPE_UINT32, &sender_pid,
358                                 DBUS_TYPE_STRING, &key,
359                                 DBUS_TYPE_STRING, &value,
360                                 DBUS_TYPE_INVALID) == FALSE)
361         {
362                 SETTING_TRACE("Fail to load data error");
363                 return -1;
364         }
365
366         if (dbus_connection_send(bus, message, NULL) == FALSE)
367         {
368                 SETTING_TRACE("Fail to send message");
369                 return -1;
370         }
371
372         dbus_connection_flush(bus);
373         dbus_message_unref(message);
374
375         SETTING_TRACE("[CLIENT] send data signal done");
376
377     return 0;
378 }
379
380
381 static void __send_int_msg(xmlNode* xmlObj, int val)
382 {
383         SETTING_TRACE_BEGIN;
384         const char *id = (char*)xmlGetProp(xmlObj, "id");
385         const char *title = (char*)xmlGetProp(xmlObj, "title");
386         char key[MAX_CONTENT_LEN] = {0,};
387         snprintf(key, sizeof(key), "%s|%s", id, title);
388
389         char value[MAX_CONTENT_LEN] = {0,};
390         snprintf(value, sizeof(value), "INT|%d", val);
391         __send_msg(key, value);
392         SETTING_TRACE_END;
393 }
394
395
396 static void __send_string_msg(xmlNode* xmlObj, char *string)
397 {
398         const char *id = (char*)xmlGetProp(xmlObj, "id");
399         const char *title = (char*)xmlGetProp(xmlObj, "title");
400         char key[MAX_CONTENT_LEN] = {0,};
401         snprintf(key, sizeof(key), "%s|%s", id, title);
402
403         char value[MAX_CONTENT_LEN] = {0,};
404         snprintf(value, sizeof(value), "STRING|%s", string);
405         __send_msg(key, value);
406 }
407
408
409 int setting_dbus_handler_init(void* user_data)
410 {
411         SETTING_TRACE_BEGIN;
412         if (bus)
413         {
414                 SETTING_TRACE("already get a bus, need release first.");
415                 setting_dbus_handler_fini();
416 //              return -1;
417         }
418         DBusError error;
419         memset(&error, 0, sizeof(DBusError));
420         char rule[MAX_LOCAL_BUFSIZE + 1] = {0,};
421         dbus_error_init(&error);
422         bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
423         if (!bus)
424         {
425                 SETTING_TRACE("Fail to connect to the D-BUS daemon: %s", error.message);
426                 dbus_error_free(&error);
427                 return -1;
428         }
429
430         dbus_connection_setup_with_g_main(bus, NULL);
431         snprintf(rule, MAX_LOCAL_BUFSIZE, "path='%s',type='signal',interface='%s'", DBUS_PATH, DBUS_SIGNAL_INTERFACE);
432
433         dbus_bus_add_match(bus, rule, &error);
434         if (dbus_error_is_set(&error))
435         {
436                 SETTING_TRACE("Fail to rule set; %s", error.message);
437                 dbus_bus_remove_match(bus, rule, &error);
438                 dbus_error_free(&error);
439                 dbus_connection_close(bus);
440                 bus = NULL;
441                 return -1;
442         }
443         PluginNode* temp = (PluginNode*)user_data;
444         s_plugin_path = temp->plugin_path;
445         //SETTING_TRACE(" >>>>> setting - s_plugin_path :: %s", s_plugin_path);
446
447         if (dbus_connection_add_filter(bus, __signal_filter, user_data, NULL) == FALSE)
448         {
449                 dbus_bus_remove_match(bus, rule, &error);
450                 dbus_error_free(&error);
451                 dbus_connection_close(bus);
452                 bus = NULL;
453                 return -1;
454         }
455
456         SETTING_TRACE("app signal initialized");
457         return 0;
458 }
459
460 int setting_dbus_handler_fini(void)
461 {
462         SETTING_TRACE_BEGIN;
463         //do safty checking first.
464         setting_retvm_if(!bus, 0, "!bus");
465         DBusError error;
466         memset(&error, 0, sizeof(DBusError));
467         char rule[MAX_LOCAL_BUFSIZE + 1] = {0, };
468
469         dbus_error_init(&error);
470
471         // why??
472         bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
473
474         //dbus_connection_remove_filter(bus, __signal_filter, NULL);
475
476
477         snprintf(rule, MAX_LOCAL_BUFSIZE, "path='%s',type='signal',interface='%s'", DBUS_PATH, DBUS_SIGNAL_INTERFACE);
478         dbus_bus_remove_match(bus, rule, &error);
479
480         if (dbus_error_is_set(&error))
481         {
482                 SETTING_TRACE("Fail to rule unset: %s", error.message);
483                 dbus_error_free(&error);
484                 //return -1;
485         }
486
487         dbus_connection_close(bus);
488         bus = NULL;
489         SETTING_TRACE("app signal finalized");
490         return 0;
491 }
492
493 /////////////////////////////
494 /////////////////////////////
495 /////////////////////////////
496
497 Elm_Genlist_Item_Class itc_layout;
498
499 // write -> update
500 static int __cfg_file_write(Draw_Data *pd)
501 {
502         SETTING_TRACE_BEGIN;
503
504         GError *error = NULL;
505         if(pd->doc != NULL)
506         {
507                 xmlSaveFormatFile(pd->cfg_file, pd->doc, 1);
508                 //xmlFreeDoc(pd->doc);
509                 //pd->doc = NULL;
510                 SETTING_TRACE("__cfg_file_write successful");
511         }
512
513         SETTING_TRACE_END;
514         return TRUE;
515 }
516
517 typedef struct {
518         int state;
519         Setting_GenGroupItem_Data* obj;
520 } HashArgs;
521
522 /**
523 * @brief eina list callback that check if there's a focused node
524 * @return false on Focused, true on Not focused
525 */
526 static Eina_Bool _plugin_foreach_cb_check_editfield(const Eina_Hash *hash, const void*key, void* data, void* fdata)
527 {
528
529         HashArgs* pret = (HashArgs*)fdata;
530         //int* pret = (int*)fdata;
531
532     Setting_GenGroupItem_Data* node = (Setting_GenGroupItem_Data*) data;
533         SETTING_TRACE("%s --- %s ", (char*)key, node->keyStr);
534
535         xmlNode* xmlObj = NULL;
536         if (node->userdata) {
537                 xmlObj = node->userdata;
538                 //SETTING_TRACE("xml node type name ---> %s ", xmlObj->name);
539         }
540
541         //if (node->keyStr && !strcmp(node->keyStr, "string"))
542         if (xmlObj && xmlObj->name && !strcmp(xmlObj->name, "string"))
543         {
544                 //SETTING_TRACE(" Size Check code !!! ");
545                 //SETTING_TRACE(" >>> entry _ string : %s ", node->sub_desc);
546                 //SETTING_TRACE(" >>> entry _ length : %d ", safeStrLen(node->sub_desc));
547                 int min_length = node->minlength;
548                 int entry_len = safeStrLen(node->sub_desc);
549
550                 // focus check
551                 //NOT PROPERLY if (elm_object_focus_get(node->eo_check))
552                 // elm_object_focus_get may have a timing issue.
553                 // node string check here
554                 if (entry_len < min_length)
555                 {
556                         SETTING_TRACE(" Size NO !!! ");
557                         pret->state = 1;
558                         pret->obj= node;
559                         return EINA_FALSE;
560                 } else {
561                         SETTING_TRACE(" Size OK !!! ");
562                         pret->state = 0;
563                 }
564         }
565
566         return EINA_TRUE;
567 }
568
569
570 static void __error_popup_inside_cb(void *data, Evas_Object *obj,
571                                      void *event_info)
572 {
573         SETTING_TRACE_BEGIN;
574
575         retm_if(data == NULL, "Data parameter is NULL");
576         retm_if(obj == NULL, "Data parameter is NULL");
577
578         #if 1
579         Setting_GenGroupItem_Data *list_item = data;
580         if (list_item->notify) {
581                 // free keygrab
582
583                 // __popup_del_cb(data, evas_object_evas_get(obj), obj, event_info);
584                 
585                 // ???  
586                 __popup_del_cb(data, evas_object_evas_get(obj), obj, event_info);
587
588                 evas_object_del(list_item->notify);
589                 list_item->notify = NULL;
590         }
591         #endif
592 }
593
594
595 static void __error_popup_cb(void *data, Evas_Object *obj,
596                                      void *event_info)
597 {
598         SETTING_TRACE_BEGIN;
599
600         retm_if(data == NULL, "Data parameter is NULL");
601         retm_if(obj == NULL, "Data parameter is NULL");
602
603         #if 1
604         Setting_GenGroupItem_Data *list_item = data;
605         if (list_item->notify) {
606
607                 // free keygrab
608                 __popup_del_cb(data, evas_object_evas_get(obj), obj, event_info);
609                 evas_object_del(list_item->notify);
610                 list_item->notify = NULL;
611         }
612         #endif
613 }
614
615
616 /**
617 * @param context
618 * @return
619 */
620 int setting_plugin_is_editfield_exist(PluginNode* context)
621 {
622         int ret = 0;
623         HashArgs arg;
624         arg.state = 0;
625         arg.obj = NULL;
626
627         if (context->ui_list) {
628                 eina_hash_foreach(context->ui_list,_plugin_foreach_cb_check_editfield, &arg);
629         }
630         SETTING_TRACE("%d -- (%x)", arg.state, arg.obj);
631
632         // in some cases, arg.state is zero even if the entry has empty string.
633         if (arg.state )
634         {
635                 ret = 0;
636
637                 Setting_GenGroupItem_Data* list_item = arg.obj;
638                 int min_length = list_item->minlength;
639                 int entry_len = safeStrLen(list_item->sub_desc);
640
641                 //SETTING_TRACE(" >>> entry _ len : %d ", entry_len);
642                 //SETTING_TRACE(" >>> minlength _ len : %d ", min_length);
643
644                 if ( entry_len < min_length)
645                 {
646                         if (!list_item->notify) {
647
648                                 list_item->notify = setting_create_popup_without_btn(list_item, list_item->win_main,
649                                                 NULL, _(EXCEED_MINLENGTH_LIMITATION_STR),
650                                                 __error_popup_cb,
651                                                 POPUP_INTERVAL, FALSE, TRUE);   // FALSE, TRUE --> key grabbing
652                                 // elm_object_focus_set(list_item->eo_check, EINA_FALSE);
653                         } else {
654                                 //postpone 2 seconds again
655                                 evas_object_show(list_item->notify);
656                                 elm_popup_timeout_set(list_item->notify, POPUP_INTERVAL);
657                         }
658                         //elm_object_focus_set(obj, EINA_TRUE);
659
660                         ret = 1;
661                 }
662         }
663
664         return ret;
665 }
666
667 /**
668 * @brief 'back' button of plugin setting UG
669 *
670 * @param data PluginNode object
671 * @param obj NOT USED
672 * @param event_info NOT USED
673 *
674 * @return TRUE on success
675 */
676 static Eina_Bool ___click_softkey_back_cb(void *data, Evas_Object *obj, void *event_info)
677 {
678         SETTING_TRACE_BEGIN;
679         ret_if(!data);
680         PluginNode* node = (PluginNode*)data;
681         Draw_Data *pd = node->pd;
682
683         static int work = 0;
684         if (work == 0)
685         {
686                 work = 1;
687
688                 /*
689                 * get a list of genlist nodes, and see if there's text entries
690                 */
691                 int is_stop = setting_plugin_is_editfield_exist(node);
692                 if (is_stop)
693                 {
694                         work = 0;
695                         return EINA_FALSE;
696                 }
697
698                 ui_gadget_h ug = node->ug;
699
700                 // ug --> destroy
701                 if(ug)
702                 {
703                         SETTING_TRACE(" before ug_destory me ----<<<<<< ");
704                         ug_destroy_me(ug);
705                         SETTING_TRACE(" after ug_destory me ----<<<<<< ");
706                 } else {
707                         setting_plugin_destroy(node);
708                         if (node->navi_bar)
709                         {
710                                 elm_naviframe_item_pop(node->navi_bar);
711                         }
712                         SETTING_TRACE(" UG is NULL  now ----<<<<<< ");
713                 }
714                 work = 0;
715         }
716
717         return EINA_TRUE;
718 }
719
720
721 static void* group_func(void *data, xmlNode *xmlObj)
722 {
723         SETTING_TRACE_BEGIN;
724         retv_if(!data || !xmlObj, NULL);
725
726         PluginNode* node = (PluginNode*)data;
727         Draw_Data *pd = node->pd;
728
729         // new code is recursive
730         const char *title = (char*)xmlGetProp(xmlObj, "title");
731         SETTING_TRACE (" >>> GROUP NAME : %s \n", title);
732         (void)setting_create_Gendial_field_titleItem(pd->scroller, &(itc_group_item), title, NULL);
733         return NULL;
734 };
735
736
737 static void* __link_list_cb(void *data, Evas_Object *obj, void *event_info)
738 {
739         SETTING_TRACE_BEGIN;
740         retv_if(data == NULL, NULL);
741         retvm_if(event_info == NULL, NULL, "Invalid argument: event info is NULL");
742         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
743         elm_genlist_item_selected_set(item, 0);
744         Setting_GenGroupItem_Data *list_item =
745             (Setting_GenGroupItem_Data *) elm_object_item_data_get(item);
746
747         xmlNode* xmlObj = data;
748         retv_if(!xmlObj, NULL);
749         const char *link_file = (char*)xmlGetProp(xmlObj, "value");
750
751         if(!link_file)
752         {
753                 SETTING_TRACE_ERROR("Invalidate liked file");
754                 return NULL;
755         }
756         char file[1024] = {0,};
757         snprintf(file, sizeof(file), "%s/%s", PLUGIN_CFG_DIR, link_file);
758         SETTING_TRACE("file:%s", file);
759
760 // Evas_Object* navi_bar, Evas_Object* win_main
761         PluginNode* plugin_node = setting_plugin_create( NULL, NULL );
762         setting_plugin_load(plugin_node, (const char *)file);
763         return NULL;
764 }
765
766 static void* __launch_list_cb(void *data, Evas_Object *obj, void *event_info)
767 {
768         SETTING_TRACE_BEGIN;
769         retv_if(data == NULL, NULL);
770         retvm_if(event_info == NULL, NULL, "Invalid argument: event info is NULL");
771         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
772         elm_genlist_item_selected_set(item, 0);
773         Setting_GenGroupItem_Data *list_item =
774             (Setting_GenGroupItem_Data *) elm_object_item_data_get(item);
775
776         xmlNode* xmlObj = data;
777         retv_if(!xmlObj, NULL);
778         const char *key_str = (char*)xmlGetProp(xmlObj, "id");
779         const char *title_str = (char*)xmlGetProp(xmlObj, "title");
780         const char *appid_str = (char*)xmlGetProp(xmlObj, "appid");
781         const char *operation_str = (char*)xmlGetProp(xmlObj, "operation");
782
783
784         service_h svc = NULL;
785         service_create(&svc);
786         if (!appid_str) appid_str = "";
787         if (!operation_str) operation_str = "";
788
789         service_set_app_id(svc, appid_str);                                                     // xml property â€“ appid
790         service_set_operation(svc, operation_str);                                              // property : operation
791         service_send_launch_request(svc, NULL, NULL);
792         service_destroy(svc);
793
794         return NULL;
795 }
796
797 static void* label_func(void *data, xmlNode *xmlObj)
798 {
799         SETTING_TRACE_BEGIN;
800         retv_if(!data || !xmlObj, NULL);
801         PluginNode* node = (PluginNode*)data;
802         Draw_Data *pd = node->pd;
803
804         const char *title = (char*)xmlGetProp(xmlObj, "title");
805
806         Setting_GenGroupItem_Data *obj =
807                 setting_create_Gendial_field_def(pd->scroller, &(itc_1text),
808                                                  NULL,
809                                                  xmlObj, SWALLOW_Type_INVALID, NULL, NULL,
810                                                  0, title, NULL, NULL);
811
812         return obj;
813 }
814
815 static void* link_func(void *data, xmlNode *xmlObj)
816 {
817         SETTING_TRACE_BEGIN;
818         retv_if(!data || !xmlObj, NULL);
819         PluginNode* node = (PluginNode*)data;
820         Draw_Data *pd = node->pd;
821
822         const char *key_str = (char*)xmlGetProp(xmlObj, "id");
823         Setting_GenGroupItem_Data * obj =
824                 setting_create_Gendial_field_def(pd->scroller, &(itc_1text),
825                                                  __link_list_cb,
826                                                  xmlObj, SWALLOW_Type_INVALID, NULL, NULL,
827                                                  0, key_str, NULL, NULL);
828
829         return (void*)obj;
830 };
831
832 static void* launch_func(void *data, xmlNode *xmlObj)
833 {
834         SETTING_TRACE_BEGIN;
835         retv_if(!data || !xmlObj, NULL);
836         PluginNode* node = (PluginNode*)data;
837         Draw_Data *pd = node->pd;
838
839         const char *title_str = (char*)xmlGetProp(xmlObj, "title");
840
841         Setting_GenGroupItem_Data * obj =
842                 setting_create_Gendial_field_def(pd->scroller, &(itc_1text),
843                                                  __launch_list_cb,
844                                                  xmlObj, SWALLOW_Type_INVALID, NULL, NULL,
845                                                  0, title_str, NULL, NULL);
846
847         return (void*)obj;
848 };
849
850 static char* __slider_format_cb(double val)
851 {
852         char buf[128];
853
854         int ival = (int)val;
855         snprintf(buf, sizeof(buf), "%d", ival);
856         return strdup(buf);
857 }
858
859 static void __slider_format_cb_free(char* str)
860 {
861         free(str);
862         str = NULL;
863 }
864
865 static void __slider_changed_cb(void *data, Evas_Object *obj, void *event_info)
866 {
867         ret_if(data == NULL || obj == NULL);
868         double val = elm_slider_value_get(obj);
869         SETTING_TRACE("val = %f", val);
870
871         Setting_GenGroupItem_Data *list_item = data;
872
873         xmlNode* xmlObj = list_item->userdata;
874         ret_if(!xmlObj);
875
876         elm_slider_indicator_format_function_set(obj, __slider_format_cb, __slider_format_cb_free);
877 }
878
879 static void __slider_stop_cb(void *data, Evas_Object *obj, void *event_info)
880 {
881         ret_if(data == NULL || obj == NULL);
882
883         double val = elm_slider_value_get(obj);
884         Setting_GenGroupItem_Data *list_item = data;
885
886         elm_slider_indicator_format_function_set(obj, __slider_format_cb, __slider_format_cb_free);
887
888         ret_if(list_item->userdata == NULL);
889
890         xmlNode* xmlObj = list_item->userdata;
891         ret_if(!xmlObj);
892
893         //apply the vconf changes after stopping moving slider..
894         if (val >= 0)
895         {
896                 list_item->chk_status = (int)(val + 0.5);
897         }
898         else {
899                 // val < 0
900                 if (val < 0) {
901                         val = (double)val - (double)0.5;
902                 }
903                 list_item->chk_status = (int)val;
904         }
905         elm_slider_value_set(obj, list_item->chk_status);
906         //SETTING_TRACE(" slider after ---> val = %d", (int) list_item->chk_status);
907         xmlAttrPtr newattr;
908         char buf[10];
909         sprintf(buf, "%d", (int) list_item->chk_status);
910         newattr = xmlSetProp(xmlObj, "value", buf);
911
912         __cfg_file_write((Draw_Data *)list_item->belongs_to);
913         SETTING_TRACE(" slider - send dbus message");
914         __send_int_msg(xmlObj, list_item->chk_status);
915 }
916
917
918 static void* slider_func(void *data, xmlNode *xmlObj)
919 {
920         SETTING_TRACE_BEGIN;
921         retv_if(!data || !xmlObj, NULL);
922         PluginNode* node = (PluginNode*)data;
923         Draw_Data *pd = node->pd;
924
925         // type casting
926         const char *title = (char*)xmlGetProp(xmlObj, "title");
927
928         SETTING_TRACE (" >>> [slider input] min=%s max=%s value=%s ",(char*)xmlGetProp(xmlObj, "min"), (char*)xmlGetProp(xmlObj, "max"), (char*)xmlGetProp(xmlObj, "value"));
929
930         int value = atoi((char*)xmlGetProp(xmlObj, "value"));
931         int min = atoi((char*)xmlGetProp(xmlObj, "min"));
932         int max = atoi((char*)xmlGetProp(xmlObj, "max"));
933
934         SETTING_TRACE ("[slider input] min=%d max=%d value=%d ", min, max, value);
935
936         setting_create_Gendial_itc("dialogue/1text.1icon.5", &(itc_layout));
937         Setting_GenGroupItem_Data *list_item =
938             setting_create_Gendial_field_def(pd->scroller, &(itc_layout), NULL,
939                                              NULL,
940                                              SWALLOW_Type_LAYOUT_SLIDER,
941                                              IMG_SENSITIVITY_ICON_01,
942                                              IMG_SENSITIVITY_ICON_02, value,
943                                              title, NULL, NULL);
944         if (list_item) {
945                 list_item->win_main = NULL;
946                 list_item->evas = NULL;
947                 list_item->isIndicatorVisible = true;
948                 list_item->slider_min = min;
949                 list_item->slider_max = max;
950                 list_item->userdata = xmlObj;
951                 list_item->chk_change_cb = __slider_changed_cb;
952                 list_item->stop_change_cb = __slider_stop_cb;
953                 list_item->belongs_to = (int)pd;
954         }
955
956         g_list_item = list_item;
957
958         return (void*)list_item;
959 };
960
961
962 static void __checkbox_logic_helper(void *data, int toggle_state)
963 {
964         Setting_GenGroupItem_Data *list_item = (Setting_GenGroupItem_Data *) data;
965
966         xmlNode* xmlObj = list_item->userdata;
967         ret_if(!xmlObj);
968
969         xmlAttrPtr newattr;
970         if (list_item->chk_status == 1) {
971                 newattr = xmlSetProp(xmlObj, "value", "true");
972         } else if (list_item->chk_status == 0) {
973                 newattr = xmlSetProp(xmlObj, "value", "false");
974         } else {
975                 newattr = xmlSetProp(xmlObj, "value", "false");
976         }
977
978         const char *id = (char*)xmlGetProp(xmlObj, "id");
979         const char *title = (char*)xmlGetProp(xmlObj, "title");
980         //SETTING_TRACE(" >>>> id:%s , title:%s", id, title);
981
982         __cfg_file_write((Draw_Data *)list_item->belongs_to);
983         __send_int_msg(xmlObj, list_item->chk_status);
984 }
985 /**
986 * @brief handler for 'toggle button'
987 *
988 * @see also __check_mouse_up_cb
989 */
990 static void __chk_btn_cb(void *data, Evas_Object *obj, void *event_info)
991 {
992         SETTING_TRACE_BEGIN;
993         /* error check */
994         retm_if(data == NULL, "Data parameter is NULL");
995         Setting_GenGroupItem_Data *list_item = (Setting_GenGroupItem_Data *) data;
996
997         list_item->chk_status = elm_check_state_get(obj);       /*  for genlist update status */
998
999         __checkbox_logic_helper(list_item, list_item->chk_status);
1000         return;
1001 }
1002
1003
1004 /**
1005 * @brief handler for 'touching' line of genlist item
1006 */
1007 static void __check_mouse_up_cb(void *data, Evas_Object *obj,
1008                                              void *event_info)
1009 {
1010         /* error check */
1011         SETTING_TRACE_BEGIN;
1012         setting_retm_if(data == NULL, "Data parameter is NULL");
1013
1014         retm_if(event_info == NULL, "Invalid argument: event info is NULL");
1015         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
1016         elm_genlist_item_selected_set(item, 0);
1017         Setting_GenGroupItem_Data *list_item =
1018             (Setting_GenGroupItem_Data *) elm_object_item_data_get(item);
1019
1020         SETTING_TRACE("clicking item[%s]", _(list_item->keyStr));
1021
1022         int old_status = elm_check_state_get(list_item->eo_check);
1023         list_item->chk_status = !old_status;
1024         elm_check_state_set(list_item->eo_check, list_item->chk_status);
1025
1026         __checkbox_logic_helper(list_item, list_item->chk_status);
1027 }
1028
1029
1030 static void* checkbox_func(void *data, xmlNode *xmlObj)
1031 {
1032         SETTING_TRACE_BEGIN;
1033         retv_if(!data || !xmlObj, NULL);
1034
1035         PluginNode* node = (PluginNode*)data;
1036         Draw_Data *pd = node->pd;
1037
1038         // [DATA] title, value
1039         const char *title = (char*)xmlGetProp(xmlObj, "title");
1040
1041         // true / false
1042         char* value = (char*)xmlGetProp(xmlObj, "value");
1043
1044         int ival = -1;
1045
1046         if ( 0 == safeStrCmp(value, "true")) {
1047                 ival = 1;
1048         } else if ( 0 == safeStrCmp(value, "false"))  {
1049                 ival = 0;
1050         } else {
1051                 ival = 0;       // default : false (0)
1052         }
1053
1054         // title, value, xmlObj
1055         Setting_GenGroupItem_Data *list_item =
1056                 setting_create_Gendial_field_def(pd->scroller,
1057                                           &(itc_1text_1icon),
1058                                           __check_mouse_up_cb,
1059                                           xmlObj,
1060                                           SWALLOW_Type_1TOGGLE,
1061                                           NULL, NULL,
1062                                           ival,
1063                                           title,
1064                                           NULL,
1065                                           __chk_btn_cb);
1066         if(list_item) {
1067                 list_item->userdata = xmlObj;
1068                 list_item->belongs_to = (int) pd;
1069                 SETTING_TRACE("pd:%p,list_item->belongs_to:%d", pd, list_item->belongs_to);
1070         }
1071
1072         return list_item;
1073 }
1074
1075
1076 static void __entry_unfocus_cb(void *data, Evas_Object *obj, void *event_info)
1077 {
1078         SETTING_TRACE_BEGIN;
1079         retm_if(!data || !obj, "Data parameter is NULL");
1080
1081         //-------------------------------------------------------------------------------------------
1082         Evas_Object *entry_container = data;
1083         //whe entry unfocused, its guidetext will becomes "Input here"
1084         elm_object_part_text_set(entry_container, "elm.guidetext", _("IDS_ST_BODY_TAP_TO_INSERT"));
1085         if (elm_entry_is_empty(obj))
1086                 elm_object_signal_emit(entry_container, "elm,state,guidetext,show", "elm");
1087         elm_object_signal_emit(entry_container, "elm,state,eraser,hide", "elm");
1088         //-------------------------------------------------------------------------------------------
1089
1090
1091         //setting_hide_input_pannel_cb(obj);
1092
1093         const char *entry_str = elm_entry_entry_get(obj);
1094         char *entry_str_utf8 = NULL;
1095         entry_str_utf8 = elm_entry_markup_to_utf8(entry_str);
1096
1097         Setting_GenGroupItem_Data *list_item = data;
1098
1099         // check minlentgh of the string
1100         int min_length = list_item->minlength;
1101         int entry_len = safeStrLen(entry_str_utf8);
1102
1103         SETTING_TRACE(" >>> minlength _ len : %d ", min_length);
1104         SETTING_TRACE(" >>> entry _ len : %d ", entry_len);
1105
1106         if (entry_len < min_length) {
1107
1108                 if (!list_item->notify) {
1109                         list_item->notify = setting_create_popup_without_btn(list_item, list_item->win_main,
1110                                                                  NULL, _(EXCEED_MINLENGTH_LIMITATION_STR),
1111                                                                          //__error_popup_inside_cb,
1112                                                                          __error_popup_cb,
1113                                                                          POPUP_INTERVAL, FALSE, TRUE);
1114                         elm_object_focus_set(list_item->eo_check, EINA_FALSE);
1115                 } else {
1116                         //postpone 2 seconds again
1117                         elm_popup_timeout_set(list_item->notify, POPUP_INTERVAL);
1118                 }
1119                 // elm_object_focus_set(obj, EINA_TRUE);
1120                 return;
1121         }
1122
1123         // send data
1124         xmlNode* xmlObj = list_item->userdata;
1125         if(!xmlObj) {
1126                 FREE(entry_str_utf8);
1127                 return;
1128         }
1129
1130         xmlAttrPtr newattr;
1131         const char *title = (char*)xmlSetProp(xmlObj, "value",entry_str_utf8);
1132
1133         __cfg_file_write((Draw_Data *)list_item->belongs_to);
1134         __send_string_msg(xmlObj, entry_str_utf8);
1135
1136         FREE(entry_str_utf8);
1137         SETTING_TRACE_END;
1138 }
1139
1140
1141 static void __editbox_list_cb(void *data, Evas_Object *obj,
1142                                             void *event_info)
1143 {
1144         SETTING_TRACE_BEGIN;
1145         /* error check */
1146 #if 0
1147         retm_if(event_info == NULL, "Invalid argument: event info is NULL");
1148         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
1149         elm_genlist_item_selected_set(item, 0);
1150         Setting_GenGroupItem_Data *list_item = (Setting_GenGroupItem_Data *) elm_object_item_data_get(item);
1151
1152         SETTING_TRACE("clicking item[%s]", _(list_item->keyStr));
1153         if (!elm_object_focus_get(list_item->eo_check)) {
1154                 elm_object_focus_set(list_item->eo_check, EINA_TRUE);
1155         }
1156         Ecore_IMF_Context *imf_context = (Ecore_IMF_Context *)elm_entry_imf_context_get(list_item->eo_check);
1157         setting_retm_if(imf_context == NULL, "imf_context is NULL");
1158         ecore_imf_context_input_panel_show(imf_context);
1159 #endif
1160 }
1161
1162
1163 static void __editbox_changed_cb(void *data, Evas_Object *obj,
1164                                        void *event_info)
1165 {
1166         SETTING_TRACE_BEGIN;
1167         retm_if(!data || !obj, "Data parameter is NULL");
1168         retm_if(!elm_object_focus_get(obj), "Entry is not focused");
1169
1170         Setting_GenGroupItem_Data *list_item = (Setting_GenGroupItem_Data *) data;
1171
1172         const char *entry_str = elm_entry_entry_get(obj);
1173         int entry_len = safeStrLen(entry_str);
1174         SETTING_TRACE("entry_str:[%s], length:%d", entry_str, entry_len);
1175
1176         G_FREE(list_item->sub_desc);//release first
1177         list_item->sub_desc = (char *)g_strdup(entry_str);
1178 }
1179
1180
1181 /**
1182  *  editbox
1183  *
1184  * @see also __editbox_changed_cb
1185  * @see also __entry_unfocus_cb
1186  */
1187 static void* editbox_func(void *data, xmlNode *xmlObj)
1188 {
1189         SETTING_TRACE_BEGIN;
1190         retv_if(!data || !xmlObj, NULL);
1191
1192         PluginNode* node = (PluginNode*)data;
1193         Draw_Data *pd = node->pd;
1194
1195         const char *title = (char*)xmlGetProp(xmlObj, "title");
1196         const char *key_str= (char*)xmlGetProp(xmlObj, "value");
1197
1198         const char *minlength= (char*)xmlGetProp(xmlObj, "minlength");
1199         const char *maxlength= (char*)xmlGetProp(xmlObj, "maxlength");
1200
1201         // MAXLENGTH HANDLER
1202         int max_len = -1;
1203         if (maxlength)
1204         {
1205                 max_len = atoi(maxlength);
1206                 SETTING_TRACE(" >> MAXLENGTH FILTER IS AVAILABLE !!!! maxlength = %d", max_len);
1207         }
1208
1209         int min_len = -1;
1210         if (maxlength)
1211         {
1212                 min_len = atoi(minlength);
1213                 SETTING_TRACE(" >> MINLENGTH FILTER IS AVAILABLE !!!! minlength = %d", min_len);
1214         }
1215
1216         Setting_GenGroupItem_Data *list_item = NULL;
1217
1218         if (max_len == -1 && min_len == -1 )
1219         {
1220                 // without maxlength filter
1221                 list_item = setting_create_Gendial_field_def(pd->scroller, &(itc_dialogue_editfield_title),
1222                                                                  __editbox_list_cb,
1223                                                          pd, SWALLOW_Type_LAYOUT_ENTRY,
1224                                                          NULL, NULL, 0, title, key_str,
1225                                                          __editbox_changed_cb);
1226
1227         } else {
1228                 // add max length filter
1229                 list_item = setting_create_Gendial_field_entry_fo(
1230                                                                         pd->scroller,
1231                                                                         &(itc_dialogue_editfield_title),
1232                                                                         __editbox_list_cb,
1233                                                                         pd,
1234                                                                         SWALLOW_Type_LAYOUT_ENTRY,
1235                                                                         NULL, NULL, 0, title, key_str,
1236                                                                         __editbox_changed_cb,
1237                                                                         __entry_unfocus_cb,
1238                                                                         ELM_INPUT_PANEL_LAYOUT_NORMAL,
1239                                                                         false,
1240                                                                         false,
1241                                                                         min_len,
1242                                                                         max_len,
1243                                                                         0,
1244                                                                         NULL, NULL);
1245
1246         }
1247         if (list_item) {
1248                 list_item->userdata = xmlObj;
1249                 list_item->stop_change_cb = __entry_unfocus_cb;
1250                 list_item->belongs_to = (int)pd;
1251
1252                 // for popup
1253                 list_item->win_main = node->win_main;
1254         }
1255
1256         return list_item;
1257 };
1258
1259
1260 static void __expanditem_func_sel_cb(void *data, Evas_Object *obj, void *event_info)
1261 {
1262         SETTING_TRACE_BEGIN;
1263         /* error check */
1264         retm_if(event_info == NULL, "Invalid argument: event info is NULL");
1265         Elm_Object_Item *subitem = (Elm_Object_Item *) event_info;
1266         Elm_Object_Item *parentItem = elm_genlist_item_parent_get(subitem);
1267         elm_genlist_item_selected_set(subitem, 0);
1268         Setting_GenGroupItem_Data *data_subItem = elm_object_item_data_get(subitem);
1269         Setting_GenGroupItem_Data *data_parentItem = elm_object_item_data_get(parentItem);      /* parent data */
1270         ret_if(NULL == data_subItem || NULL == data_parentItem);
1271
1272         elm_radio_value_set(data_subItem->rgd, data_subItem->chk_status);
1273
1274         data_parentItem->sub_desc = (char *)g_strdup(_(data_subItem->keyStr));
1275         elm_object_item_data_set(data_parentItem->item, data_parentItem);
1276         elm_genlist_item_update(data_parentItem->item);
1277
1278         xmlNode* xmlObj = data_parentItem->userdata;
1279         ret_if(!xmlObj);
1280
1281         xmlAttrPtr newattr;
1282         //newattr = xmlSetProp(xmlObj, "string", data_parentItem->sub_desc);
1283         newattr = xmlSetProp(xmlObj, "value", data_parentItem->sub_desc);
1284
1285         __cfg_file_write((Draw_Data *)data_parentItem->belongs_to);
1286         __send_string_msg(xmlObj, data_parentItem->sub_desc);
1287 }
1288
1289
1290 static void __expanditem_func_exp_cb(void *data, Evas_Object *obj, void *event_info)
1291 {
1292         ret_if(NULL == data || NULL == event_info);
1293         SETTING_TRACE_BEGIN;
1294
1295         PluginNode* node = (PluginNode*)data;
1296         Draw_Data *pd = node->pd;
1297
1298         Elm_Object_Item *parentItem = event_info;       /* parent item */
1299         Setting_GenGroupItem_Data *data_parentItem = elm_object_item_data_get(parentItem);      /* parent data */
1300         Evas_Object *scroller = elm_object_item_widget_get(parentItem);
1301
1302
1303         xmlNode *xmlObj = data_parentItem->userdata;
1304         char *value = (char*)xmlGetProp(xmlObj, "value");
1305         SETTING_TRACE(">>> value = %s", value);
1306         Evas_Object *rgd = NULL;
1307
1308         if (xmlObj->children && !data_parentItem->rgd) {//to protect from entering repeatly
1309                 xmlNode* cur = xmlObj->children;
1310
1311                 rgd = elm_radio_add(scroller);
1312                 elm_radio_value_set(rgd, -1);
1313
1314                 char *type;
1315                 char *subitem_title = NULL;
1316                 int subitem_index = 0;
1317                 int sel_idx = -1;
1318
1319 #if 0
1320                 // print out debug message
1321                 if (data_parentItem->childs)
1322                 {
1323                         int howmany = 0;
1324                         Eina_List *li = data_parentItem->childs;
1325                         while(li)
1326                         {
1327                                 Setting_GenGroupItem_Data* node = eina_list_data_get(li);
1328                                 howmany += 1;
1329                                 //SETTING_TRACE(" <<< node->keyStr : %s >>> ", node->keyStr);
1330
1331                                 // go next
1332                                 li = eina_list_next(li);
1333                         }
1334                         //SETTING_TRACE(" <<<how many : %d>>> ", howmany);
1335                 }
1336 #endif
1337                 if (data_parentItem->childs)
1338                 {
1339                         eina_list_free(data_parentItem->childs);
1340                         data_parentItem->childs = NULL;
1341                 }
1342
1343                 while (cur != NULL) {
1344                         if (!xmlStrcmp(cur->name, (const xmlChar*)"expanditem")) {
1345                                 type = (char*)xmlGetProp(cur, "type");
1346                                 if (0 == safeStrCmp(type, "radio")) {
1347                                         subitem_title = (char*)xmlGetProp(cur, "title");
1348                                         Setting_GenGroupItem_Data *list_item =
1349                                                                                         setting_create_Gendial_exp_sub_field(scroller,
1350                                                                                                         &(itc_1icon_1text_sub),
1351                                                                                                         __expanditem_func_sel_cb, NULL, parentItem,
1352                                                                                                         SWALLOW_Type_1RADIO, rgd,
1353                                                                                                         subitem_index,
1354                                                                                                         subitem_title, NULL);
1355
1356
1357                                         if (0 == safeStrCmp(value, subitem_title)) {
1358                                                 sel_idx = subitem_index;
1359                                                 SETTING_TRACE("%d is selected in Radio Group", sel_idx);
1360                                         }
1361                                         SETTING_TRACE(" eina list add >>> value = %s, subitem_title = %s ", value, subitem_title);
1362                                         data_parentItem->childs = eina_list_append(data_parentItem->childs, list_item);
1363                                         subitem_index++;
1364
1365                                 } else {
1366                                         SETTING_TRACE("invalid type[:%s]", type);
1367                                 }
1368                         }
1369                         cur = cur->next;
1370                 }
1371
1372                 // value set
1373                 elm_radio_value_set(rgd, sel_idx);
1374                 data_parentItem->rgd = rgd;//protecting condition
1375         }
1376 }
1377
1378
1379 static void __expanditem_func_smart_cb(void *data, Evas_Object *obj, void *event_info)
1380 {
1381         ret_if(data == NULL || event_info == NULL);
1382         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
1383         Setting_GenGroupItem_Data *data_item = elm_object_item_data_get(item);
1384         char *cb_type = data;
1385
1386         if (0 == safeStrCmp(cb_type, "contracted")) {
1387                 data_item->rgd = NULL;
1388                 elm_genlist_item_subitems_clear(item);
1389         }
1390 }
1391
1392
1393 static void* settings_func(void *data, xmlNode *xmlObj)
1394 {
1395         SETTING_TRACE_BEGIN;
1396         retv_if(!data || !xmlObj, NULL);
1397         PluginNode* node = (PluginNode*)data;
1398
1399         int count = 0;
1400         count = node->nitems;
1401
1402         if (count == 1)         // if there's <settings> only
1403         {
1404                 SETTING_TRACE("there's only <settings>");
1405                 setting_func(data, xmlObj);
1406         }
1407         return NULL;
1408 }
1409
1410
1411 static void __plugin_genlist_unrealized_cb(void* data,Evas_Object* obj, void* event_info)
1412 {
1413         SETTING_TRACE_BEGIN;
1414         ret_if(data == NULL);
1415
1416         Elm_Object_Item *item = (Elm_Object_Item*)event_info;
1417         Setting_GenGroupItem_Data *node = (Setting_GenGroupItem_Data *)elm_object_item_data_get(item);
1418         ret_if(node== NULL);
1419
1420         if (node->childs)
1421         {
1422                 eina_list_free(node->childs);
1423                 node->childs = NULL;
1424         }
1425 }
1426
1427 // <setting>
1428 // 1st create a window
1429 // 2nd push a window
1430 //--------------------------------------------------------
1431 static void* setting_func(void *data, xmlNode *xmlObj)
1432 {
1433         SETTING_TRACE_BEGIN;
1434         retv_if(!data || !xmlObj, NULL);
1435
1436         PluginNode* node = (PluginNode*)data;
1437         Draw_Data *pd = node->pd;
1438
1439         // [DATA] title
1440         const char *title = (char*)xmlGetProp(xmlObj, "title");
1441         if (!title)
1442                 title = "NONAME";
1443         SETTING_TRACE("before setting_create_layout_navi_bar_genlist");
1444
1445         // [UI] with DATA
1446         pd->scroller = elm_genlist_add(node->win_main);
1447         retvm_if(pd->scroller == NULL, NULL,
1448                  "Cannot set scroller object  as contento of layout");
1449         elm_object_style_set(pd->scroller, "dialogue");
1450         elm_genlist_clear(pd->scroller);        /* first to clear list */
1451
1452         evas_object_smart_callback_add(pd->scroller, "unrealized", __plugin_genlist_unrealized_cb, node);
1453
1454         SETTING_TRACE("_(title):%s", _(title));
1455
1456         if (node->ug == NULL)
1457         {
1458                 setting_push_layout_navi_bar(
1459                                                    _(title),
1460                                                    _("IDS_COM_BODY_BACK"), NULL, NULL,
1461                                                    ___click_softkey_back_cb,
1462                                                    NULL, NULL,
1463                                                    data, pd->scroller,
1464                                                    node->navi_bar, NULL);
1465         } else {
1466                 node->ly_main = setting_create_layout_navi_bar(node->win_main_layout, node->win_main,
1467                                                    _(title),
1468                                                    _("IDS_COM_BODY_BACK"), NULL, NULL,
1469                                                    ___click_softkey_back_cb,
1470                                                    NULL, NULL,
1471                                                    data, pd->scroller,
1472                                                    &node->navi_bar, NULL);
1473         }
1474         SETTING_TRACE("after setting_create_layout_navi_bar_genlist");
1475         return NULL;
1476 }
1477
1478
1479 static void* expanditem_func(void *data, xmlNode *xmlObj)
1480 {
1481         // DO NOTHING - expandlist draws this area
1482         return NULL;
1483 }
1484
1485 static void* expandlist_func(void *data, xmlNode *xmlObj)
1486 {
1487         SETTING_TRACE_BEGIN;
1488         retv_if(!data || !xmlObj, NULL);
1489
1490         PluginNode* node = (PluginNode*)data;
1491         Draw_Data *pd = node->pd;
1492
1493         const char *key_str = (char*)xmlGetProp(xmlObj, "title");
1494         const char *value = (char*)xmlGetProp(xmlObj, "value"); // string -> value
1495
1496         setting_enable_expandable_genlist(pd->scroller, data, __expanditem_func_exp_cb, __expanditem_func_smart_cb);
1497         Setting_GenGroupItem_Data *list_item =
1498             setting_create_Gendial_exp_parent_field(pd->scroller,
1499                                                     &(itc_2text_3_parent),
1500                                                     NULL, NULL,
1501                                                     SWALLOW_Type_INVALID,
1502                                                     key_str,
1503                                                     value);
1504         if (list_item) {
1505                 list_item->userdata = xmlObj;
1506                 list_item->belongs_to = (int)pd;
1507                 list_item->childs = NULL;               /* init */
1508         }
1509
1510         return list_item;
1511 }
1512
1513 static int __node_walk_check(PluginNode* context, xmlNode* cur, int* pcount)
1514 {
1515         //SETTING_TRACE_BEGIN;
1516         Draw_Data *pd = context->pd;
1517         retv_if(!pd, -1);
1518         retv_if(!context->ui_list, -1);
1519
1520         xmlNode *cur_node = NULL;
1521         for (cur_node = cur; cur_node;cur_node = cur_node->next) {
1522                 if (cur_node->type == XML_ELEMENT_NODE) {
1523                         //SETTING_TRACE("node type : %s id= %s", cur_node->name,xmlGetProp(cur_node, "id"));
1524                         *pcount += 1;
1525                 }
1526                 __node_walk_check(context, cur_node->children, pcount);         /* RECURSIVE */
1527         }
1528         return 0;
1529 }
1530
1531 static int __node_walker(PluginNode* context, xmlNode* cur)
1532 {
1533         //SETTING_TRACE_BEGIN;
1534         Draw_Data *pd = context->pd;
1535
1536         retv_if(!pd, -1);
1537         retv_if(!context->ui_list, -1);
1538
1539         xmlNode *cur_node = NULL;
1540         for (cur_node = cur; cur_node;cur_node = cur_node->next) {
1541                 if (cur_node->type == XML_ELEMENT_NODE) {
1542                         // SETTING_TRACE("node type : %s id= %s", cur_node->name,xmlGetProp(cur_node, "id"));
1543                         drawer_fp  fp = __drawer_find(cur_node->name);
1544                         if (fp)
1545                         {
1546                                 // type check
1547                                 void* vret = fp(context, cur_node); // draw it
1548
1549                                 if (vret)
1550                                 {
1551                                         Setting_GenGroupItem_Data* genlist_node = (Setting_GenGroupItem_Data* )vret;
1552                                         //SETTING_TRACE("add node to Eina List name : %s, id : ", cur_node->name, xmlGetProp(cur_node, "id"));
1553                                         // add it to the hash table create before.
1554                                         // id, object
1555                                         // add list
1556                                         char* key_name = xmlGetProp(cur_node, "id");
1557                                         eina_hash_add(context->ui_list, strdup(key_name),(void*)genlist_node);
1558                                 }
1559                         }else {
1560                                 SETTING_TRACE(" >>>> fp is NULL ");
1561                         }
1562                 }
1563                 __node_walker(context, cur_node->children);     /* RECURSIVE */
1564         }
1565         return 0;
1566 }
1567
1568 /**
1569  * @param id_str [in] "id"
1570  * @param value [in] value to be udpated
1571  * @see __expanditem_func_sel_cb
1572  */
1573 static int __node_finder(PluginNode* context, xmlNode* cur, char* id_str, char* value, bool* is_end)
1574 {
1575         SETTING_TRACE_BEGIN;
1576         xmlNode *cur_node = NULL;
1577
1578         if (! context)
1579         {
1580                 SETTING_TRACE("context is NULL - it's error CONDITION ");
1581                 return -1;
1582         }
1583
1584         retv_if(!context->ui_list, -1);
1585         if (*is_end == true) return 0;
1586
1587         for (cur_node = cur; cur_node;cur_node = cur_node->next) {
1588                 if (cur_node->type == XML_ELEMENT_NODE) {
1589
1590                         char* id_name = (char*)xmlGetProp(cur_node, "id");
1591                         if ( id_name && 0 == strcmp(id_str, id_name))
1592                         {
1593                                 SETTING_TRACE("FOUND >>>> %s", id_name);
1594                                 // cur_node     - update xml code
1595                                 xmlAttrPtr newattr = xmlSetProp(cur_node, "value", value);
1596
1597                                 //-----------------------------------------------------------
1598                                 // UI UPDATE
1599                                 // case : slider
1600                                 if ( 0 == strcmp (cur_node->name, "integer"))
1601                                 {
1602                                         SETTING_TRACE(">>>>> UPDATE SLIDER CONTROL %x --- %s ",context->ui_list, id_name);
1603                                         Setting_GenGroupItem_Data* item_to_update = (Setting_GenGroupItem_Data*)eina_hash_find(context->ui_list, id_name);
1604                                         if      (item_to_update)
1605                                         {
1606                                                 item_to_update->chk_status = atoi(value);
1607                                                 SETTING_TRACE(">>>   o-------------0 SLIDER VALUE = %d ", item_to_update->chk_status);
1608
1609                                                 elm_object_item_data_set(item_to_update->item, item_to_update);
1610                                                 elm_genlist_item_update(item_to_update->item);
1611                                         } else {
1612                                                 SETTING_TRACE("item_to_update is NULL");
1613                                         }
1614                                 }
1615                                 // case : toggle
1616                                 if ( 0 == strcmp (cur_node->name, "bool"))
1617                                 {
1618                                         SETTING_TRACE(">>>>> UPDATE TOGGLE CONTROL pluginpath:%s, ----  %x --- %s ", context->plugin_path, context->ui_list, id_name);
1619                                         Setting_GenGroupItem_Data* item_to_update = NULL;
1620                                         item_to_update = (Setting_GenGroupItem_Data*)eina_hash_find(context->ui_list, id_name);
1621                                         if      (item_to_update)
1622                                         {
1623                                                 item_to_update->chk_status = atoi(value);
1624                                                 SETTING_TRACE(">>>   o-------------0 TOGGLE VALUE = %d ", item_to_update->chk_status);
1625
1626                                                 elm_object_item_data_set(item_to_update->item, item_to_update);
1627                                                 elm_genlist_item_update(item_to_update->item);
1628                                         } else {
1629                                                 SETTING_TRACE("item_to_update is NULL");
1630                                         }
1631                                 }
1632                                 // case : edit control
1633                                 if ( 0 == strcmp (cur_node->name, "string"))
1634                                 {
1635                                         SETTING_TRACE(">>>>> UPDATE EDIT CONTROL CONTROL %x --- %s ",context->ui_list, id_name);
1636                                         Setting_GenGroupItem_Data* item_to_update = (Setting_GenGroupItem_Data*)eina_hash_find(context->ui_list, id_name);
1637                                         if      (item_to_update)
1638                                         {
1639                                                 char* old_string = item_to_update->sub_desc;
1640                                                 item_to_update->sub_desc = strdup(value);
1641                                                 SETTING_TRACE(">>>   o-------------0 STRING VALUE = %s ", value);
1642
1643                                                 // free old string
1644
1645                                                 elm_object_item_data_set(item_to_update->item, item_to_update);
1646                                                 elm_genlist_item_update(item_to_update->item);
1647
1648                                         } else {
1649                                                 SETTING_TRACE("item_to_update is NULL");
1650                                         }
1651                                 }
1652                                 // case : expand list
1653                                 // parent
1654                                 //    child1
1655                                 //    child2
1656                                 //    child3
1657                                 //    child4
1658                                 //-----------------------------------------------------------
1659                                 if ( 0 == strcmp (cur_node->name, "expandlist"))
1660                                 {
1661                                         #if 1
1662                     SETTING_TRACE(">>>>> UPDATE EXPAND LIST CONTROL %x --- %s ",context->ui_list, id_name);
1663                     Setting_GenGroupItem_Data* item_to_update = NULL;
1664                                         item_to_update = (Setting_GenGroupItem_Data*)eina_hash_find(context->ui_list, id_name);
1665                     if  (item_to_update)
1666                     {
1667                         char* old_string = item_to_update->sub_desc;
1668                         item_to_update->sub_desc = strdup(value);
1669                         SETTING_TRACE(">>>   o-------------0 EXPAND LIST VALUE = %s ", value);
1670
1671                         // free old string
1672                         // string update
1673                         elm_object_item_data_set(item_to_update->item, item_to_update);
1674                         elm_genlist_item_update(item_to_update->item);
1675
1676                         // TODO: need to update child elements
1677                         // item_to_update->childs ---> expanded list
1678
1679                                                 // debug log
1680                                                 // there should have 4 sub items.
1681                                                 //-----------------------------------------------------
1682                                                 // has it already freed by someone?
1683                                                 //-----------------------------------------------------
1684                                                 if (item_to_update->childs)
1685                                                 {
1686                                                         int howmany2 =0;
1687                                                         Eina_List *li = item_to_update->childs;
1688                                                         while(li)
1689                                                         {
1690                                                                 Setting_GenGroupItem_Data* node = eina_list_data_get(li);
1691                                                                 howmany2 += 1;
1692                                                                 li = eina_list_next(li);
1693                                                         }
1694                                                         SETTING_TRACE(" expandlist -- how many items are there? : %d ", howmany2);
1695                                                 }
1696
1697                         if (item_to_update->childs)
1698                         {
1699                             Eina_List *li = item_to_update->childs;
1700                             int radio_index = 0;
1701                             while(li)
1702                             {
1703                                 Setting_GenGroupItem_Data* node = eina_list_data_get(li);
1704
1705                                 if (node->item && node->keyStr)
1706                                 {
1707                                     // do something more
1708                                     // SETTING_TRACE(">>> RADIO LIST STRING VALUE = %s ", node->keyStr);
1709                                     // set position of radio button
1710                                     if (value && strcmp(node->keyStr, value) == 0) // << CRAAH !!!!
1711                                     {
1712                                         elm_radio_value_set(node->rgd, radio_index);
1713                                     }
1714                                 } else {
1715                                      SETTING_TRACE(">>> node has unproper values - Setting_GenGroupItem_Data");
1716                                 }
1717                                 elm_object_item_data_set(item_to_update->item, item_to_update);
1718                                 elm_genlist_item_update(item_to_update->item);
1719
1720                                 // go next
1721                                 li = eina_list_next(li);
1722                                 radio_index++;
1723                             }
1724
1725                         }
1726                     } else {
1727                         SETTING_TRACE("item_to_update is NULL");
1728                     }
1729
1730                                         #endif
1731                                 }
1732                                 *is_end = true;
1733                         }
1734                 }
1735                 __node_finder(context, cur_node->children, id_str, value, is_end);      /* RECURSIVE */
1736         }
1737         return 0;
1738 }
1739
1740 static unsigned int _plugin_string_key_length(const char*key)
1741 {
1742         if (!key)
1743                 return 0;
1744
1745         return (int)strlen(key) + 1;
1746 }
1747
1748 static int _plugin_string_key_cmp(const char* key1, int key1_length,
1749                                                                         const char* key2, int key2_length)
1750 {
1751         return strcmp(key1, key2);
1752 }
1753
1754 static void _plugin_entry_free_cb(void* data)
1755 {
1756 #if 0
1757         // this code already have done in genlist_unrealized
1758     Setting_GenGroupItem_Data* node = (Setting_GenGroupItem_Data*) data;
1759         if (node->childs)
1760         {
1761                 eina_list_free(node->childs);
1762                 node->childs = NULL;
1763         }
1764 #endif
1765 }
1766
1767 PluginNode* setting_plugin_create(Evas_Object* navi, Evas_Object* win)
1768 {
1769         PluginNode *plugin = calloc(1, sizeof(PluginNode));
1770         setting_retvm_if(!plugin, -1, "Create PluginNode obj failed");
1771         Draw_Data *pd = calloc(1, sizeof(Draw_Data));
1772
1773         if (!pd) {
1774                 FREE(plugin);
1775         }
1776
1777         setting_retvm_if(!pd, -1, "Create Draw_Data obj failed");
1778         plugin->ug = NULL;
1779         plugin->ly_main = NULL;
1780         plugin->pd = pd;
1781         plugin->navi_bar = navi;
1782         plugin->win_main = win;
1783
1784         plugin->ui_list = eina_hash_new(EINA_KEY_LENGTH(_plugin_string_key_length),
1785                                                                   EINA_KEY_CMP(_plugin_string_key_cmp),
1786                                                                   EINA_KEY_HASH(eina_hash_superfast),
1787                                                                   _plugin_entry_free_cb,
1788                                                                   5); // 2^5
1789
1790         return plugin;
1791 }
1792
1793 void setting_plugin_destroy(PluginNode* node)
1794 {
1795         SETTING_TRACE_BEGIN;
1796         if (node) {
1797                 SETTING_TRACE("node is NOT NULL")
1798                 if (node->pd) {
1799                         SETTING_TRACE("node->pd is NOT NULL")
1800                         if(node->pd->doc != NULL) {
1801                                 xmlSaveFormatFile(node->plugin_path, node->pd->doc, 1);
1802                                 xmlFreeDoc(node->pd->doc);
1803                                 node->pd->doc = NULL;
1804                                 SETTING_TRACE("__cfg_file_write successful");
1805                         }
1806
1807                         free(node->pd);
1808                         node->pd = NULL;
1809                 }
1810
1811                 if (node->ui_list) {
1812                         eina_hash_free(node->ui_list);
1813                         node->ui_list = NULL;
1814                 }
1815                 free(node);
1816                 node = NULL;
1817 //              PLUGIN_FINI;
1818         }
1819 }
1820
1821
1822 static Eina_Bool _plugin_foreach_cb(const Eina_Hash *hash, const void*key, void* data, void* fdata)
1823 {
1824     Setting_GenGroupItem_Data* node = (Setting_GenGroupItem_Data*) data;
1825         SETTING_TRACE("%s --- %s ", (char*)key, node->keyStr);
1826         return EINA_TRUE;
1827 }
1828
1829
1830 void setting_plugin_debug(PluginNode* context)
1831 {
1832 //      SETTING_TRACE("HASH TABLE -------------------------------------");
1833         if (context->ui_list) {
1834                 eina_hash_foreach(context->ui_list,_plugin_foreach_cb, NULL);
1835         }
1836 //      SETTING_TRACE("HASH TABLE -------------------------------------");
1837
1838 }
1839
1840 void setting_plugin_update(PluginNode* context)
1841 {
1842     Eina_List *li = context->ui_list;
1843
1844     while (li) {
1845         Setting_GenGroupItem_Data* node = (Setting_GenGroupItem_Data*) eina_list_data_get(li);
1846         if (node) {
1847             // SETTING_TRACE(" ---> keyStr : %s , swallow type : %d  ", node->keyStr, node->swallow_type);
1848                         Setting_GenGroupItem_Data* item_to_update = NULL;
1849                         item_to_update = node;
1850                         elm_object_item_data_set(item_to_update->item, item_to_update);
1851                         elm_genlist_item_update(item_to_update->item);
1852         }
1853         li = eina_list_next(li);
1854         }
1855 }
1856
1857
1858 /**
1859  * set modifiable
1860  */
1861 int setting_plugin_load(PluginNode* node, const char *cfg_file)
1862 {
1863         SETTING_TRACE("cfg_file:%s", cfg_file)
1864         if (isEmptyStr(cfg_file) || 0 != access(cfg_file, R_OK|W_OK|F_OK ))
1865         {
1866                 SETTING_TRACE_ERROR(" error occured : access = %d ", errno);
1867                 return -1;
1868         }
1869         node->pd->cfg_file = cfg_file;
1870
1871         node->pd->doc = xmlParseFile(cfg_file);
1872         node->pd->root = xmlDocGetRootElement(node->pd->doc);
1873
1874         // signal filter change
1875         //void* user_data = (void*)g_main_ad;
1876         void* user_data = (void*)node;
1877
1878         DBusError error;
1879         dbus_error_init(&error);
1880         char rule[MAX_LOCAL_BUFSIZE + 1] = {0,};
1881         bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
1882         if (!bus)
1883         {
1884                 SETTING_TRACE("Fail to connect to the D-BUS daemon: %s", error.message);
1885                 dbus_error_free(&error);
1886                 return -1;
1887         }
1888
1889         // get rule
1890         snprintf(rule, MAX_LOCAL_BUFSIZE, "path='%s',type='signal',interface='%s'", DBUS_PATH, DBUS_SIGNAL_INTERFACE);
1891         dbus_bus_add_match(bus, rule, &error);
1892         if (dbus_error_is_set(&error))
1893         {
1894                 SETTING_TRACE("Fail to rule set; %s", error.message);
1895                 dbus_bus_remove_match(bus, rule, &error);
1896                 dbus_error_free(&error);
1897                 dbus_connection_close(bus);
1898                 bus = NULL;
1899                 return -1;
1900         }
1901
1902         // re-add filter
1903         if (dbus_connection_add_filter(bus, __signal_filter, user_data, NULL) == FALSE)
1904         {
1905                 SETTING_TRACE("Fail to add filter ----- ");
1906                 dbus_bus_remove_match(bus, rule, &error);
1907                 dbus_error_free(&error);
1908                 dbus_connection_close(bus);
1909                 bus = NULL;
1910                 return -1;
1911         }
1912
1913         int count = 0;
1914         __node_walk_check(node, node->pd->root, &count);
1915         SETTING_TRACE(" node count : %d ", count);
1916         node->nitems = count;
1917         __node_walker(node, node->pd->root);
1918
1919         // debug message
1920         //setting_plugin_debug(node);
1921         return 1;
1922 }
1923
1924