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).
This commit is contained in:
Jean-Philippe Andre 2016-06-23 21:29:55 +09:00
parent 3ee261780a
commit 54e515bdca
7 changed files with 237 additions and 21 deletions

View File

@ -6369,3 +6369,4 @@ if test "x${efl_deprecated_option}" = "xyes"; then
echo "#-------------------------------------------------------------------#"
fi

View File

@ -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

View File

@ -269,6 +269,7 @@ EAPI extern Elm_Version *elm_version;
#include <elm_win_standard.h>
#ifdef EFL_EO_API_SUPPORT
# include <efl_config_global.eo.h>
# include <efl_ui_box.eo.h>
# include <efl_ui_box_flow.eo.h>
# include <efl_ui_grid.eo.h>

View File

@ -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<string>), 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;
}
}

View File

@ -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;
}
}

View File

@ -6,7 +6,7 @@
#include "elm_priv.h"
#include <pwd.h>
#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"

View File

@ -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;