put a note of the Flora license description
[apps/core/preloaded/settings.git] / src / setting-plugin.c
index feaa148..73c2cad 100755 (executable)
@@ -1,24 +1,19 @@
 /*
  * setting
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
  *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
- *
- * Contact: MyoungJune Park <mj2004.park@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
+ * Licensed under the Flora License, Version 1.0 (the License);
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- * http://www.apache.org/licenses/LICENSE-2.0
+ *     http://floralicense.org/license/
  *
  * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
+ * distributed under the License is distributed on an AS IS BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- *
  */
-
 #include <unistd.h>
 #include <eina_list.h>
 #include <glib.h>
 #include <setting-plugin.h>
 
 
+extern setting_main_appdata *g_main_ad;
 
 static Setting_GenGroupItem_Data *g_list_item; /*TEST*/
 
-
-
 /*
  * UI draw handler table : _g_draw_list
  *  - contains Object_Drawer typed object.
@@ -126,7 +120,7 @@ static drawer_fp __drawer_find(char* type)
        SETTING_TRACE_BEGIN;
        SETTING_TRACE("node type:%s", type);
        Eina_List *check_list = _g_drawer_list;
-       Object_Drawer *list_item = NULL;
+       Object_Drawer *list_item = NULL;
 
        while (check_list) {
                list_item = (Object_Drawer *) eina_list_data_get(check_list);
@@ -237,8 +231,14 @@ static DBusHandlerResult __signal_filter(DBusConnection* conn, DBusMessage* mess
     dbus_error_init(&error);
 
        setting_main_appdata *ad = user_data;
+       char* plugin_path = ad->plugin_path;
+       char* pkg_name = get_app_string(plugin_path);
 
-       char* pkg_name = get_app_string(ad->plugin_path);
+       if (pkg_name == NULL)
+       {
+               SETTING_TRACE("pkg_name is NULL - it's abnormal operation");
+               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+       }
 
        char str_buf[MAX_COMMON_BUFFER_LEN];
        snprintf(str_buf, MAX_COMMON_BUFFER_LEN, "Update_%s", pkg_name);
@@ -291,14 +291,25 @@ static DBusHandlerResult __signal_filter(DBusConnection* conn, DBusMessage* mess
                        char* val_name = strchr(value, '|');
                        val_name++;
 
-                       // ad->plugin_path
                        // access xml file
-                       doc = xmlParseFile(ad->plugin_path);
+                       doc = xmlParseFile(plugin_path);
+                       if (doc == NULL)
+                       {
+                               SETTING_TRACE("unable to parse file : %s", plugin_path);
+                               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;     /* xml parsing error */
+                       }
                        // generate xml tree
                        xmlNode *root = xmlDocGetRootElement(doc);
                        // find a node
                        bool is_end = false;
+
+                       // TODO : message queing
+                       // get key/value from d-bus and parse xml and search xml data with key
+                       static int count = 0;
+                       SETTING_TRACE(" BEGIN ---------------------------- dbus--> before __node_finder : %d", count);
                        __node_finder((PluginNode*)ad->plugin_node, root, key_name ,val_name, &is_end);
+                       SETTING_TRACE(" END  ----------------------------- dbus--> after __node_finder : %d", count);
+                       count += 1;
                }
                // update the node
                GError *error = NULL;
@@ -329,6 +340,7 @@ static int __send_msg(char* key, char* value)
        if (bus == NULL)
                return -1;
 
+       // ex) in gdb --> $15 = 0x43b6eb78 "Update_(null)" -> error codintion
        if (s_pkg_name == NULL)
        {
                SETTING_TRACE("s_pkg_name is NULL - it's abnormal operation");
@@ -365,6 +377,7 @@ static int __send_msg(char* key, char* value)
 
 static void __send_int_msg(xmlNode* xmlObj, int val)
 {
+       SETTING_TRACE_BEGIN;
        const char *id = (char*)xmlGetProp(xmlObj, "id");
        const char *title = (char*)xmlGetProp(xmlObj, "title");
        char key[MAX_CONTENT_LEN] = {0,};
@@ -373,6 +386,7 @@ static void __send_int_msg(xmlNode* xmlObj, int val)
        char value[MAX_CONTENT_LEN] = {0,};
        snprintf(value, sizeof(value), "INT|%d", val);
        __send_msg(key, value);
+       SETTING_TRACE_END;
 }
 
 
@@ -396,6 +410,7 @@ int setting_dbus_handler_init(void* user_data)
        {
                SETTING_TRACE("already get a bus, need release first.");
                setting_dbus_handler_fini();
+//             return -1;
        }
        DBusError error;
        memset(&error, 0, sizeof(DBusError));
@@ -438,6 +453,7 @@ int setting_dbus_handler_init(void* user_data)
 
 int setting_dbus_handler_fini(void)
 {
+       SETTING_TRACE_BEGIN;
        //do safty checking first.
        setting_retvm_if(!bus, 0, "!bus");
        DBusError error;
@@ -445,7 +461,13 @@ int setting_dbus_handler_fini(void)
        char rule[MAX_LOCAL_BUFSIZE + 1] = {0, };
 
        dbus_error_init(&error);
+
+       // why??
+       bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
+
        //dbus_connection_remove_filter(bus, __signal_filter, NULL);
+
+
        snprintf(rule, MAX_LOCAL_BUFSIZE, "path='%s',type='signal',interface='%s'", DBUS_PATH, DBUS_SIGNAL_INTERFACE);
        dbus_bus_remove_match(bus, rule, &error);
 
@@ -482,6 +504,7 @@ static int __cfg_file_write(Draw_Data *pd)
                SETTING_TRACE("__cfg_file_write successful");
        }
 
+       SETTING_TRACE_END;
        return TRUE;
 }
 
@@ -500,7 +523,10 @@ static void ___click_softkey_back_cb(void *data, Evas_Object *obj,
        }
 
        setting_plugin_destroy(node);
-
+       if (g_main_ad->navibar_main)
+       {
+               elm_naviframe_item_pop(g_main_ad->navibar_main);
+       }
        pd->scroller = NULL;
        pd->navi_bar = NULL;
        pd->cfg_file = NULL;
@@ -576,7 +602,7 @@ static void* __link_list_cb(void *data, Evas_Object *obj, void *event_info)
        snprintf(file, sizeof(file), "%s/%s", PLUGIN_CFG_DIR, link_file);
        SETTING_TRACE("file:%s", file);
 
-       PluginNode* plugin_node = setting_plugin_create();
+       PluginNode* plugin_node = setting_plugin_create(file);
        setting_plugin_load(plugin_node, (const char *)file);
 
        //setting_plugin_load(NULL, file);
@@ -916,6 +942,7 @@ static void __entry_unfocus_cb(void *data, Evas_Object *obj, void *event_info)
        __cfg_file_write((Draw_Data *)list_item->belongs_to);
 
        FREE(entry_str_utf8);
+       SETTING_TRACE_END;
 }
 
 
@@ -960,6 +987,12 @@ static void __editbox_changed_cb(void *data, Evas_Object *obj,
 }
 
 
+/**
+ *  editbox
+ *
+ * @see also __editbox_changed_cb
+ * @see also __entry_unfocus_cb
+ */
 static void* editbox_func(void *data, xmlNode *xmlObj)
 {
        SETTING_TRACE_BEGIN;
@@ -995,13 +1028,15 @@ static void* editbox_func(void *data, xmlNode *xmlObj)
 
        } else {
                // add max length filter
-               list_item = setting_create_Gendial_field_entry(
+               list_item = setting_create_Gendial_field_entry_fo(
                                                                        pd->scroller,
                                                                        &(itc_1icon),
                                                                        __editbox_list_cb,
                                                                        pd,
                                                                        SWALLOW_Type_LAYOUT_ENTRY,
-                                                                       NULL, NULL, 0, title, key_str, __editbox_changed_cb,
+                                                                       NULL, NULL, 0, title, key_str,
+                                                                       __editbox_changed_cb,
+                                                                       __entry_unfocus_cb,
                                                                        ELM_INPUT_PANEL_LAYOUT_NORMAL,
                                                                        false,
                                                                        false,
@@ -1065,7 +1100,6 @@ static void __expanditem_func_exp_cb(void *data, Evas_Object *obj, void *event_i
 
 
        xmlNode *xmlObj = data_parentItem->userdata;
-       //char *value = (char*)xmlGetProp(xmlObj, "string");
        char *value = (char*)xmlGetProp(xmlObj, "value");
        SETTING_TRACE(">>> value = %s", value);
        Evas_Object *rgd = NULL;
@@ -1081,6 +1115,30 @@ static void __expanditem_func_exp_cb(void *data, Evas_Object *obj, void *event_i
                int subitem_index = 0;
                int sel_idx = -1;
 
+#if 1
+               // print out debug message
+               if (data_parentItem->childs)
+               {
+                       int howmany = 0;
+                       Eina_List *li = data_parentItem->childs;
+                       while(li)
+                       {
+                               Setting_GenGroupItem_Data* node = eina_list_data_get(li);
+                               howmany += 1;
+                               SETTING_TRACE(" <<< node->keyStr : %s >>> ", node->keyStr);
+
+                               // go next
+                               li = eina_list_next(li);
+                       }
+                       SETTING_TRACE(" <<<how many : %d>>> ", howmany);
+               }
+#endif
+               if (data_parentItem->childs)
+               {
+                       eina_list_free(data_parentItem->childs);
+                       data_parentItem->childs = NULL;
+               }
+
                while (cur != NULL) {
                        if (!xmlStrcmp(cur->name, (const xmlChar*)"expanditem")) {
                                type = (char*)xmlGetProp(cur, "type");
@@ -1094,12 +1152,12 @@ static void __expanditem_func_exp_cb(void *data, Evas_Object *obj, void *event_i
                                                                                                        subitem_index,
                                                                                                        subitem_title, NULL);
 
-                                       // SETTING_TRACE(">>> value = %s, subitem_title = %s ", value, subitem_title);
 
                                        if (0 == safeStrCmp(value, subitem_title)) {
                                                sel_idx = subitem_index;
                                                SETTING_TRACE("%d is selected in Radio Group", sel_idx);
                                        }
+                                       SETTING_TRACE(" eina list add >>> value = %s, subitem_title = %s ", value, subitem_title);
                                        data_parentItem->childs = eina_list_append(data_parentItem->childs, list_item);
                                        subitem_index++;
 
@@ -1149,7 +1207,7 @@ static Evas_Object *setting_create_win_layout2(Evas_Object *win_layout, Evas_Obj
     elm_layout_theme_set(layout, "layout", "application", "default");
     evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
     evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
-    elm_win_resize_object_add(win_obj, layout);
+       elm_win_resize_object_add(win_obj, layout);
 
     Evas_Object *bg = setting_create_bg(layout, win_obj, "group_list");
     elm_object_part_content_set(layout, "elm.swallow.bg", bg);
@@ -1174,6 +1232,25 @@ Evas_Object *setting_create_layout_navi_bar2(Evas_Object *win_layout, Evas_Objec
        return layout;
 }
 
+static void __plugin_genlist_unrealized_cb(void* data,Evas_Object* obj, void* event_info)
+{
+       SETTING_TRACE_BEGIN;
+       ret_if(data == NULL);
+
+       Elm_Object_Item *item = (Elm_Object_Item*)event_info;
+       Setting_GenGroupItem_Data *node = (Setting_GenGroupItem_Data *)elm_object_item_data_get(item);
+       ret_if(node== NULL);
+
+       SETTING_TRACE("keyStr : %s ", node->keyStr);
+       //item_to_update->childs)
+
+       if (node->childs)
+       {
+               eina_list_free(node->childs);
+               node->childs = NULL;
+       }
+}
+
 // <setting>
 static void* setting_func(void *data, xmlNode *xmlObj)
 {
@@ -1190,23 +1267,25 @@ static void* setting_func(void *data, xmlNode *xmlObj)
        SETTING_TRACE("before setting_create_layout_navi_bar_genlist");
 
        // [UI] with DATA
-       pd->scroller = elm_genlist_add(pd->win_get);
+       pd->scroller = elm_genlist_add(g_main_ad->win_main);
        retvm_if(pd->scroller == NULL, NULL,
                 "Cannot set scroller object  as contento of layout");
        elm_object_style_set(pd->scroller, "dialogue");
        elm_genlist_clear(pd->scroller);        /* first to clear list */
 
+       evas_object_smart_callback_add(pd->scroller, "unrealized", __plugin_genlist_unrealized_cb, node);
+
 
        SETTING_TRACE("_(title):%s", _(title));
-       pd->ly_main = setting_create_layout_navi_bar2(pd->win_get, pd->win_get,
+
+       setting_push_layout_navi_bar(
                                           _(title),
                                           _("IDS_COM_BODY_BACK"), NULL, NULL,
                                           ___click_softkey_back_cb,
                                           NULL, NULL,
                                           data, pd->scroller,
-                                          &(pd->navi_bar), NULL);
+                                          g_main_ad->navibar_main, NULL);
        SETTING_TRACE("after setting_create_layout_navi_bar_genlist");
-
 #endif
        return NULL;
 }
@@ -1240,6 +1319,7 @@ static void* expandlist_func(void *data, xmlNode *xmlObj)
        if (list_item) {
                list_item->userdata = xmlObj;
                list_item->belongs_to = (int)pd;
+               list_item->childs = NULL;               /* init */
        }
 
        return list_item;
@@ -1253,6 +1333,8 @@ static int __node_walker(PluginNode* context, xmlNode* cur)
        Draw_Data *pd = context->pd;
 
        retv_if(!pd, -1);
+       retv_if(!context->ui_list, -1);
+
        xmlNode *cur_node = NULL;
        for (cur_node = cur; cur_node;cur_node = cur_node->next) {
                if (cur_node->type == XML_ELEMENT_NODE) {
@@ -1292,6 +1374,13 @@ static int __node_finder(PluginNode* context, xmlNode* cur, char* id_str, char*
        SETTING_TRACE_BEGIN;
        xmlNode *cur_node = NULL;
 
+       if (! context)
+       {
+               SETTING_TRACE("context is NULL - it's error CONDITION ");
+               return -1;
+       }
+
+       retv_if(!context->ui_list, -1);
        if (*is_end == true) return 0;
 
        for (cur_node = cur; cur_node;cur_node = cur_node->next) {
@@ -1325,8 +1414,9 @@ static int __node_finder(PluginNode* context, xmlNode* cur, char* id_str, char*
                                // case : toggle
                                if ( 0 == strcmp (cur_node->name, "bool"))
                                {
-                                       SETTING_TRACE(">>>>> UPDATE TOGGLE CONTROL %x --- %s ",context->ui_list, id_name);
-                                       Setting_GenGroupItem_Data* item_to_update = (Setting_GenGroupItem_Data*)eina_hash_find(context->ui_list, id_name);
+                                       SETTING_TRACE(">>>>> UPDATE TOGGLE CONTROL pluginpath:%s, ----  %x --- %s ", context->plugin_path, context->ui_list, id_name);
+                                       Setting_GenGroupItem_Data* item_to_update = NULL;
+                                       item_to_update = (Setting_GenGroupItem_Data*)eina_hash_find(context->ui_list, id_name);
                                        if      (item_to_update)
                                        {
                                                item_to_update->chk_status = atoi(value);
@@ -1367,49 +1457,78 @@ static int __node_finder(PluginNode* context, xmlNode* cur, char* id_str, char*
                                //-----------------------------------------------------------
                                if ( 0 == strcmp (cur_node->name, "expandlist"))
                                {
-                                       SETTING_TRACE(">>>>> UPDATE EXPAND LIST CONTROL %x --- %s ",context->ui_list, id_name);
-                                       Setting_GenGroupItem_Data* item_to_update = (Setting_GenGroupItem_Data*)eina_hash_find(context->ui_list, id_name);
-                                       if      (item_to_update)
-                                       {
-                                               char* old_string = item_to_update->sub_desc;
-                                               item_to_update->sub_desc = strdup(value);
-                                               SETTING_TRACE(">>>   o-------------0 EXPAND LIST VALUE = %s ", value);
-
-                                               // free old string
-                                               // string update
-                                               elm_object_item_data_set(item_to_update->item, item_to_update);
-                                               elm_genlist_item_update(item_to_update->item);
-
-                                               // TODO: need to update child elements
-                                               // item_to_update->childs ---> expanded list
+                                       #if 1
+                    SETTING_TRACE(">>>>> UPDATE EXPAND LIST CONTROL %x --- %s ",context->ui_list, id_name);
+                    Setting_GenGroupItem_Data* item_to_update = NULL;
+                                       item_to_update = (Setting_GenGroupItem_Data*)eina_hash_find(context->ui_list, id_name);
+                    if  (item_to_update)
+                    {
+                        char* old_string = item_to_update->sub_desc;
+                        item_to_update->sub_desc = strdup(value);
+                        SETTING_TRACE(">>>   o-------------0 EXPAND LIST VALUE = %s ", value);
+
+                        // free old string
+                        // string update
+                        elm_object_item_data_set(item_to_update->item, item_to_update);
+                        elm_genlist_item_update(item_to_update->item);
+
+                        // TODO: need to update child elements
+                        // item_to_update->childs ---> expanded list
+
+                                               // debug log
+                                               // there should have 4 sub items.
+                                               //-----------------------------------------------------
+                                               // has it already freed by someone?
+                                               //-----------------------------------------------------
                                                if (item_to_update->childs)
                                                {
+                                                       int howmany2 =0;
                                                        Eina_List *li = item_to_update->childs;
-                                                       int radio_index = 0;
                                                        while(li)
                                                        {
                                                                Setting_GenGroupItem_Data* node = eina_list_data_get(li);
-                                                               // do something more
-                                                               // SETTING_TRACE(">>> RADIO LIST STRING VALUE = %s ", node->keyStr);
-                                                               // set position of radio button
-                                                               if (strcmp(node->keyStr, value) == 0)
-                                                               {
-                                                                       elm_radio_value_set(node->rgd, radio_index);
-                                                               }
-                                                               elm_object_item_data_set(item_to_update->item, item_to_update);
-                                                               elm_genlist_item_update(item_to_update->item);
-
-                                                               // go next
+                                                               howmany2 += 1;
                                                                li = eina_list_next(li);
-                                                               radio_index++;
                                                        }
-
+                                                       SETTING_TRACE(" expandlist -- how many items are there? : %d ", howmany2);
                                                }
-                                       } else {
-                                               SETTING_TRACE("item_to_update is NULL");
-                                       }
-                               }
 
+                        if (item_to_update->childs)
+                        {
+                            Eina_List *li = item_to_update->childs;
+                            int radio_index = 0;
+                            while(li)
+                            {
+                                Setting_GenGroupItem_Data* node = eina_list_data_get(li);
+
+                                if (node->item && node->keyStr)
+                                {
+                                    // do something more
+                                    // SETTING_TRACE(">>> RADIO LIST STRING VALUE = %s ", node->keyStr);
+                                    // set position of radio button
+                                    if (strcmp(node->keyStr, value) == 0) // << CRAAH !!!!
+                                    {
+                                        elm_radio_value_set(node->rgd, radio_index);
+                                    }
+                                } else {
+                                     SETTING_TRACE(">>> node has unproper values - Setting_GenGroupItem_Data");
+                                }
+                                elm_object_item_data_set(item_to_update->item, item_to_update);
+                                elm_genlist_item_update(item_to_update->item);
+
+                                // go next
+                                li = eina_list_next(li);
+                                radio_index++;
+                            }
+
+                        }
+                    } else {
+                        SETTING_TRACE("item_to_update is NULL");
+                    }
+
+
+                                       #endif
+                               }
                                *is_end = true;
                        }
                }
@@ -1442,16 +1561,13 @@ static void _plugin_entry_free_cb(void* data)
        }
 }
 
-//static PluginNode* g_context;
-
 PluginNode* setting_plugin_create()
 {
        PluginNode *node = calloc(1, sizeof(PluginNode));
-
        setting_retvm_if(!node, -1, "Create PluginNode obj failed");
-
        Draw_Data *pd = calloc(1, sizeof(Draw_Data));
 
+
        if (!pd) {
                FREE(node);
        }
@@ -1493,6 +1609,7 @@ void setting_plugin_destroy(PluginNode* node)
                }
                free(node);
                node = NULL;
+//             PLUGIN_FINI;
        }
 }
 
@@ -1508,7 +1625,9 @@ static Eina_Bool _plugin_foreach_cb(const Eina_Hash *hash, const void*key, void*
 void setting_plugin_debug(PluginNode* context)
 {
 //     SETTING_TRACE("HASH TABLE -------------------------------------");
-       eina_hash_foreach(context->ui_list,_plugin_foreach_cb, NULL);
+       if (context->ui_list) {
+               eina_hash_foreach(context->ui_list,_plugin_foreach_cb, NULL);
+       }
 //     SETTING_TRACE("HASH TABLE -------------------------------------");
 
 }
@@ -1543,13 +1662,53 @@ bool setting_plugin_load(PluginNode* context, const char *cfg_file)
                return FALSE;
        }
        context->pd->cfg_file = cfg_file;
-       context->pd->win_get = (Evas_Object *) ug_get_window();
 
-       GError *error = NULL;
+       //GError *error = NULL;
 
        context->pd->doc = xmlParseFile(cfg_file);
        context->pd->root = xmlDocGetRootElement(context->pd->doc);
 
+       // signal filter change
+       //setting_dbus_handler_init(g_main_ad);
+       void* user_data = (void*)g_main_ad;
+
+       DBusError error;
+       dbus_error_init(&error);
+       char rule[MAX_LOCAL_BUFSIZE + 1] = {0,};
+       bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
+       if (!bus)
+       {
+               SETTING_TRACE("Fail to connect to the D-BUS daemon: %s", error.message);
+               dbus_error_free(&error);
+               return -1;
+       }
+
+       // remove filter
+       // dbus_connection_remove_filter(bus, __signal_filter, NULL);
+
+       // get rule
+       snprintf(rule, MAX_LOCAL_BUFSIZE, "path='%s',type='signal',interface='%s'", DBUS_PATH, DBUS_SIGNAL_INTERFACE);
+       dbus_bus_add_match(bus, rule, &error);
+       if (dbus_error_is_set(&error))
+       {
+               SETTING_TRACE("Fail to rule set; %s", error.message);
+               dbus_bus_remove_match(bus, rule, &error);
+               dbus_error_free(&error);
+               dbus_connection_close(bus);
+               bus = NULL;
+               return -1;
+       }
+
+       // re-add filter
+       if (dbus_connection_add_filter(bus, __signal_filter, user_data, NULL) == FALSE)
+       {
+               dbus_bus_remove_match(bus, rule, &error);
+               dbus_error_free(&error);
+               dbus_connection_close(bus);
+               bus = NULL;
+               return -1;
+       }
+
        // TODO: error handler here
        __node_walker(context, context->pd->root);