elementary: use Eio when available for fileselector.

SVN revision: 60692
This commit is contained in:
Cedric BAIL 2011-06-25 23:39:43 +00:00
parent 74dd82cf60
commit 452e2d379f
5 changed files with 311 additions and 65 deletions

View File

@ -212,7 +212,14 @@ PKG_CHECK_MODULES([ELEMENTARY],
]
)
PKG_CHECK_MODULES([EIO],[eio], [have_eio="yes"], [have_eio="no"])
PKG_CHECK_MODULES([EIO],
[eio],
[
have_eio="yes"
AC_DEFINE(HAVE_EIO, 1, [Use EIO for asynchronous file access])
requirement_elm="eio ${requirement_elm}"
],
[have_eio="no"])
AM_CONDITIONAL([HAVE_EIO], [test "x${have_eio}" = "xyes"])

View File

@ -17,11 +17,8 @@ AM_CPPFLAGS = \
@ELEMENTARY_EDBUS_CFLAGS@ \
@ELEMENTARY_EFREET_CFLAGS@ \
@ELEMENTARY_EWEATHER_CFLAGS@ \
@ELEMENTARY_ETHUMB_CFLAGS@
if HAVE_EIO
AM_CPPFLAGS += -DHAVE_EIO @EIO_CFLAGS@
endif
@ELEMENTARY_ETHUMB_CFLAGS@ \
@EIO_CFLAGS@
if ELEMENTARY_WINDOWS_BUILD
AM_CPPFLAGS += -DELEMENTARY_BUILD
@ -118,10 +115,8 @@ elementary_test_LDADD = $(top_builddir)/src/lib/libelementary.la \
@ELEMENTARY_EDBUS_LIBS@ \
@ELEMENTARY_EFREET_LIBS@ \
@ELEMENTARY_LIBS@ \
@EIO_LIBS@ \
@my_libs@
if HAVE_EIO
elementary_test_LDADD += @EIO_LIBS@
endif
elementary_test_LDFLAGS =
elementary_config_SOURCES = \
@ -160,11 +155,8 @@ elementary_testqldir = $(libdir)
elementary_testql_LTLIBRARIES = elementary_testql.la
elementary_testql_la_SOURCES = $(elementary_test_SOURCES)
elementary_testql_la_LIBADD = $(top_builddir)/src/lib/libelementary.la \
@ELEMENTARY_EWEATHER_LIBS@
if HAVE_EIO
elementary_testql_la_LIBADD += @EIO_LIBS@
endif
@ELEMENTARY_EWEATHER_LIBS@ \
@EIO_LIBS@
elementary_testql_la_CFLAGS =
elementary_testql_la_LDFLAGS = -module -avoid-version -no-undefined
@ -174,12 +166,9 @@ elementary_testql_LDADD = $(top_builddir)/src/lib/libelementary.la \
@ELEMENTARY_EDBUS_LIBS@ \
@ELEMENTARY_EFREET_LIBS@ \
@ELEMENTARY_LIBS@ \
@EIO_LIBS@
@my_libs@
if HAVE_EIO
elementary_testql_LDADD += @EIO_LIBS@
endif
elementary_testql_CFLAGS = -DELM_LIB_QUICKLAUNCH=1
elementary_testql_LDFLAGS =
endif

View File

@ -2191,6 +2191,8 @@ extern "C" {
EAPI Evas_Object *elm_gengrid_item_gengrid_get(const Elm_Gengrid_Item *item) EINA_ARG_NONNULL(1);
EAPI void elm_gengrid_item_del(Elm_Gengrid_Item *item) EINA_ARG_NONNULL(1);
EAPI void elm_gengrid_item_update(Elm_Gengrid_Item *item) EINA_ARG_NONNULL(1);
EAPI const Elm_Gengrid_Item_Class *elm_gengrid_item_item_class_get(const Elm_Gengrid_Item *item) EINA_ARG_NONNULL(1);
EAPI void elm_gengrid_item_item_class_set(Elm_Gengrid_Item *item, const Elm_Gengrid_Item_Class *gic) EINA_ARG_NONNULL(1, 2);
EAPI void *elm_gengrid_item_data_get(const Elm_Gengrid_Item *item) EINA_ARG_NONNULL(1);
EAPI void elm_gengrid_item_data_set(Elm_Gengrid_Item *item, const void *data) EINA_ARG_NONNULL(1);
EAPI void elm_gengrid_item_pos_get(const Elm_Gengrid_Item *item, unsigned int *x, unsigned int *y) EINA_ARG_NONNULL(1);
@ -2224,6 +2226,7 @@ extern "C" {
EAPI Elm_Gengrid_Item *elm_gengrid_item_insert_before(Evas_Object *obj, const Elm_Gengrid_Item_Class *gic, const void *data, Elm_Gengrid_Item *relative, Evas_Smart_Cb func, const void *func_data) EINA_ARG_NONNULL(1);
EAPI Elm_Gengrid_Item *elm_gengrid_item_insert_after(Evas_Object *obj, const Elm_Gengrid_Item_Class *gic, const void *data, Elm_Gengrid_Item *relative, Evas_Smart_Cb func, const void *func_data) EINA_ARG_NONNULL(1);
EAPI Elm_Gengrid_Item *elm_gengrid_item_sorted_insert(Evas_Object *obj, const Elm_Gengrid_Item_Class *gic, const void *data, Eina_Compare_Cb comp, Evas_Smart_Cb func, const void *func_data) EINA_ARG_NONNULL(1);
EAPI Elm_Gengrid_Item *elm_gengrid_item_direct_sorted_insert(Evas_Object *obj, const Elm_Gengrid_Item_Class *gic, const void *data, Eina_Compare_Cb comp, Evas_Smart_Cb func, const void *func_data);
/* smart callbacks called:
*
* selected - User has selected an item.
@ -3638,7 +3641,8 @@ extern "C" {
EAPI Elm_Genlist_Item *elm_genlist_item_prepend(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Genlist_Item *parent, Elm_Genlist_Item_Flags flags, Evas_Smart_Cb func, const void *func_data) EINA_ARG_NONNULL(1);
EAPI Elm_Genlist_Item *elm_genlist_item_insert_before(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Genlist_Item *parent, Elm_Genlist_Item *before, Elm_Genlist_Item_Flags flags, Evas_Smart_Cb func, const void *func_data) EINA_ARG_NONNULL(1, 5);
EAPI Elm_Genlist_Item *elm_genlist_item_insert_after(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Genlist_Item *parent, Elm_Genlist_Item *after, Elm_Genlist_Item_Flags flags, Evas_Smart_Cb func, const void *func_data) EINA_ARG_NONNULL(1, 5);
EAPI Elm_Genlist_Item *elm_genlist_item_sorted_insert(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Genlist_Item *parent, Elm_Genlist_Item_Flags flags, Eina_Compare_Cb comp, Evas_Smart_Cb func,const void *func_data);
EAPI Elm_Genlist_Item *elm_genlist_item_sorted_insert(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Genlist_Item *parent, Elm_Genlist_Item_Flags flags, Eina_Compare_Cb comp, Evas_Smart_Cb func,const void *func_data);
EAPI Elm_Genlist_Item *elm_genlist_item_direct_sorted_insert(Evas_Object *obj, const Elm_Genlist_Item_Class *itc, const void *data, Elm_Genlist_Item *parent, Elm_Genlist_Item_Flags flags, Eina_Compare_Cb comp, Evas_Smart_Cb func, const void *func_data);
/* operations to retrieve existing items */
EAPI Elm_Genlist_Item *elm_genlist_selected_item_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
EAPI const Eina_List *elm_genlist_selected_items_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
@ -3682,6 +3686,7 @@ EAPI Elm_Genlist_Item *elm_genlist_item_sorted_insert(Evas_Object *obj, const El
EAPI const Evas_Object *elm_genlist_item_object_get(const Elm_Genlist_Item *it) EINA_ARG_NONNULL(1);
EAPI void elm_genlist_item_update(Elm_Genlist_Item *item) EINA_ARG_NONNULL(1);
EAPI void elm_genlist_item_item_class_update(Elm_Genlist_Item *it, const Elm_Genlist_Item_Class *itc) EINA_ARG_NONNULL(1, 2);
EAPI const Elm_Genlist_Item_Class *elm_genlist_item_item_class_get(const Elm_Genlist_Item *it) EINA_ARG_NONNULL(1);
EAPI void elm_genlist_item_tooltip_text_set(Elm_Genlist_Item *item, const char *text) EINA_ARG_NONNULL(1);
EAPI void elm_genlist_item_tooltip_content_cb_set(Elm_Genlist_Item *item, Elm_Tooltip_Item_Content_Cb func, const void *data, Evas_Smart_Cb del_cb) EINA_ARG_NONNULL(1);
EAPI void elm_genlist_item_tooltip_unset(Elm_Genlist_Item *item) EINA_ARG_NONNULL(1);

View File

@ -23,6 +23,7 @@ AM_CPPFLAGS = \
@ELEMENTARY_ETHUMB_CFLAGS@ \
@ELEMENTARY_EMAP_CFLAGS@ \
@EVIL_CFLAGS@ \
@EIO_CFLAGS@ \
@EFL_PTHREAD_CFLAGS@
if ELEMENTARY_WINDOWS_BUILD
@ -133,6 +134,7 @@ libelementary_la_LIBADD = \
@ELEMENTARY_ETHUMB_LIBS@ \
@ELEMENTARY_EMAP_LIBS@ \
@EVIL_LIBS@ \
@EIO_LIBS@ \
@EFL_PTHREAD_LIBS@
libelementary_la_LDFLAGS = \
-no-undefined @lt_enable_auto_import@ \

View File

@ -27,10 +27,16 @@
#include <Elementary.h>
#include "elm_priv.h"
#ifdef HAVE_EIO
# include <Eio.h>
#endif
typedef struct _Widget_Data Widget_Data;
struct _Widget_Data
{
EINA_REFCOUNT;
Evas_Object *edje;
Evas_Object *filename_entry;
Evas_Object *path_entry;
@ -48,6 +54,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 +70,34 @@ 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_Genlist_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] = {
{ "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 const char *widtype = NULL;
@ -83,24 +119,37 @@ static void _do_anchors(Evas_Object *obj,
/*** 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);
}
free(wd);
}
static void
_del_hook(Evas_Object *obj)
{
Widget_Data *wd;
wd = elm_widget_data_get(obj);
if (!wd) return;
eio_file_cancel(wd->current);
wd->files_list = NULL;
wd->files_grid = NULL;
EINA_REFCOUNT_UNREF(wd)
_widget_data_free(wd);
}
static void
_sizing_eval(Evas_Object *obj)
{
@ -212,38 +261,56 @@ _itc_label_get(void *data,
}
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
@ -487,18 +554,164 @@ _do_anchors(Evas_Object *obj,
elm_entry_entry_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_Gengrid_Item *ga = a;
const Elm_Gengrid_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;
}
return strcoll(elm_gengrid_item_data_get(ga), elm_gengrid_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_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;
}
return strcoll(elm_genlist_item_data_get(la), elm_genlist_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_entry_entry_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) return ;
_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);
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"),
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)
{
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);
@ -532,30 +745,52 @@ _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 :
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->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 ***/
@ -574,10 +809,13 @@ 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);
@ -622,11 +860,16 @@ 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;
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;
}
li = elm_genlist_add(parent);
elm_widget_mirrored_automatic_set(li, EINA_FALSE);