diff --git a/src/bin/e_int_config_theme.c b/src/bin/e_int_config_theme.c index 206a37a3d..d5fd58328 100644 --- a/src/bin/e_int_config_theme.c +++ b/src/bin/e_int_config_theme.c @@ -9,10 +9,15 @@ static void _free_data (E_Config_Dialog *cfd, E_Config_Dialog static void _fill_data (E_Config_Dialog_Data *cfdata); static int _basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata); static Evas_Object *_basic_create_widgets (E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata); +static int _advanced_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata); +static Evas_Object *_advanced_create_widgets (E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata); +static Evas_List *_get_theme_categories_list(); struct _E_Config_Dialog_Data { E_Config_Dialog *cfd; + + /* Basic */ Evas_Object *o_frame; Evas_Object *o_fm; Evas_Object *o_up_button; @@ -20,8 +25,13 @@ struct _E_Config_Dialog_Data Evas_Object *o_personal; Evas_Object *o_system; int fmdir; - char *theme; + + /* Advanced */ + Evas_Object *o_categories_ilist; + Evas_Object *o_files_ilist; + int personal_file_count; + Evas_List *theme_list; /* Dialog */ E_Win *win_import; @@ -40,6 +50,8 @@ e_int_config_theme(E_Container *con) v->free_cfdata = _free_data; v->basic.apply_cfdata = _basic_apply_data; v->basic.create_widgets = _basic_create_widgets; + v->advanced.apply_cfdata = _advanced_apply_data; + v->advanced.create_widgets = _advanced_create_widgets; v->override_auto_apply = 1; cfd = e_config_dialog_new(con, _("Theme Selector"), @@ -306,7 +318,9 @@ _fill_data(E_Config_Dialog_Data *cfdata) } } } - + + cfdata->theme_list = _get_theme_categories_list(); + snprintf(path, sizeof(path), "%s/data/themes", e_prefix_data_get()); if (!strncmp(cfdata->theme, path, strlen(path))) cfdata->fmdir = 1; @@ -330,6 +344,7 @@ _free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) if (cfdata->win_import) e_int_config_theme_del(cfdata->win_import); + evas_list_free(cfdata->theme_list); E_FREE(cfdata->theme); E_FREE(cfdata); } @@ -374,8 +389,8 @@ _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cf else snprintf(path, sizeof(path), "%s/.e/e/themes", homedir); + cfdata->o_fm = NULL; o = e_fm2_add(evas); - cfdata->o_fm = o; memset(&fmc, 0, sizeof(E_Fm2_Config)); fmc.view.mode = E_FM2_VIEW_MODE_LIST; fmc.view.open_dirs_in_place = 1; @@ -413,6 +428,7 @@ _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cf e_fm2_pan_get, e_fm2_pan_max_get, e_fm2_pan_child_size_get); + cfdata->o_fm = o; cfdata->o_frame = of; e_widget_min_size_set(of, 160, 160); e_widget_table_object_append(ol, of, 0, 2, 1, 1, 1, 1, 1, 1); @@ -464,3 +480,579 @@ _basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) if ((a) && (a->func.go)) a->func.go(NULL, NULL); return 1; /* Apply was OK */ } + +/* + * -------------------------------------- + * --- A D V A N C E D S U P P O R T --- + * -------------------------------------- + */ + +static int +_cb_sort(void *data1, void *data2) +{ + const char *d1, *d2; + + d1 = data1; + d2 = data2; + if (!d1) return 1; + if (!d2) return -1; + + return strcmp(d1, d2); +} + +static Evas_List * +_get_theme_categories_list() +{ + Evas_List *themes, *tcl = NULL; + Evas_List *cats = NULL, *g = NULL, *cats2 = NULL; + const char *category; + + /* Setup some default theme categories */ + cats = evas_list_append(cats, strdup("base/theme/about")); + cats = evas_list_append(cats, strdup("base/theme/borders")); + cats = evas_list_append(cats, strdup("base/theme/background")); + cats = evas_list_append(cats, strdup("base/theme/configure")); + cats = evas_list_append(cats, strdup("base/theme/dialog")); + cats = evas_list_append(cats, strdup("base/theme/dnd")); + cats = evas_list_append(cats, strdup("base/theme/error")); + cats = evas_list_append(cats, strdup("base/theme/exebuf")); + cats = evas_list_append(cats, strdup("base/theme/fileman")); + cats = evas_list_append(cats, strdup("base/theme/gadman")); + cats = evas_list_append(cats, strdup("base/theme/icons")); + cats = evas_list_append(cats, strdup("base/theme/menus")); + cats = evas_list_append(cats, strdup("base/theme/modules")); + cats = evas_list_append(cats, strdup("base/theme/modules/pager")); + cats = evas_list_append(cats, strdup("base/theme/modules/ibar")); + cats = evas_list_append(cats, strdup("base/theme/modules/ibox")); + cats = evas_list_append(cats, strdup("base/theme/modules/clock")); + cats = evas_list_append(cats, strdup("base/theme/modules/battery")); + cats = evas_list_append(cats, strdup("base/theme/modules/cpufreq")); + cats = evas_list_append(cats, strdup("base/theme/modules/start")); + cats = evas_list_append(cats, strdup("base/theme/modules/temperature")); + cats = evas_list_append(cats, strdup("base/theme/pointer")); + cats = evas_list_append(cats, strdup("base/theme/shelf")); + cats = evas_list_append(cats, strdup("base/theme/transitions")); + cats = evas_list_append(cats, strdup("base/theme/widgets")); + cats = evas_list_append(cats, strdup("base/theme/winlist")); + + /* + * Get a list of registered themes. + * Add those which are not in the above list + */ + for (g = e_theme_category_list(); g; g = g->next) + { + const char *c; + c = g->data; + if (!c) continue; + + cats2 = cats; + while (cats2) + { + if (!strcmp(c, cats2->data)) + break; + cats2 = cats2->next; + } + if (!cats2) + cats = evas_list_append(cats, strdup(c)); + } + cats = evas_list_sort(cats, -1, _cb_sort); + + while (cats) + { + E_Config_Theme *theme, *newtheme = NULL; + + category = cats->data; + /* Not interested in adding "base" and "base/theme" */ + if (strcmp(category, "base") && strcmp(category, "base/theme")) + { + newtheme = (E_Config_Theme *)malloc(sizeof(E_Config_Theme)); + if (!newtheme) break; + newtheme->category = strdup(category); + newtheme->file = NULL; + + for (themes = e_config->themes; themes; themes = themes->next) + { + theme = themes->data; + if (!strcmp(category + 5, theme->category)) + { + newtheme->file = strdup(theme->file); + } + } + tcl = evas_list_append(tcl, newtheme); + } + cats = cats->next; + } + cats = evas_list_free(cats); + + return tcl; +} + +static void +_cb_adv_categories_change(void *data, Evas_Object *obj) +{ + E_Config_Dialog_Data *cfdata; + const char *label = NULL; + const char *file = NULL; + char category[256]; + Evas_List *themes = NULL, *l; + Evas_Object *ic = NULL; + int n; + + cfdata = data; + if (!cfdata) return; + + label = e_widget_ilist_selected_label_get(cfdata->o_categories_ilist); + if (!label) return; + + n = e_widget_ilist_selected_get(cfdata->o_categories_ilist); + ic = e_widget_ilist_nth_icon_get(cfdata->o_categories_ilist, n); + if (!ic) return; + + snprintf(category, sizeof(category), "base/theme/%s", label); + for (themes = cfdata->theme_list; themes; themes = themes->next) + { + E_Config_Theme *t; + + t = themes->data; + if (!strcmp(category, t->category) && (t->file)) + { + file = strdup(t->file); + break; + } + } + if (!file) return; + + for (n = 0, l = e_widget_ilist_items_get(cfdata->o_files_ilist); l; l = l->next, n++) + { + if (strstr(file, e_widget_ilist_nth_label_get(cfdata->o_files_ilist, n))) + { + e_widget_ilist_selected_set(cfdata->o_files_ilist, n); + break; + } + } + + free((void *)file); +} + +static void +_cb_adv_theme_change(void *data, Evas_Object *obj) +{ + E_Config_Dialog_Data *cfdata; + const char *label = NULL; + char theme[4096]; + int n; + + cfdata = data; + if (!cfdata) return; + + n = e_widget_ilist_selected_get(cfdata->o_files_ilist); + label = e_widget_ilist_selected_label_get(cfdata->o_files_ilist); + if (label) + { + if (n > cfdata->personal_file_count) + snprintf(theme, sizeof(theme), "%s/data/themes/%s.edj", + e_prefix_data_get(), label); + else + snprintf(theme, sizeof(theme), "%s/.e/e/themes/%s.edj", + e_user_homedir_get(), label); + e_widget_preview_edje_set(cfdata->o_preview, theme, + "e/desktop/background"); + } +} + +static int +_theme_file_used(Evas_List *tlist, const char *filename) +{ + E_Config_Theme *theme; + + while (tlist) + { + theme = tlist->data; + if (theme->file && strstr(theme->file, filename)) + { + return 1; + } + tlist = tlist->next; + } + + return 0; +} + +static int +_ilist_files_add(E_Config_Dialog_Data *cfdata, const char *header, const char *dir) +{ + DIR *d = NULL; + struct dirent *dentry = NULL; + Evas_List *themefiles = NULL; + int count; + char themename[256]; + Evas_Object *o; + Evas *evas; + + o = cfdata->o_files_ilist; + e_widget_ilist_header_append(o, NULL, header); + evas = evas_object_evas_get(o); + + d = opendir(dir); + if (d) + { + while ((dentry = readdir(d)) != NULL) + { + if (strstr(dentry->d_name,".edj") != NULL) + { + strncpy(themename, dentry->d_name, strlen(dentry->d_name)-3); + themename[strlen(dentry->d_name)-4] = '\0'; + themefiles = evas_list_append(themefiles, strdup(themename)); + } + } + closedir(d); + } + + if (themefiles) + { + themefiles = evas_list_sort(themefiles, -1, _cb_sort); + count = evas_list_count(themefiles); + + while (themefiles) + { + Evas_Object *ic = NULL; + if (_theme_file_used(cfdata->theme_list, themefiles->data)) + { + ic = edje_object_add(evas); + e_util_edje_icon_set(ic, "enlightenment/themes"); + } + e_widget_ilist_append(o, ic, themefiles->data, NULL, NULL, NULL); + + themefiles = themefiles->next; + } + } + + return count; +} + +static void +_fill_files_ilist(E_Config_Dialog_Data *cfdata) +{ + Evas *evas; + Evas_Object *o; + char theme_dir[4096]; + + o = cfdata->o_files_ilist; + if (!o) return; + + evas = evas_object_evas_get(o); + evas_event_freeze(evas); + edje_freeze(); + e_widget_ilist_freeze(o); + e_widget_ilist_clear(o); + + /* Grab the "Personal" themes. */ + snprintf(theme_dir, sizeof(theme_dir), "%s/.e/e/themes", + e_user_homedir_get()); + cfdata->personal_file_count = _ilist_files_add(cfdata, _("Personal"), + theme_dir); + + /* Grab the "System" themes. */ + snprintf(theme_dir, sizeof(theme_dir), + "%s/data/themes", e_prefix_data_get()); + _ilist_files_add(cfdata, _("System"), theme_dir); + + e_widget_ilist_go(o); + e_widget_ilist_thaw(o); + edje_thaw(); + evas_event_thaw(evas); +} + +static void +_fill_categories_ilist(E_Config_Dialog_Data *cfdata) +{ + Evas *evas; + Evas_List *themes; + E_Config_Theme *theme; + Evas_Object *o; + + o = cfdata->o_categories_ilist; + if (!o) return; + + evas = evas_object_evas_get(o); + evas_event_freeze(evas); + edje_freeze(); + e_widget_ilist_freeze(o); + e_widget_ilist_clear(o); + + themes = cfdata->theme_list; + while (themes) + { + Evas_Object *ic = NULL; + + theme = themes->data; + if (theme->file) + { + ic = edje_object_add(evas); + e_util_edje_icon_set(ic, "enlightenment/e"); + } + e_widget_ilist_append(o, ic, theme->category + 11, NULL, NULL, NULL); + themes = themes->next; + } + + e_widget_ilist_go(o); + e_widget_ilist_thaw(o); + edje_thaw(); + evas_event_thaw(evas); +} + +static void +_cb_adv_btn_assign(void *data1, void *data2) +{ + Evas *evas; + E_Config_Dialog_Data *cfdata; + E_Config_Theme *newtheme, *t; + Evas_List *themes; + Evas_Object *ic = NULL, *oc = NULL, *of = NULL; + char buf[1024]; + const char *label; + int n; + + cfdata = data1; + if (!cfdata) return; + + oc = cfdata->o_categories_ilist; + if (!oc) return; + of = cfdata->o_files_ilist; + if (!of) return; + + evas = evas_object_evas_get(oc); + n = e_widget_ilist_selected_get(oc); + ic = edje_object_add(evas); + e_util_edje_icon_set(ic, "enlightenment/e"); + e_widget_ilist_nth_icon_set(oc, n, ic); + + newtheme = malloc(sizeof(E_Config_Theme)); + if (!newtheme) return; + + label = e_widget_ilist_selected_label_get(oc); + snprintf(buf, sizeof(buf), "base/theme/%s", label); + newtheme->category = strdup(buf); + + n = e_widget_ilist_selected_get(of); + ic = edje_object_add(evas); + e_util_edje_icon_set(ic, "enlightenment/themes"); + e_widget_ilist_nth_icon_set(of, n, ic); + label = e_widget_ilist_selected_label_get(of); + if (n > cfdata->personal_file_count) + snprintf(buf, sizeof(buf), "%s/data/themes/%s.edj", + e_prefix_data_get(), label); + else + snprintf(buf, sizeof(buf), "%s/.e/e/themes/%s.edj", + e_user_homedir_get(), label); + newtheme->file = strdup(buf); + + for (themes = cfdata->theme_list; themes; themes = themes->next) + { + char * filename; + + t = themes->data; + if (!strcmp(t->category, newtheme->category)) + { + if (t->file) + { + filename = strdup(t->file); + free((void *)(t->file)); + t->file = NULL; + if (!_theme_file_used(cfdata->theme_list, filename)) + { + for (n = 0; n < e_widget_ilist_count(of); n++) + if (strstr(filename, e_widget_ilist_nth_label_get(of, n))) + e_widget_ilist_nth_icon_set(of, n, NULL); + } + free(filename); + } + t->file = strdup(newtheme->file); + break; + } + } + if (!themes) + cfdata->theme_list = evas_list_append(cfdata->theme_list, newtheme); + + return; +} + +static void +_cb_adv_btn_clear(void *data1, void *data2) +{ + E_Config_Dialog_Data *cfdata; + E_Config_Theme *t; + Evas_List *themes; + Evas_Object *oc = NULL, *of = NULL; + char cat[1024]; + const char *label; + int n; + + cfdata = data1; + if (!cfdata) return; + + oc = cfdata->o_categories_ilist; + if (!oc) return; + of = cfdata->o_files_ilist; + if (!of) return; + + n = e_widget_ilist_selected_get(oc); + e_widget_ilist_nth_icon_set(oc, n, NULL); + + label = e_widget_ilist_selected_label_get(oc); + snprintf(cat, sizeof(cat), "base/theme/%s", label); + + for (themes = cfdata->theme_list; themes; themes = themes->next) + { + t = themes->data; + if (!strcmp(t->category, cat)) + { + if (t->file) + { + free((void *)(t->file)); + t->file = NULL; + } + break; + } + } + + if (!_theme_file_used(cfdata->theme_list, e_widget_ilist_selected_label_get(of))) + { + n = e_widget_ilist_selected_get(of); + e_widget_ilist_nth_icon_set(of, n, NULL); + } + + return; +} + +static void +_cb_adv_btn_clearall(void *data1, void *data2) +{ + E_Config_Dialog_Data *cfdata; + E_Config_Theme *t; + Evas_List *themes; + Evas_Object *oc = NULL, *of = NULL; + int n; + + cfdata = data1; + if (!cfdata) return; + + oc = cfdata->o_categories_ilist; + if (!oc) return; + of = cfdata->o_files_ilist; + if (!of) return; + + for (n = 0; n < e_widget_ilist_count(oc); n++) + e_widget_ilist_nth_icon_set(oc, n, NULL); + for (n = 0; n < e_widget_ilist_count(of); n++) + e_widget_ilist_nth_icon_set(of, n, NULL); + + for (themes = cfdata->theme_list; themes; themes = themes->next) + { + t = themes->data; + if (t->file) + { + free((void *)(t->file)); + t->file = NULL; + } + } + + return; +} + +static Evas_Object * +_advanced_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata) +{ + Evas_Object *ot, *of, *ob, *oa, *ol; + int mw, mh; + E_Zone *zone; + + zone = e_zone_current_get(cfd->con); + ot = e_widget_table_add(evas, 0); + + of = e_widget_framelist_add(evas, _("Theme Categories"), 0); + ob = e_widget_ilist_add(evas, 16, 16, NULL); + e_widget_on_change_hook_set(ob, _cb_adv_categories_change, cfdata); + cfdata->o_categories_ilist = ob; + e_widget_ilist_multi_select_set(ob, 0); + e_widget_min_size_set(ob, 150, 250); + e_widget_framelist_object_append(of, ob); + e_widget_table_object_append(ot, of, 0, 0, 1, 1, 1, 1, 1, 1); + + of = e_widget_framelist_add(evas, _("Themes"), 0); + ob = e_widget_ilist_add(evas, 16, 16, NULL); + e_widget_on_change_hook_set(ob, _cb_adv_theme_change, cfdata); + cfdata->o_files_ilist = ob; + e_widget_ilist_multi_select_set(ob, 0); + e_widget_min_size_set(ob, 150, 250); + e_widget_framelist_object_append(of, ob); + e_widget_table_object_append(ot, of, 1, 0, 1, 1, 1, 1, 1, 1); + + ol = e_widget_list_add(evas, 1, 1); + ob = e_widget_button_add(evas, _("Assign"), NULL, _cb_adv_btn_assign, cfdata, NULL); + e_widget_list_object_append(ol, ob, 1, 0, 0.5); + ob = e_widget_button_add(evas, _("Clear"), NULL, _cb_adv_btn_clear, cfdata, NULL); + e_widget_list_object_append(ol, ob, 1, 0, 0.5); + ob = e_widget_button_add(evas, _("Clear All"), NULL, _cb_adv_btn_clearall, cfdata, NULL); + e_widget_list_object_append(ol, ob, 1, 0, 0.5); + e_widget_table_object_append(ot, ol, 0, 1, 1, 1, 1, 0, 1, 0); + + of = e_widget_framelist_add(evas, _("Preview"), 0); + mw = 320; + mh = (mw * zone->h) / zone->w; + oa = e_widget_aspect_add(evas, mw, mh); + ob = e_widget_preview_add(evas, mw, mh); + cfdata->o_preview = ob; + if (cfdata->theme) + e_widget_preview_edje_set(ob, cfdata->theme, "e/desktop/background"); + e_widget_aspect_child_set(oa, ob); + e_widget_framelist_object_append(of, oa); + e_widget_table_object_append(ot, of, 2, 0, 1, 1, 1, 1, 1, 1); + + _fill_files_ilist(cfdata); + _fill_categories_ilist(cfdata); + + e_widget_ilist_selected_set(cfdata->o_files_ilist, 1); + e_widget_ilist_selected_set(cfdata->o_categories_ilist, 0); + + e_dialog_resizable_set(cfd->dia, 1); + return ot; +} + +static int +_advanced_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) +{ + Evas_List *themes, *ec_themes; + E_Action *a; + + themes = cfdata->theme_list; + while (themes) + { + E_Config_Theme *theme, *ec_theme; + + theme = themes->data; + for (ec_themes = e_config->themes; ec_themes; ec_themes = ec_themes->next) + { + ec_theme = ec_themes->data; + if (!strcmp(theme->category + 5, ec_theme->category)) + { + if (theme->file) + e_theme_config_set(theme->category + 5, theme->file); + else + e_theme_config_remove(theme->category + 5); + break; + } + } + if ((!ec_themes) && (theme->file)) + e_theme_config_set(theme->category + 5, theme->file); + + themes = themes->next; + } + + e_config_save_queue(); + + a = e_action_find("restart"); + if ((a) && (a->func.go)) a->func.go(NULL, NULL); + + return 1; +}