[Widget] Prevent widget item API calls while item is deleting except data_get API...
authorTae-Hwan Kim <the81.kim@samsung.com>
Fri, 7 Feb 2014 09:09:46 +0000 (18:09 +0900)
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>
Fri, 7 Feb 2014 09:09:46 +0000 (18:09 +0900)
Reviewers: raster, cedric, Hermet, seoz

Reviewed By: raster

Differential Revision: https://phab.enlightenment.org/D525

src/lib/elm_widget.c
src/lib/elm_widget.h

index 1cba17b..4cb6010 100644 (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;
index a040ff2..d3fe1c3 100644 (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) {                                            \