summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/elm_prefs.c113
-rw-r--r--src/lib/elm_widget_prefs.h4
2 files changed, 80 insertions, 37 deletions
diff --git a/src/lib/elm_prefs.c b/src/lib/elm_prefs.c
index 6b3baefb9..65c6e64f2 100644
--- a/src/lib/elm_prefs.c
+++ b/src/lib/elm_prefs.c
@@ -46,6 +46,7 @@ static void _elm_prefs_values_get_default(Elm_Prefs_Page_Node *, Eina_Bool);
46static Eina_Bool _prefs_item_widget_value_from_self(Elm_Prefs_Item_Node *, Eina_Bool); 46static Eina_Bool _prefs_item_widget_value_from_self(Elm_Prefs_Item_Node *, Eina_Bool);
47static Eina_Bool _elm_prefs_value_get(Elm_Prefs_Data *, const char *, Eina_Value *); 47static Eina_Bool _elm_prefs_value_get(Elm_Prefs_Data *, const char *, Eina_Value *);
48static Eina_Bool _elm_prefs_value_set(Elm_Prefs_Data *, const char *, const Elm_Prefs_Item_Type, const Eina_Value *); 48static Eina_Bool _elm_prefs_value_set(Elm_Prefs_Data *, const char *, const Elm_Prefs_Item_Type, const Eina_Value *);
49static void _elm_prefs_value_restore(Elm_Prefs_Data *, Elm_Prefs_Item_Node *, const char *);
49static Eina_Bool _elm_prefs_item_changed(Eo *, Elm_Prefs_Data *, const char *); 50static Eina_Bool _elm_prefs_item_changed(Eo *, Elm_Prefs_Data *, const char *);
50static void _elm_prefs_values_get_user(Elm_Prefs_Data *, Elm_Prefs_Page_Node *); 51static void _elm_prefs_values_get_user(Elm_Prefs_Data *, Elm_Prefs_Page_Node *);
51static void _elm_prefs_values_fetch(Eo *, Elm_Prefs_Data *, bool); 52static void _elm_prefs_values_fetch(Eo *, Elm_Prefs_Data *, bool);
@@ -379,6 +380,13 @@ _elm_prefs_item_changed(Eo *obj,
379 Elm_Prefs_Item_Node *item = _elm_prefs_item_node_by_name(sd, key); 380 Elm_Prefs_Item_Node *item = _elm_prefs_item_node_by_name(sd, key);
380 if (!item) return EINA_FALSE; 381 if (!item) return EINA_FALSE;
381 382
383 if (sd->pending_change && strcmp(sd->pending_change, key) == 0)
384 {
385 free(sd->pending_change);
386 sd->pending_change = NULL;
387 return EINA_FALSE;
388 }
389
382 Eina_Value value; 390 Eina_Value value;
383 if (!_elm_prefs_value_get(sd, key, &value)) 391 if (!_elm_prefs_value_get(sd, key, &value))
384 { 392 {
@@ -407,7 +415,12 @@ _elm_prefs_properties_changed(Eo *obj,
407 const char *property; 415 const char *property;
408 Eina_Array_Iterator it; 416 Eina_Array_Iterator it;
409 EINA_ARRAY_ITER_NEXT(properties, i, property, it) 417 EINA_ARRAY_ITER_NEXT(properties, i, property, it)
410 changed = _elm_prefs_item_changed(obj, sd, property) || changed; 418 {
419 const char *key = eina_hash_find(sd->property_to_key, property);
420 if (!key)
421 key = property;
422 changed = _elm_prefs_item_changed(obj, sd, key) || changed;
423 }
411 424
412 return changed; 425 return changed;
413} 426}
@@ -422,7 +435,6 @@ _model_property_changed_cb(void *data,
422 Eo *obj = (Eo*)data; 435 Eo *obj = (Eo*)data;
423 436
424 ELM_PREFS_DATA_GET(obj, sd); 437 ELM_PREFS_DATA_GET(obj, sd);
425 if (sd->changing_from_ui) return EO_CALLBACK_CONTINUE;
426 438
427 Eina_Bool changed = _elm_prefs_properties_changed 439 Eina_Bool changed = _elm_prefs_properties_changed
428 (obj, sd, evt->changed_properties); 440 (obj, sd, evt->changed_properties);
@@ -444,6 +456,17 @@ _model_load_status_change_cb(void *data,
444 Eo *obj = (Eo*)data; 456 Eo *obj = (Eo*)data;
445 ELM_PREFS_DATA_GET(obj, sd); 457 ELM_PREFS_DATA_GET(obj, sd);
446 458
459 if ((load->status & EMODEL_LOAD_STATUS_ERROR) && sd->pending_change)
460 {
461 Elm_Prefs_Item_Node *item = _elm_prefs_item_node_by_name(sd, sd->pending_change);
462 if (item)
463 _elm_prefs_value_restore(sd, item, sd->pending_change);
464
465 free(sd->pending_change);
466 sd->pending_change = NULL;
467 return EO_CALLBACK_CONTINUE;
468 }
469
447 bool reset_values = !(load->status & EMODEL_LOAD_STATUS_LOADED_PROPERTIES); 470 bool reset_values = !(load->status & EMODEL_LOAD_STATUS_LOADED_PROPERTIES);
448 _elm_prefs_values_fetch(obj, sd, reset_values); 471 _elm_prefs_values_fetch(obj, sd, reset_values);
449 472
@@ -550,7 +573,9 @@ _elm_prefs_evas_object_smart_del(Eo *obj, Elm_Prefs_Data *sd)
550 _root_node_free(sd); 573 _root_node_free(sd);
551 } 574 }
552 575
553 eina_hash_free(sd->prop_con); 576 eina_hash_free(sd->key_to_property);
577 eina_hash_free(sd->property_to_key);
578 free(sd->pending_change);
554 if (sd->prefs_data) elm_prefs_data_unref(sd->prefs_data); 579 if (sd->prefs_data) elm_prefs_data_unref(sd->prefs_data);
555 if (sd->model) eo_unref(sd->model); 580 if (sd->model) eo_unref(sd->model);
556 581
@@ -608,7 +633,8 @@ _elm_prefs_eo_base_constructor(Eo *obj, Elm_Prefs_Data *pd)
608 evas_obj_type_set(MY_CLASS_NAME_LEGACY), 633 evas_obj_type_set(MY_CLASS_NAME_LEGACY),
609 evas_obj_smart_callbacks_descriptions_set(_elm_prefs_smart_callbacks), 634 evas_obj_smart_callbacks_descriptions_set(_elm_prefs_smart_callbacks),
610 elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_REDUNDANT_OBJECT)); 635 elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_REDUNDANT_OBJECT));
611 pd->prop_con = eina_hash_string_superfast_new(free); 636 pd->key_to_property = eina_hash_string_superfast_new(free);
637 pd->property_to_key = eina_hash_string_superfast_new(free);
612} 638}
613 639
614static Eina_Bool 640static Eina_Bool
@@ -670,25 +696,7 @@ _item_changed_cb(Evas_Object *it_obj)
670 if (it->w_impl->value_validate && 696 if (it->w_impl->value_validate &&
671 !it->w_impl->value_validate(it->w_obj)) 697 !it->w_impl->value_validate(it->w_obj))
672 { 698 {
673 if (sd->prefs_data || sd->model) 699 _elm_prefs_value_restore(sd, it, buf);
674 {
675 Eina_Value value;
676
677 // Restoring to the last valid value.
678 if (!_elm_prefs_value_get(sd, buf, &value))
679 goto restore_fail;
680
681 Eina_Bool ret = it->w_impl->value_set(it->w_obj, &value);
682 eina_value_flush(&value);
683 if (!ret)
684 goto restore_fail;
685 }
686 else
687 {
688 if (!_prefs_item_widget_value_from_self(it, EINA_FALSE))
689 goto restore_fail;
690 }
691
692 return; 700 return;
693 } 701 }
694 702
@@ -709,12 +717,6 @@ end:
709 if (!sd->values_fetching) _elm_prefs_item_changed_report(it->prefs, it); 717 if (!sd->values_fetching) _elm_prefs_item_changed_report(it->prefs, it);
710 718
711 _elm_prefs_mark_as_dirty(it->prefs); 719 _elm_prefs_mark_as_dirty(it->prefs);
712
713 return;
714
715restore_fail:
716 ERR("failed to restore the last valid value from widget of item %s",
717 buf);
718} 720}
719 721
720static Eina_Bool 722static Eina_Bool
@@ -2006,7 +2008,7 @@ elm_prefs_file_get(const Eo *obj, const char **file, const char **page)
2006static Eina_Bool 2008static Eina_Bool
2007_elm_prefs_value_get(Elm_Prefs_Data *sd, const char *key, Eina_Value *value) 2009_elm_prefs_value_get(Elm_Prefs_Data *sd, const char *key, Eina_Value *value)
2008{ 2010{
2009 const char *property = eina_hash_find(sd->prop_con, key); 2011 const char *property = eina_hash_find(sd->key_to_property, key);
2010 if (!property) 2012 if (!property)
2011 property = key; 2013 property = key;
2012 2014
@@ -2033,30 +2035,68 @@ _elm_prefs_value_set(Elm_Prefs_Data *sd,
2033 const Elm_Prefs_Item_Type type, 2035 const Elm_Prefs_Item_Type type,
2034 const Eina_Value *value) 2036 const Eina_Value *value)
2035{ 2037{
2036 const char *property = eina_hash_find(sd->prop_con, key); 2038 const char *property = eina_hash_find(sd->key_to_property, key);
2037 if (!property) 2039 if (!property)
2038 property = key; 2040 property = key;
2039 2041
2040 sd->changing_from_ui = EINA_TRUE;
2041 2042
2042 Eina_Bool result = EINA_FALSE; 2043 Eina_Bool result = EINA_FALSE;
2043 if (sd->prefs_data) 2044 if (sd->prefs_data)
2044 result = elm_prefs_data_value_set(sd->prefs_data, property, type, value); 2045 {
2046 sd->changing_from_ui = EINA_TRUE;
2047 result = elm_prefs_data_value_set(sd->prefs_data, property, type, value);
2048 sd->changing_from_ui = EINA_FALSE;
2049 }
2045 else 2050 else
2046 if (sd->model) 2051 if (sd->model)
2047 { 2052 {
2053 sd->pending_change = strdup(key);
2054
2048 // TODO: Convert the value 2055 // TODO: Convert the value
2049 Emodel_Load_Status status; 2056 Emodel_Load_Status status;
2050 eo_do(sd->model, status = emodel_property_set(property, value)); 2057 eo_do(sd->model, status = emodel_property_set(property, value));
2051 result = EMODEL_LOAD_STATUS_ERROR != status; 2058 result = EMODEL_LOAD_STATUS_ERROR != status;
2052 // TODO: The property changed event could be delayed for Emodel 2059
2060 if (!result)
2061 {
2062 free(sd->pending_change);
2063 sd->pending_change = NULL;
2064 }
2053 } 2065 }
2054 2066
2055 sd->changing_from_ui = EINA_FALSE;
2056 return result; 2067 return result;
2057} 2068}
2058 2069
2059static void 2070static void
2071_elm_prefs_value_restore(Elm_Prefs_Data *sd,
2072 Elm_Prefs_Item_Node *it,
2073 const char *key)
2074{
2075 if (sd->prefs_data || sd->model)
2076 {
2077 Eina_Value value;
2078
2079 // Restoring to the last valid value.
2080 if (!_elm_prefs_value_get(sd, key, &value))
2081 goto on_error;
2082
2083 Eina_Bool ret = it->w_impl->value_set(it->w_obj, &value);
2084 eina_value_flush(&value);
2085 if (!ret) goto on_error;
2086 }
2087 else
2088 {
2089 if (!_prefs_item_widget_value_from_self(it, EINA_FALSE))
2090 goto on_error;
2091 }
2092
2093 return;
2094
2095on_error:
2096 ERR("failed to restore the last valid value from widget of item %s", key);
2097}
2098
2099static void
2060_elm_prefs_property_connect(Eo *obj EINA_UNUSED, 2100_elm_prefs_property_connect(Eo *obj EINA_UNUSED,
2061 Elm_Prefs_Data *sd, 2101 Elm_Prefs_Data *sd,
2062 const char *property, 2102 const char *property,
@@ -2066,7 +2106,8 @@ _elm_prefs_property_connect(Eo *obj EINA_UNUSED,
2066 EINA_SAFETY_ON_NULL_RETURN(property); 2106 EINA_SAFETY_ON_NULL_RETURN(property);
2067 EINA_SAFETY_ON_NULL_RETURN(part); 2107 EINA_SAFETY_ON_NULL_RETURN(part);
2068 2108
2069 free(eina_hash_set(sd->prop_con, part, strdup(property))); 2109 free(eina_hash_set(sd->key_to_property, part, strdup(property)));
2110 free(eina_hash_set(sd->property_to_key, property, strdup(part)));
2070} 2111}
2071 2112
2072static void 2113static void
diff --git a/src/lib/elm_widget_prefs.h b/src/lib/elm_widget_prefs.h
index d902b3143..211b72743 100644
--- a/src/lib/elm_widget_prefs.h
+++ b/src/lib/elm_widget_prefs.h
@@ -75,9 +75,11 @@ struct _Elm_Prefs_Data
75{ 75{
76 Elm_Prefs_Page_Node *root; 76 Elm_Prefs_Page_Node *root;
77 77
78 Eina_Hash *prop_con; 78 Eina_Hash *key_to_property;
79 Eina_Hash *property_to_key;
79 Elm_Prefs_Data *prefs_data; 80 Elm_Prefs_Data *prefs_data;
80 Emodel *model; 81 Emodel *model;
82 char *pending_change;
81 const char *file; 83 const char *file;
82 const char *page; 84 const char *page;
83 85