3d, gesturelayer, index, naviframe, transit, fileselector, frame, glview, layout...
[framework/uifw/elementary.git] / src / lib / elc_fileselector.c
index 598df2b..565ddea 100644 (file)
@@ -64,7 +64,7 @@ typedef struct _Widget_Request Widget_Request;
 struct _Widget_Request
 {
    Widget_Data *wd;
-   Elm_Genlist_Item *parent;
+   Elm_Object_Item *parent;
 
    Evas_Object *obj;
    const char *path;
@@ -78,16 +78,8 @@ typedef enum {
   ELM_FILE_LAST
 } Elm_Fileselector_Type;
 
-static Elm_Genlist_Item_Class list_itc[ELM_FILE_LAST] = {
-  { "default", { NULL, NULL, NULL, NULL, NULL }, NULL },
-  { "default", { NULL, NULL, NULL, NULL, NULL }, NULL },
-  { "default", { NULL, NULL, NULL, NULL, NULL }, NULL }
-};
-static Elm_Gengrid_Item_Class grid_itc[ELM_FILE_LAST] = {
-  { "default", { NULL, NULL, NULL, NULL } },
-  { "default", { NULL, NULL, NULL, NULL } },
-  { "default", { NULL, NULL, NULL, NULL } }
-};
+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;
 
@@ -103,7 +95,7 @@ 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);
 
@@ -127,10 +119,17 @@ 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);
@@ -244,7 +243,7 @@ _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__)
 {
@@ -326,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);
 }
 
@@ -336,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);
 }
 
@@ -345,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
@@ -354,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  ***/
@@ -376,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
           {
@@ -398,7 +397,7 @@ _sel_do(void *data)
              _populate(sd->fs, p, NULL);
              eina_stringshare_del(p);
           }
-        elm_entry_entry_set(wd->filename_entry,
+        elm_object_text_set(wd->filename_entry,
                                      ecore_file_file_get(path));
      }
 
@@ -419,15 +418,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)
      {
@@ -476,10 +475,7 @@ _home(void            *data,
       void *event_info __UNUSED__)
 {
    Evas_Object *fs = data;
-   const char *path = getenv("HOME");
-   if (!path) path = "./";
-   _populate(fs, path, NULL);
-
+   _populate(fs, getenv("HOME"), NULL);
 }
 
 static void
@@ -547,7 +543,7 @@ _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
@@ -564,20 +560,20 @@ _filter_cb(void *data __UNUSED__, Eio_File *handler, const Eina_File_Direct_Info
 
    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);
+        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);
+             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);
+             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);
           }
      }
 
@@ -587,35 +583,43 @@ _filter_cb(void *data __UNUSED__, Eio_File *handler, const Eina_File_Direct_Info
 static int
 _file_grid_cmp(const void *a, const void *b)
 {
-   const Elm_Gengrid_Item *ga = a;
-   const Elm_Gengrid_Item *gb = 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 (ca == grid_itc[ELM_DIRECTORY])
      {
-        if (cb != &grid_itc[ELM_DIRECTORY])
+        if (cb != grid_itc[ELM_DIRECTORY])
           return -1;
      }
+   else if (cb == grid_itc[ELM_DIRECTORY])
+     {
+        return 1;
+     }
 
-   return strcoll(elm_gengrid_item_data_get(ga), elm_gengrid_item_data_get(gb));
+   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_Genlist_Item *la = a;
-   const Elm_Genlist_Item *lb = 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 (ca == list_itc[ELM_DIRECTORY])
      {
-        if (cb != &list_itc[ELM_DIRECTORY])
+        if (cb != list_itc[ELM_DIRECTORY])
           return -1;
      }
+   else if (cb == list_itc[ELM_DIRECTORY])
+     {
+        return 1;
+     }
 
-   return strcoll(elm_genlist_item_data_get(la), elm_genlist_item_data_get(lb));
+   return strcoll(elm_object_item_data_get(la), elm_object_item_data_get(lb));
 }
 
 static void
@@ -631,7 +635,7 @@ _signal_first(Widget_Request *wr)
         _do_anchors(wr->obj, wr->path);
      }
 
-   if (wr->wd->filename_entry) elm_entry_entry_set(wr->wd->filename_entry, "");
+   if (wr->wd->filename_entry) elm_object_text_set(wr->wd->filename_entry, "");
 
    wr->first = EINA_FALSE;
 }
@@ -652,11 +656,16 @@ _main_cb(void *data, Eio_File *handler, const Eina_File_Direct_Info *info __UNUS
    _signal_first(wr);
 
    if (wr->wd->mode == ELM_FILESELECTOR_LIST)
-     elm_genlist_item_direct_sorted_insert(wr->wd->files_list, eio_file_associate_find(handler, "type/list"),
-                                           eina_stringshare_ref(eio_file_associate_find(handler, "filename")),
-                                           wr->parent, ELM_GENLIST_ITEM_NONE, _file_list_cmp, NULL, NULL);
+     {
+        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_direct_sorted_insert(wr->wd->files_grid, eio_file_associate_find(handler, "type/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);
 }
@@ -678,9 +687,7 @@ _done_cb(void *data, Eio_File *handler __UNUSED__)
 
    _signal_first(wr);
 
-#ifdef HAVE_EIO
    wr->wd->current = NULL;
-#endif
    _widget_request_cleanup(wr);
 }
 
@@ -689,10 +696,8 @@ _error_cb(void *data, Eio_File *handler, int error __UNUSED__)
 {
    Widget_Request *wr = data;
 
-#ifdef HAVE_EIO
    if (wr->wd->current == handler)
      wr->wd->current = NULL;
-#endif
    _widget_request_cleanup(wr);
 }
 
@@ -701,7 +706,7 @@ _error_cb(void *data, Eio_File *handler, int error __UNUSED__)
 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
@@ -727,7 +732,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;
@@ -749,14 +754,14 @@ _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_DIRECTORY],
+          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_DIRECTORY],
+          elm_gengrid_item_append(wd->files_grid, grid_itc[ELM_DIRECTORY],
                                   real, /* item data */
                                   NULL, NULL);
      }
@@ -767,16 +772,17 @@ _populate(Evas_Object      *obj,
           ELM_FILE_IMAGE : ELM_FILE_UNKNOW;
 
         if (wd->mode == ELM_FILESELECTOR_LIST)
-          elm_genlist_item_append(wd->files_list, &list_itc[type],
+          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[type],
+          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));
@@ -832,7 +838,7 @@ 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_object_content_set(bt, ic);
+   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);
 
@@ -847,7 +853,7 @@ 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_object_content_set(bt, ic);
+   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);
 
@@ -856,17 +862,24 @@ elm_fileselector_add(Evas_Object *parent)
    elm_widget_sub_object_add(obj, bt);
    wd->home_button = bt;
 
-   list_itc[ELM_DIRECTORY].func.icon_get = grid_itc[ELM_DIRECTORY].func.icon_get = _itc_icon_folder_get;
-   list_itc[ELM_FILE_IMAGE].func.icon_get = grid_itc[ELM_FILE_IMAGE].func.icon_get = _itc_icon_image_get;
-   list_itc[ELM_FILE_UNKNOW].func.icon_get = grid_itc[ELM_FILE_UNKNOW].func.icon_get = _itc_icon_file_get;
-
    for (i = 0; i < ELM_FILE_LAST; ++i)
      {
-        list_itc[i].func.label_get = grid_itc[i].func.label_get = _itc_label_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[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);
    evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL);
@@ -878,7 +891,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);
 
@@ -954,7 +968,7 @@ 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);
 }
 
 EAPI void
@@ -1055,10 +1069,13 @@ elm_fileselector_expandable_get(const Evas_Object *obj)
 
 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);
 }
 
 EAPI const char *
@@ -1134,25 +1151,26 @@ elm_fileselector_selected_get(const Evas_Object *obj)
         char *dir;
 
         dir = wd->only_folder ? ecore_file_dir_get(wd->path) : strdup(wd->path);
-        name = elm_entry_entry_get(wd->filename_entry);
+        name = elm_object_text_get(wd->filename_entry);
         snprintf(buf, sizeof(buf), "%s/%s",
                  dir, name);
-        eina_stringshare_replace(&wd->selection, buf);
+        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;
@@ -1160,28 +1178,37 @@ elm_fileselector_selected_get(const Evas_Object *obj)
 
 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,
+             elm_object_text_set(wd->filename_entry,
                                           ecore_file_file_get(path));
              eina_stringshare_replace(&wd->selection, path);
           }
      }
 
-   return EINA_TRUE;
+clean_up:
+   free(path);
+   return ret;
 }