file selector:Add support mime type filter
This commit is contained in:
parent
8ad4a7f904
commit
2cfa0ce7db
|
@ -1450,3 +1450,7 @@
|
|||
2013-06-23 ChunEon Park (Hermet)
|
||||
|
||||
* Apply current ctxpopup style to the list in the ctxpopup.
|
||||
|
||||
2013-06-24 Ryuan Choi (ryuan)
|
||||
|
||||
* fileselector : Add support mime type filter
|
||||
|
|
|
@ -75,6 +75,7 @@ Additions:
|
|||
* Add magnifier to entry.
|
||||
* Add "focused" and "unfocused" smart callback for panel, video, web, web2, genlist, hover, index, list, map, photocam, progressbar, radio, scroller, slider, slideshow, spinner, toolbar, win, calendar, check, clock, colorselector, datetime, diskselector, flipselector, gengrid, ctxpopup, fileselector_button, naviframe, player, popup, bubble, button.
|
||||
* Add elm_web_url_set(), elm_web_url_get() and "url,changed" signal for web, web2.
|
||||
* Add elm_fileselector_mime_type_filter_append and elm_fileselector_filters_clear to support mime type filter.
|
||||
|
||||
Improvements:
|
||||
|
||||
|
|
|
@ -110,10 +110,27 @@ group { name: "elm/fileselector/base/default";
|
|||
align: 0.5 1.0;
|
||||
fixed: 1 1;
|
||||
rel1 {
|
||||
to_y: "elm.swallow.ok";
|
||||
to_y: "elm.swallow.filters";
|
||||
relative: 0.0 0.0;
|
||||
offset: 0 -1;
|
||||
}
|
||||
rel2 {
|
||||
to_y: "elm.swallow.filters";
|
||||
relative: 1.0 0.0;
|
||||
offset: -1 -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
part { name: "elm.swallow.filters";
|
||||
type: SWALLOW;
|
||||
description { state: "default" 0.0;
|
||||
align: 1.0 1.0;
|
||||
fixed: 1 1;
|
||||
rel1 {
|
||||
to_y: "elm.swallow.ok";
|
||||
relative: 1.0 0.0;
|
||||
offset: 0 -1;
|
||||
}
|
||||
rel2 {
|
||||
to_y: "elm.swallow.ok";
|
||||
relative: 1.0 0.0;
|
||||
|
|
|
@ -141,6 +141,7 @@ test_fileselector(void *data __UNUSED__,
|
|||
setlocale(LC_ALL, "");
|
||||
|
||||
elm_need_ethumb();
|
||||
elm_need_efreet();
|
||||
|
||||
win = elm_win_util_standard_add("fileselector", "File Selector");
|
||||
elm_win_autodel_set(win, EINA_TRUE);
|
||||
|
@ -157,6 +158,9 @@ test_fileselector(void *data __UNUSED__,
|
|||
elm_fileselector_expandable_set(fs, EINA_FALSE);
|
||||
/* start the fileselector in the home dir */
|
||||
elm_fileselector_path_set(fs, getenv("HOME"));
|
||||
elm_fileselector_mime_types_filter_append(fs, "text/*", "Text Files");
|
||||
elm_fileselector_mime_types_filter_append(fs, "image/*", "Image Files");
|
||||
|
||||
/* allow fs to expand in x & y */
|
||||
evas_object_size_hint_weight_set(fs, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
evas_object_size_hint_align_set(fs, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
* - double click to choose a file
|
||||
* - multi-selection
|
||||
* - make variable/function names that are sensible
|
||||
* - Filter support
|
||||
* - Pattern Filter support
|
||||
* - Custom Filter support
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "elementary_config.h"
|
||||
|
@ -127,6 +128,7 @@ _elm_fileselector_smart_theme(Eo *obj, void *_pd, va_list *list)
|
|||
SWALLOW("elm.swallow.path", sd->path_entry);
|
||||
|
||||
snprintf(buf, sizeof(buf), "fileselector/actions/%s", style);
|
||||
SWALLOW("elm.swallow.filters", sd->filter_hoversel);
|
||||
SWALLOW("elm.swallow.cancel", sd->cancel_button);
|
||||
SWALLOW("elm.swallow.ok", sd->ok_button);
|
||||
|
||||
|
@ -253,6 +255,50 @@ _anchors_do(Evas_Object *obj,
|
|||
elm_object_text_set(sd->path_entry, buf);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_mime_type_matched(const char *mime_filter, const char *mime_type)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (mime_filter[i] != '\0')
|
||||
{
|
||||
if (mime_filter[i] != mime_type[i])
|
||||
{
|
||||
if (mime_filter[i] == '*' && mime_filter[i + 1] == '\0')
|
||||
return EINA_TRUE;
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (mime_type[i] != '\0') return EINA_FALSE;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_check_filters(const Elm_Fileselector_Filter *filter, const char *file_name)
|
||||
{
|
||||
const char *mime_type = NULL;
|
||||
int i;
|
||||
|
||||
if (!filter) return EINA_TRUE;
|
||||
|
||||
#ifdef ELM_EFREET
|
||||
mime_type = efreet_mime_type_get(file_name);
|
||||
#endif
|
||||
|
||||
if (!mime_type) return EINA_FALSE;
|
||||
|
||||
for (i = 0; filter->mime_types[i]; ++i)
|
||||
{
|
||||
if (_mime_type_matched(filter->mime_types[i], mime_type))
|
||||
return EINA_TRUE;
|
||||
}
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_EIO
|
||||
static Eina_Bool
|
||||
_ls_filter_cb(void *data,
|
||||
|
@ -267,6 +313,9 @@ _ls_filter_cb(void *data,
|
|||
if (lreq->sd->only_folder && info->type != EINA_FILE_DIR)
|
||||
return EINA_FALSE;
|
||||
|
||||
if (info->type != EINA_FILE_DIR && !_check_filters(lreq->sd->current_filter, info->path))
|
||||
return EINA_FALSE;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
@ -452,7 +501,7 @@ _populate(Evas_Object *obj,
|
|||
filename = eina_stringshare_add(file->path);
|
||||
if (file->type == EINA_FILE_DIR)
|
||||
dirs = eina_list_append(dirs, filename);
|
||||
else if (!sd->only_folder)
|
||||
else if (!sd->only_folder && _check_filters(sd->current_filter, filename))
|
||||
files = eina_list_append(files, filename);
|
||||
}
|
||||
eina_iterator_free(it);
|
||||
|
@ -673,6 +722,21 @@ _home(void *data,
|
|||
_populate(fs, getenv("HOME"), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_current_filer_changed(void *data,
|
||||
Evas_Object *obj,
|
||||
void *event_info __UNUSED__)
|
||||
{
|
||||
Elm_Fileselector_Filter *filter = data;
|
||||
|
||||
if (filter->sd->current_filter == filter) return;
|
||||
|
||||
elm_object_text_set(obj, filter->filter_name);
|
||||
filter->sd->current_filter = filter;
|
||||
|
||||
_populate(filter->sd->obj, filter->sd->path, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_ok(void *data,
|
||||
Evas_Object *obj __UNUSED__,
|
||||
|
@ -881,6 +945,7 @@ _elm_fileselector_smart_del(Eo *obj EINA_UNUSED, void *_pd, va_list *list EINA_U
|
|||
int i;
|
||||
|
||||
Elm_Fileselector_Smart_Data *sd = _pd;
|
||||
Elm_Fileselector_Filter *filter;
|
||||
|
||||
for (i = 0; i < ELM_FILE_LAST; ++i)
|
||||
{
|
||||
|
@ -892,6 +957,16 @@ _elm_fileselector_smart_del(Eo *obj EINA_UNUSED, void *_pd, va_list *list EINA_U
|
|||
if (sd->current) eio_file_cancel(sd->current);
|
||||
#endif
|
||||
|
||||
EINA_LIST_FREE(sd->filter_list, filter)
|
||||
{
|
||||
eina_stringshare_del(filter->filter_name);
|
||||
|
||||
free(filter->mime_types[0]);
|
||||
free(filter->mime_types);
|
||||
|
||||
free(filter);
|
||||
}
|
||||
|
||||
sd->files_list = NULL;
|
||||
sd->files_grid = NULL;
|
||||
|
||||
|
@ -1265,6 +1340,93 @@ clean_up:
|
|||
free(path);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
elm_fileselector_mime_types_filter_append(Evas_Object *obj, const char *mime_type, const char *filter_name)
|
||||
{
|
||||
ELM_FILESELECTOR_CHECK(obj) EINA_FALSE;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
eo_do(obj, elm_obj_fileselector_mime_types_filter_append(mime_type, filter_name, &ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
_mime_types_filter_append(Eo *obj, void *_pd, va_list *list)
|
||||
{
|
||||
const char *mime_types = va_arg(*list, const char *);
|
||||
const char *filter_name = va_arg(*list, const char *);
|
||||
Eina_Bool *ret = va_arg(*list, Eina_Bool *);
|
||||
|
||||
Elm_Fileselector_Smart_Data *sd;
|
||||
Elm_Fileselector_Filter *ff;
|
||||
Eina_Bool int_ret = EINA_FALSE;
|
||||
Eina_Bool need_theme = EINA_FALSE;
|
||||
|
||||
if (!mime_types) goto end;
|
||||
|
||||
sd = _pd;
|
||||
|
||||
ff = malloc(sizeof(Elm_Fileselector_Filter));
|
||||
if (!ff) goto end;
|
||||
|
||||
if (filter_name)
|
||||
ff->filter_name = eina_stringshare_add(filter_name);
|
||||
else
|
||||
ff->filter_name = eina_stringshare_add(mime_types);
|
||||
|
||||
ff->sd = sd;
|
||||
|
||||
ff->mime_types = eina_str_split(mime_types, ",", 0);
|
||||
|
||||
if (!sd->filter_list)
|
||||
{
|
||||
sd->current_filter = ff;
|
||||
sd->filter_hoversel = elm_hoversel_add(obj);
|
||||
elm_object_text_set(sd->filter_hoversel, ff->filter_name);
|
||||
need_theme = EINA_TRUE;
|
||||
}
|
||||
elm_hoversel_item_add(sd->filter_hoversel, ff->filter_name, NULL, ELM_ICON_NONE, _current_filer_changed, ff);
|
||||
|
||||
sd->filter_list = eina_list_append(sd->filter_list, ff);
|
||||
|
||||
_populate(obj, sd->path, NULL);
|
||||
|
||||
if (need_theme)
|
||||
eo_do(obj, elm_wdg_theme(NULL));
|
||||
|
||||
int_ret = EINA_TRUE;
|
||||
|
||||
end:
|
||||
if (ret) *ret = int_ret;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
elm_fileselector_filters_clear(Evas_Object *obj)
|
||||
{
|
||||
ELM_FILESELECTOR_CHECK(obj);
|
||||
eo_do(obj, elm_obj_fileselector_filters_clear());
|
||||
}
|
||||
|
||||
static void
|
||||
_filters_clear(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
|
||||
{
|
||||
Elm_Fileselector_Smart_Data *sd = _pd;
|
||||
Elm_Fileselector_Filter *filter;
|
||||
|
||||
EINA_LIST_FREE(sd->filter_list, filter)
|
||||
{
|
||||
eina_stringshare_del(filter->filter_name);
|
||||
|
||||
free(filter->mime_types[0]);
|
||||
free(filter->mime_types);
|
||||
|
||||
free(filter);
|
||||
}
|
||||
|
||||
ELM_SAFE_FREE(sd->filter_hoversel, evas_object_del);
|
||||
|
||||
_populate(obj, sd->path, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_elm_fileselector_smart_focus_next_manager_is(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list)
|
||||
{
|
||||
|
@ -1308,6 +1470,8 @@ _class_constructor(Eo_Class *klass)
|
|||
EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_MODE_GET), _mode_get),
|
||||
EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_GET), _selected_get),
|
||||
EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_SET), _selected_set),
|
||||
EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_MIME_TYPES_FILTER_APPEND), _mime_types_filter_append),
|
||||
EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_FILTERS_CLEAR), _filters_clear),
|
||||
EO_OP_FUNC_SENTINEL
|
||||
};
|
||||
eo_class_funcs_set(klass, func_desc);
|
||||
|
@ -1329,6 +1493,8 @@ static const Eo_Op_Description op_desc[] = {
|
|||
EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_MODE_GET, "Get the mode in which a given file selector widget is displaying (layouting) file system entries in its view."),
|
||||
EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_GET, "Get the currently selected item's (full) path, in the given file selector widget."),
|
||||
EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_SET, "Set, programmatically, the currently selected file/directory in the given file selector widget."),
|
||||
EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_MIME_TYPES_FILTER_APPEND, "Append mime type filter"),
|
||||
EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_FILTERS_CLEAR, "Clear filters"),
|
||||
EO_OP_DESCRIPTION_SENTINEL
|
||||
};
|
||||
static const Eo_Class_Description class_desc = {
|
||||
|
|
|
@ -25,6 +25,8 @@ enum
|
|||
ELM_OBJ_FILESELECTOR_SUB_ID_MODE_GET,
|
||||
ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_GET,
|
||||
ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_SET,
|
||||
ELM_OBJ_FILESELECTOR_SUB_ID_MIME_TYPES_FILTER_APPEND,
|
||||
ELM_OBJ_FILESELECTOR_SUB_ID_FILTERS_CLEAR,
|
||||
ELM_OBJ_FILESELECTOR_SUB_ID_LAST
|
||||
};
|
||||
|
||||
|
@ -206,6 +208,32 @@ enum
|
|||
* @see elm_fileselector_selected_set
|
||||
*/
|
||||
#define elm_obj_fileselector_selected_set(_path, ret) ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_SET), EO_TYPECHECK(const char *, _path), EO_TYPECHECK(Eina_Bool *, ret)
|
||||
|
||||
/**
|
||||
* @def elm_obj_fileselector_mime_type_filter_append
|
||||
* @since 1.8
|
||||
*
|
||||
* Append mime type based filter into filter list
|
||||
*
|
||||
* @param[in] mime_types
|
||||
* @param[in] filter_name
|
||||
* @param[out] ret
|
||||
*
|
||||
* @see elm_fileselector_mime_type_filter_append
|
||||
*/
|
||||
#define elm_obj_fileselector_mime_types_filter_append(mime_types, filter_name, ret) ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_MIME_TYPES_FILTER_APPEND), EO_TYPECHECK(const char *, mime_types), EO_TYPECHECK(const char *, filter_name), EO_TYPECHECK(Eina_Bool *, ret)
|
||||
|
||||
/**
|
||||
* @def elm_obj_fileselector_filters_clear
|
||||
* @since 1.8
|
||||
*
|
||||
* Clear all filters registered
|
||||
*
|
||||
*
|
||||
* @see elm_fileselector_mime_type_filter_append
|
||||
*/
|
||||
#define elm_obj_fileselector_filters_clear() ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_FILTERS_CLEAR)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -242,3 +242,36 @@ EAPI Eina_Bool elm_fileselector_selected_set(Evas_Object *obj, const
|
|||
* @ingroup Fileselector
|
||||
*/
|
||||
EAPI const char *elm_fileselector_selected_get(const Evas_Object *obj);
|
||||
|
||||
/**
|
||||
* Append mime types filter into filter list
|
||||
*
|
||||
* @param obj The file selector object
|
||||
* @param mime_types comma(,) separated mime types to be allowed.
|
||||
* @param filter_name The name to be displayed, @p mime_types will be displayed if NULL
|
||||
* @return @c EINA_TRUE on success, @c EINA_FALSE on failure.
|
||||
*
|
||||
* @note a sub type of mime can be asterisk(*)
|
||||
* @note mime type filter is only working with efreet now.
|
||||
* @note first added filter will be the default filter at the moment.
|
||||
*
|
||||
* @see elm_need_efreet()
|
||||
* @see elm_fileselector_filters_clear()
|
||||
*
|
||||
* @ingroup Fileselector
|
||||
*/
|
||||
EAPI Eina_Bool elm_fileselector_mime_types_filter_append(Evas_Object *obj, const char *mime_types, const char *filter_name);
|
||||
|
||||
/**
|
||||
* Clear all filters registered
|
||||
*
|
||||
* @param obj The file selector object
|
||||
*
|
||||
* @note If filter list is empty, file selector assume that all
|
||||
* files are matched.
|
||||
*
|
||||
* @see elm_fileselector_mime_type_filter_append()
|
||||
*
|
||||
* @ingroup Fileselector
|
||||
*/
|
||||
EAPI void elm_fileselector_filters_clear(Evas_Object *obj);
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
* widgets which are a fileselector with some more logic on top.
|
||||
*/
|
||||
|
||||
typedef struct _Elm_Fileselector_Filter Elm_Fileselector_Filter;
|
||||
|
||||
/**
|
||||
* Base layout smart data extended with fileselector instance data.
|
||||
*/
|
||||
|
@ -22,24 +24,28 @@ struct _Elm_Fileselector_Smart_Data
|
|||
{
|
||||
EINA_REFCOUNT;
|
||||
|
||||
Evas_Object *obj;
|
||||
Evas_Object *path_entry;
|
||||
Evas_Object *files_list;
|
||||
Evas_Object *files_grid;
|
||||
Evas_Object *up_button;
|
||||
Evas_Object *home_button;
|
||||
Evas_Object *spinner;
|
||||
Evas_Object *ok_button;
|
||||
Evas_Object *cancel_button;
|
||||
Evas_Object *obj;
|
||||
Evas_Object *path_entry;
|
||||
Evas_Object *files_list;
|
||||
Evas_Object *files_grid;
|
||||
Evas_Object *up_button;
|
||||
Evas_Object *home_button;
|
||||
Evas_Object *spinner;
|
||||
Evas_Object *filter_hoversel;
|
||||
Evas_Object *ok_button;
|
||||
Evas_Object *cancel_button;
|
||||
|
||||
const char *path;
|
||||
const char *selection;
|
||||
Ecore_Idler *sel_idler;
|
||||
Eina_List *filter_list;
|
||||
Elm_Fileselector_Filter *current_filter;
|
||||
|
||||
const char *path_separator;
|
||||
const char *path;
|
||||
const char *selection;
|
||||
Ecore_Idler *sel_idler;
|
||||
|
||||
const char *path_separator;
|
||||
|
||||
#ifdef HAVE_EIO
|
||||
Eio_File *current;
|
||||
Eio_File *current;
|
||||
#endif
|
||||
|
||||
Elm_Fileselector_Mode mode;
|
||||
|
@ -72,6 +78,14 @@ typedef enum {
|
|||
ELM_FILE_LAST
|
||||
} Elm_Fileselector_Type;
|
||||
|
||||
struct _Elm_Fileselector_Filter
|
||||
{
|
||||
const char *filter_name;
|
||||
Elm_Fileselector_Smart_Data *sd;
|
||||
|
||||
char **mime_types;
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue