This works good now! Very cool feature, well done.
On 5/26/07, Ravenlock <[EMAIL PROTECTED]> wrote: > > On 05/25/2007 22:51, Ravenlock wrote: > > Hello, > > > > Please find attached a patch which will add an "Advanced" dialog to the > > Theme configuration panel. > > *sigh* > The first comment was... "it segv's before showing the advanced dialog." > > So here is a revised patch. Not sure why I cant reproduce it though > (BSD vs. Linux?). > > > > > The advanced dialog will allow a user to associate individual themed > > elements of E with any theme installed on the machine. For example, > > your borders could come from Codito, your menus from Gant, your icons > > from Kor, your winlist from carbon-14, and your pager from Blue-eyed. > > > > Example: > > http://www.ravenlock.us/pics/adv_theme.png > > > > Notice in the above image there are many elements from many different > > themes. > > > > Given this functionality you can "roll your own" theme. Note that this > > is *not* new functionality. This has always been available > > (enlightenment_remote), just not very obvious or easy to use. This gui > > will make it easier for the average user to customize their E > > environment a little more. > > > > For what its worth (a little speculation here)... it may be possible for > > themers to actually make "themes" that only consist of a particular > > element, say a menu, or a set of icons, or just borders, or maybe a > > fancy winlist.... and people could then pick and choose whichever they > > like. You could have a library of theme elements, and simply pick what > > you need. > > > > I'm hoping a few people will patch their systems and give it a spin, and > > then provide feedback. > > > > I'll be out of town this weekend... most likely will be completely > > unplugged. I'll catch up on any feedback as soon as I return (monday > > evening). > > > > > > ------------------------------------------------------------------------ > > > > > ------------------------------------------------------------------------- > > This SF.net email is sponsored by DB2 Express > > Download DB2 Express C - the FREE version of DB2 express and take > > control of your XML. No limits. Just data. Click to get it now. > > http://sourceforge.net/powerbar/db2/ > > > > > > ------------------------------------------------------------------------ > > > > _______________________________________________ > > enlightenment-devel mailing list > > enlightenment-devel@lists.sourceforge.net > > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel > > > -- > Regards, > Ravenlock > > Index: e17/apps/e/src/bin/e_int_config_theme.c > =================================================================== > RCS file: /cvs/e/e17/apps/e/src/bin/e_int_config_theme.c,v > retrieving revision 1.50 > diff -u -r1.50 e_int_config_theme.c > --- e17/apps/e/src/bin/e_int_config_theme.c 2 May 2007 18:38:23 > -0000 1.50 > +++ e17/apps/e/src/bin/e_int_config_theme.c 26 May 2007 05:08:23 -0000 > @@ -9,10 +9,15 @@ > 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 @@ > 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 @@ > 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 @@ > } > } > } > - > + > + 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 @@ > 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 @@ > 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 @@ > 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); > @@ -463,4 +479,582 @@ > a = e_action_find("restart"); > 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; > + Evas_List *all_parts; > + char theme_dir[1024]; > + > + /* 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], theme[256]; > + > + 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; > } > > ------------------------------------------------------------------------- > This SF.net email is sponsored by DB2 Express > Download DB2 Express C - the FREE version of DB2 express and take > control of your XML. No limits. Just data. Click to get it now. > http://sourceforge.net/powerbar/db2/ > _______________________________________________ > enlightenment-devel mailing list > enlightenment-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel > > ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ enlightenment-devel mailing list enlightenment-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-devel