summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyuan Choi <ryuan.choi@gmail.com>2013-10-17 11:04:57 +0900
committerRyuan Choi <ryuan.choi@gmail.com>2013-10-17 11:05:45 +0900
commit1b07838b2c6e4c90664906077ff9f62bf0a63e57 (patch)
tree6e4651bc00d596e4fa919f2468a192d848b3b24c
parent8f497603fa7d32c781030679417b40d7830fa416 (diff)
Multiple selection support in fileselector
Summary: Multiple selection support in fileselector Reviewers: seoz Reviewed By: seoz CC: seoz Differential Revision: https://phab.enlightenment.org/D207
-rw-r--r--ChangeLog4
-rw-r--r--NEWS1
-rw-r--r--src/bin/test_fileselector.c30
-rw-r--r--src/lib/elc_fileselector.c223
-rw-r--r--src/lib/elc_fileselector_eo.h39
-rw-r--r--src/lib/elc_fileselector_legacy.h56
-rw-r--r--src/lib/elm_widget_fileselector.h10
7 files changed, 359 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 68aba3ad0..7cba68f36 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1699,3 +1699,7 @@
1699 1699
1700 * hoversel: Support elm_object_item_signal_emit in hoversel. This works 1700 * hoversel: Support elm_object_item_signal_emit in hoversel. This works
1701 only when the item is created. 1701 only when the item is created.
1702
17032013-10-17 Ryuan Choi (ryuan)
1704
1705 * fileselector : Add support multi-selection.
diff --git a/NEWS b/NEWS
index a3bea3f9a..7c21ff015 100644
--- a/NEWS
+++ b/NEWS
@@ -97,6 +97,7 @@ Additions:
97 * Add the configuration fileselector_double_tap_navigation_enable. 97 * Add the configuration fileselector_double_tap_navigation_enable.
98 * Add "activated" smart callback for fileselector. 98 * Add "activated" smart callback for fileselector.
99 * Add elm_object_item_signal_emit support in hoversel. This works only when the item is created. 99 * Add elm_object_item_signal_emit support in hoversel. This works only when the item is created.
100 * Add elm_fileselector_multi_select_set/get() and elm_fileselector_selected_paths_get to support multi-selection.
100 101
101Improvements: 102Improvements:
102 103
diff --git a/src/bin/test_fileselector.c b/src/bin/test_fileselector.c
index a7b1c9b02..fa01be804 100644
--- a/src/bin/test_fileselector.c
+++ b/src/bin/test_fileselector.c
@@ -40,7 +40,17 @@ my_fileselector_selected(void *data EINA_UNUSED,
40 printf("Selected file: %s\n", selected); 40 printf("Selected file: %s\n", selected);
41 41
42 /* or you can query the selection */ 42 /* or you can query the selection */
43 printf("or: %s\n", elm_fileselector_selected_get(obj)); 43 if (elm_fileselector_multi_select_get(obj))
44 {
45 const Eina_List *li;
46 const Eina_List *paths = elm_fileselector_selected_paths_get(obj);
47 char *path;
48 printf("All selected files are:\n");
49 EINA_LIST_FOREACH(paths, li, path)
50 printf(" %s\n", path);
51 }
52 else
53 printf("or: %s\n", elm_fileselector_selected_get(obj));
44} 54}
45 55
46static void 56static void
@@ -122,6 +132,17 @@ _expandable_clicked(void *data,
122} 132}
123 133
124static void 134static void
135_multi_clicked(void *data,
136 Evas_Object *obj EINA_UNUSED,
137 void *event_info EINA_UNUSED)
138{
139 Evas_Object *fs = data;
140 Eina_Bool enabled = elm_fileselector_multi_select_get(fs);
141 printf("Toggle Multiple selection to: %s\n", !enabled ? "On" : "Off");
142 elm_fileselector_multi_select_set(fs, !enabled);
143}
144
145static void
125_buttons_clicked(void *data, 146_buttons_clicked(void *data,
126 Evas_Object *obj EINA_UNUSED, 147 Evas_Object *obj EINA_UNUSED,
127 void *event_info EINA_UNUSED) 148 void *event_info EINA_UNUSED)
@@ -249,6 +270,13 @@ test_fileselector(void *data EINA_UNUSED,
249 evas_object_show(bt); 270 evas_object_show(bt);
250 271
251 bt = elm_check_add(win); 272 bt = elm_check_add(win);
273 elm_object_text_set(bt, "multiple selection");
274 elm_check_state_set(bt, elm_fileselector_multi_select_get(fs));
275 evas_object_smart_callback_add(bt, "changed", _multi_clicked, fs);
276 elm_box_pack_end(hbox, bt);
277 evas_object_show(bt);
278
279 bt = elm_check_add(win);
252 elm_object_text_set(bt, "buttons"); 280 elm_object_text_set(bt, "buttons");
253 elm_check_state_set(bt, elm_fileselector_buttons_ok_cancel_get(fs)); 281 elm_check_state_set(bt, elm_fileselector_buttons_ok_cancel_get(fs));
254 evas_object_smart_callback_add(bt, "changed", _buttons_clicked, fs); 282 evas_object_smart_callback_add(bt, "changed", _buttons_clicked, fs);
diff --git a/src/lib/elc_fileselector.c b/src/lib/elc_fileselector.c
index d608c81a1..3eb995645 100644
--- a/src/lib/elc_fileselector.c
+++ b/src/lib/elc_fileselector.c
@@ -4,7 +4,6 @@
4 * - user defined icon/label cb 4 * - user defined icon/label cb
5 * - show/hide/add buttons ??? 5 * - show/hide/add buttons ???
6 * - show/hide hidden files 6 * - show/hide hidden files
7 * - multi-selection
8 * - make variable/function names that are sensible 7 * - make variable/function names that are sensible
9 * - Pattern Filter support 8 * - Pattern Filter support
10 * - Custom Filter support 9 * - Custom Filter support
@@ -376,6 +375,13 @@ _signal_first(Listing_Request *lreq)
376{ 375{
377 if (!lreq->first) return; 376 if (!lreq->first) return;
378 377
378 if (lreq->sd->multi)
379 {
380 char *path;
381 EINA_LIST_FREE(lreq->sd->paths, path)
382 free(path);
383 }
384
379 evas_object_smart_callback_call 385 evas_object_smart_callback_call
380 (lreq->obj, SIG_DIRECTORY_OPEN, (void *)lreq->path); 386 (lreq->obj, SIG_DIRECTORY_OPEN, (void *)lreq->path);
381 387
@@ -511,6 +517,13 @@ _populate(Evas_Object *obj,
511 it = eina_file_stat_ls(path); 517 it = eina_file_stat_ls(path);
512 if (!it) return; 518 if (!it) return;
513 519
520 if (sd->multi)
521 {
522 char *path;
523 EINA_LIST_FREE(sd->paths, path)
524 free(path);
525 }
526
514 evas_object_smart_callback_call(obj, SIG_DIRECTORY_OPEN, (void *)path); 527 evas_object_smart_callback_call(obj, SIG_DIRECTORY_OPEN, (void *)path);
515 if (!parent_it) 528 if (!parent_it)
516 { 529 {
@@ -731,6 +744,34 @@ _on_item_activated(void *data,
731} 744}
732 745
733static void 746static void
747_clear_selections(Elm_Fileselector_Smart_Data *sd, Elm_Object_Item *last_selected)
748{
749 Eina_List *items;
750 Elm_Object_Item *sel;
751
752 if (sd->mode == ELM_FILESELECTOR_LIST)
753 {
754 items = eina_list_clone(elm_genlist_selected_items_get(sd->files_list));
755
756 EINA_LIST_FREE(items, sel)
757 {
758 if (sel == last_selected) continue;
759 elm_genlist_item_selected_set(sel, EINA_FALSE);
760 }
761 }
762 else if (sd->mode == ELM_FILESELECTOR_GRID)
763 {
764 items = eina_list_clone(elm_gengrid_selected_items_get(sd->files_grid));
765
766 EINA_LIST_FREE(items, sel)
767 {
768 if (sel == last_selected) continue;
769 elm_gengrid_item_selected_set(sel, EINA_FALSE);
770 }
771 }
772}
773
774static void
734_on_item_selected(void *data, 775_on_item_selected(void *data,
735 Evas_Object *obj __UNUSED__, 776 Evas_Object *obj __UNUSED__,
736 void *event_info) 777 void *event_info)
@@ -755,11 +796,46 @@ _on_item_selected(void *data,
755 * - path is file and mode is NOT ONLY FOLDER */ 796 * - path is file and mode is NOT ONLY FOLDER */
756 if (is_dir == sd->only_folder) 797 if (is_dir == sd->only_folder)
757 { 798 {
758 elm_object_text_set(sd->name_entry, ecore_file_file_get(path)); 799 if (sd->multi)
800 {
801 Eina_List *li;
802 const char *p;
803 Eina_Strbuf *buf;
804
805 if (sd->dir_selected)
806 {
807 _clear_selections(sd, it);
808 sd->dir_selected = EINA_FALSE;
809 }
810
811 buf = eina_strbuf_new();
812 EINA_LIST_FOREACH(sd->paths, li, p)
813 {
814 eina_strbuf_append(buf, ecore_file_file_get(p));
815 eina_strbuf_append_length(buf, ", ", 2);
816 }
817
818 sd->paths = eina_list_append(sd->paths, strdup(path));
819 eina_strbuf_append(buf, ecore_file_file_get(path));
820
821 elm_object_text_set(sd->name_entry, eina_strbuf_string_get(buf));
822 eina_strbuf_free(buf);
823 }
824 else
825 elm_object_text_set(sd->name_entry, ecore_file_file_get(path));
826
759 evas_object_smart_callback_call(data, SIG_SELECTED, (void *)path); 827 evas_object_smart_callback_call(data, SIG_SELECTED, (void *)path);
760 } 828 }
761 else 829 else
762 elm_object_text_set(sd->name_entry, ""); 830 {
831 if (sd->multi && is_dir && sd->double_tap_navigation)
832 {
833 _clear_selections(sd, it);
834 sd->dir_selected = EINA_TRUE;
835 }
836
837 elm_object_text_set(sd->name_entry, "");
838 }
763 839
764 /* We need to populate, if path is directory and: 840 /* We need to populate, if path is directory and:
765 * - mode is GRID; 841 * - mode is GRID;
@@ -801,6 +877,48 @@ _on_item_selected(void *data,
801} 877}
802 878
803static void 879static void
880_on_item_unselected(void *data,
881 Evas_Object *obj __UNUSED__,
882 void *event_info)
883{
884 Eina_List *li, *l;
885 char *path;
886 const char *unselected_path;
887 Eina_Strbuf *buf;
888 Elm_Object_Item *it = event_info;
889 Eina_Bool first = EINA_TRUE;
890
891 ELM_FILESELECTOR_DATA_GET(data, sd);
892
893 if (!sd->multi) return;
894
895 unselected_path = elm_object_item_data_get(it);
896 if (!unselected_path) return;
897
898 buf = eina_strbuf_new();
899 EINA_LIST_FOREACH_SAFE(sd->paths, li, l, path)
900 {
901 if (!strcmp(path, unselected_path))
902 {
903 sd->paths = eina_list_remove_list(sd->paths, li);
904 free(path);
905 }
906 else
907 {
908 if (!first)
909 eina_strbuf_append_length(buf, ", ", 2);
910 else
911 first = EINA_FALSE;
912
913 eina_strbuf_append(buf, ecore_file_file_get(path));
914 }
915 }
916
917 elm_object_text_set(sd->name_entry, eina_strbuf_string_get(buf));
918 eina_strbuf_free(buf);
919}
920
921static void
804_on_dir_up(void *data, 922_on_dir_up(void *data,
805 Evas_Object *obj __UNUSED__, 923 Evas_Object *obj __UNUSED__,
806 void *event_info __UNUSED__) 924 void *event_info __UNUSED__)
@@ -1083,6 +1201,7 @@ _elm_fileselector_smart_add(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
1083 elm_gengrid_align_set(grid, 0.0, 0.0); 1201 elm_gengrid_align_set(grid, 0.0, 0.0);
1084 1202
1085 evas_object_smart_callback_add(li, "selected", _on_item_selected, obj); 1203 evas_object_smart_callback_add(li, "selected", _on_item_selected, obj);
1204 evas_object_smart_callback_add(li, "unselected", _on_item_unselected, obj);
1086 evas_object_smart_callback_add(li, "clicked,double", _on_item_double_clicked, obj); 1205 evas_object_smart_callback_add(li, "clicked,double", _on_item_double_clicked, obj);
1087 evas_object_smart_callback_add(li, "activated", _on_item_activated, obj); 1206 evas_object_smart_callback_add(li, "activated", _on_item_activated, obj);
1088 evas_object_smart_callback_add 1207 evas_object_smart_callback_add
@@ -1092,6 +1211,7 @@ _elm_fileselector_smart_add(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
1092 evas_object_smart_callback_add(li, "expanded", _on_list_expanded, obj); 1211 evas_object_smart_callback_add(li, "expanded", _on_list_expanded, obj);
1093 evas_object_smart_callback_add(li, "contracted", _on_list_contracted, obj); 1212 evas_object_smart_callback_add(li, "contracted", _on_list_contracted, obj);
1094 evas_object_smart_callback_add(grid, "selected", _on_item_selected, obj); 1213 evas_object_smart_callback_add(grid, "selected", _on_item_selected, obj);
1214 evas_object_smart_callback_add(grid, "unselected", _on_item_unselected, obj);
1095 evas_object_smart_callback_add(grid, "clicked,double", _on_item_double_clicked, obj); 1215 evas_object_smart_callback_add(grid, "clicked,double", _on_item_double_clicked, obj);
1096 evas_object_smart_callback_add(grid, "activated", _on_item_activated, obj); 1216 evas_object_smart_callback_add(grid, "activated", _on_item_activated, obj);
1097 1217
@@ -1141,6 +1261,7 @@ _elm_fileselector_smart_del(Eo *obj EINA_UNUSED, void *_pd, va_list *list EINA_U
1141{ 1261{
1142 Elm_Fileselector_Smart_Data *sd = _pd; 1262 Elm_Fileselector_Smart_Data *sd = _pd;
1143 Elm_Fileselector_Filter *filter; 1263 Elm_Fileselector_Filter *filter;
1264 char *path;
1144 1265
1145#ifdef HAVE_EIO 1266#ifdef HAVE_EIO
1146 if (sd->current) eio_file_cancel(sd->current); 1267 if (sd->current) eio_file_cancel(sd->current);
@@ -1156,6 +1277,9 @@ _elm_fileselector_smart_del(Eo *obj EINA_UNUSED, void *_pd, va_list *list EINA_U
1156 free(filter); 1277 free(filter);
1157 } 1278 }
1158 1279
1280 EINA_LIST_FREE(sd->paths, path)
1281 free(path);
1282
1159 sd->files_list = NULL; 1283 sd->files_list = NULL;
1160 sd->files_grid = NULL; 1284 sd->files_grid = NULL;
1161 1285
@@ -1439,6 +1563,70 @@ _mode_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list)
1439 *ret = sd->mode; 1563 *ret = sd->mode;
1440} 1564}
1441 1565
1566EAPI void
1567elm_fileselector_multi_select_set(Evas_Object *obj, Eina_Bool multi)
1568{
1569 ELM_FILESELECTOR_CHECK(obj);
1570 eo_do(obj, elm_obj_fileselector_multi_select_set(multi));
1571}
1572
1573static void
1574_multi_select_set(Eo *obj __UNUSED__, void *_pd, va_list *list __UNUSED__)
1575{
1576 Eina_Bool multi = va_arg(*list, int);
1577 Elm_Fileselector_Smart_Data *sd = _pd;
1578 char *path;
1579
1580 multi = !!multi;
1581 if (sd->multi == multi) return;
1582 sd->multi = multi;
1583
1584 elm_genlist_multi_select_set(sd->files_list, multi);
1585 elm_gengrid_multi_select_set(sd->files_grid, multi);
1586
1587 if (!sd->multi)
1588 {
1589 _clear_selections(sd, NULL);
1590
1591 EINA_LIST_FREE(sd->paths, path)
1592 free(path);
1593 }
1594 else
1595 {
1596 const Eina_List *selected_items, *li;
1597 const Elm_Object_Item *it;
1598
1599 if (sd->mode == ELM_FILESELECTOR_LIST)
1600 selected_items = elm_genlist_selected_items_get(sd->files_list);
1601 else
1602 selected_items = elm_gengrid_selected_items_get(sd->files_list);
1603
1604 EINA_LIST_FOREACH(selected_items, li, it)
1605 {
1606 path = elm_object_item_data_get(it);
1607 sd->paths = eina_list_append(sd->paths, strdup(path));
1608 }
1609 }
1610}
1611
1612EAPI Eina_Bool
1613elm_fileselector_multi_select_get(const Evas_Object *obj)
1614{
1615 ELM_FILESELECTOR_CHECK(obj) EINA_FALSE;
1616 Eina_Bool ret = EINA_FALSE;
1617 eo_do((Eo *) obj, elm_obj_fileselector_multi_select_get(&ret));
1618 return ret;
1619}
1620
1621static void
1622_multi_select_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list)
1623{
1624 Eina_Bool *ret = va_arg(*list, Eina_Bool *);
1625 Elm_Fileselector_Smart_Data *sd = _pd;
1626
1627 *ret = sd->multi;
1628}
1629
1442EAPI const char * 1630EAPI const char *
1443elm_fileselector_selected_get(const Evas_Object *obj) 1631elm_fileselector_selected_get(const Evas_Object *obj)
1444{ 1632{
@@ -1527,6 +1715,29 @@ clean_up:
1527 free(path); 1715 free(path);
1528} 1716}
1529 1717
1718EAPI const Eina_List *
1719elm_fileselector_selected_paths_get(const Evas_Object* obj)
1720{
1721 ELM_FILESELECTOR_CHECK(obj) NULL;
1722 const Eina_List *ret = NULL;
1723 eo_do((Eo *) obj, elm_obj_fileselector_selected_paths_get(&ret));
1724 return ret;
1725}
1726
1727static void
1728_selected_paths_get(Eo *obj __UNUSED__, void *_pd, va_list *list)
1729{
1730 const Eina_List **ret = va_arg(*list, const Eina_List**);
1731 Elm_Fileselector_Smart_Data *sd = _pd;
1732
1733 if (!ret) return;
1734
1735 if (sd->multi)
1736 *ret = sd->paths;
1737 else
1738 *ret = NULL;
1739}
1740
1530EAPI Eina_Bool 1741EAPI Eina_Bool
1531elm_fileselector_mime_types_filter_append(Evas_Object *obj, const char *mime_type, const char *filter_name) 1742elm_fileselector_mime_types_filter_append(Evas_Object *obj, const char *mime_type, const char *filter_name)
1532{ 1743{
@@ -1687,8 +1898,11 @@ _class_constructor(Eo_Class *klass)
1687 EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_PATH_GET), _path_get), 1898 EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_PATH_GET), _path_get),
1688 EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_MODE_SET), _mode_set), 1899 EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_MODE_SET), _mode_set),
1689 EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_MODE_GET), _mode_get), 1900 EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_MODE_GET), _mode_get),
1901 EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_MULTI_SELECT_SET), _multi_select_set),
1902 EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_MULTI_SELECT_GET), _multi_select_get),
1690 EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_GET), _selected_get), 1903 EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_GET), _selected_get),
1691 EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_SET), _selected_set), 1904 EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_SET), _selected_set),
1905 EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_PATHS_GET), _selected_paths_get),
1692 EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_MIME_TYPES_FILTER_APPEND), _mime_types_filter_append), 1906 EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_MIME_TYPES_FILTER_APPEND), _mime_types_filter_append),
1693 EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_FILTERS_CLEAR), _filters_clear), 1907 EO_OP_FUNC(ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_FILTERS_CLEAR), _filters_clear),
1694 EO_OP_FUNC_SENTINEL 1908 EO_OP_FUNC_SENTINEL
@@ -1736,8 +1950,11 @@ static const Eo_Op_Description op_desc[] = {
1736 EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_PATH_GET, "Get the parent directory's path that a given file selector widget is displaying."), 1950 EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_PATH_GET, "Get the parent directory's path that a given file selector widget is displaying."),
1737 EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_MODE_SET, "Set the mode in which a given file selector widget will display (layout) file system entries in its view."), 1951 EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_MODE_SET, "Set the mode in which a given file selector widget will display (layout) file system entries in its view."),
1738 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."), 1952 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."),
1953 EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_MULTI_SELECT_SET, "Enable or disable multi-selection in the file selector widget."),
1954 EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_MULTI_SELECT_GET, "Get if multi-selection in file selector widget is enabled or disabled."),
1739 EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_GET, "Get the currently selected item's (full) path, in the given file selector widget."), 1955 EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_GET, "Get the currently selected item's (full) path, in the given file selector widget."),
1740 EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_SET, "Set, programmatically, the currently selected file/directory in the given file selector widget."), 1956 EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_SET, "Set, programmatically, the currently selected file/directory in the given file selector widget."),
1957 EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_PATHS_GET, "Get the currently selected item's (full) path, in the given file selector widget."),
1741 EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_MIME_TYPES_FILTER_APPEND, "Append mime type filter"), 1958 EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_MIME_TYPES_FILTER_APPEND, "Append mime type filter"),
1742 EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_FILTERS_CLEAR, "Clear filters"), 1959 EO_OP_DESCRIPTION(ELM_OBJ_FILESELECTOR_SUB_ID_FILTERS_CLEAR, "Clear filters"),
1743 EO_OP_DESCRIPTION_SENTINEL 1960 EO_OP_DESCRIPTION_SENTINEL
diff --git a/src/lib/elc_fileselector_eo.h b/src/lib/elc_fileselector_eo.h
index 72fbedf4f..351c9b7dc 100644
--- a/src/lib/elc_fileselector_eo.h
+++ b/src/lib/elc_fileselector_eo.h
@@ -23,8 +23,11 @@ enum
23 ELM_OBJ_FILESELECTOR_SUB_ID_PATH_GET, 23 ELM_OBJ_FILESELECTOR_SUB_ID_PATH_GET,
24 ELM_OBJ_FILESELECTOR_SUB_ID_MODE_SET, 24 ELM_OBJ_FILESELECTOR_SUB_ID_MODE_SET,
25 ELM_OBJ_FILESELECTOR_SUB_ID_MODE_GET, 25 ELM_OBJ_FILESELECTOR_SUB_ID_MODE_GET,
26 ELM_OBJ_FILESELECTOR_SUB_ID_MULTI_SELECT_SET,
27 ELM_OBJ_FILESELECTOR_SUB_ID_MULTI_SELECT_GET,
26 ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_GET, 28 ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_GET,
27 ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_SET, 29 ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_SET,
30 ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_PATHS_GET,
28 ELM_OBJ_FILESELECTOR_SUB_ID_MIME_TYPES_FILTER_APPEND, 31 ELM_OBJ_FILESELECTOR_SUB_ID_MIME_TYPES_FILTER_APPEND,
29 ELM_OBJ_FILESELECTOR_SUB_ID_FILTERS_CLEAR, 32 ELM_OBJ_FILESELECTOR_SUB_ID_FILTERS_CLEAR,
30 ELM_OBJ_FILESELECTOR_SUB_ID_LAST 33 ELM_OBJ_FILESELECTOR_SUB_ID_LAST
@@ -183,6 +186,30 @@ enum
183#define elm_obj_fileselector_mode_get(ret) ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_MODE_GET), EO_TYPECHECK(Elm_Fileselector_Mode *, ret) 186#define elm_obj_fileselector_mode_get(ret) ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_MODE_GET), EO_TYPECHECK(Elm_Fileselector_Mode *, ret)
184 187
185/** 188/**
189 * @def elm_obj_fileselector_multi_select_set
190 * @since 1.8
191 *
192 * Enable or disable multi-selection in the fileselector
193 *
194 * @param[in] multi
195 *
196 * @see elm_fileselector_multi_select_set
197 */
198#define elm_obj_fileselector_multi_select_set(multi) ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_MULTI_SELECT_SET), EO_TYPECHECK(Eina_Bool, multi)
199
200/**
201 * @def elm_obj_fileselector_multi_select_get
202 * @since 1.8
203 *
204 * Gets if multi-selection in fileselector is enabled or disabled.
205 *
206 * @param[out] multi
207 *
208 * @see elm_fileselector_multi_select_get
209 */
210#define elm_obj_fileselector_multi_select_get(ret) ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_MULTI_SELECT_GET), EO_TYPECHECK(Eina_Bool *, ret)
211
212/**
186 * @def elm_obj_fileselector_selected_get 213 * @def elm_obj_fileselector_selected_get
187 * @since 1.8 214 * @since 1.8
188 * 215 *
@@ -210,6 +237,18 @@ enum
210#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) 237#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)
211 238
212/** 239/**
240 * @def elm_obj_fileselector_selected_paths_get
241 * @since 1.8
242 *
243 * Get a list of selected paths in the fileselector.
244 *
245 * @param[out] ret
246 *
247 * @see elm_fileselector_selected_paths_get
248 */
249#define elm_obj_fileselector_selected_paths_get(ret) ELM_OBJ_FILESELECTOR_ID(ELM_OBJ_FILESELECTOR_SUB_ID_SELECTED_PATHS_GET), EO_TYPECHECK(const Eina_List **, ret)
250
251/**
213 * @def elm_obj_fileselector_mime_types_filter_append 252 * @def elm_obj_fileselector_mime_types_filter_append
214 * @since 1.8 253 * @since 1.8
215 * 254 *
diff --git a/src/lib/elc_fileselector_legacy.h b/src/lib/elc_fileselector_legacy.h
index 6c8963580..c94a724d8 100644
--- a/src/lib/elc_fileselector_legacy.h
+++ b/src/lib/elc_fileselector_legacy.h
@@ -211,6 +211,39 @@ EAPI void elm_fileselector_mode_set(Evas_Object *obj, Elm_Files
211EAPI Elm_Fileselector_Mode elm_fileselector_mode_get(const Evas_Object *obj); 211EAPI Elm_Fileselector_Mode elm_fileselector_mode_get(const Evas_Object *obj);
212 212
213/** 213/**
214 * Enable or disable multi-selection in the file selector widget.
215 *
216 * @param obj The file selector object
217 * @param multi Multi-select enable/disable. Default is disabled.
218 *
219 * This enables (@c EINA_TRUE) or disables (@c EINA_FALSE) multi-selection in
220 * the list/grid of the file selector widget. This allows more than 1 item to
221 * be selected. To retrieve the list of selected paths, use
222 * elm_fileselector_selected_paths_get().
223 *
224 * @see elm_fileselector_selected_paths_get()
225 * @see elm_fileselector_multi_select_get()
226 *
227 * @since 1.8
228 * @ingroup Fileselector
229 */
230EAPI void elm_fileselector_multi_select_set(Evas_Object *obj, Eina_Bool multi);
231
232/**
233 * Get if multi-selection in the file selector is enabled or disabled.
234 *
235 * @param obj The file selector object
236 * @return Multi-select enabled/disabled
237 * (@c EINA_TRUE = enabled/@c EINA_FALSE = disabled). Default is @c EINA_FALSE.
238 *
239 * @see elm_fileselector_multi_select_set()
240 *
241 * @since 1.8
242 * @ingroup Fileselector
243 */
244EAPI Eina_Bool elm_fileselector_multi_select_get(const Evas_Object *obj);
245
246/**
214 * Set, programmatically, the currently selected file/directory in 247 * Set, programmatically, the currently selected file/directory in
215 * the given file selector widget 248 * the given file selector widget
216 * 249 *
@@ -244,6 +277,29 @@ EAPI Eina_Bool elm_fileselector_selected_set(Evas_Object *obj, const
244EAPI const char *elm_fileselector_selected_get(const Evas_Object *obj); 277EAPI const char *elm_fileselector_selected_get(const Evas_Object *obj);
245 278
246/** 279/**
280 * Get a list of selected paths in the file selector.
281 *
282 * @param obj The file selector object
283 * @return The list of selected paths, or NULL if not in multi-select mode or none are selected.
284 *
285 * It returns a list of the selected paths. This list pointer is only valid so
286 * long as the selection doesn't change (no items are selected or unselected, or
287 * unselected implicitly by deletion). The list contains const char *.
288 * The order of the items in this list is the order which they were selected,
289 * i.e. the first item in this list is the first item that was selected, and so on.
290 *
291 * @note If not in multi-select mode, consider using function
292 * elm_fileselector_selected_get() instead.
293 *
294 * @see elm_fileselector_multi_select_set()
295 * @see elm_fileselector_selected_get()
296 *
297 * @since 1.8
298 * @ingroup Fileselector
299 */
300EAPI const Eina_List *elm_fileselector_selected_paths_get(const Evas_Object *obj);
301
302/**
247 * Append mime types filter into filter list 303 * Append mime types filter into filter list
248 * 304 *
249 * @param obj The file selector object 305 * @param obj The file selector object
diff --git a/src/lib/elm_widget_fileselector.h b/src/lib/elm_widget_fileselector.h
index 875a2b79a..889e11b6f 100644
--- a/src/lib/elm_widget_fileselector.h
+++ b/src/lib/elm_widget_fileselector.h
@@ -39,6 +39,9 @@ struct _Elm_Fileselector_Smart_Data
39 Eina_List *filter_list; 39 Eina_List *filter_list;
40 Elm_Fileselector_Filter *current_filter; 40 Elm_Fileselector_Filter *current_filter;
41 41
42 /* a list of selected paths. only for multi selection */
43 Eina_List *paths;
44
42 const char *path; 45 const char *path;
43 const char *selection; 46 const char *selection;
44 Ecore_Idler *populate_idler; 47 Ecore_Idler *populate_idler;
@@ -54,6 +57,13 @@ struct _Elm_Fileselector_Smart_Data
54 Eina_Bool only_folder : 1; 57 Eina_Bool only_folder : 1;
55 Eina_Bool expand : 1; 58 Eina_Bool expand : 1;
56 Eina_Bool double_tap_navigation : 1; 59 Eina_Bool double_tap_navigation : 1;
60 Eina_Bool multi : 1;
61
62 /* this flag is only for multi selection.
63 * If this flag is set to EINA_TRUE, it means directory is selected
64 * so that fileselector will clear current selection when user clicked
65 * another item. */
66 Eina_Bool dir_selected : 1;
57}; 67};
58 68
59struct sel_data 69struct sel_data