From 54e515bdca1dca97efbd60ee1a3800ae1cabc095 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Thu, 23 Jun 2016 21:29:55 +0900 Subject: [PATCH] config: Add support for profiles and save Most of these functions actually shouldn't be used by standard applications. Some are hidden behind @protected. flush_all() and reload() have not been implemented, on purpose (save() should flush, and reload is automatic). --- configure.ac | 1 + src/Makefile_Elementary.am | 2 +- src/lib/elementary/Elementary.h.in | 1 + src/lib/elementary/efl_config_global.eo | 113 +++++++++++++++++++ src/lib/elementary/efl_config_internal.eo | 10 -- src/lib/elementary/elm_config.c | 129 ++++++++++++++++++++-- src/lib/elementary/elm_widget.c | 2 +- 7 files changed, 237 insertions(+), 21 deletions(-) create mode 100644 src/lib/elementary/efl_config_global.eo delete mode 100644 src/lib/elementary/efl_config_internal.eo diff --git a/configure.ac b/configure.ac index 666f39b3a7..bba3e2abb4 100644 --- a/configure.ac +++ b/configure.ac @@ -6369,3 +6369,4 @@ if test "x${efl_deprecated_option}" = "xyes"; then echo "#-------------------------------------------------------------------#" fi + diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am index fbe6e089c3..3e81fbc420 100644 --- a/src/Makefile_Elementary.am +++ b/src/Makefile_Elementary.am @@ -141,12 +141,12 @@ elm_public_eolian_files = \ lib/elementary/efl_ui_text_interactive.eo \ lib/elementary/efl_ui_text.eo \ lib/elementary/efl_ui_text_editable.eo \ + lib/elementary/efl_config_global.eo \ $(NULL) # Private classes (not exposed or shipped) elm_private_eolian_files = \ lib/elementary/efl_ui_internal_text_interactive.eo \ - lib/elementary/efl_config_internal.eo \ $(NULL) # Legacy classes - not part of public EO API diff --git a/src/lib/elementary/Elementary.h.in b/src/lib/elementary/Elementary.h.in index 405afc1a0a..0257805a6c 100644 --- a/src/lib/elementary/Elementary.h.in +++ b/src/lib/elementary/Elementary.h.in @@ -269,6 +269,7 @@ EAPI extern Elm_Version *elm_version; #include #ifdef EFL_EO_API_SUPPORT +# include # include # include # include diff --git a/src/lib/elementary/efl_config_global.eo b/src/lib/elementary/efl_config_global.eo new file mode 100644 index 0000000000..ae26b34a7b --- /dev/null +++ b/src/lib/elementary/efl_config_global.eo @@ -0,0 +1,113 @@ +class Efl.Config.Global (Eo.Base, Efl.Config) +{ + [[This class is a singleton representing the global configuration for the + running application. + ]] + data: null; + eo_prefix: efl_config; + methods { + save @protected { + [[Saves Elementary configuration to disk. + + This function will take effect (does I/O) immediately. Use it when + you want to save all configuration changes at once. The current + configuration set will get saved onto the current profile + configuration file. + + If $profile is $null, this will flush all settings to all + applications running on the same profile. + + If $profile is not $null, this will take the current in-memory + config and write it out to the named $profile. This will not + change profile for the application or make other processes switch + profile. + ]] + params { + profile: string @optional; [[The profile name.]] + } + return: bool; + } + @property profile { + [[The profile for the running application. + + Profiles are pre-set options that affect the whole look-and-feel of + Elementary-based applications. There are, for example, profiles + aimed at desktop computer applications and others aimed at mobile, + touchscreen-based ones. You most probably don't want to use the + functions in this group unless you're writing an elementary + configuration manager. + + This gets or sets the global profile that is applied to all + Elementary applications. + ]] + values { + profile: string; + } + } + profile_iterate { + [[Returns the list of available profiles.]] + params { + hidden: bool @optional; [[If $true, gets the full list of profiles, + including those stored in hidden files.]] + } + return: free(own(iterator), eina_iterator_free); + } + profile_exists { + [[Returns whether a profile exists or not.]] + params { + profile: string; + } + return: bool; + } + profile_dir_get { + [[Returns the directory where a profile is stored.]] + params { + profile: string; + is_user: bool; [[$true to lookup for a user profile or $false for + a system one.]] + } + return: own(stringshare); + } + profile_derived_add @protected { + [[Add a new profile of the given name to be derived from the current + profile. + + This creates a new profile of name $profile that will be derived + from the currently used profile using the modification commands + encoded in the $options string. + + At this point it is not expected that anyone would generally use + this API except if you are a destktop environment and so the user + base of this API will be enlightenment itself. + + @since 1.17 + ]] + params { + profile: string; [[The new profile's name.]] + options: string; [[Derive options detailing how to modify.]] + } + } + profile_derived_del @protected { + [[Deletes a profile that is derived from the current one. + + This deletes a derived profile added by @.profile_derived_add. + This will delete the profile of the given name $profile that is + derived from the current profile. + + At this point it is not expected that anyone would generally use + this API except if you are a destktop environment and so the user + base of this API will be enlightenment itself. + + @since 1.17 + ]] + params { + profile: string; [[The name of the profile that is to be deleted.]] + } + } + } + implements { + Efl.Config.config_set; + Efl.Config.config_get; + Efl.Config.config_list_get; + } +} diff --git a/src/lib/elementary/efl_config_internal.eo b/src/lib/elementary/efl_config_internal.eo deleted file mode 100644 index b7d13f0a03..0000000000 --- a/src/lib/elementary/efl_config_internal.eo +++ /dev/null @@ -1,10 +0,0 @@ -class Efl.Config.Internal (Eo.Base, Efl.Config) -{ - [[Internal class translating between Efl.Config and legacy elm_config.]] - data: null; - implements { - Efl.Config.config_set; - Efl.Config.config_get; - Efl.Config.config_list_get; - } -} diff --git a/src/lib/elementary/elm_config.c b/src/lib/elementary/elm_config.c index 14a3c72648..d14aee8c3f 100644 --- a/src/lib/elementary/elm_config.c +++ b/src/lib/elementary/elm_config.c @@ -6,7 +6,7 @@ #include "elm_priv.h" #include -#include "efl_config_internal.eo.h" +#include "efl_config_global.eo.h" EAPI int ELM_EVENT_CONFIG_ALL_CHANGED = 0; EAPI void __efl_internal_elm_config_set(Efl_Config *cfg); @@ -1682,8 +1682,9 @@ _config_system_load(void) static void _config_load(void) { - _efl_config_obj = eo_add(EFL_CONFIG_INTERNAL_CLASS, NULL); + _efl_config_obj = eo_add(EFL_CONFIG_GLOBAL_CLASS, NULL); efl_loop_register(ecore_main_loop_get(), EFL_CONFIG_INTERFACE, _efl_config_obj); + efl_loop_register(ecore_main_loop_get(), EFL_CONFIG_GLOBAL_CLASS, _efl_config_obj); _elm_config = _config_user_load(); if (_elm_config) { @@ -4242,8 +4243,9 @@ _elm_config_profile_set(const char *profile) void _elm_config_shutdown(void) { - ELM_SAFE_FREE(_efl_config_obj, eo_del); efl_loop_register(ecore_main_loop_get(), EFL_CONFIG_INTERFACE, NULL); + efl_loop_register(ecore_main_loop_get(), EFL_CONFIG_GLOBAL_CLASS, NULL); + ELM_SAFE_FREE(_efl_config_obj, eo_del); ELM_SAFE_FREE(_elm_config, _config_free); ELM_SAFE_FREE(_elm_preferred_engine, eina_stringshare_del); ELM_SAFE_FREE(_elm_accel_preference, eina_stringshare_del); @@ -4363,8 +4365,8 @@ static const struct { }; EOLIAN static Eina_Bool -_efl_config_internal_efl_config_config_set(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, - const char *name, const Eina_Value *val) +_efl_config_global_efl_config_config_set(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, + const char *name, const Eina_Value *val) { if (!name) return EINA_FALSE; // TODO: if (!val) reset to default @@ -4526,7 +4528,7 @@ _efl_config_internal_efl_config_config_set(Eo *obj EINA_UNUSED, void *_pd EINA_U } EOLIAN static Eina_Value * -_efl_config_internal_efl_config_config_get(const Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, +_efl_config_global_efl_config_config_get(const Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, const char *name) { Eina_Value *val = NULL; @@ -4654,12 +4656,121 @@ _efl_config_internal_efl_config_config_get(const Eo *obj EINA_UNUSED, void *_pd } EOLIAN static Eina_Iterator * -_efl_config_internal_efl_config_config_list_get(const Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, - const char *name) +_efl_config_global_efl_config_config_list_get(const Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, + const char *name) { // Not implemented: none of the elm_config functions returns a list of primitive types (void) name; return NULL; } -#include "efl_config_internal.eo.c" +EOLIAN static void +_efl_config_global_profile_set(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, const char *profile) +{ + elm_config_profile_set(profile); +} + +EOLIAN static const char * +_efl_config_global_profile_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED) +{ + return elm_config_profile_get(); +} + +EOLIAN static Eina_Bool +_efl_config_global_save(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, const char *profile) +{ + return _elm_config_save(_elm_config, profile); +} + +typedef struct +{ + Eina_Iterator iterator; + Eina_List *list; + Eina_Iterator *real_iterator; + Eo *object; +} Profile_Iterator; + +static Eina_Bool +_profile_iterator_next(Profile_Iterator *it, void **data) +{ + Efl_Gfx *sub; + + if (!it->object) return EINA_FALSE; + if (!eina_iterator_next(it->real_iterator, (void **) &sub)) + return EINA_FALSE; + + if (data) *data = sub; + return EINA_TRUE; +} + +static Eo * +_profile_iterator_get_container(Profile_Iterator *it) +{ + return it->object; +} + +static void +_profile_iterator_free(Profile_Iterator *it) +{ + eina_iterator_free(it->real_iterator); + elm_config_profile_list_free(it->list); + free(it); +} + +EOLIAN static Eina_Iterator * +_efl_config_global_profile_iterate(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, Eina_Bool hidden) +{ + Profile_Iterator *it; + Eina_List *list; + + list = _elm_config_profiles_list(!hidden); + if (!list) return NULL; + + it = calloc(1, sizeof(*it)); + if (!it) return NULL; + + EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); + + it->list = list; + it->real_iterator = eina_list_iterator_new(it->list); + it->iterator.version = EINA_ITERATOR_VERSION; + it->iterator.next = FUNC_ITERATOR_NEXT(_profile_iterator_next); + it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_profile_iterator_get_container); + it->iterator.free = FUNC_ITERATOR_FREE(_profile_iterator_free); + eo_wref_add(obj, &it->object); + + return &it->iterator; +} + +EOLIAN static Eina_Bool +_efl_config_global_profile_exists(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, const char *profile) +{ + return elm_config_profile_exists(profile); +} + +EOLIAN static Eina_Stringshare * +_efl_config_global_profile_dir_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, const char *profile, Eina_Bool is_user) +{ + Eina_Stringshare *str; + const char *dir; + + dir = elm_config_profile_dir_get(profile, is_user); + str = eina_stringshare_add(dir); + elm_config_profile_dir_free(dir); + + return str; +} + +EOLIAN static void +_efl_config_global_profile_derived_add(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, const char *profile, const char *options) +{ + elm_config_profile_derived_add(profile, options); +} + +EOLIAN static void +_efl_config_global_profile_derived_del(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, const char *profile) +{ + elm_config_profile_derived_del(profile); +} + +#include "efl_config_global.eo.c" diff --git a/src/lib/elementary/elm_widget.c b/src/lib/elementary/elm_widget.c index f6f2486daa..b670a1dc38 100644 --- a/src/lib/elementary/elm_widget.c +++ b/src/lib/elementary/elm_widget.c @@ -6073,7 +6073,7 @@ _elm_widget_eo_base_provider_find(Eo *obj, Elm_Widget_Smart_Data *pd, const Eo_B { Eo_Base *lookup = NULL; - if (klass == EFL_CONFIG_INTERFACE) + if ((klass == EFL_CONFIG_INTERFACE) || (klass == EFL_CONFIG_GLOBAL_CLASS)) return _efl_config_obj; if (pd->provider_lookup) return NULL;