elementary/widget - just renamed internally.
[framework/uifw/elementary.git] / src / lib / elm_widget.c
index e3e1e5a..37a8d83 100644 (file)
 
 static const char SMART_NAME[] = "elm_widget";
 
-#define API_ENTRY \
-   Smart_Data *sd = evas_object_smart_data_get(obj); \
-   if ((!obj) || (!sd) || (!_elm_widget_is(obj)))
-#define INTERNAL_ENTRY \
-   Smart_Data *sd = evas_object_smart_data_get(obj); \
-   if (!sd) return;
-
-typedef struct _Smart_Data Smart_Data;
-typedef struct _Edje_Signal_Data Edje_Signal_Data;
+#define API_ENTRY                                    \
+  Smart_Data * sd = evas_object_smart_data_get(obj); \
+  if ((!sd) || (!_elm_widget_is(obj)))
+#define INTERNAL_ENTRY                               \
+  Smart_Data * sd = evas_object_smart_data_get(obj); \
+  if (!sd) return
+
+#undef elm_widget_text_set_hook_set
+#undef elm_widget_text_get_hook_set
+#undef elm_widget_content_set_hook_set
+#undef elm_widget_content_get_hook_set
+#undef elm_widget_content_unset_hook_set
+
+typedef struct _Smart_Data        Smart_Data;
+typedef struct _Edje_Signal_Data  Edje_Signal_Data;
 typedef struct _Elm_Event_Cb_Data Elm_Event_Cb_Data;
+typedef struct _Elm_Translate_String_Data Elm_Translate_String_Data;
 
 struct _Smart_Data
 {
-   Evas_Object   *obj;
-   const char    *type;
-   Evas_Object   *parent_obj;
-   Evas_Coord     x, y, w, h;
-   Eina_List     *subobjs;
-   Evas_Object   *resize_obj;
-   Evas_Object   *hover_obj;
-   Eina_List     *tooltips, *cursors;
-   void         (*del_func) (Evas_Object *obj);
-   void         (*del_pre_func) (Evas_Object *obj);
-   void         (*focus_func) (Evas_Object *obj);
-   void         (*activate_func) (Evas_Object *obj);
-   void         (*disable_func) (Evas_Object *obj);
-   void         (*theme_func) (Evas_Object *obj);
-   Eina_Bool    (*event_func) (Evas_Object *obj, Evas_Object *source, Evas_Callback_Type type, void *event_info);
-   void         (*signal_func) (Evas_Object *obj, const char *emission,
-                               const char *source);
-   void         (*callback_add_func) (Evas_Object *obj, const char *emission,
-                               const char *source, void (*func) (void *data,
-                                  Evas_Object *o, const char *emission,
-                                  const char *source), void *data);
-   void         (*callback_del_func) (Evas_Object *obj, const char *emission,
-                                 const char *source, void (*func) (void *data,
-                                    Evas_Object *o, const char *emission,
-                                    const char *source), void *data);
-   void         (*changed_func) (Evas_Object *obj);
-   Eina_Bool    (*focus_next_func) (const Evas_Object *obj, Elm_Focus_Direction dir,
-                                    Evas_Object **next);
-   void         (*on_focus_func) (void *data, Evas_Object *obj);
-   void          *on_focus_data;
-   void         (*on_change_func) (void *data, Evas_Object *obj);
-   void          *on_change_data;
-   void         (*on_show_region_func) (void *data, Evas_Object *obj);
-   void          *on_show_region_data;
-   void         (*focus_region_func) (Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
-   void         (*on_focus_region_func) (const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
-   void          *data;
-   Evas_Coord     rx, ry, rw, rh;
-   int            scroll_hold;
-   int            scroll_freeze;
-   double         scale;
-   Elm_Theme     *theme;
-   const char    *style;
-   unsigned int   focus_order;
-   Eina_Bool      focus_order_on_calc;
-   
-   int            child_drag_x_locked;
-   int            child_drag_y_locked;
-
-   Eina_List     *edje_signals;
-
-   Eina_Bool      drag_x_locked : 1;
-   Eina_Bool      drag_y_locked : 1;
-   
-   Eina_Bool      can_focus : 1;
-   Eina_Bool      child_can_focus : 1;
-   Eina_Bool      focused : 1;
-   Eina_Bool      highlight_ignore : 1;
-   Eina_Bool      highlight_in_theme : 1;
-   Eina_Bool      disabled : 1;
-
-   Eina_List     *focus_chain;
-   Eina_List     *event_cb;
+   Evas_Object *obj;
+   const char  *type;
+   Evas_Object *parent_obj;
+   Evas_Object *parent2;
+   Evas_Coord   x, y, w, h;
+   Eina_List   *subobjs;
+   Evas_Object *resize_obj;
+   Evas_Object *hover_obj;
+   Eina_List   *tooltips, *cursors;
+   void       (*del_func)(Evas_Object *obj);
+   void       (*del_pre_func)(Evas_Object *obj);
+   void       (*focus_func)(Evas_Object *obj);
+   void       (*activate_func)(Evas_Object *obj);
+   void       (*disable_func)(Evas_Object *obj);
+   void       (*theme_func)(Evas_Object *obj);
+   void       (*translate_func)(Evas_Object *obj);
+   Eina_Bool  (*event_func)(Evas_Object       *obj,
+                            Evas_Object       *source,
+                            Evas_Callback_Type type,
+                            void              *event_info);
+   void       (*signal_func)(Evas_Object *obj,
+                             const char  *emission,
+                             const char  *source);
+   void       (*callback_add_func)(Evas_Object   *obj,
+                                   const char    *emission,
+                                   const char    *source,
+                                   Edje_Signal_Cb func,
+                                   void          *data);
+   void       (*callback_del_func)(Evas_Object   *obj,
+                                   const char    *emission,
+                                   const char    *source,
+                                   Edje_Signal_Cb func,
+                                   void          *data);
+   void       (*changed_func)(Evas_Object *obj);
+   Eina_Bool  (*focus_next_func)(const Evas_Object  *obj,
+                                 Elm_Focus_Direction dir,
+                                 Evas_Object       **next);
+   void       (*on_focus_func)(void        *data,
+                               Evas_Object *obj);
+   void        *on_focus_data;
+   void       (*on_change_func)(void        *data,
+                                Evas_Object *obj);
+   void        *on_change_data;
+   void       (*on_show_region_func)(void        *data,
+                                     Evas_Object *obj);
+   void        *on_show_region_data;
+   void       (*focus_region_func)(Evas_Object *obj,
+                                   Evas_Coord   x,
+                                   Evas_Coord   y,
+                                   Evas_Coord   w,
+                                   Evas_Coord   h);
+   void       (*on_focus_region_func)(const Evas_Object *obj,
+                                      Evas_Coord        *x,
+                                      Evas_Coord        *y,
+                                      Evas_Coord        *w,
+                                      Evas_Coord        *h);
+   Elm_Widget_Text_Set_Cb text_set_func;
+   Elm_Widget_Text_Get_Cb text_get_func;
+   Elm_Widget_Content_Set_Cb content_set_func;
+   Elm_Widget_Content_Get_Cb content_get_func;
+   Elm_Widget_Content_Unset_Cb content_unset_func;
+   void        *data;
+   Evas_Coord   rx, ry, rw, rh;
+   int          scroll_hold;
+   int          scroll_freeze;
+   double       scale;
+   Elm_Theme   *theme;
+   const char  *style;
+   const char  *access_info;
+   unsigned int focus_order;
+   Eina_Bool    focus_order_on_calc;
+
+   int          child_drag_x_locked;
+   int          child_drag_y_locked;
+
+   Eina_List   *edje_signals;
+   Eina_List   *translate_strings;
+
+   Eina_Bool    drag_x_locked : 1;
+   Eina_Bool    drag_y_locked : 1;
+
+   Eina_Bool    can_focus : 1;
+   Eina_Bool    child_can_focus : 1;
+   Eina_Bool    focused : 1;
+   Eina_Bool    top_win_focused : 1;
+   Eina_Bool    tree_unfocusable : 1;
+   Eina_Bool    highlight_ignore : 1;
+   Eina_Bool    highlight_in_theme : 1;
+   Eina_Bool    disabled : 1;
+   Eina_Bool    is_mirrored : 1;
+   Eina_Bool    mirrored_auto_mode : 1;   /* This is TRUE by default */
+   Eina_Bool    still_in : 1;
+
+   Eina_List   *focus_chain;
+   Eina_List   *event_cb;
 };
 
 struct _Edje_Signal_Data
 {
-   Evas_Object *obj;
+   Evas_Object   *obj;
    Edje_Signal_Cb func;
-   const char *emission;
-   const char *source;
-   void *data;
+   const char    *emission;
+   const char    *source;
+   void          *data;
+};
+
+struct _Elm_Event_Cb_Data
+{
+   Elm_Event_Cb func;
+   const void  *data;
 };
 
-struct _Elm_Event_Cb_Data {
-     Elm_Event_Cb func;
-     const void *data;
+struct _Elm_Translate_String_Data
+{
+   const char *id;
+   const char *domain;
+   const char *string;
 };
 
 /* local subsystem functions */
 static void _smart_reconfigure(Smart_Data *sd);
 static void _smart_add(Evas_Object *obj);
 static void _smart_del(Evas_Object *obj);
-static void _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
-static void _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
+static void _smart_move(Evas_Object *obj,
+                        Evas_Coord   x,
+                        Evas_Coord   y);
+static void _smart_resize(Evas_Object *obj,
+                          Evas_Coord   w,
+                          Evas_Coord   h);
 static void _smart_show(Evas_Object *obj);
 static void _smart_hide(Evas_Object *obj);
-static void _smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
-static void _smart_clip_set(Evas_Object *obj, Evas_Object * clip);
+static void _smart_color_set(Evas_Object *obj,
+                             int          r,
+                             int          g,
+                             int          b,
+                             int          a);
+static void _smart_clip_set(Evas_Object *obj,
+                            Evas_Object *clip);
 static void _smart_clip_unset(Evas_Object *obj);
 static void _smart_calculate(Evas_Object *obj);
 static void _smart_init(void);
 
-static void _if_focused_revert(Evas_Object *obj, Eina_Bool can_focus_only);
-static Evas_Object *_newest_focus_order_get(Evas_Object *obj, unsigned int *newest_focus_order, Eina_Bool can_focus_only);
+static void _if_focused_revert(Evas_Object *obj,
+                               Eina_Bool    can_focus_only);
+static Evas_Object *_newest_focus_order_get(Evas_Object  *obj,
+                                            unsigned int *newest_focus_order,
+                                            Eina_Bool     can_focus_only);
 
 /* local subsystem globals */
 static Evas_Smart *_e_smart = NULL;
@@ -138,8 +197,7 @@ _unfocus_parents(Evas_Object *obj)
 {
    for (; obj; obj = elm_widget_parent_get(obj))
      {
-        Smart_Data *sd = evas_object_smart_data_get(obj);
-        if (!sd) return;
+        INTERNAL_ENTRY;
         if (!sd->focused) return;
         sd->focused = 0;
      }
@@ -150,15 +208,17 @@ _focus_parents(Evas_Object *obj)
 {
    for (; obj; obj = elm_widget_parent_get(obj))
      {
-        Smart_Data *sd = evas_object_smart_data_get(obj);
-        if (!sd) return;
+        INTERNAL_ENTRY;
         if (sd->focused) return;
         sd->focused = 1;
      }
 }
 
 static void
-_sub_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+_sub_obj_del(void        *data,
+             Evas        *e __UNUSED__,
+             Evas_Object *obj,
+             void        *event_info __UNUSED__)
 {
    Smart_Data *sd = data;
 
@@ -176,24 +236,66 @@ _sub_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info
 }
 
 static void
-_sub_obj_mouse_down(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+_sub_obj_hide(void        *data __UNUSED__,
+              Evas        *e __UNUSED__,
+              Evas_Object *obj,
+              void        *event_info __UNUSED__)
 {
-   Evas_Object *o = obj;
-   do 
+   elm_widget_focus_hide_handle(obj);
+}
+
+static void
+_sub_obj_mouse_down(void        *data,
+                    Evas        *e __UNUSED__,
+                    Evas_Object *obj __UNUSED__,
+                    void        *event_info)
+{
+   Smart_Data *sd = data;
+   Evas_Event_Mouse_Down *ev = event_info;
+   if (!(ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD))
+     sd->still_in = EINA_TRUE;
+}
+
+static void
+_sub_obj_mouse_move(void        *data,
+                    Evas        *e __UNUSED__,
+                    Evas_Object *obj,
+                    void        *event_info)
+{
+   Smart_Data *sd = data;
+   Evas_Event_Mouse_Move *ev = event_info;
+   if (sd->still_in)
      {
-        if (_elm_widget_is(o)) break;
-        o = evas_object_smart_parent_get(o);
+        if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
+          sd->still_in = EINA_FALSE;
+        else
+          {
+             Evas_Coord x, y, w, h;
+             evas_object_geometry_get(obj, &x, &y, &w, &h);
+             if ((ev->cur.canvas.x < x) || (ev->cur.canvas.y < y) ||
+                 (ev->cur.canvas.x >= (x + w)) || (ev->cur.canvas.y >= (y + h)))
+               sd->still_in = EINA_FALSE;
+          }
      }
-   while (o);
-   if (!o) return;
-   if (!_is_focusable(o)) return;
-   elm_widget_focus_steal(o);
 }
 
 static void
-_propagate_x_drag_lock(Evas_Object *obj, int dir)
+_sub_obj_mouse_up(void        *data,
+                  Evas        *e __UNUSED__,
+                  Evas_Object *obj,
+                  void        *event_info __UNUSED__)
 {
-   Smart_Data *sd = evas_object_smart_data_get(obj);
+   Smart_Data *sd = data;
+   if (sd->still_in)
+     elm_widget_focus_mouse_up_handle(obj);
+   sd->still_in = EINA_FALSE;
+}
+
+static void
+_propagate_x_drag_lock(Evas_Object *obj,
+                       int          dir)
+{
+   INTERNAL_ENTRY;
    if (sd->parent_obj)
      {
         Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj);
@@ -206,9 +308,10 @@ _propagate_x_drag_lock(Evas_Object *obj, int dir)
 }
 
 static void
-_propagate_y_drag_lock(Evas_Object *obj, int dir)
+_propagate_y_drag_lock(Evas_Object *obj,
+                       int          dir)
 {
-   Smart_Data *sd = evas_object_smart_data_get(obj);
+   INTERNAL_ENTRY;
    if (sd->parent_obj)
      {
         Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj);
@@ -221,33 +324,39 @@ _propagate_y_drag_lock(Evas_Object *obj, int dir)
 }
 
 static void
-_propagate_event(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
+_propagate_event(void        *data,
+                 Evas        *e __UNUSED__,
+                 Evas_Object *obj,
+                 void        *event_info)
 {
    INTERNAL_ENTRY;
-   Evas_Callback_Type type = (Evas_Callback_Type)(long) data;
+   Evas_Callback_Type type = (Evas_Callback_Type)(long)data;
    Evas_Event_Flags *event_flags = NULL;
 
    switch (type)
      {
-     case EVAS_CALLBACK_KEY_DOWN:
+      case EVAS_CALLBACK_KEY_DOWN:
           {
-             Evas_Event_Key_Down *ev = event_info;
-             event_flags = &(ev->event_flags);
-             break;
+            Evas_Event_Key_Down *ev = event_info;
+            event_flags = &(ev->event_flags);
           }
-     case EVAS_CALLBACK_KEY_UP:
+        break;
+
+      case EVAS_CALLBACK_KEY_UP:
           {
              Evas_Event_Key_Up *ev = event_info;
              event_flags = &(ev->event_flags);
-             break;
           }
-     case EVAS_CALLBACK_MOUSE_WHEEL:
+        break;
+
+      case EVAS_CALLBACK_MOUSE_WHEEL:
           {
-             Evas_Event_Mouse_Wheel *ev = event_info;
-             event_flags = &(ev->event_flags);
-             break;
+            Evas_Event_Mouse_Wheel *ev = event_info;
+            event_flags = &(ev->event_flags);
           }
-     default:
+        break;
+
+      default:
         break;
      }
 
@@ -258,42 +367,35 @@ static void
 _parent_focus(Evas_Object *obj)
 {
    API_ENTRY return;
+   if (sd->focused) return;
 
    Evas_Object *o = elm_widget_parent_get(obj);
    sd->focus_order_on_calc = EINA_TRUE;
 
-   if (sd->focused) return;
-   if (o)
-     {
-       unsigned int i = 0;
-       Evas_Object *ret;
-
-       ret = _newest_focus_order_get(o, &i, EINA_TRUE);
-
-       /* we don't want to bump a common widget ancestor's
-          focus_order *twice* while parent focusing */
-       if (!ret || (!i) || (i != focus_order))
-         _parent_focus(o);
-     }
+   if (o) _parent_focus(o);
 
    if (!sd->focus_order_on_calc)
      return; /* we don't want to override it if by means of any of the
-               callbacks below one gets to calculate our order
-               first. */
+                callbacks below one gets to calculate our order
+                first. */
 
    focus_order++;
    sd->focus_order = focus_order;
-   sd->focused = EINA_TRUE;
-   if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
-   if (sd->focus_func) sd->focus_func(obj);
-
-   _elm_widget_focus_region_show(obj);
-
+   if (sd->top_win_focused)
+     {
+        sd->focused = EINA_TRUE;
+        if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
+        if (sd->focus_func) sd->focus_func(obj);
+        _elm_widget_focus_region_show(obj);
+     }
    sd->focus_order_on_calc = EINA_FALSE;
 }
 
 static void
-_elm_object_focus_chain_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+_elm_object_focus_chain_del_cb(void        *data,
+                               Evas        *e __UNUSED__,
+                               Evas_Object *obj,
+                               void        *event_info __UNUSED__)
 {
    Smart_Data *sd = data;
 
@@ -305,7 +407,7 @@ void
 _elm_widget_type_clear(void)
 {
    const char **ptr;
-   
+
    EINA_LIST_FREE(widtypes, ptr)
      {
         eina_stringshare_del(*ptr);
@@ -360,6 +462,18 @@ elm_widget_type_register(const char **ptr)
    widtypes = eina_list_append(widtypes, (void *)ptr);
 }
 
+/**
+ * @defgroup Widget Widget
+ *
+ * @internal
+ * Disposed api for making widgets
+ */
+EAPI void
+elm_widget_type_unregister(const char **ptr)
+{
+   widtypes = eina_list_remove(widtypes, (void *)ptr);
+}
+
 EAPI Eina_Bool
 elm_widget_api_check(int ver)
 {
@@ -374,82 +488,157 @@ elm_widget_api_check(int ver)
 EAPI Evas_Object *
 elm_widget_add(Evas *evas)
 {
+   Evas_Object *obj;
    _smart_init();
-   return evas_object_smart_add(evas, _e_smart);
+   obj = evas_object_smart_add(evas, _e_smart);
+   elm_widget_mirrored_set(obj, elm_mirrored_get());
+   return obj;
 }
 
 EAPI void
-elm_widget_del_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
+elm_widget_del_hook_set(Evas_Object *obj,
+                        void       (*func)(Evas_Object *obj))
 {
    API_ENTRY return;
    sd->del_func = func;
 }
 
 EAPI void
-elm_widget_del_pre_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
+elm_widget_del_pre_hook_set(Evas_Object *obj,
+                            void       (*func)(Evas_Object *obj))
 {
    API_ENTRY return;
    sd->del_pre_func = func;
 }
 
 EAPI void
-elm_widget_focus_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
+elm_widget_focus_hook_set(Evas_Object *obj,
+                          void       (*func)(Evas_Object *obj))
 {
    API_ENTRY return;
    sd->focus_func = func;
 }
 
 EAPI void
-elm_widget_activate_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
+elm_widget_activate_hook_set(Evas_Object *obj,
+                             void       (*func)(Evas_Object *obj))
 {
    API_ENTRY return;
    sd->activate_func = func;
 }
 
 EAPI void
-elm_widget_disable_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
+elm_widget_disable_hook_set(Evas_Object *obj,
+                            void       (*func)(Evas_Object *obj))
 {
    API_ENTRY return;
    sd->disable_func = func;
 }
 
 EAPI void
-elm_widget_theme_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
+elm_widget_theme_hook_set(Evas_Object *obj,
+                          void       (*func)(Evas_Object *obj))
 {
    API_ENTRY return;
    sd->theme_func = func;
 }
 
 EAPI void
-elm_widget_event_hook_set(Evas_Object *obj, Eina_Bool (*func) (Evas_Object *obj, Evas_Object *source, Evas_Callback_Type type, void *event_info))
+elm_widget_translate_hook_set(Evas_Object *obj,
+                              void       (*func)(Evas_Object *obj))
+{
+   API_ENTRY return;
+   sd->translate_func = func;
+}
+
+EAPI void
+elm_widget_event_hook_set(Evas_Object *obj,
+                          Eina_Bool  (*func)(Evas_Object       *obj,
+                                             Evas_Object       *source,
+                                             Evas_Callback_Type type,
+                                             void              *event_info))
 {
    API_ENTRY return;
    sd->event_func = func;
 }
 
 EAPI void
-elm_widget_changed_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
+elm_widget_text_set_hook_set(Evas_Object *obj,
+                             Elm_Widget_Text_Set_Cb func)
+{
+   API_ENTRY return;
+   sd->text_set_func = func;
+}
+
+EAPI void
+elm_widget_text_get_hook_set(Evas_Object *obj,
+                             Elm_Widget_Text_Get_Cb func)
+{
+   API_ENTRY return;
+   sd->text_get_func = func;
+}
+
+EAPI void
+elm_widget_content_set_hook_set(Evas_Object *obj,
+                                Elm_Widget_Content_Set_Cb func)
+{
+   API_ENTRY return;
+   sd->content_set_func = func;
+}
+
+EAPI void
+elm_widget_content_get_hook_set(Evas_Object *obj,
+                                Elm_Widget_Content_Get_Cb func)
+{
+   API_ENTRY return;
+   sd->content_get_func = func;
+}
+
+EAPI void
+elm_widget_content_unset_hook_set(Evas_Object *obj,
+                                  Elm_Widget_Content_Unset_Cb func)
+{
+   API_ENTRY return;
+   sd->content_unset_func = func;
+}
+
+EAPI void
+elm_widget_changed_hook_set(Evas_Object *obj,
+                            void       (*func)(Evas_Object *obj))
 {
    API_ENTRY return;
    sd->changed_func = func;
 }
 
 EAPI void
-elm_widget_signal_emit_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source))
+elm_widget_signal_emit_hook_set(Evas_Object *obj,
+                                void       (*func)(Evas_Object *obj,
+                                                   const char *emission,
+                                                   const char *source))
 {
    API_ENTRY return;
    sd->signal_func = func;
 }
 
 EAPI void
-elm_widget_signal_callback_add_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source), void *data))
+elm_widget_signal_callback_add_hook_set(Evas_Object *obj,
+                                        void       (*func)(Evas_Object   *obj,
+                                                           const char    *emission,
+                                                           const char    *source,
+                                                           Edje_Signal_Cb func_cb,
+                                                           void          *data))
 {
    API_ENTRY return;
    sd->callback_add_func = func;
 }
 
 EAPI void
-elm_widget_signal_callback_del_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source), void *data))
+elm_widget_signal_callback_del_hook_set(Evas_Object *obj,
+                                        void       (*func)(Evas_Object   *obj,
+                                                           const char    *emission,
+                                                           const char    *source,
+                                                           Edje_Signal_Cb func_cb,
+                                                           void          *data))
 {
    API_ENTRY return;
    sd->callback_del_func = func;
@@ -473,7 +662,9 @@ elm_widget_theme(Evas_Object *obj)
 }
 
 EAPI void
-elm_widget_theme_specific(Evas_Object *obj, Elm_Theme *th, Eina_Bool force)
+elm_widget_theme_specific(Evas_Object *obj,
+                          Elm_Theme   *th,
+                          Eina_Bool    force)
 {
    const Eina_List *l;
    Evas_Object *child;
@@ -521,14 +712,108 @@ elm_widget_theme_specific(Evas_Object *obj, Elm_Theme *th, Eina_Bool force)
  * @ingroup Widget
  */
 EAPI void
-elm_widget_focus_next_hook_set(Evas_Object *obj, Eina_Bool (*func) (const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next))
+elm_widget_focus_next_hook_set(Evas_Object *obj,
+                               Eina_Bool  (*func)(const Evas_Object   *obj,
+                                                   Elm_Focus_Direction dir,
+                                                   Evas_Object       **next))
 {
    API_ENTRY return;
    sd->focus_next_func = func;
 }
 
+/**
+ * Returns the widget's mirrored mode.
+ *
+ * @param obj The widget.
+ * @return mirrored mode of the object.
+ *
+ **/
+EAPI Eina_Bool
+elm_widget_mirrored_get(const Evas_Object *obj)
+{
+   API_ENTRY return EINA_FALSE;
+   return sd->is_mirrored;
+}
+
+/**
+ * Sets the widget's mirrored mode.
+ *
+ * @param obj The widget.
+ * @param mirrored EINA_TRUE to set mirrored mode. EINA_FALSE to unset.
+ */
 EAPI void
-elm_widget_on_focus_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data)
+elm_widget_mirrored_set(Evas_Object *obj,
+                        Eina_Bool    mirrored)
+{
+   API_ENTRY return;
+   if (sd->is_mirrored != mirrored)
+     {
+        sd->is_mirrored = mirrored;
+        elm_widget_theme(obj);
+     }
+}
+
+/**
+ * @internal
+ * Resets the mirrored mode from the system mirror mode for widgets that are in
+ * automatic mirroring mode. This function does not call elm_widget_theme.
+ *
+ * @param obj The widget.
+ * @param mirrored EINA_TRUE to set mirrored mode. EINA_FALSE to unset.
+ */
+void
+_elm_widget_mirrored_reload(Evas_Object *obj)
+{
+   API_ENTRY return;
+   Eina_Bool mirrored = elm_mirrored_get();
+   if (elm_widget_mirrored_automatic_get(obj) && (sd->is_mirrored != mirrored))
+     {
+        sd->is_mirrored = mirrored;
+     }
+}
+
+/**
+ * Returns the widget's mirrored mode setting.
+ *
+ * @param obj The widget.
+ * @return mirrored mode setting of the object.
+ *
+ **/
+EAPI Eina_Bool
+elm_widget_mirrored_automatic_get(const Evas_Object *obj)
+{
+   API_ENTRY return EINA_FALSE;
+   return sd->mirrored_auto_mode;
+}
+
+/**
+ * Sets the widget's mirrored mode setting.
+ * When widget in automatic mode, it follows the system mirrored mode set by
+ * elm_mirrored_set().
+ * @param obj The widget.
+ * @param automatic EINA_TRUE for auto mirrored mode. EINA_FALSE for manual.
+ */
+EAPI void
+elm_widget_mirrored_automatic_set(Evas_Object *obj,
+                                  Eina_Bool    automatic)
+{
+   API_ENTRY return;
+   if (sd->mirrored_auto_mode != automatic)
+     {
+        sd->mirrored_auto_mode = automatic;
+
+        if (automatic)
+          {
+             elm_widget_mirrored_set(obj, elm_mirrored_get());
+          }
+     }
+}
+
+EAPI void
+elm_widget_on_focus_hook_set(Evas_Object *obj,
+                             void       (*func)(void *data,
+                                                Evas_Object *obj),
+                             void        *data)
 {
    API_ENTRY return;
    sd->on_focus_func = func;
@@ -536,7 +821,10 @@ elm_widget_on_focus_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Ob
 }
 
 EAPI void
-elm_widget_on_change_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data)
+elm_widget_on_change_hook_set(Evas_Object *obj,
+                              void       (*func)(void *data,
+                                                 Evas_Object *obj),
+                              void        *data)
 {
    API_ENTRY return;
    sd->on_change_func = func;
@@ -544,7 +832,10 @@ elm_widget_on_change_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_O
 }
 
 EAPI void
-elm_widget_on_show_region_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data)
+elm_widget_on_show_region_hook_set(Evas_Object *obj,
+                                   void       (*func)(void *data,
+                                                      Evas_Object *obj),
+                                   void        *data)
 {
    API_ENTRY return;
    sd->on_show_region_func = func;
@@ -567,7 +858,12 @@ elm_widget_on_show_region_hook_set(Evas_Object *obj, void (*func) (void *data, E
  * @ingroup Widget
  */
 EAPI void
-elm_widget_focus_region_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h))
+elm_widget_focus_region_hook_set(Evas_Object *obj,
+                                 void       (*func)(Evas_Object *obj,
+                                                    Evas_Coord x,
+                                                    Evas_Coord y,
+                                                    Evas_Coord w,
+                                                    Evas_Coord h))
 {
    API_ENTRY return;
    sd->focus_region_func = func;
@@ -589,14 +885,20 @@ elm_widget_focus_region_hook_set(Evas_Object *obj, void (*func) (Evas_Object *ob
  * @ingroup Widget
  */
 EAPI void
-elm_widget_on_focus_region_hook_set(Evas_Object *obj, void (*func) (const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h))
+elm_widget_on_focus_region_hook_set(Evas_Object *obj,
+                                    void       (*func)(const Evas_Object *obj,
+                                                       Evas_Coord *x,
+                                                       Evas_Coord *y,
+                                                       Evas_Coord *w,
+                                                       Evas_Coord *h))
 {
    API_ENTRY return;
    sd->on_focus_region_func = func;
 }
 
 EAPI void
-elm_widget_data_set(Evas_Object *obj, void *data)
+elm_widget_data_set(Evas_Object *obj,
+                    void        *data)
 {
    API_ENTRY return;
    sd->data = data;
@@ -610,11 +912,13 @@ elm_widget_data_get(const Evas_Object *obj)
 }
 
 EAPI void
-elm_widget_sub_object_add(Evas_Object *obj, Evas_Object *sobj)
+elm_widget_sub_object_add(Evas_Object *obj,
+                          Evas_Object *sobj)
 {
    API_ENTRY return;
    double scale, pscale = elm_widget_scale_get(sobj);
    Elm_Theme *th, *pth = elm_widget_theme_get(sobj);
+   Eina_Bool mirrored, pmirrored = elm_widget_mirrored_get(obj);
 
    if (_elm_widget_is(sobj))
      {
@@ -623,8 +927,10 @@ elm_widget_sub_object_add(Evas_Object *obj, Evas_Object *sobj)
           {
              if (sd2->parent_obj == obj)
                return;
-             elm_widget_sub_object_del(sd2->parent_obj, sobj);
+             if (sd2->parent_obj)
+               elm_widget_sub_object_del(sd2->parent_obj, sobj);
              sd2->parent_obj = obj;
+             sd2->top_win_focused = sd->top_win_focused;
              if (!sd->child_can_focus && (_is_focusable(sobj)))
                sd->child_can_focus = EINA_TRUE;
           }
@@ -635,23 +941,26 @@ elm_widget_sub_object_add(Evas_Object *obj, Evas_Object *sobj)
         if (data)
           {
              if (data == obj) return;
-             evas_object_event_callback_del(sobj, EVAS_CALLBACK_DEL, 
+             evas_object_event_callback_del(sobj, EVAS_CALLBACK_DEL,
                                             _sub_obj_del);
           }
      }
-
    sd->subobjs = eina_list_append(sd->subobjs, sobj);
    evas_object_data_set(sobj, "elm-parent", obj);
    evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
+   if (_elm_widget_is(sobj))
+     evas_object_event_callback_add(sobj, EVAS_CALLBACK_HIDE, _sub_obj_hide, sd);
    evas_object_smart_callback_call(obj, "sub-object-add", sobj);
    scale = elm_widget_scale_get(sobj);
    th = elm_widget_theme_get(sobj);
-   if ((scale != pscale) || (th != pth)) elm_widget_theme(sobj);
+   mirrored = elm_widget_mirrored_get(sobj);
+   if ((scale != pscale) || (th != pth) || (pmirrored != mirrored)) elm_widget_theme(sobj);
    if (elm_widget_focus_get(sobj)) _focus_parents(obj);
 }
 
 EAPI void
-elm_widget_sub_object_del(Evas_Object *obj, Evas_Object *sobj)
+elm_widget_sub_object_del(Evas_Object *obj,
+                          Evas_Object *sobj)
 {
    Evas_Object *sobj_parent;
    API_ENTRY return;
@@ -660,23 +969,39 @@ elm_widget_sub_object_del(Evas_Object *obj, Evas_Object *sobj)
    sobj_parent = evas_object_data_del(sobj, "elm-parent");
    if (sobj_parent != obj)
      {
-       static int abort_on_warn = -1;
-       ERR("removing sub object %p from parent %p, "
-           "but elm-parent is different %p!",
-           sobj, obj, sobj_parent);
-       if (EINA_UNLIKELY(abort_on_warn == -1))
-         {
-            if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
-            else abort_on_warn = 0;
-         }
-       if (abort_on_warn == 1) abort();
-     }
-   if (!sd->child_can_focus)
-     {
-       if (_is_focusable(sobj)) sd->child_can_focus = 0;
+        static int abort_on_warn = -1;
+        ERR("removing sub object %p (%s) from parent %p (%s), "
+            "but elm-parent is different %p (%s)!",
+            sobj, elm_widget_type_get(sobj), obj, elm_widget_type_get(obj),
+            sobj_parent, elm_widget_type_get(sobj_parent));
+        if (EINA_UNLIKELY(abort_on_warn == -1))
+          {
+             if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
+             else abort_on_warn = 0;
+          }
+        if (abort_on_warn == 1) abort();
      }
    if (_elm_widget_is(sobj))
      {
+        if (elm_widget_focus_get(sobj))
+          {
+             elm_widget_tree_unfocusable_set(sobj, EINA_TRUE);
+             elm_widget_tree_unfocusable_set(sobj, EINA_FALSE);
+          }
+        if ((sd->child_can_focus) && (_is_focusable(sobj)))
+          {
+             Evas_Object *subobj;
+             const Eina_List *l;
+             sd->child_can_focus = EINA_FALSE;
+             EINA_LIST_FOREACH(sd->subobjs, l, subobj)
+               {
+                  if (_is_focusable(subobj))
+                    {
+                       sd->child_can_focus = EINA_TRUE;
+                       break;
+                    }
+               }
+          }
         Smart_Data *sd2 = evas_object_smart_data_get(sobj);
         if (sd2)
           {
@@ -688,103 +1013,128 @@ elm_widget_sub_object_del(Evas_Object *obj, Evas_Object *sobj)
           }
         else
           sd->subobjs = eina_list_remove(sd->subobjs, sobj);
-        if (elm_widget_focus_get(sobj)) _unfocus_parents(obj);
      }
    else
      sd->subobjs = eina_list_remove(sd->subobjs, sobj);
-   evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, 
+   evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL,
                                        _sub_obj_del, sd);
+   if (_elm_widget_is(sobj))
+     evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_HIDE,
+                                         _sub_obj_hide, sd);
    evas_object_smart_callback_call(obj, "sub-object-del", sobj);
 }
 
 EAPI void
-elm_widget_resize_object_set(Evas_Object *obj, Evas_Object *sobj)
+elm_widget_resize_object_set(Evas_Object *obj,
+                             Evas_Object *sobj)
 {
    API_ENTRY return;
    // orphan previous resize obj
    if (sd->resize_obj)
      {
-       evas_object_clip_unset(sd->resize_obj);
-       evas_object_data_del(sd->resize_obj, "elm-parent");
-       if (_elm_widget_is(sd->resize_obj))
-         {
-            Smart_Data *sd2 = evas_object_smart_data_get(sd->resize_obj);
-            if (sd2) sd2->parent_obj = NULL;
-         }
-       evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_DEL,
-                                            _sub_obj_del, sd);
-       evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_MOUSE_DOWN,
-                                            _sub_obj_mouse_down, sd);
-       evas_object_smart_member_del(sd->resize_obj);
+        evas_object_clip_unset(sd->resize_obj);
+        evas_object_data_del(sd->resize_obj, "elm-parent");
         if (_elm_widget_is(sd->resize_obj))
           {
-             if (elm_widget_focus_get(sd->resize_obj)) _unfocus_parents(obj);
-          }
-     }
-   // orphan new resize obj
-   if (sobj)
-     {
-        evas_object_data_del(sobj, "elm-parent");
-        if (_elm_widget_is(sobj))
-          {
-             Smart_Data *sd2 = evas_object_smart_data_get(sobj);
+             Smart_Data *sd2 = evas_object_smart_data_get(sd->resize_obj);
              if (sd2) sd2->parent_obj = NULL;
+             evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_HIDE,
+                                                 _sub_obj_hide, sd);
           }
-        evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL,
+        evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_DEL,
                                             _sub_obj_del, sd);
-        evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_MOUSE_DOWN,
+        evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_MOUSE_DOWN,
                                             _sub_obj_mouse_down, sd);
-        evas_object_smart_member_del(sobj);
-        if (_elm_widget_is(sobj))
+        evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_MOUSE_MOVE,
+                                            _sub_obj_mouse_move, sd);
+        evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_MOUSE_UP,
+                                            _sub_obj_mouse_up, sd);
+        evas_object_smart_member_del(sd->resize_obj);
+        if (_elm_widget_is(sd->resize_obj))
           {
-             if (elm_widget_focus_get(sobj)) _unfocus_parents(obj);
+             if (elm_widget_focus_get(sd->resize_obj)) _unfocus_parents(obj);
           }
      }
-   // set the resize obj up
+
    sd->resize_obj = sobj;
-   if (sd->resize_obj)
+   if (!sobj) return;
+
+   // orphan new resize obj
+   evas_object_data_del(sobj, "elm-parent");
+   if (_elm_widget_is(sobj))
      {
-       if (_elm_widget_is(sd->resize_obj))
-         {
-            Smart_Data *sd2 = evas_object_smart_data_get(sd->resize_obj);
-            if (sd2) sd2->parent_obj = obj;
-         }
-       evas_object_clip_set(sobj, evas_object_clip_get(obj));
-       evas_object_smart_member_add(sobj, obj);
-       evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL,
+        Smart_Data *sd2 = evas_object_smart_data_get(sobj);
+        if (sd2) sd2->parent_obj = NULL;
+        evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_HIDE,
+                                            _sub_obj_hide, sd);
+     }
+   evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL,
                                        _sub_obj_del, sd);
-       evas_object_event_callback_add(sobj, EVAS_CALLBACK_MOUSE_DOWN,
+   evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_MOUSE_DOWN,
                                        _sub_obj_mouse_down, sd);
-       _smart_reconfigure(sd);
-       evas_object_data_set(sobj, "elm-parent", obj);
-       evas_object_smart_callback_call(obj, "sub-object-add", sobj);
-        if (_elm_widget_is(sobj))
+   evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_MOUSE_MOVE,
+                                       _sub_obj_mouse_move, sd);
+   evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_MOUSE_UP,
+                                       _sub_obj_mouse_up, sd);
+   evas_object_smart_member_del(sobj);
+   if (_elm_widget_is(sobj))
+     {
+        if (elm_widget_focus_get(sobj)) _unfocus_parents(obj);
+     }
+
+   // set the resize obj up
+   if (_elm_widget_is(sobj))
+     {
+        Smart_Data *sd2 = evas_object_smart_data_get(sobj);
+        if (sd2)
           {
-             if (elm_widget_focus_get(sobj)) _focus_parents(obj);
+             sd2->parent_obj = obj;
+             sd2->top_win_focused = sd->top_win_focused;
           }
+        evas_object_event_callback_add(sobj, EVAS_CALLBACK_HIDE,
+                                       _sub_obj_hide, sd);
+     }
+   evas_object_clip_set(sobj, evas_object_clip_get(obj));
+   evas_object_smart_member_add(sobj, obj);
+   evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL,
+                                  _sub_obj_del, sd);
+   evas_object_event_callback_add(sobj, EVAS_CALLBACK_MOUSE_DOWN,
+                                  _sub_obj_mouse_down, sd);
+   evas_object_event_callback_add(sobj, EVAS_CALLBACK_MOUSE_MOVE,
+                                  _sub_obj_mouse_move, sd);
+   evas_object_event_callback_add(sobj, EVAS_CALLBACK_MOUSE_UP,
+                                  _sub_obj_mouse_up, sd);
+   _smart_reconfigure(sd);
+   evas_object_data_set(sobj, "elm-parent", obj);
+   evas_object_smart_callback_call(obj, "sub-object-add", sobj);
+   if (_elm_widget_is(sobj))
+     {
+        if (elm_widget_focus_get(sobj)) _focus_parents(obj);
      }
 }
 
 EAPI void
-elm_widget_hover_object_set(Evas_Object *obj, Evas_Object *sobj)
+elm_widget_hover_object_set(Evas_Object *obj,
+                            Evas_Object *sobj)
 {
    API_ENTRY return;
    if (sd->hover_obj)
      {
-       evas_object_event_callback_del_full(sd->hover_obj, EVAS_CALLBACK_DEL,
-           _sub_obj_del, sd);
+        evas_object_event_callback_del_full(sd->hover_obj, EVAS_CALLBACK_DEL,
+                                            _sub_obj_del, sd);
      }
    sd->hover_obj = sobj;
    if (sd->hover_obj)
      {
-       evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL,
+        evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL,
                                        _sub_obj_del, sd);
-       _smart_reconfigure(sd);
+        _smart_reconfigure(sd);
      }
 }
 
 EAPI void
-elm_widget_can_focus_set(Evas_Object *obj, Eina_Bool can_focus)
+elm_widget_can_focus_set(Evas_Object *obj,
+                         Eina_Bool    can_focus)
 {
    API_ENTRY return;
    sd->can_focus = can_focus;
@@ -792,10 +1142,10 @@ elm_widget_can_focus_set(Evas_Object *obj, Eina_Bool can_focus)
      {
         evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN,
                                        _propagate_event,
-                                       (void *)(long) EVAS_CALLBACK_KEY_DOWN);
+                                       (void *)(long)EVAS_CALLBACK_KEY_DOWN);
         evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_UP,
                                        _propagate_event,
-                                       (void *)(long) EVAS_CALLBACK_KEY_UP);
+                                       (void *)(long)EVAS_CALLBACK_KEY_UP);
         evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_WHEEL,
                                        _propagate_event,
                                        (void *)(long)EVAS_CALLBACK_MOUSE_WHEEL);
@@ -825,8 +1175,93 @@ elm_widget_child_can_focus_get(const Evas_Object *obj)
    return sd->child_can_focus;
 }
 
+/**
+ * @internal
+ *
+ * This API makes the widget object and its children to be unfocusable.
+ *
+ * This API can be helpful for an object to be deleted.
+ * When an object will be deleted soon, it and its children may not
+ * want to get focus (by focus reverting or by other focus controls).
+ * Then, just use this API before deleting.
+ *
+ * @param obj The widget root of sub-tree
+ * @param tree_unfocusable If true, set the object sub-tree as unfocusable
+ *
+ * @ingroup Widget
+ */
+EAPI void
+elm_widget_tree_unfocusable_set(Evas_Object *obj,
+                                Eina_Bool    tree_unfocusable)
+{
+   API_ENTRY return;
+
+   if (sd->tree_unfocusable == tree_unfocusable) return;
+   sd->tree_unfocusable = !!tree_unfocusable;
+   elm_widget_focus_tree_unfocusable_handle(obj);
+}
+
+/**
+ * @internal
+ *
+ * This returns true, if the object sub-tree is unfocusable.
+ *
+ * @param obj The widget root of sub-tree
+ * @return EINA_TRUE if the object sub-tree is unfocusable
+ *
+ * @ingroup Widget
+ */
+EAPI Eina_Bool
+elm_widget_tree_unfocusable_get(const Evas_Object *obj)
+{
+   API_ENTRY return EINA_FALSE;
+   return sd->tree_unfocusable;
+}
+
+/**
+ * @internal
+ *
+ * Get the list of focusable child objects.
+ *
+ * This function retruns list of child objects which can get focus.
+ *
+ * @param obj The parent widget
+ * @retrun list of focusable child objects.
+ *
+ * @ingroup Widget
+ */
+EAPI Eina_List *
+elm_widget_can_focus_child_list_get(const Evas_Object *obj)
+{
+   API_ENTRY return NULL;
+
+   const Eina_List *l;
+   Eina_List *child_list = NULL;
+   Evas_Object *child;
+
+   if (sd->subobjs)
+     {
+        EINA_LIST_FOREACH(sd->subobjs, l, child)
+          {
+             if ((elm_widget_can_focus_get(child)) &&
+                 (evas_object_visible_get(child)) &&
+                 (!elm_widget_disabled_get(child)))
+               child_list = eina_list_append(child_list, child);
+             else if (elm_widget_is(child))
+               {
+                  Eina_List *can_focus_list;
+                  can_focus_list = elm_widget_can_focus_child_list_get(child);
+                  if (can_focus_list)
+                    child_list = eina_list_merge(child_list, can_focus_list);
+               }
+          }
+     }
+   return child_list;
+}
+
 EAPI void
-elm_widget_highlight_ignore_set(Evas_Object *obj, Eina_Bool ignore)
+elm_widget_highlight_ignore_set(Evas_Object *obj,
+                                Eina_Bool    ignore)
 {
    API_ENTRY return;
    sd->highlight_ignore = !!ignore;
@@ -840,7 +1275,8 @@ elm_widget_highlight_ignore_get(const Evas_Object *obj)
 }
 
 EAPI void
-elm_widget_highlight_in_theme_set(Evas_Object *obj, Eina_Bool highlight)
+elm_widget_highlight_in_theme_set(Evas_Object *obj,
+                                  Eina_Bool    highlight)
 {
    API_ENTRY return;
    sd->highlight_in_theme = !!highlight;
@@ -871,8 +1307,8 @@ elm_widget_focused_object_get(const Evas_Object *obj)
    if (!sd->focused) return NULL;
    EINA_LIST_FOREACH(sd->subobjs, l, subobj)
      {
-       Evas_Object *fobj = elm_widget_focused_object_get(subobj);
-       if (fobj) return fobj;
+        Evas_Object *fobj = elm_widget_focused_object_get(subobj);
+        if (fobj) return fobj;
      }
    return (Evas_Object *)obj;
 }
@@ -898,29 +1334,49 @@ elm_widget_parent_widget_get(const Evas_Object *obj)
 
    if (_elm_widget_is(obj))
      {
-       Smart_Data *sd = evas_object_smart_data_get(obj);
-       if (!sd) return NULL;
-       parent = sd->parent_obj;
+        Smart_Data *sd = evas_object_smart_data_get(obj);
+        if (!sd) return NULL;
+        parent = sd->parent_obj;
      }
    else
      {
-       parent = evas_object_data_get(obj, "elm-parent");
-       if (!parent) parent = evas_object_smart_parent_get(obj);
+        parent = evas_object_data_get(obj, "elm-parent");
+        if (!parent) parent = evas_object_smart_parent_get(obj);
      }
 
    while (parent)
      {
-       Evas_Object *elm_parent;
-       if (_elm_widget_is(parent)) break;
-       elm_parent = evas_object_data_get(parent, "elm-parent");
+        Evas_Object *elm_parent;
+        if (_elm_widget_is(parent)) break;
+        elm_parent = evas_object_data_get(parent, "elm-parent");
         if (elm_parent) parent = elm_parent;
-       else parent = evas_object_smart_parent_get(parent);
+        else parent = evas_object_smart_parent_get(parent);
      }
    return parent;
 }
 
+EAPI Evas_Object *
+elm_widget_parent2_get(const Evas_Object *obj)
+{
+   if (_elm_widget_is(obj))
+     {
+        Smart_Data *sd = evas_object_smart_data_get(obj);
+        if (sd) return sd->parent2;
+     }
+   return NULL;
+}
+
+EAPI void
+elm_widget_parent2_set(Evas_Object *obj, Evas_Object *parent)
+{
+   API_ENTRY return;
+   sd->parent2 = parent;
+}
+
 EAPI void
-elm_widget_event_callback_add(Evas_Object *obj, Elm_Event_Cb func, const void *data)
+elm_widget_event_callback_add(Evas_Object *obj,
+                              Elm_Event_Cb func,
+                              const void  *data)
 {
    API_ENTRY return;
    EINA_SAFETY_ON_NULL_RETURN(func);
@@ -931,24 +1387,29 @@ elm_widget_event_callback_add(Evas_Object *obj, Elm_Event_Cb func, const void *d
 }
 
 EAPI void *
-elm_widget_event_callback_del(Evas_Object *obj, Elm_Event_Cb func, const void *data)
+elm_widget_event_callback_del(Evas_Object *obj,
+                              Elm_Event_Cb func,
+                              const void  *data)
 {
    API_ENTRY return NULL;
    EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
    Eina_List *l;
    Elm_Event_Cb_Data *ecd;
    EINA_LIST_FOREACH(sd->event_cb, l, ecd)
-      if ((ecd->func == func) && (ecd->data == data))
-        {
-           free(ecd);
-           sd->event_cb = eina_list_remove_list(sd->event_cb, l);
-           return (void *)data;
-        }
+     if ((ecd->func == func) && (ecd->data == data))
+       {
+          free(ecd);
+          sd->event_cb = eina_list_remove_list(sd->event_cb, l);
+          return (void *)data;
+       }
    return NULL;
 }
 
 EAPI Eina_Bool
-elm_widget_event_propagate(Evas_Object *obj, Evas_Callback_Type type, void *event_info, Evas_Event_Flags *event_flags)
+elm_widget_event_propagate(Evas_Object       *obj,
+                           Evas_Callback_Type type,
+                           void              *event_info,
+                           Evas_Event_Flags  *event_flags)
 {
    API_ENTRY return EINA_FALSE; //TODO reduce.
    if (!_elm_widget_is(obj)) return EINA_FALSE;
@@ -970,7 +1431,7 @@ elm_widget_event_propagate(Evas_Object *obj, Evas_Callback_Type type, void *even
           {
              if (ecd->func((void *)ecd->data, parent, obj, type, event_info) ||
                  (event_flags && ((*event_flags) & EVAS_EVENT_FLAG_ON_HOLD)))
-                 return EINA_TRUE;
+               return EINA_TRUE;
           }
         parent = sd->parent_obj;
      }
@@ -994,7 +1455,8 @@ elm_widget_event_propagate(Evas_Object *obj, Evas_Callback_Type type, void *even
  * @ingroup Widget
  */
 EAPI void
-elm_widget_focus_custom_chain_set(Evas_Object *obj, Eina_List *objs)
+elm_widget_focus_custom_chain_set(Evas_Object *obj,
+                                  Eina_List   *objs)
 {
    API_ENTRY return;
    if (!sd->focus_next_func)
@@ -1026,7 +1488,7 @@ EAPI const Eina_List *
 elm_widget_focus_custom_chain_get(const Evas_Object *obj)
 {
    API_ENTRY return NULL;
-   return (const Eina_List *) sd->focus_chain;
+   return (const Eina_List *)sd->focus_chain;
 }
 
 /**
@@ -1068,7 +1530,9 @@ elm_widget_focus_custom_chain_unset(Evas_Object *obj)
  * @ingroup Widget
  */
 EAPI void
-elm_widget_focus_custom_chain_append(Evas_Object *obj, Evas_Object *child, Evas_Object *relative_child)
+elm_widget_focus_custom_chain_append(Evas_Object *obj,
+                                     Evas_Object *child,
+                                     Evas_Object *relative_child)
 {
    API_ENTRY return;
    EINA_SAFETY_ON_NULL_RETURN(child);
@@ -1104,7 +1568,9 @@ elm_widget_focus_custom_chain_append(Evas_Object *obj, Evas_Object *child, Evas_
  * @ingroup Widget
  */
 EAPI void
-elm_widget_focus_custom_chain_prepend(Evas_Object *obj, Evas_Object *child, Evas_Object *relative_child)
+elm_widget_focus_custom_chain_prepend(Evas_Object *obj,
+                                      Evas_Object *child,
+                                      Evas_Object *relative_child)
 {
    API_ENTRY return;
    EINA_SAFETY_ON_NULL_RETURN(child);
@@ -1139,7 +1605,8 @@ elm_widget_focus_custom_chain_prepend(Evas_Object *obj, Evas_Object *child, Evas
  * @ingroup Widget
  */
 EAPI void
-elm_widget_focus_cycle(Evas_Object *obj, Elm_Focus_Direction dir)
+elm_widget_focus_cycle(Evas_Object        *obj,
+                       Elm_Focus_Direction dir)
 {
    Evas_Object *target = NULL;
    if (!_elm_widget_is(obj))
@@ -1164,7 +1631,9 @@ elm_widget_focus_cycle(Evas_Object *obj, Elm_Focus_Direction dir)
  * @ingroup Widget
  */
 EAPI void
-elm_widget_focus_direction_go(Evas_Object *obj __UNUSED__, int x __UNUSED__, int y __UNUSED__)
+elm_widget_focus_direction_go(Evas_Object *obj __UNUSED__,
+                              int          x __UNUSED__,
+                              int          y __UNUSED__)
 {
    return; /* TODO */
 }
@@ -1187,7 +1656,9 @@ elm_widget_focus_direction_go(Evas_Object *obj __UNUSED__, int x __UNUSED__, int
  * @ingroup Widget
  */
 EAPI Eina_Bool
-elm_widget_focus_next_get(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
+elm_widget_focus_next_get(const Evas_Object  *obj,
+                          Elm_Focus_Direction dir,
+                          Evas_Object       **next)
 {
    if (!next)
      return EINA_FALSE;
@@ -1196,7 +1667,9 @@ elm_widget_focus_next_get(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_
    API_ENTRY return EINA_FALSE;
 
    /* Ignore if disabled */
-   if ((!evas_object_visible_get(obj)) || (elm_widget_disabled_get(obj)))
+   if ((!evas_object_visible_get(obj))
+       || (elm_widget_disabled_get(obj))
+       || (elm_widget_tree_unfocusable_get(obj)))
      return EINA_FALSE;
 
    /* Try use hook */
@@ -1211,7 +1684,6 @@ elm_widget_focus_next_get(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_
    return !elm_widget_focus_get(obj);
 }
 
-
 /**
  * @internal
  *
@@ -1232,9 +1704,13 @@ elm_widget_focus_next_get(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_
  * @ingroup Widget
  */
 EAPI Eina_Bool
-elm_widget_focus_list_next_get(const Evas_Object *obj, const Eina_List *items, void *(*list_data_get) (const Eina_List *list), Elm_Focus_Direction dir, Evas_Object **next)
+elm_widget_focus_list_next_get(const Evas_Object  *obj,
+                               const Eina_List    *items,
+                               void *(*list_data_get)(const Eina_List * list),
+                               Elm_Focus_Direction dir,
+                               Evas_Object       **next)
 {
-   Eina_List *(*list_next) (const Eina_List *list);
+   Eina_List *(*list_next)(const Eina_List * list) = NULL;
 
    if (!next)
      return EINA_FALSE;
@@ -1293,7 +1769,7 @@ elm_widget_focus_list_next_get(const Evas_Object *obj, const Eina_List *items, v
    l = items;
 
    /* Get First possible */
-   for (;l != start; l = list_next(l))
+   for (; l != start; l = list_next(l))
      {
         Evas_Object *tmp = NULL;
         Evas_Object *cur = list_data_get(l);
@@ -1315,7 +1791,9 @@ elm_widget_focus_list_next_get(const Evas_Object *obj, const Eina_List *items, v
 }
 
 EAPI void
-elm_widget_signal_emit(Evas_Object *obj, const char *emission, const char *source)
+elm_widget_signal_emit(Evas_Object *obj,
+                       const char  *emission,
+                       const char  *source)
 {
    API_ENTRY return;
    if (!sd->signal_func) return;
@@ -1323,14 +1801,21 @@ elm_widget_signal_emit(Evas_Object *obj, const char *emission, const char *sourc
 }
 
 static void
-_edje_signal_callback(void *data, Evas_Object *obj __UNUSED__, const char *emission, const char *source)
+_edje_signal_callback(void        *data,
+                      Evas_Object *obj __UNUSED__,
+                      const char  *emission,
+                      const char  *source)
 {
    Edje_Signal_Data *esd = data;
    esd->func(esd->data, esd->obj, emission, source);
 }
 
 EAPI void
-elm_widget_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source), void *data)
+elm_widget_signal_callback_add(Evas_Object   *obj,
+                               const char    *emission,
+                               const char    *source,
+                               Edje_Signal_Cb func,
+                               void          *data)
 {
    Edje_Signal_Data *esd;
    API_ENTRY return;
@@ -1350,7 +1835,10 @@ elm_widget_signal_callback_add(Evas_Object *obj, const char *emission, const cha
 }
 
 EAPI void *
-elm_widget_signal_callback_del(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source))
+elm_widget_signal_callback_del(Evas_Object   *obj,
+                               const char    *emission,
+                               const char    *source,
+                               Edje_Signal_Cb func)
 {
    Edje_Signal_Data *esd;
    Eina_List *l;
@@ -1376,67 +1864,68 @@ elm_widget_signal_callback_del(Evas_Object *obj, const char *emission, const cha
 }
 
 EAPI void
-elm_widget_focus_set(Evas_Object *obj, int first)
+elm_widget_focus_set(Evas_Object *obj,
+                     int          first)
 {
    API_ENTRY return;
    if (!sd->focused)
      {
         focus_order++;
         sd->focus_order = focus_order;
-       sd->focused = EINA_TRUE;
-       if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
+        sd->focused = EINA_TRUE;
+        if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
      }
    if (sd->focus_func)
      {
-       sd->focus_func(obj);
-       return;
+        sd->focus_func(obj);
+        return;
      }
    else
      {
-       if (first)
-         {
-            if ((_is_focusable(sd->resize_obj)) &&
-                (!elm_widget_disabled_get(sd->resize_obj)))
-              {
-                 elm_widget_focus_set(sd->resize_obj, first);
-              }
-            else
-              {
-                 const Eina_List *l;
-                 Evas_Object *child;
-                 EINA_LIST_FOREACH(sd->subobjs, l, child)
-                   {
-                      if ((_is_focusable(child)) &&
-                          (!elm_widget_disabled_get(child)))
-                        {
-                           elm_widget_focus_set(child, first);
-                           break;
-                        }
-                   }
-              }
-         }
-       else
-         {
-            const Eina_List *l;
-            Evas_Object *child;
-            EINA_LIST_REVERSE_FOREACH(sd->subobjs, l, child)
-              {
-                 if ((_is_focusable(child)) &&
-                     (!elm_widget_disabled_get(child)))
-                   {
-                      elm_widget_focus_set(child, first);
-                      break;
-                   }
-              }
-            if (!l)
-              {
-                 if ((_is_focusable(sd->resize_obj)) &&
-                     (!elm_widget_disabled_get(sd->resize_obj)))
-                   {
-                      elm_widget_focus_set(sd->resize_obj, first);
-                   }
-              }
-         }
+        if (first)
+          {
+             if ((_is_focusable(sd->resize_obj)) &&
+                 (!elm_widget_disabled_get(sd->resize_obj)))
+               {
+                  elm_widget_focus_set(sd->resize_obj, first);
+               }
+             else
+               {
+                  const Eina_List *l;
+                  Evas_Object *child;
+                  EINA_LIST_FOREACH(sd->subobjs, l, child)
+                    {
+                       if ((_is_focusable(child)) &&
+                           (!elm_widget_disabled_get(child)))
+                         {
+                            elm_widget_focus_set(child, first);
+                            break;
+                         }
+                    }
+               }
+          }
+        else
+          {
+             const Eina_List *l;
+             Evas_Object *child;
+             EINA_LIST_REVERSE_FOREACH(sd->subobjs, l, child)
+               {
+                  if ((_is_focusable(child)) &&
+                      (!elm_widget_disabled_get(child)))
+                    {
+                       elm_widget_focus_set(child, first);
+                       break;
+                    }
+               }
+             if (!l)
+               {
+                  if ((_is_focusable(sd->resize_obj)) &&
+                      (!elm_widget_disabled_get(sd->resize_obj)))
+                    {
+                       elm_widget_focus_set(sd->resize_obj, first);
+                    }
+               }
+          }
      }
 }
 
@@ -1452,20 +1941,20 @@ elm_widget_focused_object_clear(Evas_Object *obj)
 {
    API_ENTRY return;
    if (!sd->focused) return;
-   if (elm_widget_focus_get(sd->resize_obj))
-      elm_widget_focused_object_clear(sd->resize_obj);
+   if (sd->resize_obj && elm_widget_focus_get(sd->resize_obj))
+     elm_widget_focused_object_clear(sd->resize_obj);
    else
      {
-       const Eina_List *l;
-       Evas_Object *child;
-       EINA_LIST_FOREACH(sd->subobjs, l, child)
-         {
-            if (elm_widget_focus_get(child))
-              {
-                 elm_widget_focused_object_clear(child);
-                 break;
-              }
-         }
+        const Eina_List *l;
+        Evas_Object *child;
+        EINA_LIST_FOREACH(sd->subobjs, l, child)
+          {
+             if (elm_widget_focus_get(child))
+               {
+                  elm_widget_focused_object_clear(child);
+                  break;
+               }
+          }
      }
    sd->focused = EINA_FALSE;
    if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
@@ -1475,49 +1964,95 @@ elm_widget_focused_object_clear(Evas_Object *obj)
 EAPI void
 elm_widget_focus_steal(Evas_Object *obj)
 {
-   Evas_Object *parent, *o;
+   Evas_Object *parent, *parent2, *o;
    API_ENTRY return;
 
    if (sd->focused) return;
    if (sd->disabled) return;
+   if (!sd->can_focus) return;
+   if (sd->tree_unfocusable) return;
    parent = obj;
    for (;;)
      {
-       o = elm_widget_parent_get(parent);
-       if (!o) break;
-       sd = evas_object_smart_data_get(o);
-       if (sd->focused) break;
-       parent = o;
+        o = elm_widget_parent_get(parent);
+        if (!o) break;
+        sd = evas_object_smart_data_get(o);
+        if (sd->disabled || sd->tree_unfocusable) return;
+        if (sd->focused) break;
+        parent = o;
      }
-   if (!elm_widget_parent_get(parent))
-     elm_widget_focused_object_clear(parent);
+   if ((!elm_widget_parent_get(parent)) &&
+       (!elm_widget_parent2_get(parent)))
+      elm_widget_focused_object_clear(parent);
    else
      {
-       parent = elm_widget_parent_get(parent);
-       sd = evas_object_smart_data_get(parent);
-       if (elm_widget_focus_get(sd->resize_obj))
+        parent2 = elm_widget_parent_get(parent);
+        if (!parent2) parent2 = elm_widget_parent2_get(parent);
+        parent = parent2;
+        sd = evas_object_smart_data_get(parent);
+        if (sd)
           {
-             elm_widget_focused_object_clear(sd->resize_obj);
+             if ((sd->resize_obj) && (elm_widget_focus_get(sd->resize_obj)))
+                elm_widget_focused_object_clear(sd->resize_obj);
+             else
+               {
+                  const Eina_List *l;
+                  Evas_Object *child;
+                  EINA_LIST_FOREACH(sd->subobjs, l, child)
+                    {
+                       if (elm_widget_focus_get(child))
+                         {
+                            elm_widget_focused_object_clear(child);
+                            break;
+                         }
+                    }
+               }
           }
-       else
-         {
-            const Eina_List *l;
-            Evas_Object *child;
-            EINA_LIST_FOREACH(sd->subobjs, l, child)
-              {
-                 if (elm_widget_focus_get(child))
-                   {
-                      elm_widget_focused_object_clear(child);
-                      break;
-                   }
-              }
-         }
      }
    _parent_focus(obj);
    return;
 }
 
 EAPI void
+elm_widget_focus_restore(Evas_Object *obj)
+{
+   Evas_Object *newest = NULL;
+   unsigned int newest_focus_order = 0;
+   API_ENTRY return;
+
+   newest = _newest_focus_order_get(obj, &newest_focus_order, EINA_TRUE);
+   if (newest)
+     {
+        elm_object_focus_set(newest, EINA_FALSE);
+        elm_object_focus_set(newest, EINA_TRUE);
+     }
+}
+
+void
+_elm_widget_top_win_focused_set(Evas_Object *obj, Eina_Bool top_win_focused)
+{
+   const Eina_List *l;
+   Evas_Object *child;
+   API_ENTRY return;
+
+   if (sd->top_win_focused == top_win_focused) return;
+   if (sd->resize_obj)
+     _elm_widget_top_win_focused_set(sd->resize_obj, top_win_focused);
+   EINA_LIST_FOREACH(sd->subobjs, l, child)
+     {
+        _elm_widget_top_win_focused_set(child, top_win_focused);
+     }
+   sd->top_win_focused = top_win_focused;
+}
+
+Eina_Bool
+_elm_widget_top_win_focused_get(const Evas_Object *obj)
+{
+   API_ENTRY return EINA_FALSE;
+   return sd->top_win_focused;
+}
+
+EAPI void
 elm_widget_activate(Evas_Object *obj)
 {
    API_ENTRY return;
@@ -1534,30 +2069,18 @@ elm_widget_change(Evas_Object *obj)
 }
 
 EAPI void
-elm_widget_disabled_set(Evas_Object *obj, int disabled)
+elm_widget_disabled_set(Evas_Object *obj,
+                        Eina_Bool    disabled)
 {
    API_ENTRY return;
 
    if (sd->disabled == disabled) return;
-   sd->disabled = disabled;
-   if (sd->focused)
-     {
-       Evas_Object *o, *parent;
-
-       parent = obj;
-       for (;;)
-         {
-            o = elm_widget_parent_get(parent);
-            if (!o) break;
-            parent = o;
-         }
-        if (elm_widget_focus_get(obj))
-          elm_widget_focus_cycle(parent, ELM_FOCUS_NEXT);
-     }
+   sd->disabled = !!disabled;
+   elm_widget_focus_disabled_handle(obj);
    if (sd->disable_func) sd->disable_func(obj);
 }
 
-EAPI int
+EAPI Eina_Bool
 elm_widget_disabled_get(const Evas_Object *obj)
 {
    API_ENTRY return 0;
@@ -1565,27 +2088,35 @@ elm_widget_disabled_get(const Evas_Object *obj)
 }
 
 EAPI void
-elm_widget_show_region_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
+elm_widget_show_region_set(Evas_Object *obj,
+                           Evas_Coord   x,
+                           Evas_Coord   y,
+                           Evas_Coord   w,
+                           Evas_Coord   h,
+                           Eina_Bool    forceshow)
 {
    Evas_Object *parent_obj, *child_obj;
    Evas_Coord px, py, cx, cy;
 
+   evas_smart_objects_calculate(evas_object_evas_get(obj));
+
    API_ENTRY return;
-   if ((x == sd->rx) && (y == sd->ry) && (w == sd->rw) && (h == sd->rh)) return;
+   if (!forceshow && (x == sd->rx) && (y == sd->ry)
+            && (w == sd->rw) && (h == sd->rh)) return;
    sd->rx = x;
    sd->ry = y;
    sd->rw = w;
    sd->rh = h;
    if (sd->on_show_region_func)
-      sd->on_show_region_func(sd->on_show_region_data, obj);
+     sd->on_show_region_func(sd->on_show_region_data, obj);
 
    do
      {
-        parent_obj = sd->parent_obj; 
+        parent_obj = sd->parent_obj;
         child_obj = sd->obj;
+        if ((!parent_obj) || (!_elm_widget_is(parent_obj))) break;
         sd = evas_object_smart_data_get(parent_obj);
-
-        if ((!parent_obj) || (!sd) || (!_elm_widget_is(parent_obj))) break;
+        if (!sd) break;
 
         evas_object_geometry_get(parent_obj, &px, &py, NULL, NULL);
         evas_object_geometry_get(child_obj, &cx, &cy, NULL, NULL);
@@ -1606,7 +2137,11 @@ elm_widget_show_region_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Co
 }
 
 EAPI void
-elm_widget_show_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
+elm_widget_show_region_get(const Evas_Object *obj,
+                           Evas_Coord        *x,
+                           Evas_Coord        *y,
+                           Evas_Coord        *w,
+                           Evas_Coord        *h)
 {
    API_ENTRY return;
    if (x) *x = sd->rx;
@@ -1636,7 +2171,11 @@ elm_widget_show_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y,
  * @ingroup Widget
  */
 EAPI void
-elm_widget_focus_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
+elm_widget_focus_region_get(const Evas_Object *obj,
+                            Evas_Coord        *x,
+                            Evas_Coord        *y,
+                            Evas_Coord        *w,
+                            Evas_Coord        *h)
 {
    Smart_Data *sd;
 
@@ -1659,7 +2198,7 @@ elm_widget_scroll_hold_push(Evas_Object *obj)
    API_ENTRY return;
    sd->scroll_hold++;
    if (sd->scroll_hold == 1)
-      evas_object_smart_callback_call(obj, "scroll-hold-on", obj);
+     evas_object_smart_callback_call(obj, "scroll-hold-on", obj);
    if (sd->parent_obj) elm_widget_scroll_hold_push(sd->parent_obj);
    // FIXME: on delete/reparent hold pop
 }
@@ -1669,10 +2208,10 @@ elm_widget_scroll_hold_pop(Evas_Object *obj)
 {
    API_ENTRY return;
    sd->scroll_hold--;
-   if (sd->scroll_hold < 0) sd->scroll_hold = 0;
    if (!sd->scroll_hold)
-      evas_object_smart_callback_call(obj, "scroll-hold-off", obj);
+     evas_object_smart_callback_call(obj, "scroll-hold-off", obj);
    if (sd->parent_obj) elm_widget_scroll_hold_pop(sd->parent_obj);
+   if (sd->scroll_hold < 0) sd->scroll_hold = 0;
 }
 
 EAPI int
@@ -1688,7 +2227,7 @@ elm_widget_scroll_freeze_push(Evas_Object *obj)
    API_ENTRY return;
    sd->scroll_freeze++;
    if (sd->scroll_freeze == 1)
-      evas_object_smart_callback_call(obj, "scroll-freeze-on", obj);
+     evas_object_smart_callback_call(obj, "scroll-freeze-on", obj);
    if (sd->parent_obj) elm_widget_scroll_freeze_push(sd->parent_obj);
    // FIXME: on delete/reparent freeze pop
 }
@@ -1698,10 +2237,10 @@ elm_widget_scroll_freeze_pop(Evas_Object *obj)
 {
    API_ENTRY return;
    sd->scroll_freeze--;
-   if (sd->scroll_freeze < 0) sd->scroll_freeze = 0;
    if (!sd->scroll_freeze)
-      evas_object_smart_callback_call(obj, "scroll-freeze-off", obj);
+     evas_object_smart_callback_call(obj, "scroll-freeze-off", obj);
    if (sd->parent_obj) elm_widget_scroll_freeze_pop(sd->parent_obj);
+   if (sd->scroll_freeze < 0) sd->scroll_freeze = 0;
 }
 
 EAPI int
@@ -1712,43 +2251,206 @@ elm_widget_scroll_freeze_get(const Evas_Object *obj)
 }
 
 EAPI void
-elm_widget_scale_set(Evas_Object *obj, double scale)
+elm_widget_scale_set(Evas_Object *obj,
+                     double       scale)
+{
+   API_ENTRY return;
+   if (scale <= 0.0) scale = 0.0;
+   if (sd->scale != scale)
+     {
+        sd->scale = scale;
+        elm_widget_theme(obj);
+     }
+}
+
+EAPI double
+elm_widget_scale_get(const Evas_Object *obj)
+{
+   API_ENTRY return 1.0;
+   // FIXME: save walking up the tree by storing/caching parent scale
+   if (sd->scale == 0.0)
+     {
+        if (sd->parent_obj)
+          return elm_widget_scale_get(sd->parent_obj);
+        else
+          return 1.0;
+     }
+   return sd->scale;
+}
+
+EAPI void
+elm_widget_theme_set(Evas_Object *obj,
+                     Elm_Theme   *th)
+{
+   API_ENTRY return;
+   if (sd->theme != th)
+     {
+        if (sd->theme) elm_theme_free(sd->theme);
+        sd->theme = th;
+        if (th) th->ref++;
+        elm_widget_theme(obj);
+     }
+}
+
+EAPI void
+elm_widget_text_part_set(Evas_Object *obj, const char *part, const char *label)
+{
+   API_ENTRY return;
+
+   if (!sd->text_set_func)
+     return;
+
+   sd->text_set_func(obj, part, label);
+}
+
+EAPI const char *
+elm_widget_text_part_get(const Evas_Object *obj, const char *part)
+{
+   API_ENTRY return NULL;
+
+   if (!sd->text_get_func)
+     return NULL;
+
+   return sd->text_get_func(obj, part);
+}
+
+EAPI void
+elm_widget_domain_translatable_text_part_set(Evas_Object *obj, const char *part, const char *domain, const char *label)
+{
+   const char *str;
+   Eina_List *l;
+   Elm_Translate_String_Data *ts = NULL;
+   API_ENTRY return;
+
+   str = eina_stringshare_add(part);
+   EINA_LIST_FOREACH(sd->translate_strings, l, ts)
+      if (ts->id == str)
+        break;
+      else
+        ts = NULL;
+
+   if (!ts && !label)
+     eina_stringshare_del(str);
+   else if (!ts)
+     {
+        ts = malloc(sizeof(Elm_Translate_String_Data));
+        if (!ts) return;
+
+        ts->id = str;
+        ts->domain = eina_stringshare_add(domain);
+        ts->string = eina_stringshare_add(label);
+        sd->translate_strings = eina_list_append(sd->translate_strings, ts);
+     }
+   else
+     {
+        if (label)
+          {
+             eina_stringshare_replace(&ts->domain, domain);
+             eina_stringshare_replace(&ts->string, label);
+          }
+        else
+          {
+             sd->translate_strings = eina_list_remove_list(
+                                                sd->translate_strings, l);
+             eina_stringshare_del(ts->id);
+             eina_stringshare_del(ts->domain);
+             eina_stringshare_del(ts->string);
+             free(ts);
+          }
+        eina_stringshare_del(str);
+     }
+
+#ifdef HAVE_GETTEXT
+   if (label && label[0])
+     label = dgettext(domain, label);
+#endif
+   elm_widget_text_part_set(obj, part, label);
+}
+
+EAPI const char *
+elm_widget_translatable_text_part_get(const Evas_Object *obj, const char *part)
+{
+   const char *str, *ret = NULL;
+   Eina_List *l;
+   Elm_Translate_String_Data *ts;
+   API_ENTRY return NULL;
+
+   str = eina_stringshare_add(part);
+   EINA_LIST_FOREACH(sd->translate_strings, l, ts)
+      if (ts->id == str)
+        {
+           ret = ts->string;
+           break;
+        }
+   eina_stringshare_del(str);
+   return ret;
+}
+
+EAPI void
+elm_widget_translate(Evas_Object *obj)
+{
+   const Eina_List *l;
+   Evas_Object *child;
+#ifdef HAVE_GETTEXT
+   Elm_Translate_String_Data *ts;
+#endif
+
+   API_ENTRY return;
+   EINA_LIST_FOREACH(sd->subobjs, l, child) elm_widget_translate(child);
+   if (sd->resize_obj) elm_widget_translate(sd->resize_obj);
+   if (sd->hover_obj) elm_widget_translate(sd->hover_obj);
+   if (sd->translate_func) sd->translate_func(obj);
+
+#ifdef HAVE_GETTEXT
+   EINA_LIST_FOREACH(sd->translate_strings, l, ts)
+     {
+        const char *s = dgettext(ts->domain, ts->string);
+        elm_widget_text_part_set(obj, ts->id, s);
+     }
+#endif
+}
+
+EAPI void
+elm_widget_content_part_set(Evas_Object *obj, const char *part, Evas_Object *content)
 {
    API_ENTRY return;
-   if (scale <= 0.0) scale = 0.0;
-   if (sd->scale != scale)
-     {
-       sd->scale = scale;
-       elm_widget_theme(obj);
-     }
+
+   if (!sd->content_set_func)  return;
+   sd->content_set_func(obj, part, content);
 }
 
-EAPI double
-elm_widget_scale_get(const Evas_Object *obj)
+EAPI Evas_Object *
+elm_widget_content_part_get(const Evas_Object *obj, const char *part)
 {
-   API_ENTRY return 1.0;
-   // FIXME: save walking up the tree by storing/caching parent scale
-   if (sd->scale == 0.0)
-     {
-       if (sd->parent_obj)
-           return elm_widget_scale_get(sd->parent_obj);
-       else
-           return 1.0;
-     }
-   return sd->scale;
+   API_ENTRY return NULL;
+
+   if (!sd->content_get_func) return NULL;
+   return sd->content_get_func(obj, part);
+}
+
+EAPI Evas_Object *
+elm_widget_content_part_unset(Evas_Object *obj, const char *part)
+{
+   API_ENTRY return NULL;
+
+   if (!sd->content_unset_func) return NULL;
+   return sd->content_unset_func(obj, part);
 }
 
 EAPI void
-elm_widget_theme_set(Evas_Object *obj, Elm_Theme *th)
+elm_widget_access_info_set(Evas_Object *obj, const char *txt)
 {
    API_ENTRY return;
-   if (sd->theme != th)
-     {
-        if (sd->theme) elm_theme_free(sd->theme);
-        sd->theme = th;
-        if (th) th->ref++;
-        elm_widget_theme(obj);
-     }
+   if (sd->access_info) eina_stringshare_del(sd->access_info);
+   if (!txt) sd->access_info = NULL;
+   else sd->access_info = eina_stringshare_add(txt);
+}
+
+EAPI const char *
+elm_widget_access_info_get(Evas_Object *obj)
+{
+   API_ENTRY return NULL;
+   return sd->access_info;
 }
 
 EAPI Elm_Theme *
@@ -1758,20 +2460,21 @@ elm_widget_theme_get(const Evas_Object *obj)
    if (!sd->theme)
      {
         if (sd->parent_obj)
-           return elm_widget_theme_get(sd->parent_obj);
+          return elm_widget_theme_get(sd->parent_obj);
         else
-           return NULL;
+          return NULL;
      }
    return sd->theme;
 }
 
 EAPI void
-elm_widget_style_set(Evas_Object *obj, const char *style)
+elm_widget_style_set(Evas_Object *obj,
+                     const char  *style)
 {
    API_ENTRY return;
-   
+
    if (eina_stringshare_replace(&sd->style, style))
-      elm_widget_theme(obj);
+     elm_widget_theme(obj);
 }
 
 EAPI const char *
@@ -1783,7 +2486,8 @@ elm_widget_style_get(const Evas_Object *obj)
 }
 
 EAPI void
-elm_widget_type_set(Evas_Object *obj, const char *type)
+elm_widget_type_set(Evas_Object *obj,
+                    const char  *type)
 {
    API_ENTRY return;
    eina_stringshare_replace(&sd->type, type);
@@ -1798,35 +2502,40 @@ elm_widget_type_get(const Evas_Object *obj)
 }
 
 EAPI void
-elm_widget_tooltip_add(Evas_Object *obj, Elm_Tooltip *tt)
+elm_widget_tooltip_add(Evas_Object *obj,
+                       Elm_Tooltip *tt)
 {
    API_ENTRY return;
    sd->tooltips = eina_list_append(sd->tooltips, tt);
 }
 
 EAPI void
-elm_widget_tooltip_del(Evas_Object *obj, Elm_Tooltip *tt)
+elm_widget_tooltip_del(Evas_Object *obj,
+                       Elm_Tooltip *tt)
 {
    API_ENTRY return;
    sd->tooltips = eina_list_remove(sd->tooltips, tt);
 }
 
 EAPI void
-elm_widget_cursor_add(Evas_Object *obj, Elm_Cursor *cur)
+elm_widget_cursor_add(Evas_Object *obj,
+                      Elm_Cursor  *cur)
 {
    API_ENTRY return;
    sd->cursors = eina_list_append(sd->cursors, cur);
 }
 
 EAPI void
-elm_widget_cursor_del(Evas_Object *obj, Elm_Cursor *cur)
+elm_widget_cursor_del(Evas_Object *obj,
+                      Elm_Cursor  *cur)
 {
    API_ENTRY return;
    sd->cursors = eina_list_remove(sd->cursors, cur);
 }
 
 EAPI void
-elm_widget_drag_lock_x_set(Evas_Object *obj, Eina_Bool lock)
+elm_widget_drag_lock_x_set(Evas_Object *obj,
+                           Eina_Bool    lock)
 {
    API_ENTRY return;
    if (sd->drag_x_locked == lock) return;
@@ -1836,7 +2545,8 @@ elm_widget_drag_lock_x_set(Evas_Object *obj, Eina_Bool lock)
 }
 
 EAPI void
-elm_widget_drag_lock_y_set(Evas_Object *obj, Eina_Bool lock)
+elm_widget_drag_lock_y_set(Evas_Object *obj,
+                           Eina_Bool    lock)
 {
    API_ENTRY return;
    if (sd->drag_y_locked == lock) return;
@@ -1874,14 +2584,37 @@ elm_widget_drag_child_locked_y_get(const Evas_Object *obj)
 }
 
 EAPI Eina_Bool
-elm_widget_theme_object_set(Evas_Object *obj, Evas_Object *edj, const char *wname, const char *welement, const char *wstyle)
+elm_widget_theme_object_set(Evas_Object *obj,
+                            Evas_Object *edj,
+                            const char  *wname,
+                            const char  *welement,
+                            const char  *wstyle)
 {
    API_ENTRY return EINA_FALSE;
    return _elm_theme_object_set(obj, edj, wname, welement, wstyle);
 }
 
 EAPI Eina_Bool
-elm_widget_type_check(const Evas_Object *obj, const char *type)
+elm_widget_is_check(const Evas_Object *obj)
+{
+   static int abort_on_warn = -1;
+   if (elm_widget_is(obj))
+      return EINA_TRUE;
+
+   ERR("Passing Object: %p.", obj);
+   if (abort_on_warn == -1)
+     {
+        if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
+        else abort_on_warn = 0;
+     }
+   if (abort_on_warn == 1) abort();
+   return EINA_FALSE;
+}
+
+EAPI Eina_Bool
+elm_widget_type_check(const Evas_Object *obj,
+                      const char        *type,
+                      const char        *func)
 {
    const char *provided, *expected = "(unknown)";
    static int abort_on_warn = -1;
@@ -1892,9 +2625,9 @@ elm_widget_type_check(const Evas_Object *obj, const char *type)
      {
         provided = evas_object_type_get(obj);
         if ((!provided) || (!provided[0]))
-           provided = "(unknown)";
+          provided = "(unknown)";
      }
-   ERR("Passing Object: %p, of type: '%s' when expecting type: '%s'", obj, provided, expected);
+   ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
    if (abort_on_warn == -1)
      {
         if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
@@ -1904,6 +2637,50 @@ elm_widget_type_check(const Evas_Object *obj, const char *type)
    return EINA_FALSE;
 }
 
+static Evas_Object *
+_widget_name_find(const Evas_Object *obj, const char *name, int recurse)
+{
+   Eina_List *l;
+   Evas_Object *child;
+   const char *s;
+   INTERNAL_ENTRY NULL;
+   
+   if (!_elm_widget_is(obj)) return NULL;
+   if (sd->resize_obj)
+     {
+        s = evas_object_name_get(sd->resize_obj);
+        if ((s) && (!strcmp(s, name))) return sd->resize_obj;
+        if ((recurse != 0) && 
+            ((child = _widget_name_find(sd->resize_obj, name, recurse - 1))))
+          return child;
+     }
+   EINA_LIST_FOREACH(sd->subobjs, l, child)
+     {
+        s = evas_object_name_get(child);
+        if ((s) && (!strcmp(s, name))) return child;
+        if ((recurse != 0) && 
+            ((child = _widget_name_find(child, name, recurse - 1))))
+          return child;
+     }
+   if (sd->hover_obj)
+     {
+        s = evas_object_name_get(sd->hover_obj);
+        if ((s) && (!strcmp(s, name))) return sd->hover_obj;
+        if ((recurse != 0) && 
+            ((child = _widget_name_find(sd->hover_obj, name, recurse - 1))))
+          return child;
+     }
+   return NULL;
+}
+
+EAPI Evas_Object *
+elm_widget_name_find(const Evas_Object *obj, const char *name, int recurse)
+{
+   API_ENTRY return NULL;
+   if (!name) return NULL;
+   return _widget_name_find(obj, name, recurse);
+}
+
 /**
  * @internal
  *
@@ -1923,19 +2700,19 @@ elm_widget_stringlist_get(const char *str)
    if (!str) return NULL;
    for (b = s = str; 1; s++)
      {
-       if ((*s == ' ') || (!*s))
-         {
-            char *t = malloc(s - b + 1);
-            if (t)
-              {
-                 strncpy(t, b, s - b);
-                 t[s - b] = 0;
-                 list = eina_list_append(list, eina_stringshare_add(t));
-                 free(t);
-              }
-            b = s + 1;
-         }
-       if (!*s) break;
+        if ((*s == ' ') || (!*s))
+          {
+             char *t = malloc(s - b + 1);
+             if (t)
+               {
+                  strncpy(t, b, s - b);
+                  t[s - b] = 0;
+                  list = eina_list_append(list, eina_stringshare_add(t));
+                  free(t);
+               }
+             b = s + 1;
+          }
+        if (!*s) break;
      }
    return list;
 }
@@ -1947,6 +2724,46 @@ elm_widget_stringlist_free(Eina_List *list)
    EINA_LIST_FREE(list, s) eina_stringshare_del(s);
 }
 
+EAPI void
+elm_widget_focus_hide_handle(Evas_Object *obj)
+{
+   _if_focused_revert(obj, EINA_TRUE);
+}
+
+EAPI void
+elm_widget_focus_mouse_up_handle(Evas_Object *obj)
+{
+   Evas_Object *o = obj;
+   do
+     {
+        if (_elm_widget_is(o)) break;
+        o = evas_object_smart_parent_get(o);
+     }
+   while (o);
+   if (!o) return;
+   if (!_is_focusable(o)) return;
+   elm_widget_focus_steal(o);
+}
+
+EAPI void
+elm_widget_focus_tree_unfocusable_handle(Evas_Object *obj)
+{
+   API_ENTRY return;
+
+   if (!elm_widget_parent_get(obj))
+     elm_widget_focused_object_clear(obj);
+   else
+     _if_focused_revert(obj, EINA_TRUE);
+}
+
+EAPI void
+elm_widget_focus_disabled_handle(Evas_Object *obj)
+{
+   API_ENTRY return;
+
+   elm_widget_focus_tree_unfocusable_handle(obj);
+}
+
 /**
  * @internal
  *
@@ -1967,7 +2784,8 @@ elm_widget_stringlist_free(Eina_List *list)
  * @ingroup Widget
  */
 EAPI Elm_Widget_Item *
-_elm_widget_item_new(Evas_Object *widget, size_t alloc_size)
+_elm_widget_item_new(Evas_Object *widget,
+                     size_t       alloc_size)
 {
    if (!_elm_widget_is(widget))
      return NULL;
@@ -2008,12 +2826,27 @@ _elm_widget_item_del(Elm_Widget_Item *item)
 {
    ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
 
-   if (item->del_cb)
-     item->del_cb((void *)item->data, item->widget, item);
+   if (item->del_func)
+     item->del_func((void *)item->data, item->widget, item);
+
+   if (item->del_pre_func)
+     item->del_pre_func((Elm_Object_Item *) item);
 
    if (item->view)
      evas_object_del(item->view);
 
+   if (item->access)
+     {
+        _elm_access_clear(item->access);
+        free(item->access);
+        item->access = NULL;
+     }
+   if (item->access_info)
+     {
+        eina_stringshare_del(item->access_info);
+        item->access_info = NULL;
+     }
+
    EINA_MAGIC_SET(item, EINA_MAGIC_NONE);
    free(item);
 }
@@ -2021,6 +2854,27 @@ _elm_widget_item_del(Elm_Widget_Item *item)
 /**
  * @internal
  *
+ * Set the function to notify to widgets when item is being deleted by user.
+ *
+ * This function will complain if there was a callback set already,
+ * however it will set the new one.
+ *
+ * @param item a valid #Elm_Widget_Item to be notified
+ * @see elm_widget_item_del_pre_hook_set() convenience macro.
+ * @ingroup Widget
+ */
+EAPI void
+_elm_widget_item_del_pre_hook_set(Elm_Widget_Item *item, Elm_Widget_Item_Del_Pre_Cb func)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   if ((item->del_pre_func) && (item->del_pre_func != func))
+     WRN("You're replacing a previously set del_pre_cb %p of item %p with %p", item->del_pre_func, item, func);
+   item->del_pre_func = func;
+}
+
+/**
+ * @internal
+ *
  * Notify object will be deleted without actually deleting it.
  *
  * This function will callback Elm_Widget_Item::del_cb if it is set
@@ -2035,9 +2889,9 @@ EAPI void
 _elm_widget_item_pre_notify_del(Elm_Widget_Item *item)
 {
    ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
-   if (!item->del_cb) return;
-   item->del_cb((void *)item->data, item->widget, item);
-   item->del_cb = NULL;
+   if (!item->del_func) return;
+   item->del_func((void *)item->data, item->widget, item);
+   item->del_func = NULL;
 }
 
 /**
@@ -2059,15 +2913,16 @@ _elm_widget_item_pre_notify_del(Elm_Widget_Item *item)
  * @ingroup Widget
  */
 EAPI void
-_elm_widget_item_del_cb_set(Elm_Widget_Item *item, Evas_Smart_Cb del_cb)
+_elm_widget_item_del_cb_set(Elm_Widget_Item *item,
+                            Evas_Smart_Cb    func)
 {
    ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
 
-   if ((item->del_cb) && (item->del_cb != del_cb))
+   if ((item->del_func) && (item->del_func != func))
      WRN("You're replacing a previously set del_cb %p of item %p with %p",
-         item->del_cb, item, del_cb);
+         item->del_func, item, func);
 
-   item->del_cb = del_cb;
+   item->del_func = func;
 }
 
 /**
@@ -2085,7 +2940,8 @@ _elm_widget_item_del_cb_set(Elm_Widget_Item *item, Evas_Smart_Cb del_cb)
  * @ingroup Widget
  */
 EAPI void
-_elm_widget_item_data_set(Elm_Widget_Item *item, const void *data)
+_elm_widget_item_data_set(Elm_Widget_Item *item,
+                          const void      *data)
 {
    ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
    if ((item->data) && (item->data != data))
@@ -2109,29 +2965,73 @@ _elm_widget_item_data_get(const Elm_Widget_Item *item)
    return (void *)item->data;
 }
 
+EAPI void
+_elm_widget_item_disabled_set(Elm_Widget_Item *item, Eina_Bool disabled)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+
+   if (item->disabled == disabled) return;
+   item->disabled = !!disabled;
+   if (item->disable_func) item->disable_func(item);
+}
+
+EAPI Eina_Bool
+_elm_widget_item_disabled_get(const Elm_Widget_Item *item)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
+   return item->disabled;
+}
+
+EAPI void
+_elm_widget_item_disable_set_hook_set(Elm_Widget_Item *item,
+                                      Elm_Widget_Disable_Set_Cb func)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   item->disable_func = func;
+}
+
 typedef struct _Elm_Widget_Item_Tooltip Elm_Widget_Item_Tooltip;
 
 struct _Elm_Widget_Item_Tooltip
 {
-   Elm_Widget_Item             *item;
-   Elm_Tooltip_Item_Content_Cb  func;
-   Evas_Smart_Cb                del_cb;
-   const void                  *data;
+   Elm_Widget_Item            *item;
+   Elm_Tooltip_Item_Content_Cb func;
+   Evas_Smart_Cb               del_cb;
+   const void                 *data;
 };
 
 static Evas_Object *
-_elm_widget_item_tooltip_label_create(void *data, Evas_Object *obj, void *item __UNUSED__)
+_elm_widget_item_tooltip_label_create(void        *data,
+                                      Evas_Object *obj __UNUSED__,
+                                      Evas_Object *tooltip,
+                                      void        *item __UNUSED__)
+{
+   Evas_Object *label = elm_label_add(tooltip);
+   if (!label)
+     return NULL;
+   elm_object_style_set(label, "tooltip");
+   elm_object_text_set(label, data);
+   return label;
+}
+
+static Evas_Object *
+_elm_widget_item_tooltip_trans_label_create(void        *data,
+                                            Evas_Object *obj __UNUSED__,
+                                            Evas_Object *tooltip,
+                                            void        *item __UNUSED__)
 {
-   Evas_Object *label = elm_label_add(obj);
+   Evas_Object *label = elm_label_add(tooltip);
    if (!label)
      return NULL;
    elm_object_style_set(label, "tooltip");
-   elm_label_label_set(label, data);
+   elm_object_translatable_text_set(label, data);
    return label;
 }
 
 static void
-_elm_widget_item_tooltip_label_del_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+_elm_widget_item_tooltip_label_del_cb(void        *data,
+                                      Evas_Object *obj __UNUSED__,
+                                      void        *event_info __UNUSED__)
 {
    eina_stringshare_del(data);
 }
@@ -2150,7 +3050,8 @@ _elm_widget_item_tooltip_label_del_cb(void *data, Evas_Object *obj __UNUSED__, v
  * @ingroup Widget
  */
 EAPI void
-_elm_widget_item_tooltip_text_set(Elm_Widget_Item *item, const char *text)
+_elm_widget_item_tooltip_text_set(Elm_Widget_Item *item,
+                                  const char      *text)
 {
    ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
    EINA_SAFETY_ON_NULL_RETURN(text);
@@ -2158,18 +3059,35 @@ _elm_widget_item_tooltip_text_set(Elm_Widget_Item *item, const char *text)
    text = eina_stringshare_add(text);
    _elm_widget_item_tooltip_content_cb_set
      (item, _elm_widget_item_tooltip_label_create, text,
-      _elm_widget_item_tooltip_label_del_cb);
+     _elm_widget_item_tooltip_label_del_cb);
+}
+
+EAPI void
+_elm_widget_item_tooltip_translatable_text_set(Elm_Widget_Item *item,
+                                               const char      *text)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   EINA_SAFETY_ON_NULL_RETURN(text);
+
+   text = eina_stringshare_add(text);
+   _elm_widget_item_tooltip_content_cb_set
+     (item, _elm_widget_item_tooltip_trans_label_create, text,
+     _elm_widget_item_tooltip_label_del_cb);
 }
 
 static Evas_Object *
-_elm_widget_item_tooltip_create(void *data, Evas_Object *obj)
+_elm_widget_item_tooltip_create(void        *data,
+                                Evas_Object *obj,
+                                Evas_Object *tooltip)
 {
    Elm_Widget_Item_Tooltip *wit = data;
-   return wit->func((void *)wit->data, obj, wit->item);
+   return wit->func((void *)wit->data, obj, tooltip, wit->item);
 }
 
 static void
-_elm_widget_item_tooltip_del_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
+_elm_widget_item_tooltip_del_cb(void        *data,
+                                Evas_Object *obj,
+                                void        *event_info __UNUSED__)
 {
    Elm_Widget_Item_Tooltip *wit = data;
    if (wit->del_cb) wit->del_cb((void *)wit->data, obj, wit->item);
@@ -2199,7 +3117,10 @@ _elm_widget_item_tooltip_del_cb(void *data, Evas_Object *obj, void *event_info _
  * @ingroup Widget
  */
 EAPI void
-_elm_widget_item_tooltip_content_cb_set(Elm_Widget_Item *item, Elm_Tooltip_Item_Content_Cb func, const void *data, Evas_Smart_Cb del_cb)
+_elm_widget_item_tooltip_content_cb_set(Elm_Widget_Item            *item,
+                                        Elm_Tooltip_Item_Content_Cb func,
+                                        const void                 *data,
+                                        Evas_Smart_Cb               del_cb)
 {
    Elm_Widget_Item_Tooltip *wit;
 
@@ -2220,14 +3141,14 @@ _elm_widget_item_tooltip_content_cb_set(Elm_Widget_Item *item, Elm_Tooltip_Item_
 
    elm_object_sub_tooltip_content_cb_set
      (item->view, item->widget, _elm_widget_item_tooltip_create, wit,
-      _elm_widget_item_tooltip_del_cb);
+     _elm_widget_item_tooltip_del_cb);
 
    return;
 
- error_noitem:
+error_noitem:
    if (del_cb) del_cb((void *)data, NULL, item);
    return;
- error:
+error:
    if (del_cb) del_cb((void *)data, item->widget, item);
 }
 
@@ -2268,12 +3189,27 @@ _elm_widget_item_tooltip_unset(Elm_Widget_Item *item)
  * @ingroup Widget
  */
 EAPI void
-_elm_widget_item_tooltip_style_set(Elm_Widget_Item *item, const char *style)
+_elm_widget_item_tooltip_style_set(Elm_Widget_Item *item,
+                                   const char      *style)
 {
    ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
    elm_object_tooltip_style_set(item->view, style);
 }
 
+EAPI Eina_Bool
+_elm_widget_item_tooltip_window_mode_set(Elm_Widget_Item *item, Eina_Bool disable)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
+   return elm_object_tooltip_window_mode_set(item->view, disable);
+}
+
+EAPI Eina_Bool
+_elm_widget_item_tooltip_window_mode_get(const Elm_Widget_Item *item)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
+   return elm_object_tooltip_window_mode_get(item->view);
+}
+
 /**
  * @internal
  *
@@ -2293,7 +3229,8 @@ _elm_widget_item_tooltip_style_get(const Elm_Widget_Item *item)
 }
 
 EAPI void
-_elm_widget_item_cursor_set(Elm_Widget_Item *item, const char *cursor)
+_elm_widget_item_cursor_set(Elm_Widget_Item *item,
+                            const char      *cursor)
 {
    ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
    elm_object_sub_cursor_set(item->view, item->widget, cursor);
@@ -2327,7 +3264,8 @@ _elm_widget_item_cursor_unset(Elm_Widget_Item *item)
  * @ingroup Widget
  */
 EAPI void
-_elm_widget_item_cursor_style_set(Elm_Widget_Item *item, const char *style)
+_elm_widget_item_cursor_style_set(Elm_Widget_Item *item,
+                                  const char      *style)
 {
    ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
    elm_object_cursor_style_set(item->view, style);
@@ -2368,7 +3306,8 @@ _elm_widget_item_cursor_style_get(const Elm_Widget_Item *item)
  * @ingroup Widget
  */
 EAPI void
-_elm_widget_item_cursor_engine_only_set(Elm_Widget_Item *item, Eina_Bool engine_only)
+_elm_widget_item_cursor_engine_only_set(Elm_Widget_Item *item,
+                                        Eina_Bool        engine_only)
 {
    ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
    elm_object_cursor_engine_only_set(item->view, engine_only);
@@ -2400,15 +3339,130 @@ _smart_reconfigure(Smart_Data *sd)
    if (sd->resize_obj)
      {
         evas_object_move(sd->resize_obj, sd->x, sd->y);
-       evas_object_resize(sd->resize_obj, sd->w, sd->h);
+        evas_object_resize(sd->resize_obj, sd->w, sd->h);
      }
    if (sd->hover_obj)
      {
         evas_object_move(sd->hover_obj, sd->x, sd->y);
-       evas_object_resize(sd->hover_obj, sd->w, sd->h);
+        evas_object_resize(sd->hover_obj, sd->w, sd->h);
      }
 }
 
+EAPI void
+_elm_widget_item_content_part_set(Elm_Widget_Item *item,
+                                 const char *part,
+                                 Evas_Object *content)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   if (!item->content_set_func) return;
+   item->content_set_func((Elm_Object_Item *) item, part, content);
+}
+
+EAPI Evas_Object *
+_elm_widget_item_content_part_get(const Elm_Widget_Item *item,
+                                  const char *part)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
+   if (!item->content_get_func) return NULL;
+   return item->content_get_func((Elm_Object_Item *) item, part);
+}
+
+EAPI Evas_Object *
+_elm_widget_item_content_part_unset(Elm_Widget_Item *item,
+                                    const char *part)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
+   if (!item->content_unset_func) return NULL;
+   return item->content_unset_func((Elm_Object_Item *) item, part);
+}
+
+EAPI void
+_elm_widget_item_text_part_set(Elm_Widget_Item *item,
+                              const char *part,
+                              const char *label)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   if (!item->text_set_func) return;
+   item->text_set_func((Elm_Object_Item *) item, part, label);
+}
+
+EAPI void
+_elm_widget_item_signal_emit(Elm_Widget_Item *item,
+                             const char *emission,
+                             const char *source)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   if (item->signal_emit_func)
+     item->signal_emit_func((Elm_Object_Item *) item, emission, source);
+}
+
+EAPI const char *
+_elm_widget_item_text_part_get(const Elm_Widget_Item *item,
+                               const char *part)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
+   if (!item->text_get_func) return NULL;
+   return item->text_get_func((Elm_Object_Item *) item, part);
+}
+
+EAPI void
+_elm_widget_item_content_set_hook_set(Elm_Widget_Item *item,
+                                      Elm_Widget_Content_Set_Cb func)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   item->content_set_func = func;
+}
+
+EAPI void
+_elm_widget_item_content_get_hook_set(Elm_Widget_Item *item,
+                                      Elm_Widget_Content_Get_Cb func)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   item->content_get_func = func;
+}
+
+EAPI void
+_elm_widget_item_content_unset_hook_set(Elm_Widget_Item *item,
+                                        Elm_Widget_Content_Unset_Cb func)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   item->content_unset_func = func;
+}
+
+EAPI void
+_elm_widget_item_text_set_hook_set(Elm_Widget_Item *item,
+                                   Elm_Widget_Text_Set_Cb func)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   item->text_set_func = func;
+}
+
+EAPI void
+_elm_widget_item_text_get_hook_set(Elm_Widget_Item *item,
+                                   Elm_Widget_Text_Get_Cb func)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   item->text_get_func = func;
+}
+
+EAPI void
+_elm_widget_item_signal_emit_hook_set(Elm_Widget_Item *item,
+                                      Elm_Widget_Signal_Emit_Cb func)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   item->signal_emit_func = func;
+}
+
+EAPI void
+_elm_widget_item_access_info_set(Elm_Widget_Item *item, const char *txt)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   if (item->access_info) eina_stringshare_del(item->access_info);
+   if (!txt) item->access_info = NULL;
+   else item->access_info = eina_stringshare_add(txt);
+}
+
+
 static void
 _smart_add(Evas_Object *obj)
 {
@@ -2419,17 +3473,25 @@ _smart_add(Evas_Object *obj)
    sd->obj = obj;
    sd->x = sd->y = sd->w = sd->h = 0;
    sd->can_focus = 1;
+   sd->mirrored_auto_mode = EINA_TRUE; /* will follow system locale settings */
    evas_object_smart_data_set(obj, sd);
 }
 
 static Evas_Object *
-_newest_focus_order_get(Evas_Object *obj, unsigned int *newest_focus_order, Eina_Bool can_focus_only)
+_newest_focus_order_get(Evas_Object  *obj,
+                        unsigned int *newest_focus_order,
+                        Eina_Bool     can_focus_only)
 {
    const Eina_List *l;
    Evas_Object *child, *ret, *best;
-   
+
    API_ENTRY return NULL;
-   if (!evas_object_visible_get(obj)) return NULL;
+
+   if (!evas_object_visible_get(obj)
+       || (elm_widget_disabled_get(obj))
+       || (elm_widget_tree_unfocusable_get(obj)))
+     return NULL;
+
    best = NULL;
    if (*newest_focus_order < sd->focus_order)
      {
@@ -2442,17 +3504,22 @@ _newest_focus_order_get(Evas_Object *obj, unsigned int *newest_focus_order, Eina
         if (!ret) continue;
         best = ret;
      }
-   if ((can_focus_only) && (!elm_widget_can_focus_get(best))) return NULL;
+   if (can_focus_only)
+     {
+        if ((!best) || (!elm_widget_can_focus_get(best)))
+          return NULL;
+     }
    return best;
 }
 
 static void
-_if_focused_revert(Evas_Object *obj, Eina_Bool can_focus_only)
+_if_focused_revert(Evas_Object *obj,
+                   Eina_Bool    can_focus_only)
 {
    Evas_Object *top;
    Evas_Object *newest = NULL;
    unsigned int newest_focus_order = 0;
-   
+
    INTERNAL_ENTRY;
 
    if (!sd->focused) return;
@@ -2464,8 +3531,8 @@ _if_focused_revert(Evas_Object *obj, Eina_Bool can_focus_only)
         newest = _newest_focus_order_get(top, &newest_focus_order, can_focus_only);
         if (newest)
           {
-             elm_object_unfocus(newest);
-             elm_object_focus(newest);
+             elm_object_focus_set(newest, EINA_FALSE);
+             elm_object_focus_set(newest, EINA_TRUE);
           }
      }
 }
@@ -2475,51 +3542,66 @@ _smart_del(Evas_Object *obj)
 {
    Evas_Object *sobj;
    Edje_Signal_Data *esd;
+   Elm_Translate_String_Data *ts;
 
    INTERNAL_ENTRY;
 
    if (sd->del_pre_func) sd->del_pre_func(obj);
    if (sd->resize_obj)
      {
-       sobj = sd->resize_obj;
-       sd->resize_obj = NULL;
-       evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
-       evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
-       evas_object_del(sobj);
+        sobj = sd->resize_obj;
+        sd->resize_obj = NULL;
+        evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
+        evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
+        evas_object_del(sobj);
+        sd->resize_obj = NULL;
      }
    if (sd->hover_obj)
      {
-       sobj = sd->hover_obj;
-       sd->hover_obj = NULL;
-       evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
-       evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
-       evas_object_del(sobj);
+        sobj = sd->hover_obj;
+        sd->hover_obj = NULL;
+        evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
+        evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
+        evas_object_del(sobj);
+        sd->hover_obj = NULL;
      }
    EINA_LIST_FREE(sd->subobjs, sobj)
      {
-       evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
-       evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
-       evas_object_del(sobj);
+        evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
+        evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
+        evas_object_del(sobj);
      }
-   eina_list_free(sd->tooltips); /* should be empty anyway */
-   eina_list_free(sd->cursors); /* should be empty anyway */
+   sd->tooltips = eina_list_free(sd->tooltips); /* should be empty anyway */
+   sd->cursors = eina_list_free(sd->cursors); /* should be empty anyway */
    EINA_LIST_FREE(sd->edje_signals, esd)
      {
         eina_stringshare_del(esd->emission);
         eina_stringshare_del(esd->source);
         free(esd);
      }
-   eina_list_free(sd->event_cb); /* should be empty anyway */
+   EINA_LIST_FREE(sd->translate_strings, ts)
+     {
+        eina_stringshare_del(ts->id);
+        eina_stringshare_del(ts->domain);
+        eina_stringshare_del(ts->string);
+        free(ts);
+     }
+   sd->event_cb = eina_list_free(sd->event_cb); /* should be empty anyway */
    if (sd->del_func) sd->del_func(obj);
    if (sd->style) eina_stringshare_del(sd->style);
    if (sd->type) eina_stringshare_del(sd->type);
    if (sd->theme) elm_theme_free(sd->theme);
+   sd->data = NULL;
    _if_focused_revert(obj, EINA_TRUE);
+   if (sd->access_info) eina_stringshare_del(sd->access_info);
    free(sd);
+   evas_object_smart_data_set(obj, NULL);
 }
 
 static void
-_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+_smart_move(Evas_Object *obj,
+            Evas_Coord   x,
+            Evas_Coord   y)
 {
    INTERNAL_ENTRY;
    sd->x = x;
@@ -2528,7 +3610,9 @@ _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
 }
 
 static void
-_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+_smart_resize(Evas_Object *obj,
+              Evas_Coord   w,
+              Evas_Coord   h)
 {
    INTERNAL_ENTRY;
    sd->w = w;
@@ -2558,17 +3642,21 @@ _smart_hide(Evas_Object *obj)
    Eina_List *list;
    Evas_Object *o;
    INTERNAL_ENTRY;
+
    list = evas_object_smart_members_get(obj);
    EINA_LIST_FREE(list, o)
      {
         if (evas_object_data_get(o, "_elm_leaveme")) continue;
         evas_object_hide(o);
      }
-   _if_focused_revert(obj, EINA_TRUE);
 }
 
 static void
-_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
+_smart_color_set(Evas_Object *obj,
+                 int          r,
+                 int          g,
+                 int          b,
+                 int          a)
 {
    Eina_List *list;
    Evas_Object *o;
@@ -2584,7 +3672,8 @@ _smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
 }
 
 static void
-_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
+_smart_clip_set(Evas_Object *obj,
+                Evas_Object *clip)
 {
    Eina_List *list;
    Evas_Object *o;
@@ -2628,9 +3717,9 @@ _smart_init(void)
 {
    if (_e_smart) return;
      {
-       static const Evas_Smart_Class sc =
-         {
-            SMART_NAME,
+        static const Evas_Smart_Class sc =
+          {
+             SMART_NAME,
              EVAS_SMART_CLASS_VERSION,
              _smart_add,
              _smart_del,
@@ -2648,45 +3737,48 @@ _smart_init(void)
              NULL,
              NULL,
              NULL
-         };
-       _e_smart = evas_smart_class_new(&sc);
+          };
+        _e_smart = evas_smart_class_new(&sc);
      }
 }
 
 /* happy debug functions */
 #ifdef ELM_DEBUG
 static void
-_sub_obj_tree_dump(const Evas_Object *o, int lvl)
+_sub_obj_tree_dump(const Evas_Object *obj,
+                   int                lvl)
 {
    int i;
 
-   for (i = 0; i < lvl*3; i++)
+   for (i = 0; i < lvl * 3; i++)
      putchar(' ');
 
-   if (_elm_widget_is(o))
+   if (_elm_widget_is(obj))
      {
         Eina_List *l;
-        Smart_Data *sd = evas_object_smart_data_get(o);
-        printf("+ %s(%p)\n", sd->type, o);
+        INTERNAL_ENTRY;
+        printf("+ %s(%p)\n",
+               sd->type,
+               obj);
         if (sd->resize_obj)
           _sub_obj_tree_dump(sd->resize_obj, lvl + 1);
-        EINA_LIST_FOREACH(sd->subobjs, l, o)
+        EINA_LIST_FOREACH(sd->subobjs, l, obj)
           {
-             if (o != sd->resize_obj)
-               _sub_obj_tree_dump(o, lvl + 1);
+             if (obj != sd->resize_obj)
+               _sub_obj_tree_dump(obj, lvl + 1);
           }
      }
    else
-     printf("+ %s(%p)\n", evas_object_type_get(o), o);
+     printf("+ %s(%p)\n", evas_object_type_get(obj), obj);
 }
 
 static void
-_sub_obj_tree_dot_dump(const Evas_Object *obj, FILE *output)
+_sub_obj_tree_dot_dump(const Evas_Object *obj,
+                       FILE              *output)
 {
    if (!_elm_widget_is(obj))
      return;
-
-   Smart_Data *sd = evas_object_smart_data_get(obj);
+   INTERNAL_ENTRY;
 
    Eina_Bool visible = evas_object_visible_get(obj);
    Eina_Bool disabled = elm_widget_disabled_get(obj);
@@ -2707,26 +3799,25 @@ _sub_obj_tree_dot_dump(const Evas_Object *obj, FILE *output)
      }
 
    fprintf(output, "\"%p\" [ label = \"{%p|%s|%s|visible: %d|"
-           "disabled: %d|focused: %d/%d|focus order:%d}\"", obj, obj, sd->type,
+                   "disabled: %d|focused: %d/%d|focus order:%d}\"", obj, obj, sd->type,
            evas_object_name_get(obj), visible, disabled, focused, can_focus,
            sd->focus_order);
 
    if (focused)
-        fprintf(output, ", style=bold");
+     fprintf(output, ", style=bold");
 
    if (!visible)
-        fprintf(output, ", fontcolor=gray28");
+     fprintf(output, ", fontcolor=gray28");
 
    if ((disabled) || (!visible))
-        fprintf(output, ", color=gray");
-
+     fprintf(output, ", color=gray");
 
    fprintf(output, " ];\n");
 
    Eina_List *l;
    Evas_Object *o;
    EINA_LIST_FOREACH(sd->subobjs, l, o)
-      _sub_obj_tree_dot_dump(o, output);
+     _sub_obj_tree_dot_dump(o, output);
 }
 #endif
 
@@ -2742,12 +3833,13 @@ elm_widget_tree_dump(const Evas_Object *top)
 }
 
 EAPI void
-elm_widget_tree_dot_dump(const Evas_Object *top, FILE *output)
+elm_widget_tree_dot_dump(const Evas_Object *top,
+                         FILE              *output)
 {
 #ifdef ELM_DEBUG
    if (!_elm_widget_is(top))
      return;
-   fprintf(output, "graph "" { node [shape=record];\n");
+   fprintf(output, "graph " " { node [shape=record];\n");
    _sub_obj_tree_dot_dump(top, output);
    fprintf(output, "}\n");
 #else