fixed N_SE-47240
[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         char* temp = substring(path, APPID_POS_FROM_PATH, APPID_LENGTH/*string size*/);
210         SETTING_TRACE("package ID : >>> %s ",temp );
211         return temp;
212 }
213
214 //------------------------------------------------------
215 // for client - bus
216 static DBusConnection *bus;
217 //------------------------------------------------------
218 static DBusHandlerResult __signal_filter(DBusConnection* conn, DBusMessage* message, void* user_data)
219 {
220     int my_pid = getpid();
221     int sender_pid = 0;
222     char* key = NULL;
223     char* value = NULL;
224
225         if (message == NULL)
226                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
227
228     DBusError error;
229     dbus_error_init(&error);
230
231         PluginNode* ad = (PluginNode*)user_data;
232
233         //char* plugin_path = ad->plugin_path;
234         char* plugin_path = s_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
446         if (dbus_connection_add_filter(bus, __signal_filter, user_data, NULL) == FALSE)
447         {
448                 dbus_bus_remove_match(bus, rule, &error);
449                 dbus_error_free(&error);
450                 dbus_connection_close(bus);
451                 bus = NULL;
452                 return -1;
453         }
454
455         SETTING_TRACE("app signal initialized");
456         return 0;
457 }
458
459 int setting_dbus_handler_fini(void)
460 {
461         SETTING_TRACE_BEGIN;
462         //do safty checking first.
463         setting_retvm_if(!bus, 0, "!bus");
464         DBusError error;
465         memset(&error, 0, sizeof(DBusError));
466         char rule[MAX_LOCAL_BUFSIZE + 1] = {0, };
467
468         dbus_error_init(&error);
469
470         // why??
471         bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
472
473         //dbus_connection_remove_filter(bus, __signal_filter, NULL);
474
475
476         snprintf(rule, MAX_LOCAL_BUFSIZE, "path='%s',type='signal',interface='%s'", DBUS_PATH, DBUS_SIGNAL_INTERFACE);
477         dbus_bus_remove_match(bus, rule, &error);
478
479         if (dbus_error_is_set(&error))
480         {
481                 SETTING_TRACE("Fail to rule unset: %s", error.message);
482                 dbus_error_free(&error);
483                 //return -1;
484         }
485
486         dbus_connection_close(bus);
487         bus = NULL;
488         SETTING_TRACE("app signal finalized");
489         return 0;
490 }
491
492 /////////////////////////////
493 /////////////////////////////
494 /////////////////////////////
495
496 Elm_Genlist_Item_Class itc_layout;
497
498 // write -> update
499 static int __cfg_file_write(Draw_Data *pd)
500 {
501         SETTING_TRACE_BEGIN;
502
503         GError *error = NULL;
504         if(pd->doc != NULL)
505         {
506                 xmlSaveFormatFile(pd->cfg_file, pd->doc, 1);
507                 //xmlFreeDoc(pd->doc);
508                 //pd->doc = NULL;
509                 SETTING_TRACE("__cfg_file_write successful");
510         }
511
512         SETTING_TRACE_END;
513         return TRUE;
514 }
515
516 typedef struct {
517         int state;
518         Setting_GenGroupItem_Data* obj;
519 } HashArgs;
520
521 static Eina_Bool _plugin_foreach_cb_check_editfield(const Eina_Hash *hash, const void*key, void* data, void* fdata)
522 {
523
524         HashArgs* pret = (HashArgs*)fdata;
525         //int* pret = (int*)fdata;
526
527     Setting_GenGroupItem_Data* node = (Setting_GenGroupItem_Data*) data;
528         //SETTING_TRACE("%s --- %s ", (char*)key, node->keyStr);
529
530         if (node->keyStr && !strcmp(node->keyStr, "string"))
531         {
532                 // focus check
533                 if (elm_object_focus_get(node->eo_check))
534                 {
535                         SETTING_TRACE("FOCUS SET !!! ");
536                         pret->state = 1;
537                         pret->obj= node;
538                         return EINA_FALSE;
539                 } else {
540                         SETTING_TRACE("FOCUS UN -- SET !!! ");
541                         pret->state = 0;
542                 }
543         }
544
545         return EINA_TRUE;
546 }
547
548 int setting_plugin_is_editfield_exist(PluginNode* context)
549 {
550         int ret = 0;
551         HashArgs arg;
552         arg.state = 0;
553         arg.obj = NULL;
554
555         if (context->ui_list) {
556                 eina_hash_foreach(context->ui_list,_plugin_foreach_cb_check_editfield, &arg);
557         }
558         SETTING_TRACE("%d -- (%x)", arg.state, arg.obj);
559
560         if (arg.state )
561         {
562                 ret = 0;
563
564                 Setting_GenGroupItem_Data* list_item = arg.obj;
565                 int min_length = list_item->minlength;
566                 int entry_len = safeStrLen(list_item->sub_desc);
567                 //SETTING_TRACE(" >>> entry _ len : %d ", entry_len);
568                 //SETTING_TRACE(" >>> minlength _ len : %d ", min_length);
569
570                 if ( entry_len < min_length)
571                 {
572                         if (!list_item->notify) {
573                                 SETTING_TRACE("notify 1");
574                                 list_item->notify = setting_create_popup_without_btn(list_item, list_item->win_main,
575                                                 NULL, _(EXCEED_MINLENGTH_LIMITATION_STR),
576                                                 __error_popup_response_cb,
577                                                 POPUP_INTERVAL, FALSE, FALSE);
578                                 elm_object_focus_set(list_item->eo_check, EINA_FALSE);
579                         } else {
580                                 SETTING_TRACE("notify 0 ");
581                                 //postpone 2 seconds again
582                                 elm_popup_timeout_set(list_item->notify, POPUP_INTERVAL);
583                         }
584                         //elm_object_focus_set(obj, EINA_TRUE);
585
586                         ret = 1;
587                 }
588         }
589
590         return ret;
591 }
592
593 static Eina_Bool ___click_softkey_back_cb(void *data, Evas_Object *obj, void *event_info)
594 {
595         SETTING_TRACE_BEGIN;
596         ret_if(!data);
597         PluginNode* node = (PluginNode*)data;
598         Draw_Data *pd = node->pd;
599
600         int is_stop = setting_plugin_is_editfield_exist(node);
601         if (is_stop)
602                 return EINA_FALSE;
603         // continue
604
605         static int work = 0;
606
607         if (work == 0)
608         {
609                 work = 1;
610                 #if 0
611                 if (node->navi_bar)
612                 {
613                         elm_naviframe_item_pop(node->navi_bar);
614                 }
615                 #endif
616                 ui_gadget_h ug = node->ug;
617
618                 #if 0
619                 //pd->scroller = NULL;
620                 //pd->cfg_file = NULL;
621                 //pd->root = NULL;
622                 #endif
623
624                 // check callback -----------------------------------------
625
626                 //---------------------------------------------------------
627
628                 // ug --> destroy
629                 if(ug)
630                 {
631                         SETTING_TRACE(" before ug_destory me ----<<<<<< ");
632                         ug_destroy_me(ug);
633                         SETTING_TRACE(" after ug_destory me ----<<<<<< ");
634                 } else {
635                         setting_plugin_destroy(node);
636                         if (node->navi_bar)
637                         {
638                                 elm_naviframe_item_pop(node->navi_bar);
639                         }
640                         SETTING_TRACE(" UG is NULL  now ----<<<<<< ");
641                 }
642                 work = 0;
643         }
644         return EINA_TRUE;
645 }
646
647
648 static void* group_func(void *data, xmlNode *xmlObj)
649 {
650         SETTING_TRACE_BEGIN;
651         retv_if(!data || !xmlObj, NULL);
652
653         PluginNode* node = (PluginNode*)data;
654         Draw_Data *pd = node->pd;
655
656         // new code is recursive
657         const char *title = (char*)xmlGetProp(xmlObj, "title");
658         SETTING_TRACE (" >>> GROUP NAME : %s \n", title);
659         (void)setting_create_Gendial_field_titleItem(pd->scroller, &(itc_group_item), title, NULL);
660         return NULL;
661 };
662
663
664 static void* __link_list_cb(void *data, Evas_Object *obj, void *event_info)
665 {
666         SETTING_TRACE_BEGIN;
667         retv_if(data == NULL, NULL);
668         retvm_if(event_info == NULL, NULL, "Invalid argument: event info is NULL");
669         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
670         elm_genlist_item_selected_set(item, 0);
671         Setting_GenGroupItem_Data *list_item =
672             (Setting_GenGroupItem_Data *) elm_object_item_data_get(item);
673
674         xmlNode* xmlObj = data;
675         retv_if(!xmlObj, NULL);
676         const char *link_file = (char*)xmlGetProp(xmlObj, "value");
677
678         if(!link_file)
679         {
680                 SETTING_TRACE_ERROR("Invalidate liked file");
681                 return NULL;
682         }
683         char file[1024] = {0,};
684         snprintf(file, sizeof(file), "%s/%s", PLUGIN_CFG_DIR, link_file);
685         SETTING_TRACE("file:%s", file);
686
687 // Evas_Object* navi_bar, Evas_Object* win_main
688         PluginNode* plugin_node = setting_plugin_create( NULL, NULL );
689         setting_plugin_load(plugin_node, (const char *)file);
690         return NULL;
691 }
692
693 static void* __launch_list_cb(void *data, Evas_Object *obj, void *event_info)
694 {
695         SETTING_TRACE_BEGIN;
696         retv_if(data == NULL, NULL);
697         retvm_if(event_info == NULL, NULL, "Invalid argument: event info is NULL");
698         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
699         elm_genlist_item_selected_set(item, 0);
700         Setting_GenGroupItem_Data *list_item =
701             (Setting_GenGroupItem_Data *) elm_object_item_data_get(item);
702
703         xmlNode* xmlObj = data;
704         retv_if(!xmlObj, NULL);
705         const char *key_str = (char*)xmlGetProp(xmlObj, "id");
706         const char *title_str = (char*)xmlGetProp(xmlObj, "title");
707         const char *appid_str = (char*)xmlGetProp(xmlObj, "appid");
708         const char *operation_str = (char*)xmlGetProp(xmlObj, "operation");
709
710
711         service_h svc = NULL;
712         service_create(&svc);
713         if (!appid_str) appid_str = "";
714         if (!operation_str) operation_str = "";
715
716         service_set_app_id(svc, appid_str);                                                     // xml property â€“ appid
717         service_set_operation(svc, operation_str);                                              // property : operation
718         service_send_launch_request(svc, NULL, NULL);
719         service_destroy(svc);
720
721         return NULL;
722 }
723
724 static void* label_func(void *data, xmlNode *xmlObj)
725 {
726         SETTING_TRACE_BEGIN;
727         retv_if(!data || !xmlObj, NULL);
728         PluginNode* node = (PluginNode*)data;
729         Draw_Data *pd = node->pd;
730
731         const char *title = (char*)xmlGetProp(xmlObj, "title");
732
733         Setting_GenGroupItem_Data *obj =
734                 setting_create_Gendial_field_def(pd->scroller, &(itc_1text),
735                                                  NULL,
736                                                  xmlObj, SWALLOW_Type_INVALID, NULL, NULL,
737                                                  0, title, NULL, NULL);
738
739         return obj;
740 }
741
742 static void* link_func(void *data, xmlNode *xmlObj)
743 {
744         SETTING_TRACE_BEGIN;
745         retv_if(!data || !xmlObj, NULL);
746         PluginNode* node = (PluginNode*)data;
747         Draw_Data *pd = node->pd;
748
749         const char *key_str = (char*)xmlGetProp(xmlObj, "id");
750         Setting_GenGroupItem_Data * obj =
751                 setting_create_Gendial_field_def(pd->scroller, &(itc_1text),
752                                                  __link_list_cb,
753                                                  xmlObj, SWALLOW_Type_INVALID, NULL, NULL,
754                                                  0, key_str, NULL, NULL);
755
756         return (void*)obj;
757 };
758
759 static void* launch_func(void *data, xmlNode *xmlObj)
760 {
761         SETTING_TRACE_BEGIN;
762         retv_if(!data || !xmlObj, NULL);
763         PluginNode* node = (PluginNode*)data;
764         Draw_Data *pd = node->pd;
765
766         const char *title_str = (char*)xmlGetProp(xmlObj, "title");
767
768         Setting_GenGroupItem_Data * obj =
769                 setting_create_Gendial_field_def(pd->scroller, &(itc_1text),
770                                                  __launch_list_cb,
771                                                  xmlObj, SWALLOW_Type_INVALID, NULL, NULL,
772                                                  0, title_str, NULL, NULL);
773
774         return (void*)obj;
775 };
776
777 static void __slider_stop_cb(void *data, Evas_Object *obj,
778                                     void *event_info)
779 {
780         ret_if(data == NULL || obj == NULL);
781         double val = elm_slider_value_get(obj);
782         SETTING_TRACE("val = %f", val);
783         Setting_GenGroupItem_Data *list_item = data;
784         ret_if(list_item->userdata == NULL);
785
786         xmlNode* xmlObj = list_item->userdata;
787         ret_if(!xmlObj);
788
789         //apply the vconf changes after stopping moving slider..
790         list_item->chk_status = (int)(val + 0.5);
791         elm_slider_value_set(obj, list_item->chk_status);
792
793         SETTING_TRACE(" slider after ---> val = %d", (int) list_item->chk_status);
794
795         // int -> double -> xmlChar*
796         xmlAttrPtr newattr;
797         char buf[10];
798         sprintf(buf, "%d", (int) list_item->chk_status);
799         newattr = xmlSetProp(xmlObj, "value", buf);
800
801         __send_int_msg(xmlObj, list_item->chk_status);
802         __cfg_file_write((Draw_Data *)list_item->belongs_to);
803 }
804
805
806 static void* slider_func(void *data, xmlNode *xmlObj)
807 {
808         SETTING_TRACE_BEGIN;
809         retv_if(!data || !xmlObj, NULL);
810         PluginNode* node = (PluginNode*)data;
811         Draw_Data *pd = node->pd;
812
813         // type casting
814         const char *title = (char*)xmlGetProp(xmlObj, "title");
815
816         SETTING_TRACE (" >>> [slider input] min=%s max=%s value=%s ",(char*)xmlGetProp(xmlObj, "min"), (char*)xmlGetProp(xmlObj, "max"), (char*)xmlGetProp(xmlObj, "value"));
817
818         int value = atoi((char*)xmlGetProp(xmlObj, "value"));
819         int min = atoi((char*)xmlGetProp(xmlObj, "min"));
820         int max = atoi((char*)xmlGetProp(xmlObj, "max"));
821
822         SETTING_TRACE ("[slider input] min=%d max=%d value=%d ", min, max, value);
823
824         setting_create_Gendial_itc("dialogue/1text.1icon.5", &(itc_layout));
825         Setting_GenGroupItem_Data *list_item =
826             setting_create_Gendial_field_def(pd->scroller, &(itc_layout), NULL,
827                                              NULL,
828                                              SWALLOW_Type_LAYOUT_SLIDER,
829                                              IMG_SENSITIVITY_ICON_01,
830                                              IMG_SENSITIVITY_ICON_02, value,
831                                              title, NULL, NULL);
832         if (list_item) {
833                 list_item->win_main = NULL;
834                 list_item->evas = NULL;
835                 list_item->isIndicatorVisible = true;
836                 list_item->slider_min = min;
837                 list_item->slider_max = max;
838                 list_item->userdata = xmlObj;
839                 list_item->stop_change_cb = __slider_stop_cb;
840                 list_item->belongs_to = (int)pd;
841         }
842
843         g_list_item = list_item;
844
845         return (void*)list_item;
846 };
847
848 static void __check_mouse_up_cb(void *data, Evas_Object *obj,
849                                              void *event_info)
850 {
851         /* error check */
852         SETTING_TRACE_BEGIN;
853         setting_retm_if(data == NULL, "Data parameter is NULL");
854
855         retm_if(event_info == NULL, "Invalid argument: event info is NULL");
856         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
857         elm_genlist_item_selected_set(item, 0);
858         Setting_GenGroupItem_Data *list_item =
859             (Setting_GenGroupItem_Data *) elm_object_item_data_get(item);
860
861         SETTING_TRACE("clicking item[%s]", _(list_item->keyStr));
862
863         int old_status = elm_check_state_get(list_item->eo_check);
864         list_item->chk_status = !old_status;
865         elm_check_state_set(list_item->eo_check, list_item->chk_status);
866
867         xmlNode *xmlObj = data;
868         xmlAttrPtr newattr;
869         newattr = xmlSetProp(xmlObj, "state", xmlXPathCastNumberToString(list_item->chk_status));
870
871         __send_int_msg(xmlObj, list_item->chk_status);
872         __cfg_file_write((Draw_Data *)list_item->belongs_to);
873 }
874
875
876 static void __chk_btn_cb(void *data, Evas_Object *obj,
877                                              void *event_info)
878 {
879         SETTING_TRACE_BEGIN;
880         /* error check */
881         retm_if(data == NULL, "Data parameter is NULL");
882         Setting_GenGroupItem_Data *list_item = (Setting_GenGroupItem_Data *) data;
883
884         xmlNode* xmlObj = list_item->userdata;
885         ret_if(!xmlObj);
886         list_item->chk_status = elm_check_state_get(obj);       /*  for genlist update status */
887
888         xmlAttrPtr newattr;
889         if (list_item->chk_status == 1) {
890                 newattr = xmlSetProp(xmlObj, "value", "true");
891         } else if (list_item->chk_status == 0) {
892                 newattr = xmlSetProp(xmlObj, "value", "false");
893         } else {
894                 newattr = xmlSetProp(xmlObj, "value", "false");
895         }
896
897         const char *id = (char*)xmlGetProp(xmlObj, "id");
898         const char *title = (char*)xmlGetProp(xmlObj, "title");
899         //SETTING_TRACE(" >>>> id:%s , title:%s", id, title);
900         __send_int_msg(xmlObj, list_item->chk_status);
901         __cfg_file_write((Draw_Data *)list_item->belongs_to);
902         return;
903 }
904
905
906 static void* checkbox_func(void *data, xmlNode *xmlObj)
907 {
908         SETTING_TRACE_BEGIN;
909         retv_if(!data || !xmlObj, NULL);
910
911         PluginNode* node = (PluginNode*)data;
912         Draw_Data *pd = node->pd;
913
914         // [DATA] title, value
915         const char *title = (char*)xmlGetProp(xmlObj, "title");
916
917         // true / false
918         char* value = (char*)xmlGetProp(xmlObj, "value");
919
920         int ival = -1;
921
922         if ( 0 == safeStrCmp(value, "true")) {
923                 ival = 1;
924         } else if ( 0 == safeStrCmp(value, "false"))  {
925                 ival = 0;
926         } else {
927                 ival = 0;       // default : false (0)
928         }
929
930         // title, value, xmlObj
931         Setting_GenGroupItem_Data *list_item =
932                 setting_create_Gendial_field_def(pd->scroller,
933                                           &(itc_1text_1icon),
934                                           __check_mouse_up_cb,
935                                           xmlObj,
936                                           SWALLOW_Type_1TOGGLE,
937                                           NULL, NULL,
938                                           ival,
939                                           title,
940                                           NULL,
941                                           __chk_btn_cb);
942         if(list_item) {
943                 list_item->userdata = xmlObj;
944                 list_item->belongs_to = (int) pd;
945                 SETTING_TRACE("pd:%p,list_item->belongs_to:%d", pd, list_item->belongs_to);
946         }
947
948         return list_item;
949 }
950
951
952 static void __entry_unfocus_cb(void *data, Evas_Object *obj, void *event_info)
953 {
954         SETTING_TRACE_BEGIN;
955         retm_if(!data || !obj, "Data parameter is NULL");
956
957         //-------------------------------------------------------------------------------------------
958         Evas_Object *entry_container = data;
959         //whe entry unfocused, its guidetext will becomes "Input here"
960         elm_object_part_text_set(entry_container, "elm.guidetext", _("IDS_ST_BODY_TAP_TO_INSERT"));
961         if (elm_entry_is_empty(obj))
962                 elm_object_signal_emit(entry_container, "elm,state,guidetext,show", "elm");
963         elm_object_signal_emit(entry_container, "elm,state,eraser,hide", "elm");
964         //-------------------------------------------------------------------------------------------
965
966
967         //setting_hide_input_pannel_cb(obj);
968
969         const char *entry_str = elm_entry_entry_get(obj);
970         char *entry_str_utf8 = NULL;
971         entry_str_utf8 = elm_entry_markup_to_utf8(entry_str);
972
973         Setting_GenGroupItem_Data *list_item = data;
974
975         // check minlentgh of the string
976         int min_length = list_item->minlength;
977         int entry_len = safeStrLen(entry_str_utf8);
978
979         SETTING_TRACE(" >>> minlength _ len : %d ", min_length);
980         SETTING_TRACE(" >>> entry _ len : %d ", entry_len);
981
982         SETTING_TRACE(" >>> 1");
983         if (entry_len < min_length) {
984
985                 if (!list_item->notify) {
986                         list_item->notify = setting_create_popup_without_btn(list_item, list_item->win_main,
987                                                                  NULL, _(EXCEED_MINLENGTH_LIMITATION_STR),
988                                                                          __error_popup_response_cb,
989                                                                          POPUP_INTERVAL, FALSE, FALSE);
990                         elm_object_focus_set(list_item->eo_check, EINA_FALSE);
991                 } else {
992                         //postpone 2 seconds again
993                         elm_popup_timeout_set(list_item->notify, POPUP_INTERVAL);
994                 }
995                 // elm_object_focus_set(obj, EINA_TRUE);
996                 return;
997         }
998
999         // send data
1000         xmlNode* xmlObj = list_item->userdata;
1001         if(!xmlObj) {
1002                 FREE(entry_str_utf8);
1003                 return;
1004         }
1005
1006         xmlAttrPtr newattr;
1007         const char *title = (char*)xmlSetProp(xmlObj, "value",entry_str_utf8);
1008
1009         __send_string_msg(xmlObj, entry_str_utf8);
1010         __cfg_file_write((Draw_Data *)list_item->belongs_to);
1011
1012         FREE(entry_str_utf8);
1013         SETTING_TRACE_END;
1014 }
1015
1016
1017 static void __editbox_list_cb(void *data, Evas_Object *obj,
1018                                             void *event_info)
1019 {
1020         SETTING_TRACE_BEGIN;
1021         /* error check */
1022 #if 0
1023         retm_if(event_info == NULL, "Invalid argument: event info is NULL");
1024         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
1025         elm_genlist_item_selected_set(item, 0);
1026         Setting_GenGroupItem_Data *list_item = (Setting_GenGroupItem_Data *) elm_object_item_data_get(item);
1027
1028         SETTING_TRACE("clicking item[%s]", _(list_item->keyStr));
1029         if (!elm_object_focus_get(list_item->eo_check)) {
1030                 elm_object_focus_set(list_item->eo_check, EINA_TRUE);
1031         }
1032         Ecore_IMF_Context *imf_context = (Ecore_IMF_Context *)elm_entry_imf_context_get(list_item->eo_check);
1033         setting_retm_if(imf_context == NULL, "imf_context is NULL");
1034         ecore_imf_context_input_panel_show(imf_context);
1035 #endif
1036 }
1037
1038
1039 static void __editbox_changed_cb(void *data, Evas_Object *obj,
1040                                        void *event_info)
1041 {
1042         SETTING_TRACE_BEGIN;
1043         retm_if(!data || !obj, "Data parameter is NULL");
1044         retm_if(!elm_object_focus_get(obj), "Entry is not focused");
1045
1046         Setting_GenGroupItem_Data *list_item = (Setting_GenGroupItem_Data *) data;
1047
1048         const char *entry_str = elm_entry_entry_get(obj);
1049         int entry_len = safeStrLen(entry_str);
1050         SETTING_TRACE("entry_str:[%s], length:%d", entry_str, entry_len);
1051
1052         G_FREE(list_item->sub_desc);//release first
1053         list_item->sub_desc = (char *)g_strdup(entry_str);
1054 }
1055
1056
1057 /**
1058  *  editbox
1059  *
1060  * @see also __editbox_changed_cb
1061  * @see also __entry_unfocus_cb
1062  */
1063 static void* editbox_func(void *data, xmlNode *xmlObj)
1064 {
1065         SETTING_TRACE_BEGIN;
1066         retv_if(!data || !xmlObj, NULL);
1067
1068         PluginNode* node = (PluginNode*)data;
1069         Draw_Data *pd = node->pd;
1070
1071         const char *title = (char*)xmlGetProp(xmlObj, "title");
1072         const char *key_str= (char*)xmlGetProp(xmlObj, "value");
1073
1074         const char *minlength= (char*)xmlGetProp(xmlObj, "minlength");
1075         const char *maxlength= (char*)xmlGetProp(xmlObj, "maxlength");
1076
1077         // MAXLENGTH HANDLER
1078         int max_len = -1;
1079         if (maxlength)
1080         {
1081                 max_len = atoi(maxlength);
1082                 SETTING_TRACE(" >> MAXLENGTH FILTER IS AVAILABLE !!!! maxlength = %d", max_len);
1083         }
1084
1085         int min_len = -1;
1086         if (maxlength)
1087         {
1088                 min_len = atoi(minlength);
1089                 SETTING_TRACE(" >> MINLENGTH FILTER IS AVAILABLE !!!! minlength = %d", min_len);
1090         }
1091
1092         Setting_GenGroupItem_Data *list_item = NULL;
1093
1094         if (max_len == -1 && min_len == -1 )
1095         {
1096                 // without maxlength filter
1097                 list_item = setting_create_Gendial_field_def(pd->scroller, &(itc_dialogue_editfield_title),
1098                                                                  __editbox_list_cb,
1099                                                          pd, SWALLOW_Type_LAYOUT_ENTRY,
1100                                                          NULL, NULL, 0, title, key_str,
1101                                                          __editbox_changed_cb);
1102
1103         } else {
1104                 // add max length filter
1105                 list_item = setting_create_Gendial_field_entry_fo(
1106                                                                         pd->scroller,
1107                                                                         &(itc_dialogue_editfield_title),
1108                                                                         __editbox_list_cb,
1109                                                                         pd,
1110                                                                         SWALLOW_Type_LAYOUT_ENTRY,
1111                                                                         NULL, NULL, 0, title, key_str,
1112                                                                         __editbox_changed_cb,
1113                                                                         __entry_unfocus_cb,
1114                                                                         ELM_INPUT_PANEL_LAYOUT_NORMAL,
1115                                                                         false,
1116                                                                         false,
1117                                                                         min_len,
1118                                                                         max_len,
1119                                                                         0,
1120                                                                         NULL, NULL);
1121
1122         }
1123         if (list_item) {
1124                 list_item->userdata = xmlObj;
1125                 list_item->stop_change_cb = __entry_unfocus_cb;
1126                 list_item->belongs_to = (int)pd;
1127
1128                 // for popup
1129                 list_item->win_main = node->win_main;
1130         }
1131
1132         return list_item;
1133 };
1134
1135
1136 static void __expanditem_func_sel_cb(void *data, Evas_Object *obj, void *event_info)
1137 {
1138         SETTING_TRACE_BEGIN;
1139         /* error check */
1140         retm_if(event_info == NULL, "Invalid argument: event info is NULL");
1141         Elm_Object_Item *subitem = (Elm_Object_Item *) event_info;
1142         Elm_Object_Item *parentItem = elm_genlist_item_parent_get(subitem);
1143         elm_genlist_item_selected_set(subitem, 0);
1144         Setting_GenGroupItem_Data *data_subItem = elm_object_item_data_get(subitem);
1145         Setting_GenGroupItem_Data *data_parentItem = elm_object_item_data_get(parentItem);      /* parent data */
1146         ret_if(NULL == data_subItem || NULL == data_parentItem);
1147
1148         elm_radio_value_set(data_subItem->rgd, data_subItem->chk_status);
1149
1150         data_parentItem->sub_desc = (char *)g_strdup(_(data_subItem->keyStr));
1151         elm_object_item_data_set(data_parentItem->item, data_parentItem);
1152         elm_genlist_item_update(data_parentItem->item);
1153
1154         xmlNode* xmlObj = data_parentItem->userdata;
1155         ret_if(!xmlObj);
1156
1157         xmlAttrPtr newattr;
1158         //newattr = xmlSetProp(xmlObj, "string", data_parentItem->sub_desc);
1159         newattr = xmlSetProp(xmlObj, "value", data_parentItem->sub_desc);
1160
1161         __send_string_msg(xmlObj, data_parentItem->sub_desc);
1162         __cfg_file_write((Draw_Data *)data_parentItem->belongs_to);
1163 }
1164
1165
1166 static void __expanditem_func_exp_cb(void *data, Evas_Object *obj, void *event_info)
1167 {
1168         ret_if(NULL == data || NULL == event_info);
1169         SETTING_TRACE_BEGIN;
1170
1171         PluginNode* node = (PluginNode*)data;
1172         Draw_Data *pd = node->pd;
1173
1174         Elm_Object_Item *parentItem = event_info;       /* parent item */
1175         Setting_GenGroupItem_Data *data_parentItem = elm_object_item_data_get(parentItem);      /* parent data */
1176         Evas_Object *scroller = elm_object_item_widget_get(parentItem);
1177
1178
1179         xmlNode *xmlObj = data_parentItem->userdata;
1180         char *value = (char*)xmlGetProp(xmlObj, "value");
1181         SETTING_TRACE(">>> value = %s", value);
1182         Evas_Object *rgd = NULL;
1183
1184         if (xmlObj->children && !data_parentItem->rgd) {//to protect from entering repeatly
1185                 xmlNode* cur = xmlObj->children;
1186
1187                 rgd = elm_radio_add(scroller);
1188                 elm_radio_value_set(rgd, -1);
1189
1190                 char *type;
1191                 char *subitem_title = NULL;
1192                 int subitem_index = 0;
1193                 int sel_idx = -1;
1194
1195 #if 0
1196                 // print out debug message
1197                 if (data_parentItem->childs)
1198                 {
1199                         int howmany = 0;
1200                         Eina_List *li = data_parentItem->childs;
1201                         while(li)
1202                         {
1203                                 Setting_GenGroupItem_Data* node = eina_list_data_get(li);
1204                                 howmany += 1;
1205                                 //SETTING_TRACE(" <<< node->keyStr : %s >>> ", node->keyStr);
1206
1207                                 // go next
1208                                 li = eina_list_next(li);
1209                         }
1210                         //SETTING_TRACE(" <<<how many : %d>>> ", howmany);
1211                 }
1212 #endif
1213                 if (data_parentItem->childs)
1214                 {
1215                         eina_list_free(data_parentItem->childs);
1216                         data_parentItem->childs = NULL;
1217                 }
1218
1219                 while (cur != NULL) {
1220                         if (!xmlStrcmp(cur->name, (const xmlChar*)"expanditem")) {
1221                                 type = (char*)xmlGetProp(cur, "type");
1222                                 if (0 == safeStrCmp(type, "radio")) {
1223                                         subitem_title = (char*)xmlGetProp(cur, "title");
1224                                         Setting_GenGroupItem_Data *list_item =
1225                                                                                         setting_create_Gendial_exp_sub_field(scroller,
1226                                                                                                         &(itc_1icon_1text_sub),
1227                                                                                                         __expanditem_func_sel_cb, NULL, parentItem,
1228                                                                                                         SWALLOW_Type_1RADIO, rgd,
1229                                                                                                         subitem_index,
1230                                                                                                         subitem_title, NULL);
1231
1232
1233                                         if (0 == safeStrCmp(value, subitem_title)) {
1234                                                 sel_idx = subitem_index;
1235                                                 SETTING_TRACE("%d is selected in Radio Group", sel_idx);
1236                                         }
1237                                         SETTING_TRACE(" eina list add >>> value = %s, subitem_title = %s ", value, subitem_title);
1238                                         data_parentItem->childs = eina_list_append(data_parentItem->childs, list_item);
1239                                         subitem_index++;
1240
1241                                 } else {
1242                                         SETTING_TRACE("invalid type[:%s]", type);
1243                                 }
1244                         }
1245                         cur = cur->next;
1246                 }
1247
1248                 // value set
1249                 elm_radio_value_set(rgd, sel_idx);
1250                 data_parentItem->rgd = rgd;//protecting condition
1251         }
1252 }
1253
1254
1255 static void __expanditem_func_smart_cb(void *data, Evas_Object *obj, void *event_info)
1256 {
1257         ret_if(data == NULL || event_info == NULL);
1258         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
1259         Setting_GenGroupItem_Data *data_item = elm_object_item_data_get(item);
1260         char *cb_type = data;
1261
1262         if (0 == safeStrCmp(cb_type, "contracted")) {
1263                 data_item->rgd = NULL;
1264                 elm_genlist_item_subitems_clear(item);
1265         }
1266 }
1267
1268
1269 static void* settings_func(void *data, xmlNode *xmlObj)
1270 {
1271         SETTING_TRACE_BEGIN;
1272         retv_if(!data || !xmlObj, NULL);
1273         PluginNode* node = (PluginNode*)data;
1274
1275         int count = 0;
1276         count = node->nitems;
1277
1278         if (count == 1)         // if there's <settings> only
1279         {
1280                 SETTING_TRACE("there's only <settings>");
1281                 setting_func(data, xmlObj);
1282         }
1283         return NULL;
1284 }
1285
1286
1287 static void __plugin_genlist_unrealized_cb(void* data,Evas_Object* obj, void* event_info)
1288 {
1289         SETTING_TRACE_BEGIN;
1290         ret_if(data == NULL);
1291
1292         Elm_Object_Item *item = (Elm_Object_Item*)event_info;
1293         Setting_GenGroupItem_Data *node = (Setting_GenGroupItem_Data *)elm_object_item_data_get(item);
1294         ret_if(node== NULL);
1295
1296         // SETTING_TRACE("keyStr : %s ", node->keyStr);
1297         // item_to_update->childs)
1298
1299         if (node->childs)
1300         {
1301                 eina_list_free(node->childs);
1302                 node->childs = NULL;
1303         }
1304 }
1305
1306 // <setting>
1307 // 1st create a window
1308 // 2nd push a window
1309 //--------------------------------------------------------
1310 static void* setting_func(void *data, xmlNode *xmlObj)
1311 {
1312         SETTING_TRACE_BEGIN;
1313         retv_if(!data || !xmlObj, NULL);
1314
1315         PluginNode* node = (PluginNode*)data;
1316         Draw_Data *pd = node->pd;
1317
1318         // [DATA] title
1319         const char *title = (char*)xmlGetProp(xmlObj, "title");
1320         if (!title)
1321                 title = "NONAME";
1322         SETTING_TRACE("before setting_create_layout_navi_bar_genlist");
1323
1324         // [UI] with DATA
1325         pd->scroller = elm_genlist_add(node->win_main);
1326         retvm_if(pd->scroller == NULL, NULL,
1327                  "Cannot set scroller object  as contento of layout");
1328         elm_object_style_set(pd->scroller, "dialogue");
1329         elm_genlist_clear(pd->scroller);        /* first to clear list */
1330
1331         evas_object_smart_callback_add(pd->scroller, "unrealized", __plugin_genlist_unrealized_cb, node);
1332
1333         SETTING_TRACE("_(title):%s", _(title));
1334
1335         if (node->ug == NULL)
1336         {
1337                 setting_push_layout_navi_bar(
1338                                                    _(title),
1339                                                    _("IDS_COM_BODY_BACK"), NULL, NULL,
1340                                                    ___click_softkey_back_cb,
1341                                                    NULL, NULL,
1342                                                    data, pd->scroller,
1343                                                    node->navi_bar, NULL);
1344         } else {
1345                 node->ly_main = setting_create_layout_navi_bar(node->win_main_layout, node->win_main,
1346                                                    _(title),
1347                                                    _("IDS_COM_BODY_BACK"), NULL, NULL,
1348                                                    ___click_softkey_back_cb,
1349                                                    NULL, NULL,
1350                                                    data, pd->scroller,
1351                                                    &node->navi_bar, NULL);
1352         }
1353         SETTING_TRACE("after setting_create_layout_navi_bar_genlist");
1354         return NULL;
1355 }
1356
1357
1358 static void* expanditem_func(void *data, xmlNode *xmlObj)
1359 {
1360         // DO NOTHING - expandlist draws this area
1361         return NULL;
1362 }
1363
1364 static void* expandlist_func(void *data, xmlNode *xmlObj)
1365 {
1366         SETTING_TRACE_BEGIN;
1367         retv_if(!data || !xmlObj, NULL);
1368
1369         PluginNode* node = (PluginNode*)data;
1370         Draw_Data *pd = node->pd;
1371
1372         const char *key_str = (char*)xmlGetProp(xmlObj, "title");
1373         const char *value = (char*)xmlGetProp(xmlObj, "value"); // string -> value
1374
1375         setting_enable_expandable_genlist(pd->scroller, data, __expanditem_func_exp_cb, __expanditem_func_smart_cb);
1376         Setting_GenGroupItem_Data *list_item =
1377             setting_create_Gendial_exp_parent_field(pd->scroller,
1378                                                     &(itc_2text_3_parent),
1379                                                     NULL, NULL,
1380                                                     SWALLOW_Type_INVALID,
1381                                                     key_str,
1382                                                     value);
1383         if (list_item) {
1384                 list_item->userdata = xmlObj;
1385                 list_item->belongs_to = (int)pd;
1386                 list_item->childs = NULL;               /* init */
1387         }
1388
1389         return list_item;
1390 }
1391
1392 static int __node_walk_check(PluginNode* context, xmlNode* cur, int* pcount)
1393 {
1394         //SETTING_TRACE_BEGIN;
1395         Draw_Data *pd = context->pd;
1396         retv_if(!pd, -1);
1397         retv_if(!context->ui_list, -1);
1398
1399         xmlNode *cur_node = NULL;
1400         for (cur_node = cur; cur_node;cur_node = cur_node->next) {
1401                 if (cur_node->type == XML_ELEMENT_NODE) {
1402                         //SETTING_TRACE("node type : %s id= %s", cur_node->name,xmlGetProp(cur_node, "id"));
1403                         *pcount += 1;
1404                 }
1405                 __node_walk_check(context, cur_node->children, pcount);         /* RECURSIVE */
1406         }
1407         return 0;
1408 }
1409
1410 static int __node_walker(PluginNode* context, xmlNode* cur)
1411 {
1412         //SETTING_TRACE_BEGIN;
1413         Draw_Data *pd = context->pd;
1414
1415         retv_if(!pd, -1);
1416         retv_if(!context->ui_list, -1);
1417
1418         xmlNode *cur_node = NULL;
1419         for (cur_node = cur; cur_node;cur_node = cur_node->next) {
1420                 if (cur_node->type == XML_ELEMENT_NODE) {
1421                         // SETTING_TRACE("node type : %s id= %s", cur_node->name,xmlGetProp(cur_node, "id"));
1422                         drawer_fp  fp = __drawer_find(cur_node->name);
1423                         if (fp)
1424                         {
1425                                 // type check
1426                                 void* vret = fp(context, cur_node); // draw it
1427
1428                                 if (vret)
1429                                 {
1430                                         Setting_GenGroupItem_Data* genlist_node = (Setting_GenGroupItem_Data* )vret;
1431                                         //SETTING_TRACE("add node to Eina List name : %s, id : ", cur_node->name, xmlGetProp(cur_node, "id"));
1432                                         // add it to the hash table create before.
1433                                         // id, object
1434                                         // add list
1435                                         char* key_name = xmlGetProp(cur_node, "id");
1436                                         eina_hash_add(context->ui_list, strdup(key_name),(void*)genlist_node);
1437                                 }
1438                         }else {
1439                                 SETTING_TRACE(" >>>> fp is NULL ");
1440                         }
1441                 }
1442                 __node_walker(context, cur_node->children);     /* RECURSIVE */
1443         }
1444         return 0;
1445 }
1446
1447 /**
1448  * @param id_str [in] "id"
1449  * @param value [in] value to be udpated
1450  * @see __expanditem_func_sel_cb
1451  */
1452 static int __node_finder(PluginNode* context, xmlNode* cur, char* id_str, char* value, bool* is_end)
1453 {
1454         SETTING_TRACE_BEGIN;
1455         xmlNode *cur_node = NULL;
1456
1457         if (! context)
1458         {
1459                 SETTING_TRACE("context is NULL - it's error CONDITION ");
1460                 return -1;
1461         }
1462
1463         retv_if(!context->ui_list, -1);
1464         if (*is_end == true) return 0;
1465
1466         for (cur_node = cur; cur_node;cur_node = cur_node->next) {
1467                 if (cur_node->type == XML_ELEMENT_NODE) {
1468
1469                         char* id_name = (char*)xmlGetProp(cur_node, "id");
1470                         if ( id_name && 0 == strcmp(id_str, id_name))
1471                         {
1472                                 SETTING_TRACE("FOUND >>>> %s", id_name);
1473                                 // cur_node     - update xml code
1474                                 xmlAttrPtr newattr = xmlSetProp(cur_node, "value", value);
1475
1476                                 //-----------------------------------------------------------
1477                                 // UI UPDATE
1478                                 // case : slider
1479                                 if ( 0 == strcmp (cur_node->name, "integer"))
1480                                 {
1481                                         SETTING_TRACE(">>>>> UPDATE SLIDER CONTROL %x --- %s ",context->ui_list, id_name);
1482                                         Setting_GenGroupItem_Data* item_to_update = (Setting_GenGroupItem_Data*)eina_hash_find(context->ui_list, id_name);
1483                                         if      (item_to_update)
1484                                         {
1485                                                 item_to_update->chk_status = atoi(value);
1486                                                 SETTING_TRACE(">>>   o-------------0 SLIDER VALUE = %d ", item_to_update->chk_status);
1487
1488                                                 elm_object_item_data_set(item_to_update->item, item_to_update);
1489                                                 elm_genlist_item_update(item_to_update->item);
1490                                         } else {
1491                                                 SETTING_TRACE("item_to_update is NULL");
1492                                         }
1493                                 }
1494                                 // case : toggle
1495                                 if ( 0 == strcmp (cur_node->name, "bool"))
1496                                 {
1497                                         SETTING_TRACE(">>>>> UPDATE TOGGLE CONTROL pluginpath:%s, ----  %x --- %s ", context->plugin_path, context->ui_list, id_name);
1498                                         Setting_GenGroupItem_Data* item_to_update = NULL;
1499                                         item_to_update = (Setting_GenGroupItem_Data*)eina_hash_find(context->ui_list, id_name);
1500                                         if      (item_to_update)
1501                                         {
1502                                                 item_to_update->chk_status = atoi(value);
1503                                                 SETTING_TRACE(">>>   o-------------0 TOGGLE VALUE = %d ", item_to_update->chk_status);
1504
1505                                                 elm_object_item_data_set(item_to_update->item, item_to_update);
1506                                                 elm_genlist_item_update(item_to_update->item);
1507                                         } else {
1508                                                 SETTING_TRACE("item_to_update is NULL");
1509                                         }
1510                                 }
1511                                 // case : edit control
1512                                 if ( 0 == strcmp (cur_node->name, "string"))
1513                                 {
1514                                         SETTING_TRACE(">>>>> UPDATE EDIT CONTROL CONTROL %x --- %s ",context->ui_list, id_name);
1515                                         Setting_GenGroupItem_Data* item_to_update = (Setting_GenGroupItem_Data*)eina_hash_find(context->ui_list, id_name);
1516                                         if      (item_to_update)
1517                                         {
1518                                                 char* old_string = item_to_update->sub_desc;
1519                                                 item_to_update->sub_desc = strdup(value);
1520                                                 SETTING_TRACE(">>>   o-------------0 STRING VALUE = %s ", value);
1521
1522                                                 // free old string
1523
1524                                                 elm_object_item_data_set(item_to_update->item, item_to_update);
1525                                                 elm_genlist_item_update(item_to_update->item);
1526
1527                                         } else {
1528                                                 SETTING_TRACE("item_to_update is NULL");
1529                                         }
1530                                 }
1531                                 // case : expand list
1532                                 // parent
1533                                 //    child1
1534                                 //    child2
1535                                 //    child3
1536                                 //    child4
1537                                 //-----------------------------------------------------------
1538                                 if ( 0 == strcmp (cur_node->name, "expandlist"))
1539                                 {
1540                                         #if 1
1541                     SETTING_TRACE(">>>>> UPDATE EXPAND LIST CONTROL %x --- %s ",context->ui_list, id_name);
1542                     Setting_GenGroupItem_Data* item_to_update = NULL;
1543                                         item_to_update = (Setting_GenGroupItem_Data*)eina_hash_find(context->ui_list, id_name);
1544                     if  (item_to_update)
1545                     {
1546                         char* old_string = item_to_update->sub_desc;
1547                         item_to_update->sub_desc = strdup(value);
1548                         SETTING_TRACE(">>>   o-------------0 EXPAND LIST VALUE = %s ", value);
1549
1550                         // free old string
1551                         // string update
1552                         elm_object_item_data_set(item_to_update->item, item_to_update);
1553                         elm_genlist_item_update(item_to_update->item);
1554
1555                         // TODO: need to update child elements
1556                         // item_to_update->childs ---> expanded list
1557
1558                                                 // debug log
1559                                                 // there should have 4 sub items.
1560                                                 //-----------------------------------------------------
1561                                                 // has it already freed by someone?
1562                                                 //-----------------------------------------------------
1563                                                 if (item_to_update->childs)
1564                                                 {
1565                                                         int howmany2 =0;
1566                                                         Eina_List *li = item_to_update->childs;
1567                                                         while(li)
1568                                                         {
1569                                                                 Setting_GenGroupItem_Data* node = eina_list_data_get(li);
1570                                                                 howmany2 += 1;
1571                                                                 li = eina_list_next(li);
1572                                                         }
1573                                                         SETTING_TRACE(" expandlist -- how many items are there? : %d ", howmany2);
1574                                                 }
1575
1576                         if (item_to_update->childs)
1577                         {
1578                             Eina_List *li = item_to_update->childs;
1579                             int radio_index = 0;
1580                             while(li)
1581                             {
1582                                 Setting_GenGroupItem_Data* node = eina_list_data_get(li);
1583
1584                                 if (node->item && node->keyStr)
1585                                 {
1586                                     // do something more
1587                                     // SETTING_TRACE(">>> RADIO LIST STRING VALUE = %s ", node->keyStr);
1588                                     // set position of radio button
1589                                     if (value && strcmp(node->keyStr, value) == 0) // << CRAAH !!!!
1590                                     {
1591                                         elm_radio_value_set(node->rgd, radio_index);
1592                                     }
1593                                 } else {
1594                                      SETTING_TRACE(">>> node has unproper values - Setting_GenGroupItem_Data");
1595                                 }
1596                                 elm_object_item_data_set(item_to_update->item, item_to_update);
1597                                 elm_genlist_item_update(item_to_update->item);
1598
1599                                 // go next
1600                                 li = eina_list_next(li);
1601                                 radio_index++;
1602                             }
1603
1604                         }
1605                     } else {
1606                         SETTING_TRACE("item_to_update is NULL");
1607                     }
1608
1609                                         #endif
1610                                 }
1611                                 *is_end = true;
1612                         }
1613                 }
1614                 __node_finder(context, cur_node->children, id_str, value, is_end);      /* RECURSIVE */
1615         }
1616         return 0;
1617 }
1618
1619 static unsigned int _plugin_string_key_length(const char*key)
1620 {
1621         if (!key)
1622                 return 0;
1623
1624         return (int)strlen(key) + 1;
1625 }
1626
1627 static int _plugin_string_key_cmp(const char* key1, int key1_length,
1628                                                                         const char* key2, int key2_length)
1629 {
1630         return strcmp(key1, key2);
1631 }
1632
1633 static void _plugin_entry_free_cb(void* data)
1634 {
1635 #if 0
1636         // this code already have done in genlist_unrealized
1637     Setting_GenGroupItem_Data* node = (Setting_GenGroupItem_Data*) data;
1638         if (node->childs)
1639         {
1640                 eina_list_free(node->childs);
1641                 node->childs = NULL;
1642         }
1643 #endif
1644 }
1645
1646 PluginNode* setting_plugin_create(Evas_Object* navi, Evas_Object* win)
1647 {
1648         PluginNode *plugin = calloc(1, sizeof(PluginNode));
1649         setting_retvm_if(!plugin, -1, "Create PluginNode obj failed");
1650         Draw_Data *pd = calloc(1, sizeof(Draw_Data));
1651
1652         if (!pd) {
1653                 FREE(plugin);
1654         }
1655
1656         setting_retvm_if(!pd, -1, "Create Draw_Data obj failed");
1657         plugin->ug = NULL;
1658         plugin->ly_main = NULL;
1659         plugin->pd = pd;
1660         plugin->navi_bar = navi;
1661         plugin->win_main = win;
1662
1663         plugin->ui_list = eina_hash_new(EINA_KEY_LENGTH(_plugin_string_key_length),
1664                                                                   EINA_KEY_CMP(_plugin_string_key_cmp),
1665                                                                   EINA_KEY_HASH(eina_hash_superfast),
1666                                                                   _plugin_entry_free_cb,
1667                                                                   5); // 2^5
1668
1669         return plugin;
1670 }
1671
1672 void setting_plugin_destroy(PluginNode* node)
1673 {
1674         SETTING_TRACE_BEGIN;
1675         if (node) {
1676                 SETTING_TRACE("node is NOT NULL")
1677                 if (node->pd) {
1678                         SETTING_TRACE("node->pd is NOT NULL")
1679                         if(node->pd->doc != NULL) {
1680                                 xmlSaveFormatFile(node->plugin_path, node->pd->doc, 1);
1681                                 xmlFreeDoc(node->pd->doc);
1682                                 node->pd->doc = NULL;
1683                                 SETTING_TRACE("__cfg_file_write successful");
1684                         }
1685
1686                         free(node->pd);
1687                         node->pd = NULL;
1688                 }
1689
1690                 if (node->ui_list) {
1691                         eina_hash_free(node->ui_list);
1692                         node->ui_list = NULL;
1693                 }
1694                 free(node);
1695                 node = NULL;
1696 //              PLUGIN_FINI;
1697         }
1698 }
1699
1700
1701 static Eina_Bool _plugin_foreach_cb(const Eina_Hash *hash, const void*key, void* data, void* fdata)
1702 {
1703     Setting_GenGroupItem_Data* node = (Setting_GenGroupItem_Data*) data;
1704         SETTING_TRACE("%s --- %s ", (char*)key, node->keyStr);
1705         return EINA_TRUE;
1706 }
1707
1708
1709 void setting_plugin_debug(PluginNode* context)
1710 {
1711 //      SETTING_TRACE("HASH TABLE -------------------------------------");
1712         if (context->ui_list) {
1713                 eina_hash_foreach(context->ui_list,_plugin_foreach_cb, NULL);
1714         }
1715 //      SETTING_TRACE("HASH TABLE -------------------------------------");
1716
1717 }
1718
1719 void setting_plugin_update(PluginNode* context)
1720 {
1721     Eina_List *li = context->ui_list;
1722
1723     while (li) {
1724         Setting_GenGroupItem_Data* node = (Setting_GenGroupItem_Data*) eina_list_data_get(li);
1725         if (node) {
1726             // SETTING_TRACE(" ---> keyStr : %s , swallow type : %d  ", node->keyStr, node->swallow_type);
1727                         Setting_GenGroupItem_Data* item_to_update = NULL;
1728                         item_to_update = node;
1729                         elm_object_item_data_set(item_to_update->item, item_to_update);
1730                         elm_genlist_item_update(item_to_update->item);
1731         }
1732         li = eina_list_next(li);
1733         }
1734 }
1735
1736
1737 /**
1738  * set modifiable
1739  */
1740 int setting_plugin_load(PluginNode* node, const char *cfg_file)
1741 {
1742         SETTING_TRACE("cfg_file:%s", cfg_file)
1743         if (isEmptyStr(cfg_file) || 0 != access(cfg_file, R_OK|W_OK|F_OK ))
1744         {
1745                 SETTING_TRACE_ERROR(" error occured : access = %d ", errno);
1746                 return -1;
1747         }
1748         node->pd->cfg_file = cfg_file;
1749
1750         node->pd->doc = xmlParseFile(cfg_file);
1751         node->pd->root = xmlDocGetRootElement(node->pd->doc);
1752
1753         // signal filter change
1754         //void* user_data = (void*)g_main_ad;
1755         void* user_data = (void*)node;
1756
1757         DBusError error;
1758         dbus_error_init(&error);
1759         char rule[MAX_LOCAL_BUFSIZE + 1] = {0,};
1760         bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
1761         if (!bus)
1762         {
1763                 SETTING_TRACE("Fail to connect to the D-BUS daemon: %s", error.message);
1764                 dbus_error_free(&error);
1765                 return -1;
1766         }
1767
1768         // get rule
1769         snprintf(rule, MAX_LOCAL_BUFSIZE, "path='%s',type='signal',interface='%s'", DBUS_PATH, DBUS_SIGNAL_INTERFACE);
1770         dbus_bus_add_match(bus, rule, &error);
1771         if (dbus_error_is_set(&error))
1772         {
1773                 SETTING_TRACE("Fail to rule set; %s", error.message);
1774                 dbus_bus_remove_match(bus, rule, &error);
1775                 dbus_error_free(&error);
1776                 dbus_connection_close(bus);
1777                 bus = NULL;
1778                 return -1;
1779         }
1780
1781         // re-add filter
1782         if (dbus_connection_add_filter(bus, __signal_filter, user_data, NULL) == FALSE)
1783         {
1784                 SETTING_TRACE("Fail to add filter ----- ");
1785                 dbus_bus_remove_match(bus, rule, &error);
1786                 dbus_error_free(&error);
1787                 dbus_connection_close(bus);
1788                 bus = NULL;
1789                 return -1;
1790         }
1791
1792         int count = 0;
1793         __node_walk_check(node, node->pd->root, &count);
1794         SETTING_TRACE(" node count : %d ", count);
1795         node->nitems = count;
1796         __node_walker(node, node->pd->root);
1797
1798         // debug message
1799         //setting_plugin_debug(node);
1800         return 1;
1801 }
1802
1803