[Widget] Prevent widget item API calls while item is deleting except data_get API call. The data by data_set is user_data. So it can be needed inside deleting function trace.

Reviewers: raster, cedric, Hermet, seoz

Reviewed By: raster

Differential Revision: https://phab.enlightenment.org/D525
This commit is contained in:
Tae-Hwan Kim 2014-02-07 18:09:46 +09:00 committed by Carsten Haitzler (Rasterman)
parent 07a4f33868
commit a9aec7a43e
2 changed files with 85 additions and 0 deletions

View File

@ -5154,6 +5154,8 @@ EAPI void
_elm_widget_item_del(Elm_Widget_Item *item)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
item->on_deletion = EINA_TRUE;
//Widget item delete callback
if (item->del_pre_func)
@ -5179,6 +5181,7 @@ _elm_widget_item_del_pre_hook_set(Elm_Widget_Item *item,
Elm_Widget_Del_Pre_Cb func)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
item->del_pre_func = func;
}
/**
@ -5195,6 +5198,7 @@ _elm_widget_item_style_set_hook_set(Elm_Widget_Item *item,
Elm_Widget_Style_Set_Cb func)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
item->style_set_func = func;
}
@ -5212,6 +5216,7 @@ _elm_widget_item_style_get_hook_set(Elm_Widget_Item *item,
Elm_Widget_Style_Get_Cb func)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
item->style_get_func = func;
}
/**
@ -5259,6 +5264,7 @@ _elm_widget_item_del_cb_set(Elm_Widget_Item *item,
Evas_Smart_Cb func)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
if ((item->del_func) && (item->del_func != func))
WRN("You're replacing a previously set del_cb %p of item %p with %p",
@ -5280,6 +5286,8 @@ EAPI Evas_Object *
_elm_widget_item_widget_get(const Elm_Widget_Item *item)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
return item->widget;
}
@ -5302,6 +5310,8 @@ _elm_widget_item_data_set(Elm_Widget_Item *item,
const void *data)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
if ((item->data) && (item->data != data))
DBG("Replacing item %p data %p with %p", item, item->data, data);
item->data = data;
@ -5328,6 +5338,7 @@ _elm_widget_item_disabled_set(Elm_Widget_Item *item,
Eina_Bool disabled)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
if (item->disabled == disabled) return;
item->disabled = !!disabled;
@ -5345,6 +5356,7 @@ EAPI void
_elm_widget_item_style_set(Elm_Widget_Item *item, const char *style)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
item->style_set_func(item, style);
}
@ -5360,6 +5372,7 @@ _elm_widget_item_disable_hook_set(Elm_Widget_Item *item,
Elm_Widget_Disable_Cb func)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
item->disable_func = func;
}
@ -5370,6 +5383,7 @@ _elm_widget_item_domain_translatable_part_text_set(Elm_Widget_Item *item,
const char *label)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
Elm_Translate_String_Data *ts;
if (!label)
@ -5400,6 +5414,8 @@ _elm_widget_item_translatable_part_text_get(const Elm_Widget_Item *item,
const char *part)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
Elm_Translate_String_Data *ts;
ts = _translate_string_data_get(item->translate_strings, part);
if (ts) return ts->string;
@ -5413,6 +5429,7 @@ _elm_widget_item_domain_part_text_translatable_set(Elm_Widget_Item *item,
Eina_Bool translatable)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
Elm_Translate_String_Data *ts;
const char *text;
@ -5440,6 +5457,7 @@ EAPI void
_elm_widget_item_track_cancel(Elm_Widget_Item *item)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
if (!item->track_obj) return;
@ -5453,6 +5471,7 @@ EAPI Evas_Object *
elm_widget_item_track(Elm_Widget_Item *item)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
if (item->track_obj)
{
@ -5496,6 +5515,7 @@ void
elm_widget_item_untrack(Elm_Widget_Item *item)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
if (!item->track_obj) return;
evas_object_unref(item->track_obj);
@ -5508,6 +5528,7 @@ int
elm_widget_item_track_get(const Elm_Widget_Item *item)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, 0);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, 0);
if (!item->track_obj) return 0;
return evas_object_ref_get(item->track_obj);
@ -5577,6 +5598,7 @@ _elm_widget_item_tooltip_text_set(Elm_Widget_Item *item,
const char *text)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
EINA_SAFETY_ON_NULL_RETURN(text);
text = eina_stringshare_add(text);
@ -5590,6 +5612,7 @@ _elm_widget_item_tooltip_translatable_text_set(Elm_Widget_Item *item,
const char *text)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
EINA_SAFETY_ON_NULL_RETURN(text);
text = eina_stringshare_add(text);
@ -5648,6 +5671,7 @@ _elm_widget_item_tooltip_content_cb_set(Elm_Widget_Item *item,
Elm_Widget_Item_Tooltip *wit;
ELM_WIDGET_ITEM_CHECK_OR_GOTO(item, error_noitem);
//ELM_WIDGET_ITEM_RETURN_IF_GOTO(item, error_noitem);
if (!func)
{
@ -5694,6 +5718,8 @@ EAPI void
_elm_widget_item_tooltip_unset(Elm_Widget_Item *item)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
elm_object_tooltip_unset(item->view);
}
@ -5716,6 +5742,8 @@ _elm_widget_item_tooltip_style_set(Elm_Widget_Item *item,
const char *style)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
elm_object_tooltip_style_set(item->view, style);
}
@ -5724,6 +5752,8 @@ _elm_widget_item_tooltip_window_mode_set(Elm_Widget_Item *item,
Eina_Bool disable)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, EINA_FALSE);
return elm_object_tooltip_window_mode_set(item->view, disable);
}
@ -5731,6 +5761,8 @@ EAPI Eina_Bool
_elm_widget_item_tooltip_window_mode_get(const Elm_Widget_Item *item)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, EINA_FALSE);
return elm_object_tooltip_window_mode_get(item->view);
}
@ -5749,6 +5781,7 @@ EAPI const char *
_elm_widget_item_tooltip_style_get(const Elm_Widget_Item *item)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
return elm_object_tooltip_style_get(item->view);
}
@ -5757,6 +5790,8 @@ _elm_widget_item_cursor_set(Elm_Widget_Item *item,
const char *cursor)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
elm_object_sub_cursor_set(item->view, item->widget, cursor);
}
@ -5771,6 +5806,8 @@ EAPI void
_elm_widget_item_cursor_unset(Elm_Widget_Item *item)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
elm_object_cursor_unset(item->view);
}
@ -5792,6 +5829,8 @@ _elm_widget_item_cursor_style_set(Elm_Widget_Item *item,
const char *style)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
elm_object_cursor_style_set(item->view, style);
}
@ -5834,6 +5873,8 @@ _elm_widget_item_cursor_engine_only_set(Elm_Widget_Item *item,
Eina_Bool engine_only)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
elm_object_cursor_theme_search_enabled_set(item->view, !engine_only);
}
@ -5862,6 +5903,7 @@ _elm_widget_item_part_content_set(Elm_Widget_Item *item,
Evas_Object *content)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
if (!item->content_set_func)
{
ERR("%s does not support elm_object_item_part_content_set() API.",
@ -5876,6 +5918,7 @@ _elm_widget_item_part_content_get(const Elm_Widget_Item *item,
const char *part)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
if (!item->content_get_func)
{
ERR("%s does not support elm_object_item_part_content_get() API.",
@ -5890,6 +5933,7 @@ _elm_widget_item_part_content_unset(Elm_Widget_Item *item,
const char *part)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
if (!item->content_unset_func)
{
ERR("%s does not support elm_object_item_part_content_unset() API.",
@ -5905,6 +5949,7 @@ _elm_widget_item_part_text_set(Elm_Widget_Item *item,
const char *label)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
if (!item->text_set_func)
{
ERR("%s does not support elm_object_item_part_text_set() API.",
@ -5919,6 +5964,7 @@ _elm_widget_item_part_text_get(const Elm_Widget_Item *item,
const char *part)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
if (!item->text_get_func)
{
ERR("%s does not support elm_object_item_part_text_get() API.",
@ -5945,6 +5991,7 @@ _elm_widget_item_part_text_custom_set(Elm_Widget_Item *item,
{
Elm_Label_Data *label;
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
if (!item->text_get_func)
{
@ -5995,6 +6042,7 @@ EAPI void
_elm_widget_item_part_text_custom_update(Elm_Widget_Item *item)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
if (item->labels)
eina_hash_foreach(item->labels,
_elm_widget_item_part_text_custom_foreach, item);
@ -6005,6 +6053,8 @@ _elm_widget_item_content_set_hook_set(Elm_Widget_Item *item,
Elm_Widget_Content_Set_Cb func)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
item->content_set_func = func;
}
@ -6013,6 +6063,8 @@ _elm_widget_item_content_get_hook_set(Elm_Widget_Item *item,
Elm_Widget_Content_Get_Cb func)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
item->content_get_func = func;
}
@ -6021,6 +6073,8 @@ _elm_widget_item_content_unset_hook_set(Elm_Widget_Item *item,
Elm_Widget_Content_Unset_Cb func)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
item->content_unset_func = func;
}
@ -6029,6 +6083,8 @@ _elm_widget_item_text_set_hook_set(Elm_Widget_Item *item,
Elm_Widget_Text_Set_Cb func)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
item->text_set_func = func;
}
@ -6037,6 +6093,8 @@ _elm_widget_item_text_get_hook_set(Elm_Widget_Item *item,
Elm_Widget_Text_Get_Cb func)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
item->text_get_func = func;
}
@ -6046,6 +6104,8 @@ _elm_widget_item_signal_emit(Elm_Widget_Item *item,
const char *source)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
if (item->signal_emit_func)
item->signal_emit_func((Elm_Object_Item *)item, emission, source);
}
@ -6055,6 +6115,8 @@ _elm_widget_item_signal_emit_hook_set(Elm_Widget_Item *item,
Elm_Widget_Signal_Emit_Cb func)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
item->signal_emit_func = func;
}
@ -6066,6 +6128,7 @@ _elm_widget_item_signal_callback_add(Elm_Widget_Item *item,
void *data)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
EINA_SAFETY_ON_NULL_RETURN(func);
Elm_Widget_Item_Signal_Data *wisd;
@ -6104,6 +6167,7 @@ _elm_widget_item_signal_callback_del(Elm_Widget_Item *item,
Eina_List *l;
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
EINA_LIST_FOREACH(item->signals, l, wisd)
@ -6122,6 +6186,8 @@ _elm_widget_item_access_info_set(Elm_Widget_Item *item,
const char *txt)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
eina_stringshare_del(item->access_info);
if (!txt) item->access_info = NULL;
else item->access_info = eina_stringshare_add(txt);
@ -6131,6 +6197,7 @@ EAPI void
_elm_widget_item_translate(Elm_Widget_Item *item)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
#ifdef HAVE_GETTEXT
Elm_Translate_String_Data *ts;

View File

@ -586,6 +586,7 @@ struct _Elm_Widget_Item
Evas_Object *track_obj;
Eina_Bool disabled : 1;
Eina_Bool on_deletion : 1;
Eina_Bool on_translate : 1;
};
@ -1072,6 +1073,23 @@ EAPI void elm_widget_tree_dot_dump(const Evas_Object *top, FILE *out
#define elm_widget_item_part_text_custom_update(item) \
_elm_widget_item_part_text_custom_update((Elm_Widget_Item *)item)
#define ELM_WIDGET_CHECK_OR_RETURN(obj, ...) \
do { \
if (!obj || !evas_object_smart_data_get(obj)) \
{ \
ERR("Object [%p] is NULL or already deleted", obj);\
return __VA_ARGS__; \
} \
} while (0)
#define ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, ...) \
do { \
if (item && (item)->on_deletion) { \
WRN("Elm_Widget_Item " # item " is deleting"); \
return __VA_ARGS__; \
} \
} while (0)
#define ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, ...) \
do { \
if (!item) { \