/* * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.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 * * Unless required by applicable law or agreed to in writing, software * 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 #include "settingviewmgr.h" #include "data_wrapper.h" #include "timeout_handler.h" #include "view_maincatalog.h" #include "view_uigadget.h" #include "view_sublist.h" #include "view_pwd_popup.h" #include "view_system_clock.h" #include "view_need_pwd.h" //#include "settingviewmgr.h" #define MAINCATALOG "maincatalog" #define PATH_FACTOR 3 struct SSettingMgr { Evas_Object *win; int depth; unsigned int refresh; unsigned int relaunch; Eina_List *view_list; struct settingmgr_data *data; Eina_Array *item_path; CTimeoutHandler *handler; Eina_Bool is_freeze; }; struct _settinginfo { Evas_Object *base; CSettingBaseView *sclass; struct settingview_data *sview; }; struct settingui_func_map { const char *style; CSettingBaseView *view; //struct setting_class* (*get_vclass)(void); }; CSettingBaseView::CSettingBaseView(const char *pViewId) { m_title = new char[strlen(pViewId) + 1]; strcpy(m_title, pViewId); } CSettingBaseView::~CSettingBaseView() { delete[] m_title; } Evas_Object *CSettingBaseView::Base(void) { return NULL; } static struct settingui_func_map g_func_map[5];/* = { { .style = STYLE_UIGADGET, .get_vclass = view_uigadget_get_vclass }, { .style = STYLE_CTXPOPUP, .get_vclass = view_sublist_get_vclass }, { .style = STYLE_PASSCODE_POPUP, .get_vclass = view_passcode_popup_get_vclass }, { .style = STYLE_CLOCK_CTXPOPUP, .get_vclass = view_system_clock_get_vclass }, { .style = STYLE_NEED_PASSCODE, .get_vclass = view_need_passcode_get_vclass }*/ //}; /** * This function is invoked to build setting view data. * * @param mgr [in] The SSettingMgr data pointer. * @param name[in] The item name to be created view. * @return The settingview_data data pointer, NULL on error. */ static struct settingview_data *_build_setting_view( struct SSettingMgr *mgr, const char *name) { struct settingview_data *data; int r; if (!mgr || !mgr->data || !name) { _ERR("Parameter error!"); return NULL; } r = viewmgr_data_read_jsonfile_into_hash(mgr->data, name); if (r != 0) { _ERR("Read new json file failed\n"); return NULL; } data = viewmgr_data_build_view(mgr->data, name); if (!data) { _ERR("Build view data failed\n"); return NULL; } return data; } CMainCatalogView *g_maincatalog; /** * This function is invoked to get setting_class data pointer, this data stand for a kind of view. * * @param mgr [in] The SSettingMgr data pointer. * @param view[in] The settingview_data data pointer. * @return The setting_class data pointer, NULL on error. */ static CSettingBaseView *_get_view_class(SSettingMgr *mgr, struct settingview_data *view) { CSettingBaseView *vclass; struct settingitem *parent; Eina_List *list; const char *style; int size, i; if (!mgr || !view) { _ERR("Parameter error!"); return NULL; } parent = viewdata_get_parentitem(view); list = settingitem_get_subitems(parent); style = settingitem_get_settingui_style(parent); if (!list && !style) { _ERR("there is something wrong in json file."); return NULL; } vclass = NULL; if (list && !style) { if (mgr->depth == 1){ g_maincatalog = new CMainCatalogView(VCLASS_TITLE_MAIN_VIEW); vclass = (CSettingBaseView *) g_maincatalog;// view_maincatalog_get_vclass(); } } else { size = sizeof(g_func_map) / sizeof(*g_func_map); for (i = 0; i < size; i++) { if (!strncmp(style, g_func_map[i].style, strlen(style)) && g_func_map[i].view) { vclass = g_func_map[i].view;// get_vclass(); break; } } } return vclass; } /** * This function is invoked to hide all views stored in view list. * * @param mgr [in] The SSettingMgr data pointer. * @return void. */ void _hide_view_in_list(struct SSettingMgr *mgr) { Eina_List *l; struct _settinginfo *sinfo; void* obj; if (!mgr) { _ERR("Invalid arguments\n"); return; } EINA_LIST_FOREACH(mgr->view_list, l, obj) { sinfo = (struct _settinginfo *) obj; sinfo->sclass->Hide(); //if (sinfo->sclass->hide) // sinfo->sclass->hide(sinfo->base); } } /** * This function is invoked to show all views stored in view list. * * @param mgr [in] The SSettingMgr data pointer. * @return void. */ void _show_view_in_list(struct SSettingMgr *mgr) { Eina_List *l; struct _settinginfo *sinfo; void* obj; if (!mgr) { _ERR("Invalid arguments\n"); return; } EINA_LIST_FOREACH(mgr->view_list, l, obj) { sinfo = (struct _settinginfo *) obj; sinfo->sclass->Show(); //if (sinfo->sclass->show) // sinfo->sclass->show(sinfo->base); } } /** * This function is invoked to destroy all views stored in view list. * * @param mgr [in] The SSettingMgr data pointer. * @return void. */ void _destroy_views_in_list(struct SSettingMgr *mgr) { Eina_List *l; struct _settinginfo *sinfo; void* obj; if (!mgr) { _ERR("Invalid arguments\n"); return; } EINA_LIST_FOREACH(mgr->view_list, l, obj) { sinfo = (struct _settinginfo *) obj; sinfo->sclass->Destroy(); //if (sinfo->sclass->destroy) // sinfo->sclass->destroy(sinfo->base); } } /** * This function is invoked to freeze all views's event stored in view list. * * @param mgr [in] The SSettingMgr data pointer. * @return void. */ void _frozen_view_in_list(struct SSettingMgr *mgr) { Eina_List *l; struct _settinginfo *sinfo; void* obj; if (!mgr) { _ERR("Invalid argument"); return; } if(mgr->view_list) { EINA_LIST_REVERSE_FOREACH(mgr->view_list, l, obj) { sinfo = (struct _settinginfo *)obj; sinfo->sclass->Frozen(); //if (sinfo->sclass->frozen) // sinfo->sclass->frozen(sinfo->base); } } } /** * This function is invoked to activate all views's event stored in view list. * * @param mgr [in] The SSettingMgr data pointer. * @return void. */ void _active_view_in_list(struct SSettingMgr *mgr) { Eina_List *l; struct _settinginfo *sinfo; void* obj; if (!mgr) { _ERR("Invalid argument"); return; } EINA_LIST_REVERSE_FOREACH(mgr->view_list, l, obj) { sinfo = (struct _settinginfo *)obj; sinfo->sclass->Active(); //if (sinfo->sclass->active) // sinfo->sclass->active(sinfo->base); } } CSettingMgr *CSettingMgr::instance = NULL; /** * This function is invoked to initialize setting manager. * * @param win [in] The window's evas object. * @return The SSettingMgr data pointer. */ bool CSettingMgr::Initialize(Evas_Object *win) { ASSERT(!instance); ASSERT(win); //struct settingmgr_data *data; //CTimeoutHandler *handler; _CREATE_BEGIN{ _CHECK(instance = new CSettingMgr); _CHECK(instance->m = new SSettingMgr); _CHECK(instance->m->data = viewmgr_data_init()); _CHECK(instance->m->handler = new CTimeoutHandler); _CHECK(instance->m->handler->Create(TIMEOUT_SECS)); _CHECK_FAIL{ instance->m->handler->Destroy(); } _CHECK_FAIL{ delete instance->m->handler; } _CHECK_FAIL{ viewmgr_data_fini(instance->m->data); } _CHECK_FAIL{ delete instance->m; } _CHECK_FAIL{ delete instance; instance = NULL; } } _CREATE_END_AND_CATCH{ return false; } g_func_map[0].style = STYLE_UIGADGET; g_func_map[0].view = new CUiGadgetView(VCLASS_TITLE_UG); g_func_map[1].style = STYLE_CTXPOPUP; g_func_map[1].view = new CSublistView(VCLASS_TITLE_SUBLIST); g_func_map[2].style = STYLE_PASSCODE_POPUP; g_func_map[2].view = new CPasscodePopupView(VCLASS_TITLE_CHANGE_PASSCODE); g_func_map[3].style = STYLE_CLOCK_CTXPOPUP; g_func_map[3].view = new CSystemClockView(VCLASS_TITLE_SYSTEM_CLOCK); g_func_map[4].style = STYLE_NEED_PASSCODE; g_func_map[4].view = new CNeedPasscodeView(VCLASS_TITLE_NEED_PASSCODE); instance->m->win = win; instance->m->depth = 0; instance->m->is_freeze = EINA_FALSE; instance->m->view_list = NULL; instance->m->item_path = NULL; return true; } /** * This function is invoked to destroy all views stored in view list and release * SSettingMgr data structure. * * @param mgr [in] The SSettingMgr data pointer. * @return void. */ void CSettingMgr::Finalize(void) { ASSERT(instance); ASSERT(instance->m); struct _settinginfo *sinfo; void* obj; _hide_view_in_list(instance->m); _destroy_views_in_list(instance->m); EINA_LIST_FREE(instance->m->view_list, obj) { sinfo = (struct _settinginfo *)obj; free(sinfo); } if (instance->m->item_path) eina_array_free(instance->m->item_path); viewmgr_data_fini(instance->m->data); instance->m->handler->Destroy(); delete instance->m->handler; delete instance->m; delete instance; instance = NULL; } CSettingMgr *CSettingMgr::GetInstance(void) { return instance; } /** * This function is invoked to push a view with specific name and data. * * Firstly, it will build view data, then get specific view class to create view. * Otherwise, it will freeze or hide background view and store _settinginfo data into view list. * * @param mgr [in] The SSettingMgr data pointer. * @param name [in] The item name to be pushed view. * @param data [in] The function specific data passed by caller. * @return 0 if success, -1 if fail. */ bool CSettingMgr::ViewPush(const char *name, void *data) { ASSERT(m); ASSERT(name); struct _settinginfo *sinfo = NULL; CSettingBaseView *sclass = NULL; struct settingview_data *view = NULL; m->depth++; sinfo = new _settinginfo; if (!sinfo) return false; view = _build_setting_view(m, name); if (!view) { _ERR("Build setting view data failed\n"); goto error; } sclass = _get_view_class(m, view); if (!sclass) { _ERR("failed to get view class."); goto error; } if (!sclass->Create(view, data)) { _ERR("failed to create base layout."); goto error; } _frozen_view_in_list(m); if (sclass->hide_view) _hide_view_in_list(m); sclass->Show(); sinfo->base = sclass->Base(); sinfo->sclass = sclass; sinfo->sview = view; m->view_list = eina_list_prepend(m->view_list, sinfo); return 0; error: m->depth--; free(sinfo); viewdata_release(view); return -1; } /** * This function is invoked to pop top view. * * Firstly, get top view's _settinginfo data from view list, then call destroy interface of * view class, finally it will refresh second view, activate and show all views behind top view. * * @param mgr [in] The SSettingMgr data pointer. * @return void. */ void CSettingMgr::ViewPop(void) { ASSERT(m); struct _settinginfo *sinfo, *prev; CSettingBaseView *sclass; int hide; char *item; const char *title; m->depth--; sinfo = (struct _settinginfo *) eina_list_data_get(m->view_list); if (!sinfo) { _DBG("get sinfo failed\n"); return; } sclass = sinfo->sclass; hide = sclass->hide_view; title = sclass->Title(); item = NULL; if (!strncmp(title, VCLASS_TITLE_BOTTOM_SLIDER, strlen(title))) item = (char *)evas_object_data_del(sinfo->base, SELECTED_ITEM_ID); sclass->Destroy(); m->view_list = eina_list_remove_list(m->view_list, m->view_list); free(sinfo); if (!m->view_list) return; prev = (struct _settinginfo *) eina_list_data_get(m->view_list); if (!prev || !prev->sclass) return; sclass = prev->sclass; if (item && !strncmp(title, VCLASS_TITLE_BOTTOM_SLIDER, strlen(title))) evas_object_data_set(prev->base, SELECTED_ITEM_ID, item); sclass->Refresh(); sclass->Update(); _active_view_in_list(m); if (hide) _show_view_in_list(m); } /** * This function is invoked to get window's evas object. * * @param mgr [in] The SSettingMgr data pointer. * @return The window's evas object, NULL on error. */ Evas_Object *CSettingMgr::Window(void) { ASSERT(m); return m->win; } /** * This function is invoked to get view data with specific name. * * @param mgr [in] The SSettingMgr data pointer. * @param name [in] The view name to be got. * @return The settingview_data data pointer, NULL on error. */ settingview_data *CSettingMgr::GetView(const char *name) { ASSERT(m); return _build_setting_view(m, name); } /** * This function is invoked to get setting manager data. * * @param mgr [in] The SSettingMgr data pointer. * @return The settingmgr_data data pointer, NULL on error. */ settingmgr_data *CSettingMgr::GetData(void) { ASSERT(m); return m->data; } /** * This function is invoked to get view list. * * @param mgr [in] The SSettingMgr data pointer. * @return The Eina_List data pointer, NULL on error. */ Eina_List *CSettingMgr::GetViewList(void) { ASSERT(m); return m->view_list; } /** * This function is invoked to launch view with specific item name. * * When launch setting by command-line, this function will be invoked. In this launching * way, setting will be launched and move focus to specific item. * * @param mgr [in] The SSettingMgr data pointer. * @param name [in] The item name. * @return 0 if success, -1 if fail. */ bool CSettingMgr::LaunchItem(const char *name) { ASSERT(m); ASSERT(name); const char *parent; struct settingitem *item; Eina_Array *path; int i, cnt; path = eina_array_new(1); if (!path) { _ERR("new eina array failed."); return false; } eina_array_push(path, name); parent = parser_get_parent_item_name(JSON_HELPER_FILE, name); if (!parent) { _ERR("get parent item name failed."); eina_array_free(path); return false; } eina_array_push(path, parent); do { viewmgr_data_read_jsonfile_into_hash(m->data, parent); item = viewmgr_data_get_settingitem(m->data, parent); if (!item) break; parent = settingitem_get_parentitem(item); eina_array_push(path, parent); } while (parent && strncmp(parent, MAINCATALOG, strlen(parent))); m->item_path = path; ViewPush(MAINCATALOG, NULL); cnt = eina_array_count(path); for (i = cnt - PATH_FACTOR; i > 0; i--) ViewPush((const char *) eina_array_data_get(path, i), NULL); return true; } /** * This function is invoked to get item path. * * Item path is a value described all node value from root node to item * in setting tree of json files. * * @param mgr [in] The SSettingMgr data pointer. * @return The Eina_Array data pointer, NULL on error. */ Eina_Array *CSettingMgr::GetItemPath(void) { ASSERT(m); return m->item_path; } /** * This function is invoked to refresh all view stored in view list. * * @param mgr [in] The SSettingMgr data pointer. * @return void. */ void CSettingMgr::ViewRefresh(void) { ASSERT(m); struct _settinginfo *info; CSettingBaseView *vclass; if (!m->view_list) return; info = (struct _settinginfo *) eina_list_data_get(m->view_list); if (!info) return; vclass = info->sclass; vclass->Refresh(); vclass->Update(); } /** * This function is invoked to set refresh flag. * * @param mgr [in] The SSettingMgr data pointer. * @param val [in] The value to be set. * @return void. */ void CSettingMgr::SetRefreshFlag(unsigned int val) { ASSERT(m); m->refresh = val; } /** * This function is invoked to get refresh flag. * * @param mgr [in] The SSettingMgr data pointer. * @return The refresh flag value, -1 if fail. */ unsigned int CSettingMgr::GetRefreshFlag(void) { ASSERT(m); return m->refresh; } /** * This function is invoked to set relaunch flag. * * @param mgr [in] The SSettingMgr data pointer. * @param val [in] The value to be set. * @return void. */ void CSettingMgr::SetRelaunchFlag(unsigned int val) { ASSERT(m); m->relaunch = val; } /** * This function is invoked to get relaunch flag. * * @param mgr [in] The SSettingMgr data pointer. * @return The refresh flag value, -1 if fail. */ unsigned int CSettingMgr::GetRelaunchFlag(void) { ASSERT(m); return m->relaunch; } /** * This function wrapped timeout_handler interface to freeze timer. * * @param mgr [in] The SSettingMgr data pointer. * @return void. */ void CSettingMgr::FreezeTimeout(void) { ASSERT(m); m->is_freeze = EINA_TRUE; m->handler->FreezeTimer(); } /** * This function wrapped timeout_handler interface to thaw timer. * * @param mgr [in] The SSettingMgr data pointer. * @return void. */ void CSettingMgr::ThawTimeout(void) { ASSERT(m); m->handler->ThawTimer(); m->is_freeze = EINA_FALSE; } /** * This function is invoked to get timeout freeze state. * * @param mgr [in] The SSettingMgr data pointer. * @return EINA_TRUE if current state is frozen * EINA_FALSE if current state is normal or occurred error. */ Eina_Bool CSettingMgr::GetTimeoutFreezeState(void) { ASSERT(m); return m->is_freeze; } /** * This function is invoked to refresh all views when system language changed. * * @param mgr [in] The SSettingMgr data pointer. * @return void. */ void CSettingMgr::LangChanged(void) { ASSERT(m); struct _settinginfo *sinfo; Eina_List *l; void* obj; if (!m->view_list) { _ERR("Invalid argument"); return; } EINA_LIST_FOREACH(m->view_list, l, obj) { sinfo = (struct _settinginfo *) obj; if (!sinfo || !sinfo->sclass) { _ERR("settings info is NULL"); return; } sinfo->sclass->LangChanged(); } }