diff options
author | David Walter Seikel | 2012-04-22 09:20:32 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-04-22 09:20:32 +1000 |
commit | 3ad3455551be0d7859ecb02290376206d5e66498 (patch) | |
tree | 497917e12b4d7f458dff9765d9b53f64c4e03fc3 /libraries/elementary/src/lib/elc_fileselector.c | |
parent | Update EFL to latest beta. (diff) | |
download | SledjHamr-3ad3455551be0d7859ecb02290376206d5e66498.zip SledjHamr-3ad3455551be0d7859ecb02290376206d5e66498.tar.gz SledjHamr-3ad3455551be0d7859ecb02290376206d5e66498.tar.bz2 SledjHamr-3ad3455551be0d7859ecb02290376206d5e66498.tar.xz |
And actually include new files, plus elementary libraries.
Diffstat (limited to 'libraries/elementary/src/lib/elc_fileselector.c')
-rw-r--r-- | libraries/elementary/src/lib/elc_fileselector.c | 1249 |
1 files changed, 1249 insertions, 0 deletions
diff --git a/libraries/elementary/src/lib/elc_fileselector.c b/libraries/elementary/src/lib/elc_fileselector.c new file mode 100644 index 0000000..148c73d --- /dev/null +++ b/libraries/elementary/src/lib/elc_fileselector.c | |||
@@ -0,0 +1,1249 @@ | |||
1 | /* | ||
2 | * TODO: | ||
3 | * - child elements focusing support | ||
4 | * - user defined icon/label cb | ||
5 | * - show/hide/add buttons ??? | ||
6 | * - show/hide hidden files | ||
7 | * - double click to choose a file | ||
8 | * - multi-selection | ||
9 | * - make variable/function names that are sensible | ||
10 | * - Filter support | ||
11 | */ | ||
12 | |||
13 | #ifdef HAVE_CONFIG_H | ||
14 | # include "elementary_config.h" | ||
15 | #endif | ||
16 | |||
17 | #ifdef HAVE_EIO | ||
18 | # include <Eio.h> | ||
19 | #endif | ||
20 | |||
21 | #include <Elementary.h> | ||
22 | #include "elm_priv.h" | ||
23 | |||
24 | typedef struct _Widget_Data Widget_Data; | ||
25 | |||
26 | struct _Widget_Data | ||
27 | { | ||
28 | EINA_REFCOUNT; | ||
29 | |||
30 | Evas_Object *edje; | ||
31 | Evas_Object *filename_entry; | ||
32 | Evas_Object *path_entry; | ||
33 | Evas_Object *files_list; | ||
34 | Evas_Object *files_grid; | ||
35 | Evas_Object *up_button; | ||
36 | Evas_Object *home_button; | ||
37 | |||
38 | Evas_Object *ok_button; | ||
39 | Evas_Object *cancel_button; | ||
40 | |||
41 | const char *path; | ||
42 | const char *selection; | ||
43 | Ecore_Idler *sel_idler; | ||
44 | |||
45 | const char *path_separator; | ||
46 | |||
47 | #ifdef HAVE_EIO | ||
48 | Eio_File *current; | ||
49 | #endif | ||
50 | |||
51 | Elm_Fileselector_Mode mode; | ||
52 | |||
53 | Eina_Bool only_folder : 1; | ||
54 | Eina_Bool expand : 1; | ||
55 | }; | ||
56 | |||
57 | struct sel_data | ||
58 | { | ||
59 | Evas_Object *fs; | ||
60 | const char *path; | ||
61 | }; | ||
62 | |||
63 | typedef struct _Widget_Request Widget_Request; | ||
64 | struct _Widget_Request | ||
65 | { | ||
66 | Widget_Data *wd; | ||
67 | Elm_Object_Item *parent; | ||
68 | |||
69 | Evas_Object *obj; | ||
70 | const char *path; | ||
71 | Eina_Bool first : 1; | ||
72 | }; | ||
73 | |||
74 | typedef enum { | ||
75 | ELM_DIRECTORY = 0, | ||
76 | ELM_FILE_IMAGE = 1, | ||
77 | ELM_FILE_UNKNOW = 2, | ||
78 | ELM_FILE_LAST | ||
79 | } Elm_Fileselector_Type; | ||
80 | |||
81 | static Elm_Genlist_Item_Class *list_itc[ELM_FILE_LAST]; | ||
82 | static Elm_Gengrid_Item_Class *grid_itc[ELM_FILE_LAST]; | ||
83 | |||
84 | static const char *widtype = NULL; | ||
85 | |||
86 | static const char SIG_DIRECTORY_OPEN[] = "directory,open"; | ||
87 | static const char SIG_DONE[] = "done"; | ||
88 | static const char SIG_SELECTED[] = "selected"; | ||
89 | static const Evas_Smart_Cb_Description _signals[] = { | ||
90 | {SIG_DIRECTORY_OPEN, "s"}, | ||
91 | {SIG_DONE, "s"}, | ||
92 | {SIG_SELECTED, "s"}, | ||
93 | {NULL, NULL} | ||
94 | }; | ||
95 | |||
96 | static void _populate(Evas_Object *obj, | ||
97 | const char *path, | ||
98 | Elm_Object_Item *parent); | ||
99 | static void _do_anchors(Evas_Object *obj, | ||
100 | const char *path); | ||
101 | |||
102 | /*** ELEMENTARY WIDGET ***/ | ||
103 | static void | ||
104 | _widget_data_free(Widget_Data *wd) | ||
105 | { | ||
106 | if (wd->path) eina_stringshare_del(wd->path); | ||
107 | if (wd->selection) eina_stringshare_del(wd->selection); | ||
108 | if (wd->sel_idler) | ||
109 | { | ||
110 | void *sd; | ||
111 | |||
112 | sd = ecore_idler_del(wd->sel_idler); | ||
113 | free(sd); | ||
114 | } | ||
115 | free(wd); | ||
116 | } | ||
117 | |||
118 | static void | ||
119 | _del_hook(Evas_Object *obj) | ||
120 | { | ||
121 | Widget_Data *wd; | ||
122 | int i; | ||
123 | |||
124 | wd = elm_widget_data_get(obj); | ||
125 | if (!wd) return; | ||
126 | |||
127 | for (i = 0; i < ELM_FILE_LAST; ++i) | ||
128 | { | ||
129 | elm_genlist_item_class_free(list_itc[i]); | ||
130 | elm_gengrid_item_class_free(grid_itc[i]); | ||
131 | } | ||
132 | |||
133 | #ifdef HAVE_EIO | ||
134 | if (wd->current) | ||
135 | eio_file_cancel(wd->current); | ||
136 | #endif | ||
137 | |||
138 | wd->files_list = NULL; | ||
139 | wd->files_grid = NULL; | ||
140 | |||
141 | EINA_REFCOUNT_UNREF(wd) | ||
142 | _widget_data_free(wd); | ||
143 | } | ||
144 | |||
145 | static void | ||
146 | _sizing_eval(Evas_Object *obj) | ||
147 | { | ||
148 | Widget_Data *wd = elm_widget_data_get(obj); | ||
149 | Evas_Coord minw = -1, minh = -1; | ||
150 | if (!wd) return; | ||
151 | elm_coords_finger_size_adjust(1, &minw, 1, &minh); | ||
152 | edje_object_size_min_restricted_calc(wd->edje, &minw, &minh, minw, minh); | ||
153 | evas_object_size_hint_min_set(obj, minw, minh); | ||
154 | } | ||
155 | |||
156 | static void | ||
157 | _mirrored_set(Evas_Object *obj, Eina_Bool rtl) | ||
158 | { | ||
159 | Widget_Data *wd = elm_widget_data_get(obj); | ||
160 | if (!wd) return; | ||
161 | elm_widget_mirrored_set(wd->cancel_button, rtl); | ||
162 | elm_widget_mirrored_set(wd->ok_button, rtl); | ||
163 | elm_widget_mirrored_set(wd->files_list, rtl); | ||
164 | elm_widget_mirrored_set(wd->up_button, rtl); | ||
165 | elm_widget_mirrored_set(wd->home_button, rtl); | ||
166 | edje_object_mirrored_set(wd->edje, rtl); | ||
167 | } | ||
168 | |||
169 | static void | ||
170 | _theme_hook(Evas_Object *obj) | ||
171 | { | ||
172 | Widget_Data *wd = elm_widget_data_get(obj); | ||
173 | const char *style = elm_widget_style_get(obj); | ||
174 | const char *data; | ||
175 | char buf[1024]; | ||
176 | |||
177 | if (!wd) return; | ||
178 | _elm_widget_mirrored_reload(obj); | ||
179 | |||
180 | _elm_theme_object_set(obj, wd->edje, "fileselector", "base", style); | ||
181 | |||
182 | if (elm_object_disabled_get(obj)) | ||
183 | edje_object_signal_emit(wd->edje, "elm,state,disabled", "elm"); | ||
184 | |||
185 | data = edje_object_data_get(wd->edje, "path_separator"); | ||
186 | if (data) | ||
187 | wd->path_separator = data; | ||
188 | else | ||
189 | wd->path_separator = "/"; | ||
190 | |||
191 | if (!style) style = "default"; | ||
192 | snprintf(buf, sizeof(buf), "fileselector/%s", style); | ||
193 | |||
194 | #define SWALLOW(part_name, object_ptn) \ | ||
195 | if (object_ptn) \ | ||
196 | { \ | ||
197 | elm_widget_style_set(object_ptn, buf); \ | ||
198 | if (edje_object_part_swallow(wd->edje, part_name, object_ptn)) \ | ||
199 | evas_object_show(object_ptn); \ | ||
200 | else \ | ||
201 | evas_object_hide(object_ptn); \ | ||
202 | } | ||
203 | SWALLOW("elm.swallow.up", wd->up_button); | ||
204 | SWALLOW("elm.swallow.home", wd->home_button); | ||
205 | |||
206 | if (wd->mode == ELM_FILESELECTOR_LIST) | ||
207 | { | ||
208 | if (edje_object_part_swallow(wd->edje, "elm.swallow.files", | ||
209 | wd->files_list)) | ||
210 | { | ||
211 | evas_object_show(wd->files_list); | ||
212 | evas_object_hide(wd->files_grid); | ||
213 | } | ||
214 | else | ||
215 | evas_object_hide(wd->files_list); | ||
216 | } | ||
217 | else | ||
218 | { | ||
219 | if (edje_object_part_swallow(wd->edje, "elm.swallow.files", | ||
220 | wd->files_grid)) | ||
221 | { | ||
222 | evas_object_show(wd->files_grid); | ||
223 | evas_object_hide(wd->files_list); | ||
224 | } | ||
225 | else | ||
226 | evas_object_hide(wd->files_grid); | ||
227 | } | ||
228 | |||
229 | SWALLOW("elm.swallow.filename", wd->filename_entry); | ||
230 | SWALLOW("elm.swallow.path", wd->path_entry); | ||
231 | |||
232 | snprintf(buf, sizeof(buf), "fileselector/actions/%s", style); | ||
233 | SWALLOW("elm.swallow.cancel", wd->cancel_button); | ||
234 | SWALLOW("elm.swallow.ok", wd->ok_button); | ||
235 | #undef SWALLOW | ||
236 | |||
237 | edje_object_message_signal_process(wd->edje); | ||
238 | _mirrored_set(obj, elm_widget_mirrored_get(obj)); | ||
239 | edje_object_scale_set | ||
240 | (wd->edje, elm_widget_scale_get(obj) * _elm_config->scale); | ||
241 | _sizing_eval(obj); | ||
242 | } | ||
243 | |||
244 | /*** GENLIST "MODEL" ***/ | ||
245 | static char * | ||
246 | _itc_text_get(void *data, | ||
247 | Evas_Object *obj __UNUSED__, | ||
248 | const char *source __UNUSED__) | ||
249 | { | ||
250 | return elm_entry_utf8_to_markup(ecore_file_file_get(data)); /* NOTE this will be | ||
251 | * free() by the | ||
252 | * caller */ | ||
253 | } | ||
254 | |||
255 | static Evas_Object * | ||
256 | _itc_icon_folder_get(void *data __UNUSED__, | ||
257 | Evas_Object *obj, | ||
258 | const char *source) | ||
259 | { | ||
260 | Evas_Object *ic; | ||
261 | |||
262 | if (strcmp(source, "elm.swallow.icon")) return NULL; | ||
263 | |||
264 | ic = elm_icon_add(obj); | ||
265 | elm_icon_standard_set(ic, "folder"); | ||
266 | |||
267 | evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, | ||
268 | 1, 1); | ||
269 | return ic; | ||
270 | } | ||
271 | |||
272 | static Evas_Object * | ||
273 | _itc_icon_image_get(void *data, | ||
274 | Evas_Object *obj, | ||
275 | const char *source) | ||
276 | { | ||
277 | const char *filename = data; | ||
278 | Evas_Object *ic; | ||
279 | |||
280 | if (strcmp(source, "elm.swallow.icon")) return NULL; | ||
281 | |||
282 | ic = elm_icon_add(obj); | ||
283 | elm_icon_standard_set(ic, "image"); | ||
284 | elm_icon_thumb_set(ic, filename, NULL); | ||
285 | |||
286 | evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, | ||
287 | 1, 1); | ||
288 | return ic; | ||
289 | } | ||
290 | |||
291 | static Evas_Object * | ||
292 | _itc_icon_file_get(void *data __UNUSED__, | ||
293 | Evas_Object *obj, | ||
294 | const char *source) | ||
295 | { | ||
296 | Evas_Object *ic; | ||
297 | |||
298 | if (strcmp(source, "elm.swallow.icon")) return NULL; | ||
299 | |||
300 | ic = elm_icon_add(obj); | ||
301 | elm_icon_standard_set(ic, "file"); | ||
302 | |||
303 | evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, | ||
304 | 1, 1); | ||
305 | return ic; | ||
306 | } | ||
307 | |||
308 | static Eina_Bool | ||
309 | _itc_state_get(void *data __UNUSED__, | ||
310 | Evas_Object *obj __UNUSED__, | ||
311 | const char *source __UNUSED__) | ||
312 | { | ||
313 | return EINA_FALSE; | ||
314 | } | ||
315 | |||
316 | static void | ||
317 | _itc_del(void *data, | ||
318 | Evas_Object *obj __UNUSED__) | ||
319 | { | ||
320 | eina_stringshare_del(data); | ||
321 | } | ||
322 | |||
323 | static void | ||
324 | _expand_done(void *data, | ||
325 | Evas_Object *obj __UNUSED__, | ||
326 | void *event_info) | ||
327 | { | ||
328 | Elm_Object_Item *it = event_info; | ||
329 | const char *path = elm_object_item_data_get(it); | ||
330 | _populate(data, path, it); | ||
331 | } | ||
332 | |||
333 | static void | ||
334 | _contract_done(void *data __UNUSED__, | ||
335 | Evas_Object *obj __UNUSED__, | ||
336 | void *event_info) | ||
337 | { | ||
338 | Elm_Object_Item *it = event_info; | ||
339 | elm_genlist_item_subitems_clear(it); | ||
340 | } | ||
341 | |||
342 | static void | ||
343 | _expand_req(void *data __UNUSED__, | ||
344 | Evas_Object *obj __UNUSED__, | ||
345 | void *event_info) | ||
346 | { | ||
347 | Elm_Object_Item *it = event_info; | ||
348 | elm_genlist_item_expanded_set(it, EINA_TRUE); | ||
349 | } | ||
350 | |||
351 | static void | ||
352 | _contract_req(void *data __UNUSED__, | ||
353 | Evas_Object *obj __UNUSED__, | ||
354 | void *event_info) | ||
355 | { | ||
356 | Elm_Object_Item *it = event_info; | ||
357 | elm_genlist_item_expanded_set(it, EINA_FALSE); | ||
358 | } | ||
359 | |||
360 | /*** PRIVATES ***/ | ||
361 | static Eina_Bool | ||
362 | _sel_do(void *data) | ||
363 | { | ||
364 | struct sel_data *sd; | ||
365 | const char *path; | ||
366 | Widget_Data *wd; | ||
367 | const char *p; | ||
368 | |||
369 | sd = data; | ||
370 | wd = elm_widget_data_get(sd->fs); | ||
371 | path = sd->path; | ||
372 | |||
373 | if ((!wd->only_folder) && ecore_file_is_dir(path)) | ||
374 | { | ||
375 | if (wd->expand && wd->mode == ELM_FILESELECTOR_LIST) | ||
376 | { | ||
377 | _do_anchors(sd->fs, path); | ||
378 | elm_object_text_set(wd->filename_entry, ""); | ||
379 | } | ||
380 | else | ||
381 | { | ||
382 | /* keep a ref to path 'couse it will be destroyed by _populate */ | ||
383 | p = eina_stringshare_add(path); | ||
384 | _populate(sd->fs, p, NULL); | ||
385 | eina_stringshare_del(p); | ||
386 | } | ||
387 | goto end; | ||
388 | } | ||
389 | else /* navigating through folders only or file is not a dir. */ | ||
390 | { | ||
391 | char *s; | ||
392 | |||
393 | if (wd->expand && wd->mode == ELM_FILESELECTOR_LIST) | ||
394 | _do_anchors(sd->fs, path); | ||
395 | else if (wd->only_folder) | ||
396 | { | ||
397 | /* keep a ref to path 'couse it will be destroyed by _populate */ | ||
398 | p = eina_stringshare_add(path); | ||
399 | _populate(sd->fs, p, NULL); | ||
400 | eina_stringshare_del(p); | ||
401 | } | ||
402 | s = elm_entry_utf8_to_markup(ecore_file_file_get(path)); | ||
403 | if (s) | ||
404 | { | ||
405 | elm_object_text_set(wd->filename_entry, s); | ||
406 | free(s); | ||
407 | } | ||
408 | else | ||
409 | elm_object_text_set(wd->filename_entry, ""); | ||
410 | } | ||
411 | |||
412 | evas_object_smart_callback_call(sd->fs, SIG_SELECTED, (void *)path); | ||
413 | |||
414 | end: | ||
415 | wd->sel_idler = NULL; | ||
416 | free(sd); | ||
417 | return ECORE_CALLBACK_CANCEL; | ||
418 | } | ||
419 | |||
420 | static void | ||
421 | _sel(void *data, | ||
422 | Evas_Object *obj __UNUSED__, | ||
423 | void *event_info) | ||
424 | { | ||
425 | struct sel_data *sd; | ||
426 | Widget_Data *wd; | ||
427 | void *old_sd; | ||
428 | char *dir; | ||
429 | //This event_info could be a list or gengrid item | ||
430 | Elm_Object_Item *it = event_info; | ||
431 | |||
432 | wd = elm_widget_data_get(data); | ||
433 | if (!wd) return; | ||
434 | |||
435 | sd = malloc(sizeof(*sd)); | ||
436 | sd->fs = data; | ||
437 | sd->path = elm_object_item_data_get(it); | ||
438 | |||
439 | if (!sd->path) | ||
440 | { | ||
441 | eina_stringshare_replace(&wd->path, ""); | ||
442 | goto end; | ||
443 | } | ||
444 | |||
445 | dir = wd->only_folder ? strdup(sd->path) : ecore_file_dir_get(sd->path); | ||
446 | if (dir) | ||
447 | { | ||
448 | eina_stringshare_replace(&wd->path, dir); | ||
449 | free(dir); | ||
450 | } | ||
451 | else | ||
452 | { | ||
453 | eina_stringshare_replace(&wd->path, ""); | ||
454 | } | ||
455 | |||
456 | end: | ||
457 | if (wd->sel_idler) | ||
458 | { | ||
459 | old_sd = ecore_idler_del(wd->sel_idler); | ||
460 | free(old_sd); | ||
461 | } | ||
462 | wd->sel_idler = ecore_idler_add(_sel_do, sd); | ||
463 | } | ||
464 | |||
465 | static void | ||
466 | _up(void *data, | ||
467 | Evas_Object *obj __UNUSED__, | ||
468 | void *event_info __UNUSED__) | ||
469 | { | ||
470 | Evas_Object *fs = data; | ||
471 | char *parent; | ||
472 | |||
473 | Widget_Data *wd = elm_widget_data_get(fs); | ||
474 | if (!wd) return; | ||
475 | parent = ecore_file_dir_get(wd->path); | ||
476 | _populate(fs, parent, NULL); | ||
477 | free(parent); | ||
478 | } | ||
479 | |||
480 | static void | ||
481 | _home(void *data, | ||
482 | Evas_Object *obj __UNUSED__, | ||
483 | void *event_info __UNUSED__) | ||
484 | { | ||
485 | Evas_Object *fs = data; | ||
486 | _populate(fs, getenv("HOME"), NULL); | ||
487 | } | ||
488 | |||
489 | static void | ||
490 | _ok(void *data, | ||
491 | Evas_Object *obj __UNUSED__, | ||
492 | void *event_info __UNUSED__) | ||
493 | { | ||
494 | Evas_Object *fs = data; | ||
495 | evas_object_smart_callback_call(fs, SIG_DONE, | ||
496 | (void *)elm_fileselector_selected_get(fs)); | ||
497 | } | ||
498 | |||
499 | static void | ||
500 | _canc(void *data, | ||
501 | Evas_Object *obj __UNUSED__, | ||
502 | void *event_info __UNUSED__) | ||
503 | { | ||
504 | Evas_Object *fs = data; | ||
505 | evas_object_smart_callback_call(fs, SIG_DONE, NULL); | ||
506 | } | ||
507 | |||
508 | static void | ||
509 | _anchor_clicked(void *data, | ||
510 | Evas_Object *obj __UNUSED__, | ||
511 | void *event_info) | ||
512 | { | ||
513 | Evas_Object *fs = data; | ||
514 | Widget_Data *wd = elm_widget_data_get(fs); | ||
515 | Elm_Entry_Anchor_Info *info = event_info; | ||
516 | const char *p; | ||
517 | if (!wd) return; | ||
518 | // keep a ref to path 'couse it will be destroyed by _populate | ||
519 | p = eina_stringshare_add(info->name); | ||
520 | _populate(fs, p, NULL); | ||
521 | evas_object_smart_callback_call(data, SIG_SELECTED, (void *)p); | ||
522 | eina_stringshare_del(p); | ||
523 | } | ||
524 | |||
525 | static void | ||
526 | _do_anchors(Evas_Object *obj, | ||
527 | const char *path) | ||
528 | { | ||
529 | Widget_Data *wd = elm_widget_data_get(obj); | ||
530 | char **tok, buf[PATH_MAX * 3], *s; | ||
531 | int i, j; | ||
532 | |||
533 | if (!wd) return; | ||
534 | s = elm_entry_utf8_to_markup(path); | ||
535 | if (!s) return; | ||
536 | buf[0] = '\0'; | ||
537 | tok = eina_str_split(s, "/", 0); | ||
538 | free(s); | ||
539 | eina_strlcat(buf, "<a href=/>root</a>", sizeof(buf)); | ||
540 | for (i = 0; tok[i]; i++) | ||
541 | { | ||
542 | if ((!tok[i]) || (!tok[i][0])) continue; | ||
543 | eina_strlcat(buf, wd->path_separator, sizeof(buf)); | ||
544 | eina_strlcat(buf, "<a href=", sizeof(buf)); | ||
545 | for (j = 0; j <= i; j++) | ||
546 | { | ||
547 | if (strlen(tok[j]) < 1) continue; | ||
548 | eina_strlcat(buf, "/", sizeof(buf)); | ||
549 | eina_strlcat(buf, tok[j], sizeof(buf)); | ||
550 | } | ||
551 | eina_strlcat(buf, ">", sizeof(buf)); | ||
552 | eina_strlcat(buf, tok[i], sizeof(buf)); | ||
553 | eina_strlcat(buf, "</a>", sizeof(buf)); | ||
554 | } | ||
555 | free(tok[0]); | ||
556 | free(tok); | ||
557 | |||
558 | elm_object_text_set(wd->path_entry, buf); | ||
559 | } | ||
560 | |||
561 | #ifdef HAVE_EIO | ||
562 | static Eina_Bool | ||
563 | _filter_cb(void *data __UNUSED__, Eio_File *handler, const Eina_File_Direct_Info *info) | ||
564 | { | ||
565 | const char *filename; | ||
566 | |||
567 | if (info->path[info->name_start] == '.') | ||
568 | return EINA_FALSE; | ||
569 | |||
570 | filename = eina_stringshare_add(info->path); | ||
571 | eio_file_associate_direct_add(handler, "filename", filename, EINA_FREE_CB(eina_stringshare_del)); | ||
572 | |||
573 | if (info->type == EINA_FILE_DIR) | ||
574 | { | ||
575 | eio_file_associate_direct_add(handler, "type/grid", grid_itc[ELM_DIRECTORY], NULL); | ||
576 | eio_file_associate_direct_add(handler, "type/list", list_itc[ELM_DIRECTORY], NULL); | ||
577 | } | ||
578 | else | ||
579 | { | ||
580 | if (evas_object_image_extension_can_load_get(info->path + info->name_start)) | ||
581 | { | ||
582 | eio_file_associate_direct_add(handler, "type/grid", grid_itc[ELM_FILE_IMAGE], NULL); | ||
583 | eio_file_associate_direct_add(handler, "type/list", list_itc[ELM_FILE_IMAGE], NULL); | ||
584 | } | ||
585 | else | ||
586 | { | ||
587 | eio_file_associate_direct_add(handler, "type/grid", grid_itc[ELM_FILE_UNKNOW], NULL); | ||
588 | eio_file_associate_direct_add(handler, "type/list", list_itc[ELM_FILE_UNKNOW], NULL); | ||
589 | } | ||
590 | } | ||
591 | |||
592 | return EINA_TRUE; | ||
593 | } | ||
594 | |||
595 | static int | ||
596 | _file_grid_cmp(const void *a, const void *b) | ||
597 | { | ||
598 | const Elm_Object_Item *ga = a; | ||
599 | const Elm_Object_Item *gb = b; | ||
600 | const Elm_Gengrid_Item_Class *ca = elm_gengrid_item_item_class_get(ga); | ||
601 | const Elm_Gengrid_Item_Class *cb = elm_gengrid_item_item_class_get(gb); | ||
602 | |||
603 | if (ca == grid_itc[ELM_DIRECTORY]) | ||
604 | { | ||
605 | if (cb != grid_itc[ELM_DIRECTORY]) | ||
606 | return -1; | ||
607 | } | ||
608 | else if (cb == grid_itc[ELM_DIRECTORY]) | ||
609 | { | ||
610 | return 1; | ||
611 | } | ||
612 | |||
613 | return strcoll(elm_object_item_data_get(ga), elm_object_item_data_get(gb)); | ||
614 | } | ||
615 | |||
616 | static int | ||
617 | _file_list_cmp(const void *a, const void *b) | ||
618 | { | ||
619 | const Elm_Object_Item *la = a; | ||
620 | const Elm_Object_Item *lb = b; | ||
621 | const Elm_Genlist_Item_Class *ca = elm_genlist_item_item_class_get(la); | ||
622 | const Elm_Genlist_Item_Class *cb = elm_genlist_item_item_class_get(lb); | ||
623 | |||
624 | if (ca == list_itc[ELM_DIRECTORY]) | ||
625 | { | ||
626 | if (cb != list_itc[ELM_DIRECTORY]) | ||
627 | return -1; | ||
628 | } | ||
629 | else if (cb == list_itc[ELM_DIRECTORY]) | ||
630 | { | ||
631 | return 1; | ||
632 | } | ||
633 | |||
634 | return strcoll(elm_object_item_data_get(la), elm_object_item_data_get(lb)); | ||
635 | } | ||
636 | |||
637 | static void | ||
638 | _signal_first(Widget_Request *wr) | ||
639 | { | ||
640 | if (!wr->first) return ; | ||
641 | evas_object_smart_callback_call(wr->obj, SIG_DIRECTORY_OPEN, (void *)wr->path); | ||
642 | if (!wr->parent) | ||
643 | { | ||
644 | elm_genlist_clear(wr->wd->files_list); | ||
645 | elm_gengrid_clear(wr->wd->files_grid); | ||
646 | eina_stringshare_replace(&wr->wd->path, wr->path); | ||
647 | _do_anchors(wr->obj, wr->path); | ||
648 | } | ||
649 | |||
650 | if (wr->wd->filename_entry) elm_object_text_set(wr->wd->filename_entry, ""); | ||
651 | |||
652 | wr->first = EINA_FALSE; | ||
653 | } | ||
654 | |||
655 | static void | ||
656 | _main_cb(void *data, Eio_File *handler, const Eina_File_Direct_Info *info __UNUSED__) | ||
657 | { | ||
658 | Widget_Request *wr = data; | ||
659 | |||
660 | if (eio_file_check(handler)) | ||
661 | return ; | ||
662 | if (!wr->wd->files_list || !wr->wd->files_grid || wr->wd->current != handler) | ||
663 | { | ||
664 | eio_file_cancel(handler); | ||
665 | return ; | ||
666 | } | ||
667 | |||
668 | _signal_first(wr); | ||
669 | |||
670 | if (wr->wd->mode == ELM_FILESELECTOR_LIST) | ||
671 | { | ||
672 | Eina_Bool is_dir = (eio_file_associate_find(handler, "type/list") == list_itc[ELM_DIRECTORY]); | ||
673 | |||
674 | elm_genlist_item_sorted_insert(wr->wd->files_list, eio_file_associate_find(handler, "type/list"), | ||
675 | eina_stringshare_ref(eio_file_associate_find(handler, "filename")), | ||
676 | wr->parent, wr->wd->expand && is_dir ? ELM_GENLIST_ITEM_TREE : ELM_GENLIST_ITEM_NONE, | ||
677 | _file_list_cmp, NULL, NULL); | ||
678 | } | ||
679 | else if (wr->wd->mode == ELM_FILESELECTOR_GRID) | ||
680 | elm_gengrid_item_sorted_insert(wr->wd->files_grid, eio_file_associate_find(handler, "type/grid"), | ||
681 | eina_stringshare_ref(eio_file_associate_find(handler, "filename")), | ||
682 | _file_grid_cmp, NULL, NULL); | ||
683 | } | ||
684 | |||
685 | static void | ||
686 | _widget_request_cleanup(Widget_Request *wr) | ||
687 | { | ||
688 | EINA_REFCOUNT_UNREF(wr->wd) | ||
689 | _widget_data_free(wr->wd); | ||
690 | |||
691 | eina_stringshare_del(wr->path); | ||
692 | free(wr); | ||
693 | } | ||
694 | |||
695 | static void | ||
696 | _done_cb(void *data, Eio_File *handler __UNUSED__) | ||
697 | { | ||
698 | Widget_Request *wr = data; | ||
699 | |||
700 | _signal_first(wr); | ||
701 | |||
702 | wr->wd->current = NULL; | ||
703 | _widget_request_cleanup(wr); | ||
704 | } | ||
705 | |||
706 | static void | ||
707 | _error_cb(void *data, Eio_File *handler, int error __UNUSED__) | ||
708 | { | ||
709 | Widget_Request *wr = data; | ||
710 | |||
711 | if (wr->wd->current == handler) | ||
712 | wr->wd->current = NULL; | ||
713 | _widget_request_cleanup(wr); | ||
714 | } | ||
715 | |||
716 | #endif | ||
717 | |||
718 | static void | ||
719 | _populate(Evas_Object *obj, | ||
720 | const char *path, | ||
721 | Elm_Object_Item *parent) | ||
722 | { | ||
723 | Widget_Data *wd = elm_widget_data_get(obj); | ||
724 | #ifdef HAVE_EIO | ||
725 | Widget_Request *wr; | ||
726 | #else | ||
727 | Eina_File_Direct_Info *file; | ||
728 | Eina_Iterator *it; | ||
729 | const char *real; | ||
730 | Eina_List *files = NULL, *dirs = NULL; | ||
731 | #endif | ||
732 | |||
733 | if (!wd) return; | ||
734 | #ifndef HAVE_EIO | ||
735 | if (!ecore_file_is_dir(path)) return ; | ||
736 | it = eina_file_stat_ls(path); | ||
737 | if (!it) return ; | ||
738 | evas_object_smart_callback_call(obj, SIG_DIRECTORY_OPEN, (void *)path); | ||
739 | if (!parent) | ||
740 | { | ||
741 | elm_genlist_clear(wd->files_list); | ||
742 | elm_gengrid_clear(wd->files_grid); | ||
743 | eina_stringshare_replace(&wd->path, path); | ||
744 | _do_anchors(obj, path); | ||
745 | } | ||
746 | |||
747 | if (wd->filename_entry) elm_object_text_set(wd->filename_entry, ""); | ||
748 | EINA_ITERATOR_FOREACH(it, file) | ||
749 | { | ||
750 | const char *filename; | ||
751 | |||
752 | if (file->path[file->name_start] == '.') | ||
753 | continue ; | ||
754 | |||
755 | filename = eina_stringshare_add(file->path); | ||
756 | if (file->type == EINA_FILE_DIR) | ||
757 | dirs = eina_list_append(dirs, filename); | ||
758 | else if (!wd->only_folder) | ||
759 | files = eina_list_append(files, filename); | ||
760 | } | ||
761 | eina_iterator_free(it); | ||
762 | |||
763 | files = eina_list_sort(files, eina_list_count(files), | ||
764 | EINA_COMPARE_CB(strcoll)); | ||
765 | dirs = eina_list_sort(dirs, eina_list_count(dirs), EINA_COMPARE_CB(strcoll)); | ||
766 | EINA_LIST_FREE(dirs, real) | ||
767 | { | ||
768 | if (wd->mode == ELM_FILESELECTOR_LIST) | ||
769 | elm_genlist_item_append(wd->files_list, list_itc[ELM_DIRECTORY], | ||
770 | real, /* item data */ | ||
771 | parent, | ||
772 | wd->expand ? ELM_GENLIST_ITEM_TREE : | ||
773 | ELM_GENLIST_ITEM_NONE, | ||
774 | NULL, NULL); | ||
775 | else if (wd->mode == ELM_FILESELECTOR_GRID) | ||
776 | elm_gengrid_item_append(wd->files_grid, grid_itc[ELM_DIRECTORY], | ||
777 | real, /* item data */ | ||
778 | NULL, NULL); | ||
779 | } | ||
780 | |||
781 | EINA_LIST_FREE(files, real) | ||
782 | { | ||
783 | Elm_Fileselector_Type type = evas_object_image_extension_can_load_fast_get(real) ? | ||
784 | ELM_FILE_IMAGE : ELM_FILE_UNKNOW; | ||
785 | |||
786 | if (wd->mode == ELM_FILESELECTOR_LIST) | ||
787 | elm_genlist_item_append(wd->files_list, list_itc[type], | ||
788 | real, /* item data */ | ||
789 | parent, ELM_GENLIST_ITEM_NONE, | ||
790 | NULL, NULL); | ||
791 | else if (wd->mode == ELM_FILESELECTOR_GRID) | ||
792 | elm_gengrid_item_append(wd->files_grid, grid_itc[type], | ||
793 | real, /* item data */ | ||
794 | NULL, NULL); | ||
795 | } | ||
796 | #else | ||
797 | if (wd->expand && wd->current) return ; | ||
798 | if (wd->current) | ||
799 | eio_file_cancel(wd->current); | ||
800 | wr = malloc(sizeof (Widget_Request)); | ||
801 | if (!wr) return ; | ||
802 | wr->wd = wd; | ||
803 | EINA_REFCOUNT_REF(wr->wd); | ||
804 | wr->parent = parent; /* FIXME: should we refcount the parent ? */ | ||
805 | wr->obj = obj; | ||
806 | wr->path = eina_stringshare_add(path); | ||
807 | wr->first = EINA_TRUE; | ||
808 | |||
809 | wd->current = eio_file_stat_ls(path, | ||
810 | _filter_cb, | ||
811 | _main_cb, | ||
812 | _done_cb, | ||
813 | _error_cb, | ||
814 | wr); | ||
815 | #endif | ||
816 | } | ||
817 | |||
818 | /*** API ***/ | ||
819 | |||
820 | EAPI Evas_Object * | ||
821 | elm_fileselector_add(Evas_Object *parent) | ||
822 | { | ||
823 | Evas *e; | ||
824 | Evas_Object *obj, *ic, *bt, *li, *en, *grid; | ||
825 | Widget_Data *wd; | ||
826 | unsigned int i; | ||
827 | int s; | ||
828 | |||
829 | ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); | ||
830 | |||
831 | EINA_REFCOUNT_INIT(wd); | ||
832 | |||
833 | ELM_SET_WIDTYPE(widtype, "fileselector"); | ||
834 | elm_widget_type_set(obj, "fileselector"); | ||
835 | elm_widget_sub_object_add(parent, obj); | ||
836 | elm_widget_data_set(obj, wd); | ||
837 | elm_widget_del_hook_set(obj, _del_hook); | ||
838 | elm_widget_theme_hook_set(obj, _theme_hook); | ||
839 | elm_widget_can_focus_set(obj, EINA_FALSE); | ||
840 | |||
841 | wd->expand = !!_elm_config->fileselector_expand_enable; | ||
842 | |||
843 | wd->edje = edje_object_add(e); | ||
844 | _elm_theme_object_set(obj, wd->edje, "fileselector", "base", "default"); | ||
845 | elm_widget_resize_object_set(obj, wd->edje); | ||
846 | |||
847 | // up btn | ||
848 | ic = elm_icon_add(parent); | ||
849 | elm_icon_standard_set(ic, "arrow_up"); | ||
850 | evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); | ||
851 | bt = elm_button_add(parent); | ||
852 | elm_widget_mirrored_automatic_set(bt, EINA_FALSE); | ||
853 | elm_object_part_content_set(bt, "icon", ic); | ||
854 | elm_object_domain_translatable_text_set(bt, PACKAGE, N_("Up")); | ||
855 | evas_object_size_hint_align_set(bt, 0.0, 0.0); | ||
856 | |||
857 | evas_object_smart_callback_add(bt, "clicked", _up, obj); | ||
858 | |||
859 | elm_widget_sub_object_add(obj, bt); | ||
860 | wd->up_button = bt; | ||
861 | |||
862 | // home btn | ||
863 | ic = elm_icon_add(parent); | ||
864 | elm_icon_standard_set(ic, "home"); | ||
865 | evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); | ||
866 | bt = elm_button_add(parent); | ||
867 | elm_widget_mirrored_automatic_set(bt, EINA_FALSE); | ||
868 | elm_object_part_content_set(bt, "icon", ic); | ||
869 | elm_object_domain_translatable_text_set(bt, PACKAGE, N_("Home")); | ||
870 | evas_object_size_hint_align_set(bt, 0.0, 0.0); | ||
871 | |||
872 | evas_object_smart_callback_add(bt, "clicked", _home, obj); | ||
873 | |||
874 | elm_widget_sub_object_add(obj, bt); | ||
875 | wd->home_button = bt; | ||
876 | |||
877 | for (i = 0; i < ELM_FILE_LAST; ++i) | ||
878 | { | ||
879 | list_itc[i] = elm_genlist_item_class_new(); | ||
880 | grid_itc[i] = elm_gengrid_item_class_new(); | ||
881 | |||
882 | list_itc[i]->item_style = "default"; | ||
883 | list_itc[i]->func.text_get = grid_itc[i]->func.text_get = _itc_text_get; | ||
884 | list_itc[i]->func.state_get = grid_itc[i]->func.state_get = _itc_state_get; | ||
885 | list_itc[i]->func.del = grid_itc[i]->func.del = _itc_del; | ||
886 | } | ||
887 | |||
888 | list_itc[ELM_DIRECTORY]->func.content_get = | ||
889 | grid_itc[ELM_DIRECTORY]->func.content_get = _itc_icon_folder_get; | ||
890 | list_itc[ELM_FILE_IMAGE]->func.content_get = | ||
891 | grid_itc[ELM_FILE_IMAGE]->func.content_get = _itc_icon_image_get; | ||
892 | list_itc[ELM_FILE_UNKNOW]->func.content_get = | ||
893 | grid_itc[ELM_FILE_UNKNOW]->func.content_get = _itc_icon_file_get; | ||
894 | |||
895 | li = elm_genlist_add(parent); | ||
896 | elm_widget_mirrored_automatic_set(li, EINA_FALSE); | ||
897 | evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL); | ||
898 | evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); | ||
899 | evas_object_size_hint_min_set(li, 100, 100); | ||
900 | |||
901 | grid = elm_gengrid_add(parent); | ||
902 | elm_widget_mirrored_automatic_set(grid, EINA_FALSE); | ||
903 | evas_object_size_hint_align_set(grid, EVAS_HINT_FILL, EVAS_HINT_FILL); | ||
904 | evas_object_size_hint_weight_set(grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); | ||
905 | |||
906 | // XXX: will fail for dynamic finger size changing | ||
907 | s = _elm_config->finger_size * 2; | ||
908 | elm_gengrid_item_size_set(grid, s, s); | ||
909 | elm_gengrid_align_set(grid, 0.0, 0.0); | ||
910 | |||
911 | evas_object_smart_callback_add(li, "selected", _sel, obj); | ||
912 | evas_object_smart_callback_add(li, "expand,request", _expand_req, obj); | ||
913 | evas_object_smart_callback_add(li, "contract,request", _contract_req, obj); | ||
914 | evas_object_smart_callback_add(li, "expanded", _expand_done, obj); | ||
915 | evas_object_smart_callback_add(li, "contracted", _contract_done, obj); | ||
916 | |||
917 | evas_object_smart_callback_add(grid, "selected", _sel, obj); | ||
918 | |||
919 | elm_widget_sub_object_add(obj, li); | ||
920 | elm_widget_sub_object_add(obj, grid); | ||
921 | wd->files_list = li; | ||
922 | wd->files_grid = grid; | ||
923 | |||
924 | // path entry | ||
925 | en = elm_entry_add(parent); | ||
926 | elm_entry_scrollable_set(en, EINA_TRUE); | ||
927 | elm_widget_mirrored_automatic_set(en, EINA_FALSE); | ||
928 | elm_entry_editable_set(en, EINA_FALSE); | ||
929 | elm_entry_single_line_set(en, EINA_TRUE); | ||
930 | elm_entry_line_wrap_set(en, ELM_WRAP_CHAR); | ||
931 | evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); | ||
932 | evas_object_size_hint_align_set(en, EVAS_HINT_FILL, EVAS_HINT_FILL); | ||
933 | |||
934 | evas_object_smart_callback_add(en, "anchor,clicked", _anchor_clicked, obj); | ||
935 | |||
936 | elm_widget_sub_object_add(obj, en); | ||
937 | wd->path_entry = en; | ||
938 | |||
939 | // filename entry | ||
940 | en = elm_entry_add(parent); | ||
941 | elm_entry_scrollable_set(en, EINA_TRUE); | ||
942 | elm_widget_mirrored_automatic_set(en, EINA_FALSE); | ||
943 | elm_entry_editable_set(en, EINA_TRUE); | ||
944 | elm_entry_single_line_set(en, EINA_TRUE); | ||
945 | elm_entry_line_wrap_set(en, ELM_WRAP_CHAR); | ||
946 | evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); | ||
947 | evas_object_size_hint_align_set(en, EVAS_HINT_FILL, EVAS_HINT_FILL); | ||
948 | |||
949 | elm_widget_sub_object_add(obj, en); | ||
950 | wd->filename_entry = en; | ||
951 | |||
952 | elm_fileselector_buttons_ok_cancel_set(obj, EINA_TRUE); | ||
953 | elm_fileselector_is_save_set(obj, EINA_FALSE); | ||
954 | |||
955 | _theme_hook(obj); | ||
956 | |||
957 | evas_object_smart_callbacks_descriptions_set(obj, _signals); | ||
958 | return obj; | ||
959 | } | ||
960 | |||
961 | EAPI void | ||
962 | elm_fileselector_is_save_set(Evas_Object *obj, | ||
963 | Eina_Bool is_save) | ||
964 | { | ||
965 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
966 | Widget_Data *wd = elm_widget_data_get(obj); | ||
967 | if (!wd) return; | ||
968 | |||
969 | elm_object_disabled_set(wd->filename_entry, !is_save); | ||
970 | |||
971 | if (is_save) | ||
972 | edje_object_signal_emit(wd->edje, "elm,state,save,on", "elm"); | ||
973 | else | ||
974 | edje_object_signal_emit(wd->edje, "elm,state,save,off", "elm"); | ||
975 | } | ||
976 | |||
977 | EAPI Eina_Bool | ||
978 | elm_fileselector_is_save_get(const Evas_Object *obj) | ||
979 | { | ||
980 | ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; | ||
981 | Widget_Data *wd = elm_widget_data_get(obj); | ||
982 | if (!wd) return EINA_FALSE; | ||
983 | return !elm_object_disabled_get(wd->filename_entry); | ||
984 | } | ||
985 | |||
986 | EAPI void | ||
987 | elm_fileselector_folder_only_set(Evas_Object *obj, | ||
988 | Eina_Bool only) | ||
989 | { | ||
990 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
991 | Widget_Data *wd = elm_widget_data_get(obj); | ||
992 | if (!wd) return; | ||
993 | if (wd->only_folder == only) return; | ||
994 | wd->only_folder = !!only; | ||
995 | if (wd->path) _populate(obj, wd->path, NULL); | ||
996 | } | ||
997 | |||
998 | EAPI Eina_Bool | ||
999 | elm_fileselector_folder_only_get(const Evas_Object *obj) | ||
1000 | { | ||
1001 | ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; | ||
1002 | Widget_Data *wd = elm_widget_data_get(obj); | ||
1003 | if (!wd) return EINA_FALSE; | ||
1004 | return wd->only_folder; | ||
1005 | } | ||
1006 | |||
1007 | EAPI void | ||
1008 | elm_fileselector_buttons_ok_cancel_set(Evas_Object *obj, | ||
1009 | Eina_Bool visible) | ||
1010 | { | ||
1011 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
1012 | Widget_Data *wd = elm_widget_data_get(obj); | ||
1013 | Evas_Object *bt; | ||
1014 | if (!wd) return; | ||
1015 | |||
1016 | if (visible) | ||
1017 | { | ||
1018 | // cancel btn | ||
1019 | bt = elm_button_add(obj); | ||
1020 | elm_widget_mirrored_automatic_set(bt, EINA_FALSE); | ||
1021 | elm_object_domain_translatable_text_set(bt, PACKAGE, N_("Cancel")); | ||
1022 | |||
1023 | evas_object_smart_callback_add(bt, "clicked", _canc, obj); | ||
1024 | |||
1025 | elm_widget_sub_object_add(obj, bt); | ||
1026 | wd->cancel_button = bt; | ||
1027 | |||
1028 | // ok btn | ||
1029 | bt = elm_button_add(obj); | ||
1030 | elm_widget_mirrored_automatic_set(bt, EINA_FALSE); | ||
1031 | elm_object_domain_translatable_text_set(bt, PACKAGE, N_("OK")); | ||
1032 | |||
1033 | evas_object_smart_callback_add(bt, "clicked", _ok, obj); | ||
1034 | |||
1035 | elm_widget_sub_object_add(obj, bt); | ||
1036 | wd->ok_button = bt; | ||
1037 | |||
1038 | _theme_hook(obj); | ||
1039 | } | ||
1040 | else | ||
1041 | { | ||
1042 | evas_object_del(wd->cancel_button); | ||
1043 | wd->cancel_button = NULL; | ||
1044 | evas_object_del(wd->ok_button); | ||
1045 | wd->ok_button = NULL; | ||
1046 | } | ||
1047 | } | ||
1048 | |||
1049 | EAPI Eina_Bool | ||
1050 | elm_fileselector_buttons_ok_cancel_get(const Evas_Object *obj) | ||
1051 | { | ||
1052 | ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; | ||
1053 | Widget_Data *wd = elm_widget_data_get(obj); | ||
1054 | if (!wd) return EINA_FALSE; | ||
1055 | return wd->ok_button ? EINA_TRUE : EINA_FALSE; | ||
1056 | } | ||
1057 | |||
1058 | EAPI void | ||
1059 | elm_fileselector_expandable_set(Evas_Object *obj, | ||
1060 | Eina_Bool expand) | ||
1061 | { | ||
1062 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
1063 | Widget_Data *wd; | ||
1064 | |||
1065 | wd = elm_widget_data_get(obj); | ||
1066 | if (!wd) return; | ||
1067 | |||
1068 | wd->expand = !!expand; | ||
1069 | |||
1070 | if (wd->path) _populate(obj, wd->path, NULL); | ||
1071 | } | ||
1072 | |||
1073 | EAPI Eina_Bool | ||
1074 | elm_fileselector_expandable_get(const Evas_Object *obj) | ||
1075 | { | ||
1076 | ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; | ||
1077 | Widget_Data *wd = elm_widget_data_get(obj); | ||
1078 | if (!wd) return EINA_FALSE; | ||
1079 | return wd->expand; | ||
1080 | } | ||
1081 | |||
1082 | EAPI void | ||
1083 | elm_fileselector_path_set(Evas_Object *obj, | ||
1084 | const char *_path) | ||
1085 | { | ||
1086 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
1087 | char *path; | ||
1088 | path = ecore_file_realpath(_path); | ||
1089 | _populate(obj, path, NULL); | ||
1090 | free(path); | ||
1091 | } | ||
1092 | |||
1093 | EAPI const char * | ||
1094 | elm_fileselector_path_get(const Evas_Object *obj) | ||
1095 | { | ||
1096 | ELM_CHECK_WIDTYPE(obj, widtype) NULL; | ||
1097 | Widget_Data *wd = elm_widget_data_get(obj); | ||
1098 | if (!wd) return NULL; | ||
1099 | return wd->path; | ||
1100 | } | ||
1101 | |||
1102 | EAPI void | ||
1103 | elm_fileselector_mode_set(Evas_Object *obj, | ||
1104 | Elm_Fileselector_Mode mode) | ||
1105 | { | ||
1106 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
1107 | |||
1108 | Widget_Data *wd = elm_widget_data_get(obj); | ||
1109 | if (!wd) return; | ||
1110 | |||
1111 | if (mode == wd->mode) return; | ||
1112 | |||
1113 | if (mode == ELM_FILESELECTOR_LIST) | ||
1114 | { | ||
1115 | if (edje_object_part_swallow(wd->edje, "elm.swallow.files", | ||
1116 | wd->files_list)) | ||
1117 | { | ||
1118 | evas_object_show(wd->files_list); | ||
1119 | evas_object_hide(wd->files_grid); | ||
1120 | } | ||
1121 | else | ||
1122 | evas_object_hide(wd->files_list); | ||
1123 | } | ||
1124 | else | ||
1125 | { | ||
1126 | if (edje_object_part_swallow(wd->edje, "elm.swallow.files", | ||
1127 | wd->files_grid)) | ||
1128 | { | ||
1129 | evas_object_show(wd->files_grid); | ||
1130 | evas_object_hide(wd->files_list); | ||
1131 | } | ||
1132 | else | ||
1133 | evas_object_hide(wd->files_grid); | ||
1134 | } | ||
1135 | |||
1136 | wd->mode = mode; | ||
1137 | |||
1138 | _populate(obj, wd->path, NULL); | ||
1139 | } | ||
1140 | |||
1141 | EAPI Elm_Fileselector_Mode | ||
1142 | elm_fileselector_mode_get(const Evas_Object *obj) | ||
1143 | { | ||
1144 | ELM_CHECK_WIDTYPE(obj, widtype) ELM_FILESELECTOR_LAST; | ||
1145 | |||
1146 | Widget_Data *wd = elm_widget_data_get(obj); | ||
1147 | if (!wd) return ELM_FILESELECTOR_LAST; | ||
1148 | |||
1149 | return wd->mode; | ||
1150 | } | ||
1151 | |||
1152 | EAPI const char * | ||
1153 | elm_fileselector_selected_get(const Evas_Object *obj) | ||
1154 | { | ||
1155 | ELM_CHECK_WIDTYPE(obj, widtype) NULL; | ||
1156 | Widget_Data *wd = elm_widget_data_get(obj); | ||
1157 | if (!wd) return NULL; | ||
1158 | |||
1159 | if (!wd->path) return NULL; | ||
1160 | |||
1161 | if (wd->filename_entry) | ||
1162 | { | ||
1163 | const char *name; | ||
1164 | char buf[PATH_MAX]; | ||
1165 | char *dir, *s; | ||
1166 | |||
1167 | dir = wd->only_folder ? ecore_file_dir_get(wd->path) : strdup(wd->path); | ||
1168 | name = elm_object_text_get(wd->filename_entry); | ||
1169 | if (name) | ||
1170 | { | ||
1171 | s = elm_entry_markup_to_utf8(name); | ||
1172 | if (s) | ||
1173 | { | ||
1174 | snprintf(buf, sizeof(buf), "%s/%s", dir, s); | ||
1175 | free(s); | ||
1176 | } | ||
1177 | else | ||
1178 | snprintf(buf, sizeof(buf), "%s", dir); | ||
1179 | } | ||
1180 | else | ||
1181 | { | ||
1182 | snprintf(buf, sizeof(buf), "%s", dir); | ||
1183 | } | ||
1184 | if (wd->only_folder && !ecore_file_is_dir(buf)) | ||
1185 | eina_stringshare_replace(&wd->selection, ecore_file_dir_get(buf)); | ||
1186 | else | ||
1187 | eina_stringshare_replace(&wd->selection, buf); | ||
1188 | if (dir) free(dir); | ||
1189 | return wd->selection; | ||
1190 | } | ||
1191 | |||
1192 | if (wd->mode == ELM_FILESELECTOR_LIST) | ||
1193 | { | ||
1194 | Elm_Object_Item *gl_it = elm_genlist_selected_item_get(wd->files_list); | ||
1195 | if (gl_it) return elm_object_item_data_get(gl_it); | ||
1196 | } | ||
1197 | else | ||
1198 | { | ||
1199 | Elm_Object_Item *gg_it = elm_gengrid_selected_item_get(wd->files_grid); | ||
1200 | if (gg_it) return elm_object_item_data_get(gg_it); | ||
1201 | } | ||
1202 | |||
1203 | return wd->path; | ||
1204 | } | ||
1205 | |||
1206 | EAPI Eina_Bool | ||
1207 | elm_fileselector_selected_set(Evas_Object *obj, | ||
1208 | const char *_path) | ||
1209 | { | ||
1210 | ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; | ||
1211 | Widget_Data *wd = elm_widget_data_get(obj); | ||
1212 | if (!wd) return EINA_FALSE; | ||
1213 | |||
1214 | Eina_Bool ret = EINA_TRUE; | ||
1215 | char *path; | ||
1216 | path = ecore_file_realpath(_path); | ||
1217 | |||
1218 | if (ecore_file_is_dir(path)) | ||
1219 | _populate(obj, path, NULL); | ||
1220 | else | ||
1221 | { | ||
1222 | if (!ecore_file_exists(path)) | ||
1223 | { | ||
1224 | ret = EINA_FALSE; | ||
1225 | goto clean_up; | ||
1226 | } | ||
1227 | |||
1228 | _populate(obj, ecore_file_dir_get(path), NULL); | ||
1229 | if (wd->filename_entry) | ||
1230 | { | ||
1231 | char *s; | ||
1232 | |||
1233 | s = elm_entry_utf8_to_markup(ecore_file_file_get(path)); | ||
1234 | if (s) | ||
1235 | { | ||
1236 | elm_object_text_set(wd->filename_entry, s); | ||
1237 | free(s); | ||
1238 | } | ||
1239 | else | ||
1240 | elm_object_text_set(wd->filename_entry, ""); | ||
1241 | eina_stringshare_replace(&wd->selection, path); | ||
1242 | } | ||
1243 | } | ||
1244 | |||
1245 | clean_up: | ||
1246 | free(path); | ||
1247 | return ret; | ||
1248 | } | ||
1249 | |||