svn update: 48945 (latest:48959)
[framework/uifw/elementary.git] / src / lib / elc_fileselector_button.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4  /**
5  * @defgroup File_Selector_Button File Selector Button
6  *
7  * A button that, when clicked, creates an Elementary window (or inner
8  * window) with an Elementary File Selector within. When a file is
9  * chosen, the (inner) window is closed and the selected file is
10  * exposed as an evas_object_smart_callback_call() of the button.
11  */
12
13 typedef struct _Widget_Data Widget_Data;
14
15 struct _Widget_Data
16 {
17    Evas_Object *btn, *icon, *fs;
18    const char *window_title;
19    const char *btn_label;
20    Evas_Coord w, h;
21    struct {
22       const char *path;
23       Eina_Bool expandable:1;
24       Eina_Bool folder_only:1;
25       Eina_Bool is_save:1;
26    } fsd;
27    Eina_Bool inwin_mode:1;
28 };
29
30 static const char DEFAULT_WINDOW_TITLE[] = "Select a file";
31
32 static const char *widtype = NULL;
33 static void _del_hook(Evas_Object *obj);
34 static void _theme_hook(Evas_Object *obj);
35 static void _disable_hook(Evas_Object *obj);
36 static void _sizing_eval(Evas_Object *obj);
37 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
38 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
39 static void _signal_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
40 static void _signal_pressed(void *data, Evas_Object *obj, const char *emission, const char *source);
41 static void _signal_unpressed(void *data, Evas_Object *obj, const char *emission, const char *source);
42 static void _on_focus_hook(void *data, Evas_Object *obj);
43 static void _selection_done(void *data, Evas_Object *obj, void *event_info);
44
45 static const char SIG_CLICKED[] = "clicked";
46 static const char SIG_UNPRESSED[] = "unpressed";
47 static const char SIG_FILE_CHOSEN[] = "file,chosen";
48 static const Evas_Smart_Cb_Description _signals[] = {
49   {SIG_CLICKED, ""},
50   {SIG_UNPRESSED, ""},
51   {SIG_FILE_CHOSEN, "s"},
52   {NULL, NULL}
53 };
54
55 static void
56 _del_hook(Evas_Object *obj)
57 {
58    Evas_Object *win;
59    Widget_Data *wd;
60
61    wd = elm_widget_data_get(obj);
62    if (!wd) return;
63
64    if (wd->btn_label) eina_stringshare_del(wd->btn_label);
65    if (wd->window_title) eina_stringshare_del(wd->window_title);
66    if (wd->fsd.path) eina_stringshare_del(wd->fsd.path);
67    if (wd->fs)
68      {
69         win = evas_object_data_del(obj, "win");
70         evas_object_del(win);
71      }
72    free(wd);
73 }
74
75 static void
76 _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
77 {
78    Widget_Data *wd = elm_widget_data_get(obj);
79    if (!wd) return;
80    if (elm_widget_focus_get(obj))
81      {
82         edje_object_signal_emit(wd->btn, "elm,action,focus", "elm");
83         evas_object_focus_set(wd->btn, 1);
84      }
85    else
86      {
87         edje_object_signal_emit(wd->btn, "elm,action,unfocus", "elm");
88         evas_object_focus_set(wd->btn, 0);
89      }
90 }
91
92 static void
93 _theme_hook(Evas_Object *obj)
94 {
95    Widget_Data *wd = elm_widget_data_get(obj);
96    if (!wd) return;
97    _elm_theme_object_set(obj, wd->btn, "button", "base", elm_widget_style_get(obj));
98    if (wd->icon)
99      edje_object_part_swallow(wd->btn, "elm.swallow.content", wd->icon);
100    if (wd->btn_label)
101      edje_object_signal_emit(wd->btn, "elm,state,text,visible", "elm");
102    else
103      edje_object_signal_emit(wd->btn, "elm,state,text,hidden", "elm");
104    if (wd->icon)
105      edje_object_signal_emit(wd->btn, "elm,state,icon,visible", "elm");
106    else
107      edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm");
108    edje_object_part_text_set(wd->btn, "elm.text", wd->btn_label);
109    edje_object_message_signal_process(wd->btn);
110    edje_object_scale_set(wd->btn, elm_widget_scale_get(obj) *   \
111                          _elm_config->scale);
112    _sizing_eval(obj);
113 }
114
115 static void
116 _disable_hook(Evas_Object *obj)
117 {
118    Widget_Data *wd = elm_widget_data_get(obj);
119    if (!wd) return;
120    if (elm_widget_disabled_get(obj))
121      edje_object_signal_emit(wd->btn, "elm,state,disabled", "elm");
122    else
123      edje_object_signal_emit(wd->btn, "elm,state,enabled", "elm");
124 }
125
126 static void
127 _sizing_eval(Evas_Object *obj)
128 {
129    Widget_Data *wd = elm_widget_data_get(obj);
130    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
131
132    if (!wd) return;
133    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
134    edje_object_size_min_restricted_calc(wd->btn, &minw, &minh, minw, minh);
135    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
136    evas_object_size_hint_min_set(obj, minw, minh);
137    evas_object_size_hint_max_set(obj, maxw, maxh);
138 }
139
140 static void
141 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
142 {
143    Widget_Data *wd = elm_widget_data_get(data);
144    if (!wd) return;
145    if (obj != wd->icon) return;
146    _sizing_eval(data);
147 }
148
149 static void
150 _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
151 {
152    Widget_Data *wd = elm_widget_data_get(obj);
153    Evas_Object *sub = event_info;
154    if (!wd) return;
155    if (sub == wd->icon)
156      {
157         edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm");
158         evas_object_event_callback_del_full(sub,
159                                             EVAS_CALLBACK_CHANGED_SIZE_HINTS,
160                                             _changed_size_hints, obj);
161         wd->icon = NULL;
162         edje_object_message_signal_process(wd->btn);
163         _sizing_eval(obj);
164      }
165 }
166
167 static void
168 _signal_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
169 {
170
171    Widget_Data *wd = elm_widget_data_get(data);
172    if (!wd) return;
173
174    evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
175
176    /* safe guard when the theme does not emit the 'unpress' signal */
177    _signal_unpressed(data, obj, emission, source);
178 }
179
180 static Evas_Object *
181 _parent_win_get(Evas_Object *obj)
182 {
183    Evas_Object *ret;
184
185    ret = elm_object_parent_widget_get(obj);
186    if (!ret) return NULL;
187
188    if (strcmp(elm_widget_type_get(ret), "win") != 0)
189      {
190         DBG("Widget type (%s) is not \"win\", going up\n",
191             elm_widget_type_get(ret));
192         return _parent_win_get(ret);
193      }
194
195    return ret;
196 }
197
198 static Evas_Object *
199 _new_window_add(Widget_Data *wd)
200 {
201    Evas_Object *win, *bg;
202
203    win = elm_win_add(NULL, "fileselector_button", ELM_WIN_DIALOG_BASIC);
204    elm_win_title_set(win, wd->window_title);
205    elm_win_autodel_set(win, EINA_TRUE);
206
207    bg = elm_bg_add(win);
208    elm_win_resize_object_add(win, bg);
209    evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
210    evas_object_show(bg);
211
212    evas_object_resize(win, wd->w, wd->h);
213    return win;
214 }
215
216 static void
217 _fs_launch(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
218 {
219    Evas_Object *fs_btn, *win, *iw;
220    Eina_Bool win_fallback;
221    Widget_Data *wd;
222
223    fs_btn = data;
224    wd = elm_widget_data_get(fs_btn);
225
226    if (!wd) return;
227    if (wd->fs) return;
228
229    win_fallback = EINA_FALSE;
230    if (wd->inwin_mode)
231      {
232         win = _parent_win_get(fs_btn);
233
234         if (!win)
235           {
236              ERR("No elementary window found as parent of the file selector "
237                  "button! Launching the file selector inside a new elementary"
238                  " window, then.");
239              win_fallback = EINA_TRUE;
240           }
241         else
242           {
243              iw = elm_win_inwin_add(win);
244              evas_object_data_set(fs_btn, "win", iw);
245           }
246      }
247
248    if (!wd->inwin_mode || win_fallback)
249      {
250         win = _new_window_add(wd);
251         evas_object_data_set(fs_btn, "win", win);
252      }
253
254    wd->fs = elm_fileselector_add(win);
255    elm_fileselector_expandable_set(wd->fs, wd->fsd.expandable);
256    elm_fileselector_folder_only_set(wd->fs, wd->fsd.folder_only);
257    elm_fileselector_is_save_set(wd->fs, wd->fsd.is_save);
258    elm_fileselector_selected_set(wd->fs, wd->fsd.path);
259    evas_object_size_hint_weight_set(wd->fs, EVAS_HINT_EXPAND,
260                                     EVAS_HINT_EXPAND);
261    evas_object_size_hint_align_set(wd->fs, EVAS_HINT_FILL, EVAS_HINT_FILL);
262    evas_object_smart_callback_add(wd->fs, "done", _selection_done, fs_btn);
263    evas_object_show(wd->fs);
264
265    if (wd->inwin_mode && !win_fallback)
266      {
267         elm_win_inwin_content_set(iw, wd->fs);
268         elm_win_inwin_activate(iw);
269      }
270    else
271      {
272         elm_win_resize_object_add(win, wd->fs);
273         evas_object_show(win);
274      }
275 }
276
277 static void
278 _selection_done(void *data, Evas_Object *obj __UNUSED__, void *event_info)
279 {
280    Evas_Object *fs_btn, *win;
281    const char *file;
282    Widget_Data *wd;
283
284    file = event_info;
285    fs_btn = data;
286
287    wd = elm_widget_data_get(fs_btn);
288    if (!wd) return;
289
290    win = evas_object_data_del(fs_btn, "win");
291
292    evas_object_smart_callback_call(fs_btn, SIG_FILE_CHOSEN, event_info);
293    if (file) eina_stringshare_replace(&wd->fsd.path, file);
294
295    wd->fs = NULL;
296    evas_object_del(win);
297 }
298
299 static void
300 _signal_pressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
301 {
302    Widget_Data *wd = elm_widget_data_get(data);
303    if (!wd) return;
304 }
305
306 static void
307 _signal_unpressed(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
308 {
309    Widget_Data *wd = elm_widget_data_get(data);
310    if (!wd) return;
311    evas_object_smart_callback_call(data, SIG_UNPRESSED, NULL);
312 }
313
314 /**
315  * Add a new file selector button into the parent object.
316  *
317  * @param parent The parent object
318  * @return The new object or NULL if it cannot be created
319  *
320  * @ingroup File_Selector_Button
321  */
322 EAPI Evas_Object *
323 elm_fileselector_button_add(Evas_Object *parent)
324 {
325    Evas_Object *obj;
326    Evas *e;
327    Widget_Data *wd;
328
329    wd = ELM_NEW(Widget_Data);
330    wd->window_title = eina_stringshare_add(DEFAULT_WINDOW_TITLE);
331    wd->fsd.path = eina_stringshare_add(getenv("HOME"));
332    wd->w = 400;
333    wd->h = 400;
334
335    e = evas_object_evas_get(parent);
336    obj = elm_widget_add(e);
337    ELM_SET_WIDTYPE(widtype, "fileselector_button");
338    elm_widget_type_set(obj, "fileselector_button");
339    elm_widget_sub_object_add(parent, obj);
340    elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
341    elm_widget_data_set(obj, wd);
342    elm_widget_del_hook_set(obj, _del_hook);
343    elm_widget_theme_hook_set(obj, _theme_hook);
344    elm_widget_disable_hook_set(obj, _disable_hook);
345    elm_widget_can_focus_set(obj, 1);
346
347    wd->btn = edje_object_add(e);
348    _elm_theme_object_set(obj, wd->btn, "button", "base", "default");
349    edje_object_signal_callback_add(wd->btn, "elm,action,click", "",
350                                    _signal_clicked, obj);
351    edje_object_signal_callback_add(wd->btn, "elm,action,click", "",
352                                    _fs_launch, obj);
353    edje_object_signal_callback_add(wd->btn, "elm,action,press", "",
354                                    _signal_pressed, obj);
355    edje_object_signal_callback_add(wd->btn, "elm,action,unpress", "",
356                                    _signal_unpressed, obj);
357    elm_widget_resize_object_set(obj, wd->btn);
358
359    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
360
361    _sizing_eval(obj);
362
363    // TODO: convert Elementary to subclassing of Evas_Smart_Class
364    // TODO: and save some bytes, making descriptions per-class and not instance!
365    evas_object_smart_callbacks_descriptions_set(obj, _signals);
366    return obj;
367 }
368
369 /**
370  * Set the label used in the file selector button.
371  *
372  * @param obj The button object
373  * @param label The text label text to be displayed on the button
374  *
375  * @ingroup File_Selector_Button
376  */
377 EAPI void
378 elm_fileselector_button_label_set(Evas_Object *obj, const char *label)
379 {
380    ELM_CHECK_WIDTYPE(obj, widtype);
381    Widget_Data *wd = elm_widget_data_get(obj);
382    if (!wd) return;
383    eina_stringshare_replace(&wd->btn_label, label);
384    if (label)
385      edje_object_signal_emit(wd->btn, "elm,state,text,visible", "elm");
386    else
387      edje_object_signal_emit(wd->btn, "elm,state,text,hidden", "elm");
388    edje_object_message_signal_process(wd->btn);
389    edje_object_part_text_set(wd->btn, "elm.text", label);
390    _sizing_eval(obj);
391 }
392
393 EAPI const char *
394 elm_fileselector_button_label_get(const Evas_Object *obj)
395 {
396    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
397    Widget_Data *wd = elm_widget_data_get(obj);
398    if (!wd) return NULL;
399    return wd->btn_label;
400 }
401
402 /**
403  * Set the path to start the button's file selector with, when clicked.
404  *
405  * @param obj The button object
406  * @param path Path to a file/directory
407  *
408  * Default path is "HOME" environment variable's value.
409  *
410  * @ingroup File_Selector_Button
411  */
412 EAPI void
413 elm_fileselector_button_selected_set(Evas_Object *obj, const char *path)
414 {
415    ELM_CHECK_WIDTYPE(obj, widtype);
416    Widget_Data *wd = elm_widget_data_get(obj);
417    if (!wd) return;
418
419    eina_stringshare_replace(&wd->fsd.path, path);
420 }
421
422 /**
423  * Get the <b>last</b> path which the button's file selector was set to.
424  *
425  * @param obj The button object
426  * @param path Path to a file/directory
427  *
428  * Default path is "HOME" environment variable's value.
429  *
430  * @ingroup File_Selector_Button
431  */
432 EAPI const char *
433 elm_fileselector_button_selected_get(const Evas_Object *obj)
434 {
435    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
436    Widget_Data *wd = elm_widget_data_get(obj);
437    if (!wd) return NULL;
438    return wd->fsd.path;
439 }
440
441 /**
442  * Set the title of the file selector button's window.
443  *
444  * @param obj The button object
445  * @param title The title string
446  *
447  * Note that it will only take any effect if the fileselector button
448  * not at "inwin mode".
449  *
450  * @ingroup File_Selector_Button
451  */
452 EAPI void
453 elm_fileselector_button_window_title_set(Evas_Object *obj, const char *title)
454 {
455    ELM_CHECK_WIDTYPE(obj, widtype);
456    Widget_Data *wd = elm_widget_data_get(obj);
457    if (!wd) return;
458    eina_stringshare_replace(&wd->window_title, title);
459 }
460
461 /**
462  * Get the title of the file selector button's window.
463  *
464  * @param obj The button object
465  *
466  * @ingroup File_Selector_Button
467  */
468 EAPI const char *
469 elm_fileselector_button_window_title_get(Evas_Object *obj)
470 {
471    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
472    Widget_Data *wd = elm_widget_data_get(obj);
473    if (!wd) return NULL;
474    return wd->window_title;
475 }
476
477 /**
478  * Set the size of the file selector button's window.
479  *
480  * @param obj The button object
481  * @param width The width
482  * @param height The height
483  *
484  * Note that it will only take any effect if the fileselector button not at
485  * "inwin mode". Default size for the window (when applicable) is 400x400.
486  *
487  * @ingroup File_Selector_Button
488  */
489 EAPI void
490 elm_fileselector_button_window_size_set(Evas_Object *obj, Evas_Coord width, Evas_Coord height)
491 {
492    ELM_CHECK_WIDTYPE(obj, widtype);
493    Widget_Data *wd = elm_widget_data_get(obj);
494    if (!wd) return;
495
496    wd->w = width;
497    wd->h = height;
498 }
499
500 /**
501  * Get the size of the file selector button's window.
502  *
503  * @param obj The button object
504  * @param width Pointer into which to store the width value
505  * @param height Pointer into which to store the height value
506  *
507  * @ingroup File_Selector_Button
508  */
509 EAPI void
510 elm_fileselector_button_window_size_get(Evas_Object *obj, Evas_Coord *width, Evas_Coord *height)
511 {
512    ELM_CHECK_WIDTYPE(obj, widtype);
513    Widget_Data *wd = elm_widget_data_get(obj);
514    if (!wd) return;
515
516    if (width) *width = wd->w;
517    if (height) *height = wd->h;
518 }
519
520 /**
521  * Set the starting path of the file selector button's window.
522  *
523  * @param obj The button object
524  * @param path The path string
525  *
526  * It must be a <b>directory</b> path.
527  *
528  * @ingroup File_Selector_Button
529  */
530 EAPI void
531 elm_fileselector_button_path_set(Evas_Object *obj, const char *path)
532 {
533    ELM_CHECK_WIDTYPE(obj, widtype);
534    Widget_Data *wd = elm_widget_data_get(obj);
535    if (!wd) return;
536    eina_stringshare_replace(&wd->fsd.path, path);
537 }
538
539 /**
540  * Get the <b>last</b> path of the file selector button's window.
541  *
542  * @param obj The button object
543  *
544  * @ingroup File_Selector_Button
545  */
546 EAPI const char *
547 elm_fileselector_button_path_get(Evas_Object *obj)
548 {
549    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
550    Widget_Data *wd = elm_widget_data_get(obj);
551    if (!wd) return NULL;
552    return wd->fsd.path;
553 }
554
555 /**
556  * Set whether the button's file selector is to present itself as an
557  * Elementary Generic List (which will expand its entries for nested
558  * directories) or as canonical list, which will be rendered again
559  * with the contents of each selected directory.
560  *
561  * @param obj The button object
562  * @param value The expandable flag
563  *
564  * @ingroup File_Selector_Button
565  */
566 EAPI void
567 elm_fileselector_button_expandable_set(Evas_Object *obj, Eina_Bool value)
568 {
569    ELM_CHECK_WIDTYPE(obj, widtype);
570    Widget_Data *wd = elm_widget_data_get(obj);
571    if (!wd) return;
572
573    wd->fsd.expandable = value;
574 }
575
576 /**
577  * Get the button's file selector expandable flag.
578  *
579  * @param obj The button object
580  * @return value The expandable flag
581  *
582  * @ingroup File_Selector_Button
583  */
584 EAPI Eina_Bool
585 elm_fileselector_button_expandable_get(Evas_Object *obj)
586 {
587    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
588    Widget_Data *wd = elm_widget_data_get(obj);
589    if (!wd) return EINA_FALSE;
590
591    return wd->fsd.expandable;
592 }
593
594 /**
595  * Set whether the button's file selector list is to display folders
596  * only or the directory contents, as well.
597  *
598  * @param obj The button object
599  * @param value The "folder only" flag
600  *
601  * @ingroup File_Selector_Button
602  */
603 EAPI void
604 elm_fileselector_button_folder_only_set(Evas_Object *obj, Eina_Bool value)
605 {
606    ELM_CHECK_WIDTYPE(obj, widtype);
607    Widget_Data *wd = elm_widget_data_get(obj);
608    if (!wd) return;
609
610    wd->fsd.folder_only = value;
611 }
612
613 /**
614  * Get the button's file selector "folder only" flag.
615  *
616  * @param obj The button object
617  * @return value The "folder only" flag
618  *
619  * @ingroup File_Selector_Button
620  */
621 EAPI Eina_Bool
622 elm_fileselector_button_folder_only_get(Evas_Object *obj)
623 {
624    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
625    Widget_Data *wd = elm_widget_data_get(obj);
626    if (!wd) return EINA_FALSE;
627
628    return wd->fsd.folder_only;
629 }
630
631 /**
632  * Set whether the button's file selector has an editable text entry
633  * which will hold its current selection.
634  *
635  * @param obj The button object
636  * @param value The "is save" flag
637  *
638  * @ingroup File_Selector_Button
639  */
640 EAPI void
641 elm_fileselector_button_is_save_set(Evas_Object *obj, Eina_Bool value)
642 {
643    ELM_CHECK_WIDTYPE(obj, widtype);
644    Widget_Data *wd = elm_widget_data_get(obj);
645    if (!wd) return;
646
647    wd->fsd.is_save = value;
648 }
649
650 /**
651  * Get the button's file selector "is save" flag.
652  *
653  * @param obj The button object
654  * @return value The "is save" flag
655  *
656  * @ingroup File_Selector_Button
657  */
658 EAPI Eina_Bool
659 elm_fileselector_button_is_save_get(Evas_Object *obj)
660 {
661    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
662    Widget_Data *wd = elm_widget_data_get(obj);
663    if (!wd) return EINA_FALSE;
664
665    return wd->fsd.is_save;
666 }
667
668 /**
669  * Set whether the button's file selector will raise an Elementary
670  * Inner Window, instead of a dedicated Elementary Window. By default,
671  * it won't.
672  *
673  * @param obj The button object
674  * @param value The "inwin mode" flag
675  *
676  * @ingroup File_Selector_Button
677  */
678 EAPI void
679 elm_fileselector_button_inwin_mode_set(Evas_Object *obj, Eina_Bool value)
680 {
681    ELM_CHECK_WIDTYPE(obj, widtype);
682    Widget_Data *wd = elm_widget_data_get(obj);
683    if (!wd) return;
684
685    wd->inwin_mode = value;
686 }
687
688 /**
689  * Get the button's file selector "inwin mode" flag.
690  *
691  * @param obj The button object
692  * @return value The "inwin mode" flag
693  *
694  * @ingroup File_Selector_Button
695  */
696 EAPI Eina_Bool
697 elm_fileselector_button_inwin_mode_get(Evas_Object *obj)
698 {
699    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
700    Widget_Data *wd = elm_widget_data_get(obj);
701    if (!wd) return EINA_FALSE;
702
703    return wd->inwin_mode;
704 }
705
706 /**
707  * Set the icon used for the button
708  *
709  * @param obj The button object
710  * @param icon  The image for the button
711  *
712  * @ingroup File_Selector_Button
713  */
714 EAPI void
715 elm_fileselector_button_icon_set(Evas_Object *obj, Evas_Object *icon)
716 {
717    ELM_CHECK_WIDTYPE(obj, widtype);
718    Widget_Data *wd = elm_widget_data_get(obj);
719    if (!wd) return;
720    if ((wd->icon != icon) && (wd->icon))
721      elm_widget_sub_object_del(obj, wd->icon);
722    if ((icon) && (wd->icon != icon))
723      {
724         wd->icon = icon;
725         elm_widget_sub_object_add(obj, icon);
726         evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
727                                        _changed_size_hints, obj);
728         edje_object_part_swallow(wd->btn, "elm.swallow.content", icon);
729         edje_object_signal_emit(wd->btn, "elm,state,icon,visible", "elm");
730         edje_object_message_signal_process(wd->btn);
731         _sizing_eval(obj);
732      }
733    else
734      wd->icon = icon;
735 }
736
737 /**
738  * Get the icon used for the button
739  *
740  * @param obj The button object
741  * @return The image for the button
742  *
743  * @ingroup File_Selector_Button
744  */
745 EAPI Evas_Object *
746 elm_fileselector_button_icon_get(const Evas_Object *obj)
747 {
748    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
749    Widget_Data *wd = elm_widget_data_get(obj);
750    if (!wd) return NULL;
751    return wd->icon;
752 }