In case a user sets min-value of the item, the toolbar shouldn't set the min-value...
[framework/uifw/elementary.git] / src / lib / elc_fileselector.c
index 36a9709..148c73d 100644 (file)
@@ -1,29 +1,23 @@
-/**
- * @defgroup Fileselector Fileselector
- *
- * A fileselector is a widget that allows a user to navigate through a
- * tree of files.  It contains buttons for Home(~) and Up(..) as well
- * as cancel/ok buttons to confirm/cancel a selection.  This widget is
- * currently very much in progress.
- *
- * TODO
- * child elements focusing support
- * userdefined icon/label cb
- * show/hide/add buttons ???
- * show/Hide hidden files
- * double click to choose a file
- * multiselection
- * make variable/function names that are sensible
- * Filter support
- *
- * Signals that you can add callbacks for are:
- *
- * "selected" - the user clicks on a file
- * "directory,open" - the list is populated with new content.
- *                    event_info is a directory.
- * "done" - the user clicks on the ok or cancel button
+/*
+ * TODO:
+ *  - child elements focusing support
+ *  - user defined icon/label cb
+ *  - show/hide/add buttons ???
+ *  - show/hide hidden files
+ *  - double click to choose a file
+ *  - multi-selection
+ *  - make variable/function names that are sensible
+ *  - Filter support
  */
 
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#ifdef HAVE_EIO
+# include <Eio.h>
+#endif
+
 #include <Elementary.h>
 #include "elm_priv.h"
 
@@ -31,6 +25,8 @@ typedef struct _Widget_Data Widget_Data;
 
 struct _Widget_Data
 {
+   EINA_REFCOUNT;
+
    Evas_Object *edje;
    Evas_Object *filename_entry;
    Evas_Object *path_entry;
@@ -48,6 +44,10 @@ struct _Widget_Data
 
    const char  *path_separator;
 
+#ifdef HAVE_EIO
+   Eio_File    *current;
+#endif
+
    Elm_Fileselector_Mode mode;
 
    Eina_Bool    only_folder : 1;
@@ -60,8 +60,26 @@ struct sel_data
    const char  *path;
 };
 
-Elm_Genlist_Item_Class list_itc;
-Elm_Gengrid_Item_Class grid_itc;
+typedef struct _Widget_Request Widget_Request;
+struct _Widget_Request
+{
+   Widget_Data *wd;
+   Elm_Object_Item *parent;
+
+   Evas_Object *obj;
+   const char *path;
+   Eina_Bool first : 1;
+};
+
+typedef enum {
+  ELM_DIRECTORY = 0,
+  ELM_FILE_IMAGE = 1,
+  ELM_FILE_UNKNOW = 2,
+  ELM_FILE_LAST
+} Elm_Fileselector_Type;
+
+static Elm_Genlist_Item_Class *list_itc[ELM_FILE_LAST];
+static Elm_Gengrid_Item_Class *grid_itc[ELM_FILE_LAST];
 
 static const char *widtype = NULL;
 
@@ -77,24 +95,20 @@ static const Evas_Smart_Cb_Description _signals[] = {
 
 static void _populate(Evas_Object      *obj,
                       const char       *path,
-                      Elm_Genlist_Item *parent);
+                      Elm_Object_Item  *parent);
 static void _do_anchors(Evas_Object *obj,
                         const char  *path);
 
 /***  ELEMENTARY WIDGET  ***/
 static void
-_del_hook(Evas_Object *obj)
+_widget_data_free(Widget_Data *wd)
 {
-   Widget_Data *wd;
-   void *sd;
-
-   wd = elm_widget_data_get(obj);
-   if (!wd) return;
-
    if (wd->path) eina_stringshare_del(wd->path);
    if (wd->selection) eina_stringshare_del(wd->selection);
    if (wd->sel_idler)
      {
+        void *sd;
+
         sd = ecore_idler_del(wd->sel_idler);
         free(sd);
      }
@@ -102,6 +116,33 @@ _del_hook(Evas_Object *obj)
 }
 
 static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd;
+   int i;
+
+   wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   for (i = 0; i < ELM_FILE_LAST; ++i)
+     {
+        elm_genlist_item_class_free(list_itc[i]);
+        elm_gengrid_item_class_free(grid_itc[i]);
+     }
+
+#ifdef HAVE_EIO
+   if (wd->current)
+     eio_file_cancel(wd->current);
+#endif
+
+   wd->files_list = NULL;
+   wd->files_grid = NULL;
+
+   EINA_REFCOUNT_UNREF(wd)
+     _widget_data_free(wd);
+}
+
+static void
 _sizing_eval(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
@@ -202,48 +243,66 @@ _theme_hook(Evas_Object *obj)
 
 /***  GENLIST "MODEL"  ***/
 static char *
-_itc_label_get(void              *data,
+_itc_text_get(void              *data,
                Evas_Object *obj   __UNUSED__,
                const char *source __UNUSED__)
 {
-   return strdup(ecore_file_file_get(data)); /* NOTE this will be
-                                              * free() by the
-                                              * caller */
+   return elm_entry_utf8_to_markup(ecore_file_file_get(data)); /* NOTE this will be
+                                                                * free() by the
+                                                                * caller */
 }
 
 static Evas_Object *
-_itc_icon_get(void        *data,
-              Evas_Object *obj,
-              const char  *source)
+_itc_icon_folder_get(void        *data __UNUSED__,
+                     Evas_Object *obj,
+                     const char  *source)
 {
    Evas_Object *ic;
 
-   if (!strcmp(source, "elm.swallow.icon"))
-     {
-        const char *filename = data;
+   if (strcmp(source, "elm.swallow.icon")) return NULL;
 
-        ic = elm_icon_add(obj);
-        if (ecore_file_is_dir((char *)data))
-          elm_icon_standard_set(ic, "folder");
-        else
-          {
-             if (evas_object_image_extension_can_load_fast_get(filename))
-               {
-                  elm_icon_standard_set(ic, "image");
-                  elm_icon_thumb_set(ic, filename, NULL);
-               }
-             else
-               {
-                  elm_icon_standard_set(ic, "file");
-               }
-          }
+   ic = elm_icon_add(obj);
+   elm_icon_standard_set(ic, "folder");
 
-        evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL,
-                                         1, 1);
-        evas_object_show(ic);
-        return ic;
-     }
-   return NULL;
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL,
+                                    1, 1);
+   return ic;
+}
+
+static Evas_Object *
+_itc_icon_image_get(void        *data,
+                    Evas_Object *obj,
+                    const char  *source)
+{
+   const char *filename = data;
+   Evas_Object *ic;
+
+   if (strcmp(source, "elm.swallow.icon")) return NULL;
+
+   ic = elm_icon_add(obj);
+   elm_icon_standard_set(ic, "image");
+   elm_icon_thumb_set(ic, filename, NULL);
+
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL,
+                                    1, 1);
+   return ic;
+}
+
+static Evas_Object *
+_itc_icon_file_get(void        *data __UNUSED__,
+                   Evas_Object *obj,
+                   const char  *source)
+{
+   Evas_Object *ic;
+
+   if (strcmp(source, "elm.swallow.icon")) return NULL;
+
+   ic = elm_icon_add(obj);
+   elm_icon_standard_set(ic, "file");
+
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL,
+                                    1, 1);
+   return ic;
 }
 
 static Eina_Bool
@@ -266,8 +325,8 @@ _expand_done(void            *data,
              Evas_Object *obj __UNUSED__,
              void            *event_info)
 {
-   Elm_Genlist_Item *it = event_info;
-   const char *path = elm_genlist_item_data_get(it);
+   Elm_Object_Item *it = event_info;
+   const char *path = elm_object_item_data_get(it);
    _populate(data, path, it);
 }
 
@@ -276,7 +335,7 @@ _contract_done(void *data       __UNUSED__,
                Evas_Object *obj __UNUSED__,
                void            *event_info)
 {
-   Elm_Genlist_Item *it = event_info;
+   Elm_Object_Item *it = event_info;
    elm_genlist_item_subitems_clear(it);
 }
 
@@ -285,8 +344,8 @@ _expand_req(void *data       __UNUSED__,
             Evas_Object *obj __UNUSED__,
             void            *event_info)
 {
-   Elm_Genlist_Item *it = event_info;
-   elm_genlist_item_expanded_set(it, 1);
+   Elm_Object_Item *it = event_info;
+   elm_genlist_item_expanded_set(it, EINA_TRUE);
 }
 
 static void
@@ -294,8 +353,8 @@ _contract_req(void *data       __UNUSED__,
               Evas_Object *obj __UNUSED__,
               void            *event_info)
 {
-   Elm_Genlist_Item *it = event_info;
-   elm_genlist_item_expanded_set(it, 0);
+   Elm_Object_Item *it = event_info;
+   elm_genlist_item_expanded_set(it, EINA_FALSE);
 }
 
 /***  PRIVATES  ***/
@@ -316,7 +375,7 @@ _sel_do(void *data)
         if (wd->expand && wd->mode == ELM_FILESELECTOR_LIST)
           {
              _do_anchors(sd->fs, path);
-             elm_entry_entry_set(wd->filename_entry, "");
+             elm_object_text_set(wd->filename_entry, "");
           }
         else
           {
@@ -329,6 +388,8 @@ _sel_do(void *data)
      }
    else /* navigating through folders only or file is not a dir. */
      {
+        char *s;
+        
         if (wd->expand && wd->mode == ELM_FILESELECTOR_LIST)
           _do_anchors(sd->fs, path);
         else if (wd->only_folder)
@@ -338,8 +399,14 @@ _sel_do(void *data)
              _populate(sd->fs, p, NULL);
              eina_stringshare_del(p);
           }
-        elm_entry_entry_set(wd->filename_entry,
-                                     ecore_file_file_get(path));
+        s = elm_entry_utf8_to_markup(ecore_file_file_get(path));
+        if (s)
+          {
+             elm_object_text_set(wd->filename_entry, s);
+             free(s);
+          }
+        else
+          elm_object_text_set(wd->filename_entry, "");
      }
 
    evas_object_smart_callback_call(sd->fs, SIG_SELECTED, (void *)path);
@@ -359,15 +426,15 @@ _sel(void            *data,
    Widget_Data *wd;
    void *old_sd;
    char *dir;
+   //This event_info could be a list or gengrid item
+   Elm_Object_Item *it = event_info;
 
    wd = elm_widget_data_get(data);
    if (!wd) return;
 
    sd = malloc(sizeof(*sd));
    sd->fs = data;
-   sd->path = wd->mode == ELM_FILESELECTOR_LIST ?
-       elm_genlist_item_data_get(event_info) :
-       elm_gengrid_item_data_get(event_info);
+   sd->path = elm_object_item_data_get(it);
 
    if (!sd->path)
      {
@@ -460,11 +527,15 @@ _do_anchors(Evas_Object *obj,
             const char  *path)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
-   char **tok, buf[PATH_MAX * 3];
+   char **tok, buf[PATH_MAX * 3], *s;
    int i, j;
+   
    if (!wd) return;
+   s = elm_entry_utf8_to_markup(path);
+   if (!s) return;
    buf[0] = '\0';
-   tok = eina_str_split(path, "/", 0);
+   tok = eina_str_split(s, "/", 0);
+   free(s);
    eina_strlcat(buf, "<a href=/>root</a>", sizeof(buf));
    for (i = 0; tok[i]; i++)
      {
@@ -484,21 +555,184 @@ _do_anchors(Evas_Object *obj,
    free(tok[0]);
    free(tok);
 
-   elm_entry_entry_set(wd->path_entry, buf);
+   elm_object_text_set(wd->path_entry, buf);
+}
+
+#ifdef HAVE_EIO
+static Eina_Bool
+_filter_cb(void *data __UNUSED__, Eio_File *handler, const Eina_File_Direct_Info *info)
+{
+   const char *filename;
+
+   if (info->path[info->name_start] == '.')
+     return EINA_FALSE;
+
+   filename = eina_stringshare_add(info->path);
+   eio_file_associate_direct_add(handler, "filename", filename, EINA_FREE_CB(eina_stringshare_del));
+
+   if (info->type == EINA_FILE_DIR)
+     {
+        eio_file_associate_direct_add(handler, "type/grid", grid_itc[ELM_DIRECTORY], NULL);
+        eio_file_associate_direct_add(handler, "type/list", list_itc[ELM_DIRECTORY], NULL);
+     }
+   else
+     {
+        if (evas_object_image_extension_can_load_get(info->path + info->name_start))
+          {
+             eio_file_associate_direct_add(handler, "type/grid", grid_itc[ELM_FILE_IMAGE], NULL);
+             eio_file_associate_direct_add(handler, "type/list", list_itc[ELM_FILE_IMAGE], NULL);
+          }
+        else
+          {
+             eio_file_associate_direct_add(handler, "type/grid", grid_itc[ELM_FILE_UNKNOW], NULL);
+             eio_file_associate_direct_add(handler, "type/list", list_itc[ELM_FILE_UNKNOW], NULL);
+          }
+     }
+
+   return EINA_TRUE;
+}
+
+static int
+_file_grid_cmp(const void *a, const void *b)
+{
+   const Elm_Object_Item *ga = a;
+   const Elm_Object_Item *gb = b;
+   const Elm_Gengrid_Item_Class *ca = elm_gengrid_item_item_class_get(ga);
+   const Elm_Gengrid_Item_Class *cb = elm_gengrid_item_item_class_get(gb);
+
+   if (ca == grid_itc[ELM_DIRECTORY])
+     {
+        if (cb != grid_itc[ELM_DIRECTORY])
+          return -1;
+     }
+   else if (cb == grid_itc[ELM_DIRECTORY])
+     {
+        return 1;
+     }
+
+   return strcoll(elm_object_item_data_get(ga), elm_object_item_data_get(gb));
+}
+
+static int
+_file_list_cmp(const void *a, const void *b)
+{
+   const Elm_Object_Item *la = a;
+   const Elm_Object_Item *lb = b;
+   const Elm_Genlist_Item_Class *ca = elm_genlist_item_item_class_get(la);
+   const Elm_Genlist_Item_Class *cb = elm_genlist_item_item_class_get(lb);
+
+   if (ca == list_itc[ELM_DIRECTORY])
+     {
+        if (cb != list_itc[ELM_DIRECTORY])
+          return -1;
+     }
+   else if (cb == list_itc[ELM_DIRECTORY])
+     {
+        return 1;
+     }
+
+   return strcoll(elm_object_item_data_get(la), elm_object_item_data_get(lb));
+}
+
+static void
+_signal_first(Widget_Request *wr)
+{
+   if (!wr->first) return ;
+   evas_object_smart_callback_call(wr->obj, SIG_DIRECTORY_OPEN, (void *)wr->path);
+   if (!wr->parent)
+     {
+        elm_genlist_clear(wr->wd->files_list);
+        elm_gengrid_clear(wr->wd->files_grid);
+        eina_stringshare_replace(&wr->wd->path, wr->path);
+        _do_anchors(wr->obj, wr->path);
+     }
+
+   if (wr->wd->filename_entry) elm_object_text_set(wr->wd->filename_entry, "");
+
+   wr->first = EINA_FALSE;
+}
+
+static void
+_main_cb(void *data, Eio_File *handler, const Eina_File_Direct_Info *info __UNUSED__)
+{
+   Widget_Request *wr = data;
+
+   if (eio_file_check(handler))
+     return ;
+   if (!wr->wd->files_list || !wr->wd->files_grid || wr->wd->current != handler)
+     {
+        eio_file_cancel(handler);
+        return ;
+     }
+
+   _signal_first(wr);
+
+   if (wr->wd->mode == ELM_FILESELECTOR_LIST)
+     {
+        Eina_Bool is_dir = (eio_file_associate_find(handler, "type/list") == list_itc[ELM_DIRECTORY]);
+
+        elm_genlist_item_sorted_insert(wr->wd->files_list, eio_file_associate_find(handler, "type/list"),
+                                       eina_stringshare_ref(eio_file_associate_find(handler, "filename")),
+                                       wr->parent, wr->wd->expand && is_dir ? ELM_GENLIST_ITEM_TREE : ELM_GENLIST_ITEM_NONE,
+                                       _file_list_cmp, NULL, NULL);
+     }
+   else if (wr->wd->mode == ELM_FILESELECTOR_GRID)
+     elm_gengrid_item_sorted_insert(wr->wd->files_grid, eio_file_associate_find(handler, "type/grid"),
+                                           eina_stringshare_ref(eio_file_associate_find(handler, "filename")),
+                                           _file_grid_cmp, NULL, NULL);
+}
+
+static void
+_widget_request_cleanup(Widget_Request *wr)
+{
+   EINA_REFCOUNT_UNREF(wr->wd)
+     _widget_data_free(wr->wd);
+
+   eina_stringshare_del(wr->path);
+   free(wr);
 }
 
 static void
+_done_cb(void *data, Eio_File *handler __UNUSED__)
+{
+   Widget_Request *wr = data;
+
+   _signal_first(wr);
+
+   wr->wd->current = NULL;
+   _widget_request_cleanup(wr);
+}
+
+static void
+_error_cb(void *data, Eio_File *handler, int error __UNUSED__)
+{
+   Widget_Request *wr = data;
+
+   if (wr->wd->current == handler)
+     wr->wd->current = NULL;
+   _widget_request_cleanup(wr);
+}
+
+#endif
+
+static void
 _populate(Evas_Object      *obj,
           const char       *path,
-          Elm_Genlist_Item *parent)
+          Elm_Object_Item  *parent)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
+#ifdef HAVE_EIO
+   Widget_Request *wr;
+#else
    Eina_File_Direct_Info *file;
    Eina_Iterator *it;
    const char *real;
    Eina_List *files = NULL, *dirs = NULL;
+#endif
 
-   if ((!wd) || (!ecore_file_is_dir(path))) return;
+   if (!wd) return;
+#ifndef HAVE_EIO
+   if (!ecore_file_is_dir(path)) return ;
    it = eina_file_stat_ls(path);
    if (!it) return ;
    evas_object_smart_callback_call(obj, SIG_DIRECTORY_OPEN, (void *)path);
@@ -510,7 +744,7 @@ _populate(Evas_Object      *obj,
         _do_anchors(obj, path);
      }
 
-   if (wd->filename_entry) elm_entry_entry_set(wd->filename_entry, "");
+   if (wd->filename_entry) elm_object_text_set(wd->filename_entry, "");
    EINA_ITERATOR_FOREACH(it, file)
      {
         const char *filename;
@@ -532,52 +766,70 @@ _populate(Evas_Object      *obj,
    EINA_LIST_FREE(dirs, real)
      {
         if (wd->mode == ELM_FILESELECTOR_LIST)
-          elm_genlist_item_append(wd->files_list, &list_itc,
+          elm_genlist_item_append(wd->files_list, list_itc[ELM_DIRECTORY],
                                   real, /* item data */
                                   parent,
-                                  wd->expand ? ELM_GENLIST_ITEM_SUBITEMS :
+                                  wd->expand ? ELM_GENLIST_ITEM_TREE :
                                   ELM_GENLIST_ITEM_NONE,
                                   NULL, NULL);
         else if (wd->mode == ELM_FILESELECTOR_GRID)
-          elm_gengrid_item_append(wd->files_grid, &grid_itc,
+          elm_gengrid_item_append(wd->files_grid, grid_itc[ELM_DIRECTORY],
                                   real, /* item data */
                                   NULL, NULL);
      }
 
    EINA_LIST_FREE(files, real)
      {
+        Elm_Fileselector_Type type = evas_object_image_extension_can_load_fast_get(real) ?
+          ELM_FILE_IMAGE : ELM_FILE_UNKNOW;
+
         if (wd->mode == ELM_FILESELECTOR_LIST)
-          elm_genlist_item_append(wd->files_list, &list_itc,
+          elm_genlist_item_append(wd->files_list, list_itc[type],
                                   real, /* item data */
                                   parent, ELM_GENLIST_ITEM_NONE,
                                   NULL, NULL);
         else if (wd->mode == ELM_FILESELECTOR_GRID)
-          elm_gengrid_item_append(wd->files_grid, &grid_itc,
+          elm_gengrid_item_append(wd->files_grid, grid_itc[type],
                                   real, /* item data */
                                   NULL, NULL);
      }
+#else
+   if (wd->expand && wd->current) return ;
+   if (wd->current)
+     eio_file_cancel(wd->current);
+   wr = malloc(sizeof (Widget_Request));
+   if (!wr) return ;
+   wr->wd = wd;
+   EINA_REFCOUNT_REF(wr->wd);
+   wr->parent = parent; /* FIXME: should we refcount the parent ? */
+   wr->obj = obj;
+   wr->path = eina_stringshare_add(path);
+   wr->first = EINA_TRUE;
+
+   wd->current = eio_file_stat_ls(path,
+                                  _filter_cb,
+                                  _main_cb,
+                                  _done_cb,
+                                  _error_cb,
+                                  wr);
+#endif
 }
 
 /***  API  ***/
 
-/**
- * Add a new Fileselector object
- *
- * @param parent The parent object
- * @return The new object or NULL if it cannot be created
- *
- * @ingroup Fileselector
- */
 EAPI Evas_Object *
 elm_fileselector_add(Evas_Object *parent)
 {
    Evas *e;
    Evas_Object *obj, *ic, *bt, *li, *en, *grid;
    Widget_Data *wd;
+   unsigned int i;
    int s;
 
    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
 
+   EINA_REFCOUNT_INIT(wd);
+
    ELM_SET_WIDTYPE(widtype, "fileselector");
    elm_widget_type_set(obj, "fileselector");
    elm_widget_sub_object_add(parent, obj);
@@ -598,8 +850,8 @@ elm_fileselector_add(Evas_Object *parent)
    evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
    bt = elm_button_add(parent);
    elm_widget_mirrored_automatic_set(bt, EINA_FALSE);
-   elm_button_icon_set(bt, ic);
-   elm_button_label_set(bt, E_("Up"));
+   elm_object_part_content_set(bt, "icon", ic);
+   elm_object_domain_translatable_text_set(bt, PACKAGE, N_("Up"));
    evas_object_size_hint_align_set(bt, 0.0, 0.0);
 
    evas_object_smart_callback_add(bt, "clicked", _up, obj);
@@ -613,8 +865,8 @@ elm_fileselector_add(Evas_Object *parent)
    evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
    bt = elm_button_add(parent);
    elm_widget_mirrored_automatic_set(bt, EINA_FALSE);
-   elm_button_icon_set(bt, ic);
-   elm_button_label_set(bt, E_("Home"));
+   elm_object_part_content_set(bt, "icon", ic);
+   elm_object_domain_translatable_text_set(bt, PACKAGE, N_("Home"));
    evas_object_size_hint_align_set(bt, 0.0, 0.0);
 
    evas_object_smart_callback_add(bt, "clicked", _home, obj);
@@ -622,11 +874,23 @@ elm_fileselector_add(Evas_Object *parent)
    elm_widget_sub_object_add(obj, bt);
    wd->home_button = bt;
 
-   list_itc.item_style = grid_itc.item_style = "default";
-   list_itc.func.label_get = grid_itc.func.label_get = _itc_label_get;
-   list_itc.func.icon_get = grid_itc.func.icon_get = _itc_icon_get;
-   list_itc.func.state_get = grid_itc.func.state_get = _itc_state_get;
-   list_itc.func.del = grid_itc.func.del = _itc_del;
+   for (i = 0; i < ELM_FILE_LAST; ++i)
+     {
+        list_itc[i] = elm_genlist_item_class_new();
+        grid_itc[i] = elm_gengrid_item_class_new();
+
+        list_itc[i]->item_style = "default";
+        list_itc[i]->func.text_get = grid_itc[i]->func.text_get = _itc_text_get;
+        list_itc[i]->func.state_get = grid_itc[i]->func.state_get = _itc_state_get;
+        list_itc[i]->func.del = grid_itc[i]->func.del = _itc_del;
+     }
+
+   list_itc[ELM_DIRECTORY]->func.content_get =
+     grid_itc[ELM_DIRECTORY]->func.content_get = _itc_icon_folder_get;
+   list_itc[ELM_FILE_IMAGE]->func.content_get =
+     grid_itc[ELM_FILE_IMAGE]->func.content_get = _itc_icon_image_get;
+   list_itc[ELM_FILE_UNKNOW]->func.content_get =
+     grid_itc[ELM_FILE_UNKNOW]->func.content_get = _itc_icon_file_get;
 
    li = elm_genlist_add(parent);
    elm_widget_mirrored_automatic_set(li, EINA_FALSE);
@@ -639,7 +903,8 @@ elm_fileselector_add(Evas_Object *parent)
    evas_object_size_hint_align_set(grid, EVAS_HINT_FILL, EVAS_HINT_FILL);
    evas_object_size_hint_weight_set(grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
 
-   s = elm_finger_size_get() * 2;
+   // XXX: will fail for dynamic finger size changing
+   s = _elm_config->finger_size * 2;
    elm_gengrid_item_size_set(grid, s, s);
    elm_gengrid_align_set(grid, 0.0, 0.0);
 
@@ -693,15 +958,6 @@ elm_fileselector_add(Evas_Object *parent)
    return obj;
 }
 
-/**
- * This enables/disables the file name entry box where the user can
- * type in a name for the file to be saved as.
- *
- * @param obj The fileselector object
- * @param is_save If true, the fileselector is a save dialog
- *
- * @ingroup Fileselector
- */
 EAPI void
 elm_fileselector_is_save_set(Evas_Object *obj,
                              Eina_Bool    is_save)
@@ -718,32 +974,15 @@ elm_fileselector_is_save_set(Evas_Object *obj,
      edje_object_signal_emit(wd->edje, "elm,state,save,off", "elm");
 }
 
-/**
- * This returns whether the fileselector is a "save" type fileselector
- *
- * @param obj The fileselector object
- * @return If true, the fileselector is a save type.
- *
- * @ingroup Fileselector
- */
 EAPI Eina_Bool
 elm_fileselector_is_save_get(const Evas_Object *obj)
 {
    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return EINA_FALSE;
-   return elm_object_disabled_get(wd->filename_entry);
+   return !elm_object_disabled_get(wd->filename_entry);
 }
 
-/**
- * This enables/disables folder-only view in the fileselector.
- *
- * @param obj The fileselector object
- * @param only If true, the fileselector will only display directories.
- * If false, files are displayed also.
- *
- * @ingroup Fileselector
- */
 EAPI void
 elm_fileselector_folder_only_set(Evas_Object *obj,
                                  Eina_Bool    only)
@@ -756,15 +995,6 @@ elm_fileselector_folder_only_set(Evas_Object *obj,
    if (wd->path) _populate(obj, wd->path, NULL);
 }
 
-/**
- * This gets the state of file display in the fileselector.
- *
- * @param obj The fileselector object
- * @return If true, files are not being shown in the fileselector.
- * If false, files are being shown.
- *
- * @ingroup Fileselector
- */
 EAPI Eina_Bool
 elm_fileselector_folder_only_get(const Evas_Object *obj)
 {
@@ -774,15 +1004,6 @@ elm_fileselector_folder_only_get(const Evas_Object *obj)
    return wd->only_folder;
 }
 
-/**
- * This enables/disables the ok,cancel buttons.
- *
- * @param obj The fileselector object
- * @param only If true, a box containing ok and cancel buttons is created.
- * If false, the box and the buttons are destroyed.
- *
- * @ingroup Fileselector
- */
 EAPI void
 elm_fileselector_buttons_ok_cancel_set(Evas_Object *obj,
                                        Eina_Bool    visible)
@@ -797,7 +1018,7 @@ elm_fileselector_buttons_ok_cancel_set(Evas_Object *obj,
         // cancel btn
         bt = elm_button_add(obj);
         elm_widget_mirrored_automatic_set(bt, EINA_FALSE);
-        elm_button_label_set(bt, E_("Cancel"));
+        elm_object_domain_translatable_text_set(bt, PACKAGE, N_("Cancel"));
 
         evas_object_smart_callback_add(bt, "clicked", _canc, obj);
 
@@ -807,7 +1028,7 @@ elm_fileselector_buttons_ok_cancel_set(Evas_Object *obj,
         // ok btn
         bt = elm_button_add(obj);
         elm_widget_mirrored_automatic_set(bt, EINA_FALSE);
-        elm_button_label_set(bt, E_("OK"));
+        elm_object_domain_translatable_text_set(bt, PACKAGE, N_("OK"));
 
         evas_object_smart_callback_add(bt, "clicked", _ok, obj);
 
@@ -825,15 +1046,6 @@ elm_fileselector_buttons_ok_cancel_set(Evas_Object *obj,
      }
 }
 
-/**
- * This gets the state of the box containing ok and cancel buttons.
- *
- * @param obj The fileselector object
- * @return If true, the box exists.
- * If false, the box does not exist.
- *
- * @ingroup Fileselector
- */
 EAPI Eina_Bool
 elm_fileselector_buttons_ok_cancel_get(const Evas_Object *obj)
 {
@@ -843,21 +1055,6 @@ elm_fileselector_buttons_ok_cancel_get(const Evas_Object *obj)
    return wd->ok_button ? EINA_TRUE : EINA_FALSE;
 }
 
-/**
- * This enables a tree view in the fileselector, <b>if in @c
- * ELM_FILESELECTOR_LIST mode</b>. If it's in other mode, the changes
- * made by this function will only be visible when one switches back
- * to list mode.
- *
- * @param obj The fileselector object
- * @param expand If true, tree view is enabled.
- * If false, tree view is disabled.
- *
- * In a tree view, arrows are created on the sides of directories,
- * allowing them to expand in place.
- *
- * @ingroup Fileselector
- */
 EAPI void
 elm_fileselector_expandable_set(Evas_Object *obj,
                                 Eina_Bool    expand)
@@ -873,15 +1070,6 @@ elm_fileselector_expandable_set(Evas_Object *obj,
    if (wd->path) _populate(obj, wd->path, NULL);
 }
 
-/**
- * This gets the state of tree view in the fileselector.
- *
- * @param obj The fileselector object
- * @return If true, tree view is enabled and folders will be expandable.
- * If false, tree view is disabled.
- *
- * @ingroup Fileselector
- */
 EAPI Eina_Bool
 elm_fileselector_expandable_get(const Evas_Object *obj)
 {
@@ -891,30 +1079,17 @@ elm_fileselector_expandable_get(const Evas_Object *obj)
    return wd->expand;
 }
 
-/**
- * This sets the path that the fileselector will display.
- *
- * @param obj The fileselector object
- * @param path The path of the fileselector
- *
- * @ingroup Fileselector
- */
 EAPI void
 elm_fileselector_path_set(Evas_Object *obj,
-                          const char  *path)
+                          const char  *_path)
 {
    ELM_CHECK_WIDTYPE(obj, widtype);
+   char *path;
+   path = ecore_file_realpath(_path);
    _populate(obj, path, NULL);
+   free(path);
 }
 
-/**
- * This gets the path that the fileselector displays.
- *
- * @param obj The fileselector object
- * @return The path that the fileselector is displaying
- *
- * @ingroup Fileselector
- */
 EAPI const char *
 elm_fileselector_path_get(const Evas_Object *obj)
 {
@@ -924,22 +1099,6 @@ elm_fileselector_path_get(const Evas_Object *obj)
    return wd->path;
 }
 
-/**
- * This sets the mode in which the fileselector will display files.
- *
- * @param obj The fileselector object
-
- * @param mode The mode of the fileselector, being it one of @c
- * ELM_FILESELECTOR_LIST (default) or @c ELM_FILESELECTOR_GRID. The
- * first one, naturally, will display the files in a list. By using
- * elm_fileselector_expandable_set(), the user will trigger a tree
- * view for that list. The latter will make the widget to display its
- * entries in a grid form.
- *
- * @see elm_fileselector_expandable_set().
- *
- * @ingroup Fileselector
- */
 EAPI void
 elm_fileselector_mode_set(Evas_Object          *obj,
                           Elm_Fileselector_Mode mode)
@@ -979,14 +1138,6 @@ elm_fileselector_mode_set(Evas_Object          *obj,
    _populate(obj, wd->path, NULL);
 }
 
-/**
- * This gets the mode in which the fileselector is displaying files.
- *
- * @param obj The fileselector object
- * @return The mode in which the fileselector is at
- *
- * @ingroup Fileselector
- */
 EAPI Elm_Fileselector_Mode
 elm_fileselector_mode_get(const Evas_Object *obj)
 {
@@ -998,14 +1149,6 @@ elm_fileselector_mode_get(const Evas_Object *obj)
    return wd->mode;
 }
 
-/**
- * This gets the currently selected path in the file selector.
- *
- * @param obj The file selector object
- * @return The absolute path of the selected object in the fileselector
- *
- * @ingroup Fileselector
- */
 EAPI const char *
 elm_fileselector_selected_get(const Evas_Object *obj)
 {
@@ -1013,70 +1156,94 @@ elm_fileselector_selected_get(const Evas_Object *obj)
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return NULL;
 
+   if (!wd->path) return NULL;
+   
    if (wd->filename_entry)
      {
         const char *name;
         char buf[PATH_MAX];
+        char *dir, *s;
 
-        name = elm_entry_entry_get(wd->filename_entry);
-        snprintf(buf, sizeof(buf), "%s/%s",
-                 wd->only_folder ? ecore_file_dir_get(wd->path) : wd->path,
-                 name);
-        eina_stringshare_replace(&wd->selection, buf);
+        dir = wd->only_folder ? ecore_file_dir_get(wd->path) : strdup(wd->path);
+        name = elm_object_text_get(wd->filename_entry);
+        if (name)
+          {
+             s = elm_entry_markup_to_utf8(name);
+             if (s)
+               {
+                  snprintf(buf, sizeof(buf), "%s/%s", dir, s);
+                  free(s);
+               }
+             else
+               snprintf(buf, sizeof(buf), "%s", dir);
+          }
+        else
+          {
+             snprintf(buf, sizeof(buf), "%s", dir);
+          }
+        if (wd->only_folder && !ecore_file_is_dir(buf))
+          eina_stringshare_replace(&wd->selection, ecore_file_dir_get(buf));
+        else
+          eina_stringshare_replace(&wd->selection, buf);
+        if (dir) free(dir);
         return wd->selection;
      }
 
    if (wd->mode == ELM_FILESELECTOR_LIST)
      {
-        Elm_Genlist_Item *it;
-        it = elm_genlist_selected_item_get(wd->files_list);
-        if (it) return elm_genlist_item_data_get(it);
+        Elm_Object_Item *gl_it = elm_genlist_selected_item_get(wd->files_list);
+        if (gl_it) return elm_object_item_data_get(gl_it);
      }
    else
      {
-        Elm_Gengrid_Item *it;
-        it = elm_gengrid_selected_item_get(wd->files_grid);
-        if (it) return elm_gengrid_item_data_get(it);
+        Elm_Object_Item *gg_it = elm_gengrid_selected_item_get(wd->files_grid);
+        if (gg_it) return elm_object_item_data_get(gg_it);
      }
 
    return wd->path;
 }
 
-/**
- * This sets the currently selected path in the file selector.
- *
- * @param obj The file selector object
- * @param path The path to a file or directory
- * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. The
- * latter case occurs if the directory or file pointed to do not
- * exist.
- *
- * @ingroup Fileselector
- */
 EAPI Eina_Bool
 elm_fileselector_selected_set(Evas_Object *obj,
-                              const char  *path)
+                              const char  *_path)
 {
    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return EINA_FALSE;
 
+   Eina_Bool ret = EINA_TRUE;
+   char *path;
+   path = ecore_file_realpath(_path);
+
    if (ecore_file_is_dir(path))
      _populate(obj, path, NULL);
    else
      {
         if (!ecore_file_exists(path))
-          return EINA_FALSE;
+          {
+             ret = EINA_FALSE;
+             goto clean_up;
+          }
 
         _populate(obj, ecore_file_dir_get(path), NULL);
         if (wd->filename_entry)
           {
-             elm_entry_entry_set(wd->filename_entry,
-                                          ecore_file_file_get(path));
+             char *s;
+             
+             s = elm_entry_utf8_to_markup(ecore_file_file_get(path));
+             if (s)
+               {
+                  elm_object_text_set(wd->filename_entry, s);
+                  free(s);
+               }
+             else
+               elm_object_text_set(wd->filename_entry, "");
              eina_stringshare_replace(&wd->selection, path);
           }
      }
 
-   return EINA_TRUE;
+clean_up:
+   free(path);
+   return ret;
 }