@since ? 
 
------------------------------------
-Regards, Hermet- 
-----Original Message-----
From: "Ryuan Choi - Enlightenment Git"<[email protected]> 
To: <[email protected]>; 
Cc: 
Sent: 2013-06-24 (월) 15:45:53
Subject: [EGIT] [core/elementary] master 01/01: file selector:Add support mime 
type filter

ryuan pushed a commit to branch master.

commit 4c7285db3967e731e2891478bca1b39f69918304
Author: Ryuan Choi <ryuan.choi>@gmail.com>
Date:   Wed Jun 19 09:00:41 2013 +0900

    file selector:Add support mime type filter
---
 ChangeLog                               4 +
 NEWS                                    1 +
 data/themes/widgets/fileselector.edc   19 +++-
 src/bin/test_fileselector.c             4 +
 src/lib/elc_fileselector.c            170 ++++++++++++++++++++++++++++++++++-
 src/lib/elc_fileselector_eo.h          28 ++++++
 src/lib/elc_fileselector_legacy.h      33 +++++++
 src/lib/elm_widget_fileselector.h      42 ++++++---
 8 files changed, 284 insertions(+), 17 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f3f38d1..a5d36f2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/NEWS b/NEWS
index 50a252d..8fb389f 100644
--- a/NEWS
+++ b/NEWS
@@ -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:
 
diff --git a/data/themes/widgets/fileselector.edc 
b/data/themes/widgets/fileselector.edc
index ccd9e6e..f8d158c 100644
--- a/data/themes/widgets/fileselector.edc
+++ b/data/themes/widgets/fileselector.edc
@@ -110,11 +110,28 @@ 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;
                offset: -1 -1;
diff --git a/src/bin/test_fileselector.c b/src/bin/test_fileselector.c
index dd532ff..dfa7f02 100644
--- a/src/bin/test_fileselector.c
+++ b/src/bin/test_fileselector.c
@@ -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);
diff --git a/src/lib/elc_fileselector.c b/src/lib/elc_fileselector.c
index 7aafda5..c774218 100644
--- a/src/lib/elc_fileselector.c
+++ b/src/lib/elc_fileselector.c
@@ -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);
@@ -674,6 +723,21 @@ _home(void *data,
 }
 
 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__,
     void *event_info __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 = {
diff --git a/src/lib/elc_fileselector_eo.h b/src/lib/elc_fileselector_eo.h
index 06eba98..38485d1 100644
--- a/src/lib/elc_fileselector_eo.h
+++ b/src/lib/elc_fileselector_eo.h
@@ -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)
+
 /**
  * @}
  */
diff --git a/src/lib/elc_fileselector_legacy.h 
b/src/lib/elc_fileselector_legacy.h
index 505b787..52edeea 100644
--- a/src/lib/elc_fileselector_legacy.h
+++ b/src/lib/elc_fileselector_legacy.h
@@ -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);
diff --git a/src/lib/elm_widget_fileselector.h 
b/src/lib/elm_widget_fileselector.h
index d656d0a..ad8c35a 100644
--- a/src/lib/elm_widget_fileselector.h
+++ b/src/lib/elm_widget_fileselector.h
@@ -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;
+
+   Eina_List               *filter_list;
+   Elm_Fileselector_Filter *current_filter;
 
-   const char           *path;
-   const char           *selection;
-   Ecore_Idler          *sel_idler;
+   const char              *path;
+   const char              *selection;
+   Ecore_Idler             *sel_idler;
 
-   const char           *path_separator;
+   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;
+};
+
 /**
  * @}
  */

-- 

------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev

------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to