Tizen 2.1 release
[platform/core/uifw/e17.git] / src / modules / fileman / e_fwin.c
1 #include "e.h"
2 #include "e_mod_main.h"
3 #include "e_widget_filepreview.h"
4
5 /* FIXME: fwin - the fm2 filemanager wrapped with a window and scrollframe.
6  * primitive BUT enough to test generic dnd and fm stuff more easily. don't
7  * play with this unless u want to help with it. NOT COMPLETE! BEWARE!
8  */
9 /* FIXME: multiple selected files across different fwins - you can only dnd the
10  * ones in the 1 window src - not all selected ones. also selecting a new file
11  * in a new fwin doesn't deseclect other selections in other fwin's (unless
12  * multi-selecting)
13  */
14
15 #define DEFAULT_WIDTH  600
16 #define DEFAULT_HEIGHT 350
17
18 typedef struct _E_Fwin             E_Fwin;
19 typedef struct _E_Fwin_Page        E_Fwin_Page;
20 typedef struct _E_Fwin_Apps_Dialog E_Fwin_Apps_Dialog;
21
22 #define E_FWIN_TYPE 0xE0b0101f
23
24 struct _E_Fwin
25 {
26    E_Object             e_obj_inherit;
27
28    E_Win               *win;
29    E_Zone              *zone;
30    Fileman_Path *path; /* not freed with fwin, actually attached to config */
31    Evas_Object         *bg_obj;
32    E_Fwin_Apps_Dialog  *fad;
33
34    E_Fwin_Page         *cur_page;
35
36    Evas_Object         *under_obj;
37    Evas_Object         *over_obj;
38
39    const char          *wallpaper_file;
40    Eina_Bool            wallpaper_is_edj : 1;
41    const char          *overlay_file;
42    const char          *scrollframe_file;
43    const char          *theme_file;
44
45    Ecore_Timer *popup_timer;
46    E_Fm2_Icon_Info *popup_icon;
47    E_Popup *popup;
48
49    Ecore_Timer *spring_timer;
50    Ecore_Timer *spring_close_timer;
51    E_Fwin *spring_parent;
52    E_Fwin *spring_child;
53    
54    Ecore_Event_Handler *zone_handler;
55    Ecore_Event_Handler *zone_del_handler;
56 };
57
58 struct _E_Fwin_Page
59 {
60    E_Fwin              *fwin;
61    Ecore_Event_Handler *fm_op_entry_add_handler;
62
63    Evas_Object         *box;
64    Evas_Object         *flist;
65    Evas_Object         *flist_frame;
66    Evas_Object         *scrollframe_obj;
67    Evas_Object         *scr;
68    Evas_Object         *fm_obj;
69    E_Toolbar           *tbar;
70
71    struct
72    {
73       Evas_Coord x, y, max_x, max_y, w, h;
74    } fm_pan, fm_pan_last;
75
76    int                  index;
77    Eina_Bool           setting : 1;
78 };
79
80 struct _E_Fwin_Apps_Dialog
81 {
82    E_Dialog    *dia;
83    E_Fwin      *fwin;
84    const char  *app2;
85    Evas_Object *o_filepreview;
86    Evas_Object *o_all;
87    Evas_Object *o_entry;
88    char        *exec_cmd;
89 };
90
91 typedef enum
92 {
93    E_FWIN_EXEC_NONE,
94    E_FWIN_EXEC_DIRECT,
95    E_FWIN_EXEC_SH,
96    E_FWIN_EXEC_TERMINAL_DIRECT,
97    E_FWIN_EXEC_TERMINAL_SH,
98    E_FWIN_EXEC_DESKTOP
99 } E_Fwin_Exec_Type;
100
101 /* local subsystem prototypes */
102 static int _e_fwin_cb_dir_handler_test(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const char *path);
103 static void _e_fwin_cb_dir_handler(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const char *path);
104 static void _e_fwin_page_favorites_add(E_Fwin_Page *page);
105 static void _e_fwin_icon_mouse_out(void *data, Evas_Object *obj __UNUSED__, void *event_info);
106 static void _e_fwin_icon_mouse_in(void *data, Evas_Object *obj __UNUSED__, void *event_info);
107 static E_Fwin *_e_fwin_open(E_Fwin_Page *page, E_Fm2_Icon_Info *ici, Eina_Bool force, int *need_dia);
108 static E_Fwin          *_e_fwin_new(E_Container *con,
109                                     const char *dev,
110                                     const char *path);
111 static void             _e_fwin_free(E_Fwin *fwin);
112 static E_Fwin_Page     *_e_fwin_page_create(E_Fwin *fwin);
113 static void             _e_fwin_page_free(E_Fwin_Page *page);
114 static void             _e_fwin_cb_delete(E_Win *win);
115 static void             _e_fwin_cb_move(E_Win *win);
116 static void             _e_fwin_cb_resize(E_Win *win);
117 static void             _e_fwin_deleted(void *data,
118                                         Evas_Object *obj,
119                                         void *event_info);
120 static const char      *_e_fwin_custom_file_path_eval(E_Fwin *fwin,
121                                                       Efreet_Desktop *ef,
122                                                       const char *prev_path,
123                                                       const char *key);
124 static void             _e_fwin_desktop_run(Efreet_Desktop *desktop,
125                                             E_Fwin_Page *page,
126                                             Eina_Bool skip_history);
127 static Eina_List       *_e_fwin_suggested_apps_list_get(Eina_List *files,
128                                                         Eina_List **mime_list,
129                                                         Eina_Bool *has_default);
130 static void             _e_fwin_changed(void *data,
131                                         Evas_Object *obj,
132                                         void *event_info);
133 static void             _e_fwin_favorite_selected(void *data,
134                                                    Evas_Object *obj,
135                                                    void *event_info);
136 static void             _e_fwin_selected(void *data,
137                                          Evas_Object *obj,
138                                          void *event_info);
139 static void             _e_fwin_selection_change(void *data,
140                                                  Evas_Object *obj,
141                                                  void *event_info);
142 static void             _e_fwin_cb_menu_extend_open_with(void *data,
143                                                          E_Menu *m);
144 static void             _e_fwin_cb_menu_open_fast(void *data,
145                                                   E_Menu *m,
146                                                   E_Menu_Item *mi);
147 static void             _e_fwin_parent(void *data,
148                                        E_Menu *m,
149                                        E_Menu_Item *mi);
150 static void             _e_fwin_cb_key_down(void *data,
151                                             Evas *e,
152                                             Evas_Object *obj,
153                                             void *event_info);
154 static void             _e_fwin_cb_menu_extend_start(void *data,
155                                                      Evas_Object *obj,
156                                                      E_Menu *m,
157                                                      E_Fm2_Icon_Info *info);
158 static void             _e_fwin_cb_menu_open(void *data,
159                                              E_Menu *m,
160                                              E_Menu_Item *mi);
161 static void             _e_fwin_cb_menu_open_with(void *data,
162                                                   E_Menu *m,
163                                                   E_Menu_Item *mi);
164 static void             _e_fwin_cb_all_change(void *data,
165                                               Evas_Object *obj);
166 static void             _e_fwin_cb_exec_cmd_changed(void *data,
167                                                     void *data2);
168 static void             _e_fwin_cb_open(void *data,
169                                         E_Dialog *dia);
170 static void             _e_fwin_cb_close(void *data,
171                                          E_Dialog *dia);
172 static void             _e_fwin_cb_dialog_free(void *obj);
173 static E_Fwin_Exec_Type _e_fwin_file_is_exec(E_Fm2_Icon_Info *ici);
174 static void             _e_fwin_file_exec(E_Fwin_Page *page,
175                                           E_Fm2_Icon_Info *ici,
176                                           E_Fwin_Exec_Type ext);
177 static void            _e_fwin_file_open_dialog(E_Fwin_Page *page,
178                                                  Eina_List *files,
179                                                  int always);
180 static void             _e_fwin_file_open_dialog_preview_set(void *data1,
181                                                              void *data2);
182 static void             _e_fwin_file_open_dialog_cb_key_down(void *data,
183                                                              Evas *e,
184                                                              Evas_Object *obj,
185                                                              void *event_info);
186
187 static void             _e_fwin_pan_set(Evas_Object *obj,
188                                         Evas_Coord x,
189                                         Evas_Coord y);
190 static void             _e_fwin_pan_get(Evas_Object *obj,
191                                         Evas_Coord *x,
192                                         Evas_Coord *y);
193 static void             _e_fwin_pan_max_get(Evas_Object *obj,
194                                             Evas_Coord *x,
195                                             Evas_Coord *y);
196 static void             _e_fwin_pan_child_size_get(Evas_Object *obj,
197                                                    Evas_Coord *w,
198                                                    Evas_Coord *h);
199 static void             _e_fwin_pan_scroll_update(E_Fwin_Page *page);
200 static void             _e_fwin_cb_page_obj_del(void *data, Evas *evas,
201                                                 Evas_Object *obj, void *event_info);
202 static void             _e_fwin_zone_cb_mouse_down(void *data,
203                                                    Evas *evas,
204                                                    Evas_Object *obj,
205                                                    void *event_info);
206 static void             _e_fwin_zone_focus_out(void *data,
207                                                    Evas *evas,
208                                                    Evas_Object *obj,
209                                                    void *event_info);
210 static void             _e_fwin_zone_focus_in(void *data,
211                                                    Evas *evas,
212                                                    void *event_info);
213 static Eina_Bool        _e_fwin_zone_move_resize(void *data,
214                                                  int type,
215                                                  void *event);
216 static Eina_Bool        _e_fwin_zone_del(void *data,
217                                          int type,
218                                          void *event);
219 static void             _e_fwin_config_set(E_Fwin_Page *page);
220 static void             _e_fwin_window_title_set(E_Fwin_Page *page);
221 static void             _e_fwin_toolbar_resize(E_Fwin_Page *page);
222 static int              _e_fwin_dlg_cb_desk_sort(const void *p1,
223                                                  const void *p2);
224 static int              _e_fwin_dlg_cb_desk_list_sort(const void *data1,
225                                                       const void *data2);
226
227 static void             _e_fwin_op_registry_listener_cb(void *data,
228                                                         const E_Fm2_Op_Registry_Entry *ere);
229 static Eina_Bool        _e_fwin_op_registry_entry_add_cb(void *data,
230                                                          int type,
231                                                          void *event);
232 static void             _e_fwin_op_registry_entry_iter(E_Fwin_Page *page);
233 static void             _e_fwin_op_registry_abort_cb(void *data,
234                                                      Evas_Object *obj,
235                                                      const char *emission,
236                                                      const char *source);
237
238 static E_Fwin *drag_fwin = NULL;
239
240 /* local subsystem globals */
241 static Eina_List *fwins = NULL;
242 static E_Fm2_Mime_Handler *dir_handler = NULL;
243 static Efreet_Desktop *tdesktop = NULL;
244
245 /* externally accessible functions */
246 int
247 e_fwin_init(void)
248 {
249    tdesktop = e_util_terminal_desktop_get();
250    if (!tdesktop) return 1;
251    dir_handler = e_fm2_mime_handler_new(_("Open Terminal Here"),
252                                    tdesktop->icon,
253                                    _e_fwin_cb_dir_handler, NULL,
254                                    _e_fwin_cb_dir_handler_test, NULL);
255    e_fm2_mime_handler_mime_add(dir_handler, "inode/directory");
256    return 1;
257 }
258
259 int
260 e_fwin_shutdown(void)
261 {
262    E_Fwin *fwin;
263
264    EINA_LIST_FREE(fwins, fwin)
265      e_object_del(E_OBJECT(fwin));
266
267    if (dir_handler)
268      {
269         e_fm2_mime_handler_mime_del(dir_handler, "inode/directory");
270         e_fm2_mime_handler_free(dir_handler);
271      }
272    efreet_desktop_free(tdesktop);
273
274    tdesktop = NULL;
275    dir_handler = NULL;
276
277    return 1;
278 }
279
280 /* FIXME: this opens a new window - we need a way to inherit a zone as the
281  * "fwin" window
282  */
283 void
284 e_fwin_new(E_Container *con,
285            const char *dev,
286            const char *path)
287 {
288    _e_fwin_new(con, dev, path);
289 }
290
291 static Eina_Bool
292 _e_fwin_spring_cb(E_Fwin *fwin)
293 {
294    E_Fm2_Icon_Info *ici;
295    E_Fwin *f;
296
297    if (fwin->spring_child)
298      _e_fwin_free(fwin->spring_child);
299
300    ici = e_fm2_drop_icon_get(fwin->cur_page->fm_obj);
301    if (!ici)
302      ici = e_fm2_drop_icon_get(fwin->cur_page->flist);
303    while (ici)
304      {
305         /* FIXME: could use an animation here */
306         f = _e_fwin_open(fwin->cur_page, ici, EINA_TRUE, NULL);
307         if (!f) break;
308         f->spring_parent = fwin;
309         fwin->spring_child = f;
310         break;
311      }
312    if (fwin->spring_timer) ecore_timer_del(fwin->spring_timer);
313    fwin->spring_timer = NULL;
314    return EINA_FALSE;
315 }
316
317 /* called on the drop source */
318 static void
319 _e_fwin_dnd_end_cb(E_Fwin *fwin, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
320 {
321    if (fwin->spring_timer) ecore_timer_del(fwin->spring_timer);
322    fwin->spring_timer = NULL;
323    if (!drag_fwin) return;
324    if (drag_fwin->spring_timer) ecore_timer_del(drag_fwin->spring_timer);
325    drag_fwin->spring_timer = NULL;
326
327    /* NOTE: closing the drop target window here WILL break things */
328    fwin = drag_fwin->spring_parent;
329    if (!fwin) return;
330
331    fwin->spring_child->spring_parent = NULL;
332    fwin->spring_child = NULL;
333    while (fwin->spring_parent)
334      {
335         /* FIXME: needs closing animation? */
336         fwin = fwin->spring_parent;
337         _e_fwin_free(fwin->spring_child);
338      }
339    drag_fwin = NULL;
340 }
341
342 static void
343 _e_fwin_dnd_change_cb(E_Fwin *fwin, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
344 {
345    drag_fwin = fwin;
346    if (fwin->spring_timer)
347      ecore_timer_reset(fwin->spring_timer);
348    else
349      fwin->spring_timer = ecore_timer_add(fileman_config->view.spring_delay, (Ecore_Task_Cb)_e_fwin_spring_cb, fwin);
350 }
351
352 static void
353 _e_fwin_dnd_enter_cb(E_Fwin *fwin, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
354 {
355    if (drag_fwin == fwin) return;
356    if (fwin->spring_timer) ecore_timer_del(fwin->spring_timer);
357    fwin->spring_timer = NULL;
358    if (fwin->spring_child && (drag_fwin == fwin->spring_child)) _e_fwin_free(fwin->spring_child);
359    drag_fwin = fwin;
360    if (fwin->spring_close_timer) ecore_timer_del(fwin->spring_close_timer);
361    fwin->spring_close_timer = NULL;
362 }
363
364 static Eina_Bool
365 _e_fwin_dnd_close_cb(E_Fwin *fwin)
366 {
367    _e_fwin_free(fwin);
368    return EINA_FALSE;
369 }
370
371 static void
372 _e_fwin_dnd_leave_cb(E_Fwin *fwin, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
373 {
374    if (fwin->spring_timer) ecore_timer_del(fwin->spring_timer);
375    fwin->spring_timer = NULL;
376    if (fwin->spring_parent && (!fwin->spring_child))
377      {
378         if (!fwin->spring_close_timer)
379           fwin->spring_close_timer = ecore_timer_add(0.01, (Ecore_Task_Cb)_e_fwin_dnd_close_cb, fwin);
380      }
381    drag_fwin = NULL;
382 }
383
384 static void
385 _e_fwin_dnd_begin_cb(E_Fwin *fwin __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
386 {
387    drag_fwin = NULL;
388 }
389
390 void
391 e_fwin_zone_new(E_Zone *zone, void *p)
392 {
393    E_Fwin *fwin;
394    Fileman_Path *path = p;
395    E_Fwin_Page *page;
396    Evas_Object *o;
397    int x, y, w, h;
398
399    fwin = E_OBJECT_ALLOC(E_Fwin, E_FWIN_TYPE, _e_fwin_free);
400    if (!fwin) return;
401    fwin->zone = zone;
402
403    page = E_NEW(E_Fwin_Page, 1);
404    page->fwin = fwin;
405    fwin->path = path;
406
407    /* Add Event Handler for zone move/resize & del */
408    fwin->zone_handler =
409      ecore_event_handler_add(E_EVENT_ZONE_MOVE_RESIZE,
410                              _e_fwin_zone_move_resize, fwin);
411    fwin->zone_del_handler =
412      ecore_event_handler_add(E_EVENT_ZONE_DEL,
413                              _e_fwin_zone_del, fwin);
414
415    /* Trap the mouse_down on zone so we can unselect */
416    evas_object_event_callback_add(zone->bg_event_object,
417                                   EVAS_CALLBACK_MOUSE_DOWN,
418                                   _e_fwin_zone_cb_mouse_down, fwin);
419
420    fwins = eina_list_append(fwins, fwin);
421
422    o = e_fm2_add(zone->container->bg_evas);
423    page->fm_obj = o;
424    evas_event_callback_add(zone->container->bg_evas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _e_fwin_zone_focus_in, fwin);
425    evas_object_event_callback_add(o, EVAS_CALLBACK_FOCUS_OUT, _e_fwin_zone_focus_out, fwin);
426    _e_fwin_config_set(page);
427
428    e_fm2_custom_theme_content_set(o, "desktop");
429
430    evas_object_smart_callback_add(o, "dir_changed",
431                                   _e_fwin_changed, page);
432    evas_object_smart_callback_add(o, "dir_deleted",
433                                   _e_fwin_deleted, page);
434    evas_object_smart_callback_add(o, "selected",
435                                   _e_fwin_selected, page);
436    evas_object_smart_callback_add(o, "selection_change",
437                                   _e_fwin_selection_change, page);
438    evas_object_event_callback_add(o, EVAS_CALLBACK_DEL,
439                                   _e_fwin_cb_page_obj_del, page);
440    evas_object_smart_callback_add(o, "dnd_enter", (Evas_Smart_Cb)_e_fwin_dnd_enter_cb, fwin);
441    evas_object_smart_callback_add(o, "dnd_leave", (Evas_Smart_Cb)_e_fwin_dnd_leave_cb, fwin);
442    evas_object_smart_callback_add(o, "dnd_changed", (Evas_Smart_Cb)_e_fwin_dnd_change_cb, fwin);
443    evas_object_smart_callback_add(o, "dnd_begin", (Evas_Smart_Cb)_e_fwin_dnd_begin_cb, fwin);
444    evas_object_smart_callback_add(o, "dnd_end", (Evas_Smart_Cb)_e_fwin_dnd_end_cb, fwin);
445    evas_object_smart_callback_add(o, "icon_mouse_in", (Evas_Smart_Cb)_e_fwin_icon_mouse_in, fwin);
446    evas_object_smart_callback_add(o, "icon_mouse_out", (Evas_Smart_Cb)_e_fwin_icon_mouse_out, fwin);
447    e_fm2_icon_menu_start_extend_callback_set(o, _e_fwin_cb_menu_extend_start, page);
448    e_fm2_underlay_hide(o);
449    evas_object_show(o);
450
451    o = e_scrollframe_add(zone->container->bg_evas);
452    ecore_x_icccm_state_set(zone->container->bg_win, ECORE_X_WINDOW_STATE_HINT_NORMAL);
453    e_drop_xdnd_register_set(zone->container->event_win, 1);
454    e_scrollframe_custom_theme_set(o, "base/theme/fileman",
455                                   "e/fileman/desktop/scrollframe");
456    /* FIXME: this theme object will have more versions and options later
457     * for things like swallowing widgets/buttons ot providing them - a
458     * gadcon for starters for fm widgets. need to register the owning
459     * e_object of the gadcon so gadcon clients can get it and thus do
460     * things like find out what dirs/path the fwin is for etc. this will
461     * probably be how you add optional gadgets to fwin views like empty/full
462     * meters for disk usage, and other dir info/stats or controls. also it
463     * might be possible that we can have custom frames per dir later so need
464     * a way to set an edje file directly
465     */
466    /* FIXME: allow specialised scrollframe obj per dir - get from e config,
467     * then look in the dir itself for a magic dot-file, if not - use theme.
468     * same as currently done for bg & overlay. also add to fm2 the ability
469     * to specify the .edj files to get the list and icon theme stuff from
470     */
471    evas_object_data_set(page->fm_obj, "fm_page", page);
472    evas_object_data_set(page->fm_obj, "page_is_zone", page);
473    e_scrollframe_extern_pan_set(o, page->fm_obj,
474                                 _e_fwin_pan_set,
475                                 _e_fwin_pan_get,
476                                 _e_fwin_pan_max_get,
477                                 _e_fwin_pan_child_size_get);
478    evas_object_propagate_events_set(page->fm_obj, 0);
479    e_widget_can_focus_set(o, 0);
480    page->scrollframe_obj = page->scr = o;
481
482    e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
483    evas_object_move(o, x, y);
484    evas_object_resize(o, w, h);
485    evas_object_show(o);
486
487    e_fm2_window_object_set(page->fm_obj, E_OBJECT(fwin->zone));
488
489    evas_object_focus_set(page->fm_obj, 1);
490
491    e_fm2_path_set(page->fm_obj, path->dev, path->path);
492
493    fwin->cur_page = page;
494 }
495
496 void
497 e_fwin_all_unsel(void *data)
498 {
499    E_Fwin *fwin;
500
501    fwin = data;
502    E_OBJECT_CHECK(fwin);
503    E_OBJECT_TYPE_CHECK(fwin, E_FWIN_TYPE);
504    e_fm2_all_unsel(fwin->cur_page->fm_obj);
505 }
506
507 void
508 e_fwin_zone_shutdown(E_Zone *zone)
509 {
510    Eina_List *f, *fn;
511    E_Fwin *win;
512    const char *dev, *path;
513
514    EINA_LIST_FOREACH_SAFE(fwins, f, fn, win)
515      {
516         if (win->zone != zone) continue;
517         win->path->desktop_mode = e_fm2_view_mode_get(win->cur_page->fm_obj);
518         e_fm2_path_get(win->cur_page->fm_obj, &dev, &path);
519         eina_stringshare_replace(&win->path->dev, dev);
520         eina_stringshare_replace(&win->path->path, path);
521         evas_event_callback_del_full(zone->container->bg_evas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _e_fwin_zone_focus_in, win);
522         e_object_del(E_OBJECT(win));
523         win = NULL;
524      }
525 }
526
527 void
528 e_fwin_reload_all(void)
529 {
530    Eina_List *l, *ll, *lll;
531    E_Container *con;
532    E_Manager *man;
533    E_Fwin *fwin;
534    E_Zone *zone;
535
536    /* Reload/recreate zones cause of property changes */
537    EINA_LIST_FOREACH(fwins, l, fwin)
538      {
539         if (!fwin) continue;  //safety
540         if (fwin->zone)
541           e_fwin_zone_shutdown(fwin->zone);
542         else
543           {
544              _e_fwin_config_set(fwin->cur_page);
545              if (fileman_config->view.show_toolbar)
546                {
547                   if (!fwin->cur_page->tbar)
548                     {
549                        fwin->cur_page->tbar = e_toolbar_new(e_win_evas_get(fwin->win), "toolbar",
550                                                             fwin->win, fwin->cur_page->fm_obj);
551                        e_toolbar_show(fwin->cur_page->tbar);
552                     }
553                }
554              else
555                {
556                   if (fwin->cur_page->tbar)
557                     {
558                        e_object_del(E_OBJECT(fwin->cur_page->tbar));
559                        fwin->cur_page->tbar = NULL;
560                     }
561                }
562              if (fileman_config->view.show_sidebar)
563                {
564                   if (!fwin->cur_page->flist_frame)
565                     _e_fwin_page_favorites_add(fwin->cur_page);
566                }
567              else
568                {
569                   if (fwin->cur_page->flist_frame)
570                     {
571                        evas_object_del(fwin->cur_page->flist_frame);
572                        fwin->cur_page->flist_frame = fwin->cur_page->flist = NULL;
573                     }
574                }
575              _e_fwin_window_title_set(fwin->cur_page);
576              _e_fwin_cb_resize(fwin->win);
577           }
578      }
579
580    /* Hook into zones */
581    EINA_LIST_FOREACH(e_manager_list(), l, man)
582      EINA_LIST_FOREACH(man->containers, ll, con)
583        EINA_LIST_FOREACH(con->zones, lll, zone)
584          {
585             if (e_fwin_zone_find(zone)) continue;
586             if (fileman_config->view.show_desktop_icons)
587               e_fwin_zone_new(zone, e_mod_fileman_path_find(zone));
588          }
589 }
590
591 int
592 e_fwin_zone_find(E_Zone *zone)
593 {
594    Eina_List *f;
595    E_Fwin *win;
596
597    EINA_LIST_FOREACH(fwins, f, win)
598      if (win->zone == zone) return 1;
599    return 0;
600 }
601
602 /* local subsystem functions */
603 static void
604 _e_fwin_bg_mouse_down(E_Fwin *fwin, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
605 {
606    int x, y, w, h, zx, zy, zw, zh;
607    e_zone_useful_geometry_get(fwin->win->border->zone, &zx, &zy, &zw, &zh);
608    x = fwin->win->border->x, y = fwin->win->border->y;
609    e_fm2_optimal_size_calc(fwin->cur_page->fm_obj, zw - x, zh - y, &w, &h);
610    if (x + w > zx + zw)
611      w = zx + zw - x;
612    if (y + x > zy + zh)
613      h = zy + zh - y;
614    e_win_resize(fwin->win, w, h);
615 }
616
617 static E_Fwin *
618 _e_fwin_new(E_Container *con,
619             const char *dev,
620             const char *path)
621 {
622    E_Fwin *fwin;
623    E_Fwin_Page *page;
624    Evas_Object *o;
625    E_Zone *zone;
626
627    fwin = E_OBJECT_ALLOC(E_Fwin, E_FWIN_TYPE, _e_fwin_free);
628    if (!fwin) return NULL;
629    fwin->win = e_win_new(con);
630    if (!fwin->win)
631      {
632         free(fwin);
633         return NULL;
634      }
635    fwins = eina_list_append(fwins, fwin);
636    e_win_delete_callback_set(fwin->win, _e_fwin_cb_delete);
637    e_win_move_callback_set(fwin->win, _e_fwin_cb_move);
638    e_win_resize_callback_set(fwin->win, _e_fwin_cb_resize);
639    fwin->win->data = fwin;
640
641    o = edje_object_add(e_win_evas_get(fwin->win));
642    e_theme_edje_object_set(o, "base/theme/fileman",
643                            "e/fileman/default/window/main");
644    evas_object_show(o);
645    fwin->bg_obj = o;
646
647    page = _e_fwin_page_create(fwin);
648    fwin->cur_page = page;
649
650 /*
651    o = edje_object_add(fwin->win->evas);
652    //   o = e_icon_add(e_win_evas_get(fwin->win));
653    //   e_icon_scale_size_set(o, 0);
654    //   e_icon_fill_inside_set(o, 0);
655    edje_object_part_swallow(fwin->bg_obj, "e.swallow.bg", o);
656    evas_object_pass_events_set(o, 1);
657    fwin->under_obj = o;
658  */
659
660    o = edje_object_add(fwin->win->evas);
661 //   o = e_icon_add(e_win_evas_get(fwin->win));
662 //   e_icon_scale_size_set(o, 0);
663 //   e_icon_fill_inside_set(o, 0);
664    edje_object_part_swallow(e_scrollframe_edje_object_get(page->scr), "e.swallow.overlay", o);
665    evas_object_pass_events_set(o, 1);
666    fwin->over_obj = o;
667
668    e_fm2_path_set(page->fm_obj, dev, path);
669    _e_fwin_window_title_set(page);
670
671    e_win_size_min_set(fwin->win, 24, 24);
672
673    zone = e_util_zone_current_get(e_manager_current_get());
674    if ((zone) && (zone->w < DEFAULT_WIDTH))
675      {
676         int w, h;
677         e_zone_useful_geometry_get(zone, NULL, NULL, &w, &h);
678         e_win_resize(fwin->win, w, h);
679      }
680    else
681      e_win_resize(fwin->win, DEFAULT_WIDTH, DEFAULT_HEIGHT);
682
683    e_win_show(fwin->win);
684    if (fwin->win->evas_win)
685      e_drop_xdnd_register_set(fwin->win->evas_win, 1);
686    if (fwin->win->border)
687      eina_stringshare_replace(&fwin->win->border->internal_icon, "system-file-manager");
688
689    return fwin;
690 }
691
692 static void
693 _e_fwin_free(E_Fwin *fwin)
694 {
695    if (!fwin) return;  //safety
696
697    _e_fwin_page_free(fwin->cur_page);
698
699    if (fwin->zone)
700      {
701         evas_object_event_callback_del(fwin->zone->bg_event_object,
702                                        EVAS_CALLBACK_MOUSE_DOWN,
703                                        _e_fwin_zone_cb_mouse_down);
704      }
705
706    if (fwin->zone_handler)
707      ecore_event_handler_del(fwin->zone_handler);
708    if (fwin->zone_del_handler)
709      ecore_event_handler_del(fwin->zone_del_handler);
710    if (fwin->spring_timer) ecore_timer_del(fwin->spring_timer);
711    fwin->spring_timer = NULL;
712    if (fwin->spring_close_timer) ecore_timer_del(fwin->spring_close_timer);
713    fwin->spring_close_timer = NULL;
714    fwins = eina_list_remove(fwins, fwin);
715    if (fwin->wallpaper_file) eina_stringshare_del(fwin->wallpaper_file);
716    if (fwin->overlay_file) eina_stringshare_del(fwin->overlay_file);
717    if (fwin->scrollframe_file) eina_stringshare_del(fwin->scrollframe_file);
718    if (fwin->theme_file) eina_stringshare_del(fwin->theme_file);
719    if (fwin->fad)
720      {
721         e_object_del(E_OBJECT(fwin->fad->dia));
722         fwin->fad = NULL;
723      }
724    if (fwin->popup) e_object_del(E_OBJECT(fwin->popup));
725    if (fwin->popup_timer) ecore_timer_del(fwin->popup_timer);
726    fwin->popup_timer = NULL;
727    if (fwin->spring_parent) fwin->spring_parent->spring_child = NULL;
728    if (fwin->win) e_object_del(E_OBJECT(fwin->win));
729    free(fwin);
730 }
731
732 static Eina_Bool
733 _e_fwin_icon_popup(void *data)
734 {
735    E_Fwin *fwin = data;
736    Evas_Object *bg, *edje, *list, *o;
737    E_Zone *zone;
738    char buf[4096];
739    int x, y, w, h, mw, mh, fx, fy, px, py;
740
741    fwin->popup_timer = NULL;
742    if (!fwin->popup_icon) return EINA_FALSE;
743    snprintf(buf, sizeof(buf), "%s/%s", e_fm2_real_path_get(fwin->cur_page->fm_obj), fwin->popup_icon->file);
744    if (!ecore_file_can_read(buf)) return EINA_FALSE;
745    if (fwin->popup) e_object_del(E_OBJECT(fwin->popup));
746    zone = fwin->zone ?: fwin->win->border->zone;
747    e_fm2_icon_geometry_get(fwin->popup_icon->ic, &x, &y, &w, &h);
748    if (fwin->zone)
749      {
750         evas_object_geometry_get(fwin->popup_icon->fm, &fx, &fy, NULL, NULL);
751         fx -= fwin->zone->x;
752         x -= fwin->zone->x;
753         fy -= fwin->zone->y;
754         y -= fwin->zone->y;
755      }
756    else
757      fx = fwin->win->x, fy = fwin->win->y;
758    fwin->popup = e_popup_new(zone, 0, 0, 1, 1);
759    e_popup_ignore_events_set(fwin->popup, 1);
760    ecore_x_window_shape_input_rectangle_set(fwin->popup->evas_win, 0, 0, 0, 0);
761    bg = edje_object_add(fwin->popup->evas);
762    e_theme_edje_object_set(bg, "base/theme/fileman", "e/fileman/default/window/main");
763    e_popup_edje_bg_object_set(fwin->popup, bg);
764    edje = edje_object_add(fwin->popup->evas);
765    e_theme_edje_object_set(edje, "base/theme/borders", "e/widgets/border/pixel/border");
766    edje_object_signal_emit(edje, "e,state,focused", "e");
767    mw = zone->w * fileman_config->tooltip.size / 100.0;
768    mh = zone->h * fileman_config->tooltip.size / 100.0;
769    /*
770     * NO! this causes the filename label to either take up the whole screen or be cut off!!!
771    if (fwin->popup_icon->link)
772      {
773         if (fwin->popup_icon->real_link == NULL)
774           snprintf(buf, sizeof(buf), _("%s â†’ %s â‡’ (broken)"), fwin->popup_icon->file, fwin->popup_icon->link);
775         else if (fwin->popup_icon->real_link != fwin->popup_icon->link)
776           snprintf(buf, sizeof(buf), _("%s â†’ %s â‡’ %s"), fwin->popup_icon->file, fwin->popup_icon->link, fwin->popup_icon->real_link);
777         else if (fwin->popup_icon->broken_link)
778           snprintf(buf, sizeof(buf), _("%s â†’ %s (broken)"), fwin->popup_icon->file, fwin->popup_icon->link);
779         else
780           snprintf(buf, sizeof(buf), _("%s â†’ %s"), fwin->popup_icon->file, fwin->popup_icon->link);
781      }
782    else
783      snprintf(buf, sizeof(buf), "%s", fwin->popup_icon->file);
784    list = e_widget_framelist_add(fwin->popup->evas, buf, 0);
785    */
786    list = e_widget_framelist_add(fwin->popup->evas, fwin->popup_icon->file, 0);
787    o = e_widget_filepreview_add(fwin->popup->evas, mw, mh, 0);
788    e_widget_filepreview_path_set(o, buf, fwin->popup_icon->mime);
789    e_widget_framelist_object_append(list, o);
790    e_widget_size_min_get(list, &mw, &mh);
791    edje_extern_object_min_size_set(list, mw, mh);
792    edje_object_part_swallow(edje, "e.swallow.client", list);
793    edje_object_size_min_calc(edje, &mw, &mh);
794    edje_extern_object_min_size_set(edje, mw, mh);
795    edje_object_part_swallow(bg, "e.swallow.bg", edje);
796    edje_object_size_min_calc(bg, &mw, &mh);
797    evas_object_show(o);
798    evas_object_show(list);
799    evas_object_show(edje);
800    evas_object_show(bg);
801
802    /* prefer tooltip left of icon */
803    px = (fx + x) - mw - 3;
804    /* if it's offscreen, try right of icon */
805    if (px < 0) px = (fx + x + w) + 3;
806    /* fuck this, stick it right on the icon */
807    if (px + mw + 3 > zone->w)
808      px = (x + w / 2) - (mw / 2);
809    /* give up */
810    if (px < 0) px = 0;
811
812    /* prefer tooltip above icon */
813    py = (fy + y) - mh - 3;
814    /* if it's offscreen, try below icon */
815    if (py < 0) py = (fy + y + h) + 3;
816    /* fuck this, stick it right on the icon */
817    if (py + mh + 3 > zone->h)
818      py = (y + h / 2) - (mh / 2);
819    /* give up */
820    if (py < 0) py = 0;
821    e_popup_move_resize(fwin->popup, px, py, mw, mh);
822    evas_object_resize(bg, mw, mh);
823    e_popup_show(fwin->popup);
824    return EINA_FALSE;
825 }
826
827 static void
828 _e_fwin_icon_mouse_out(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
829 {
830    E_Fwin *fwin = data;
831
832    if (fwin->popup_timer) ecore_timer_del(fwin->popup_timer);
833    if (fwin->popup) e_object_del(E_OBJECT(fwin->popup));
834    fwin->popup = NULL;
835    fwin->popup_timer = NULL;
836    fwin->popup_icon = NULL;
837 }
838
839 static void
840 _e_fwin_icon_mouse_in(void *data, Evas_Object *obj __UNUSED__, void *event_info)
841 {
842    E_Fwin *fwin = data;
843    E_Fm2_Icon_Info *ici = event_info;
844
845    if (fwin->popup_timer) ecore_timer_del(fwin->popup_timer);
846    fwin->popup_timer = NULL;
847    if (!fileman_config->tooltip.enable) return;
848    fwin->popup_timer = ecore_timer_add(fileman_config->tooltip.delay, _e_fwin_icon_popup, fwin);
849    fwin->popup_icon = ici;
850 }
851
852 static void
853 _e_fwin_page_favorites_add(E_Fwin_Page *page)
854 {
855    E_Fm2_Config fmc;
856    Evas_Object *o;
857    Evas *evas = evas_object_evas_get(page->box);
858
859    o = e_fm2_add(evas);
860    evas_object_data_set(o, "fm_page", page);
861    page->flist = o;
862    memset(&fmc, 0, sizeof(E_Fm2_Config));
863    fmc.view.mode = E_FM2_VIEW_MODE_LIST;
864    fmc.view.open_dirs_in_place = 1;
865    fmc.view.selector = 1;
866    fmc.view.single_click = 1;
867    fmc.view.no_subdir_jump = 1;
868    fmc.view.link_drop = 1;
869    fmc.icon.list.w = 24;
870    fmc.icon.list.h = 24;
871    fmc.icon.fixed.w = 1;
872    fmc.icon.fixed.h = 1;
873    fmc.icon.extension.show = 0;
874    fmc.icon.key_hint = NULL;
875    fmc.list.sort.no_case = 1;
876    fmc.list.sort.dirs.first = 0;
877    fmc.list.sort.dirs.last = 0;
878    fmc.selection.single = 1;
879    fmc.selection.windows_modifiers = 0;
880    fmc.view.no_click_rename = 1;
881    e_fm2_config_set(o, &fmc);
882    e_fm2_icon_menu_flags_set(o, E_FM2_MENU_NO_NEW | E_FM2_MENU_NO_ACTIVATE_CHANGE | E_FM2_MENU_NO_VIEW_CHANGE);
883    //evas_object_smart_callback_add(o, "changed", _cb, fwin);
884    evas_object_smart_callback_add(o, "selected", _e_fwin_favorite_selected, page);
885    evas_object_smart_callback_add(o, "dnd_enter", (Evas_Smart_Cb)_e_fwin_dnd_enter_cb, page->fwin);
886    evas_object_smart_callback_add(o, "dnd_leave", (Evas_Smart_Cb)_e_fwin_dnd_leave_cb, page->fwin);
887    evas_object_smart_callback_add(o, "dnd_changed", (Evas_Smart_Cb)_e_fwin_dnd_change_cb, page->fwin);
888    evas_object_smart_callback_add(o, "dnd_begin", (Evas_Smart_Cb)_e_fwin_dnd_begin_cb, page->fwin);
889    evas_object_smart_callback_add(o, "dnd_end", (Evas_Smart_Cb)_e_fwin_dnd_end_cb, page->fwin);
890    e_fm2_path_set(o, "favorites", "/");
891
892    o = e_widget_scrollframe_pan_add(evas, page->flist,
893                                     e_fm2_pan_set,
894                                     e_fm2_pan_get,
895                                     e_fm2_pan_max_get,
896                                     e_fm2_pan_child_size_get);
897    evas_object_propagate_events_set(page->flist, 0);
898    e_widget_can_focus_set(o, EINA_FALSE);
899    e_fm2_window_object_set(page->flist, E_OBJECT(page->fwin->win));
900    e_widget_scrollframe_focus_object_set(o, page->flist);
901
902    page->flist_frame = o;
903    e_widget_size_min_set(o, 128, 128);
904    e_widget_list_object_prepend(page->box, o, 1, 0, 0);
905 }
906
907 static E_Fwin_Page *
908 _e_fwin_page_create(E_Fwin *fwin)
909 {
910    Evas_Object *o;
911    E_Fwin_Page *page;
912    Evas *evas;
913
914    page = E_NEW(E_Fwin_Page, 1);
915    page->fwin = fwin;
916    evas = e_win_evas_get(fwin->win);
917
918    page->box = e_widget_list_add(evas, 0, 1);
919
920    if (fileman_config->view.show_sidebar)
921      _e_fwin_page_favorites_add(page);
922
923    o = e_fm2_add(evas);
924    page->fm_obj = o;
925    e_fm2_view_flags_set(o, E_FM2_VIEW_DIR_CUSTOM);
926    evas_object_event_callback_add(o, EVAS_CALLBACK_KEY_DOWN, _e_fwin_cb_key_down, page);
927
928    evas_object_smart_callback_add(o, "dir_changed",
929                                   _e_fwin_changed, page);
930    evas_object_smart_callback_add(o, "dir_deleted",
931                                   _e_fwin_deleted, page);
932    evas_object_smart_callback_add(o, "selected",
933                                   _e_fwin_selected, page);
934    evas_object_smart_callback_add(o, "selection_change",
935                                   _e_fwin_selection_change, page);
936    evas_object_event_callback_add(o, EVAS_CALLBACK_DEL,
937                                   _e_fwin_cb_page_obj_del, page);
938    evas_object_smart_callback_add(o, "dnd_enter", (Evas_Smart_Cb)_e_fwin_dnd_enter_cb, fwin);
939    evas_object_smart_callback_add(o, "dnd_leave", (Evas_Smart_Cb)_e_fwin_dnd_leave_cb, fwin);
940    evas_object_smart_callback_add(o, "dnd_changed", (Evas_Smart_Cb)_e_fwin_dnd_change_cb, fwin);
941    evas_object_smart_callback_add(o, "dnd_begin", (Evas_Smart_Cb)_e_fwin_dnd_begin_cb, fwin);
942    evas_object_smart_callback_add(o, "dnd_end", (Evas_Smart_Cb)_e_fwin_dnd_end_cb, fwin);
943    evas_object_smart_callback_add(o, "double_clicked", (Evas_Smart_Cb)_e_fwin_bg_mouse_down, fwin);
944    evas_object_smart_callback_add(o, "icon_mouse_in", (Evas_Smart_Cb)_e_fwin_icon_mouse_in, fwin);
945    evas_object_smart_callback_add(o, "icon_mouse_out", (Evas_Smart_Cb)_e_fwin_icon_mouse_out, fwin);
946    e_fm2_icon_menu_start_extend_callback_set(o, _e_fwin_cb_menu_extend_start, page);
947    e_fm2_window_object_set(o, E_OBJECT(fwin->win));
948    evas_object_focus_set(o, 1);
949    _e_fwin_config_set(page);
950
951    /* FIXME: this theme object will have more versions and options later
952     * for things like swallowing widgets/buttons ot providing them - a
953     * gadcon for starters for fm widgets. need to register the owning
954     * e_object of the gadcon so gadcon clients can get it and thus do
955     * things like find out what dirs/path the fwin is for etc. this will
956     * probably be how you add optional gadgets to fwin views like empty/full
957     * meters for disk usage, and other dir info/stats or controls. also it
958     * might be possible that we can have custom frames per dir later so need
959     * a way to set an edje file directly
960     */
961    /* FIXME: allow specialised scrollframe obj per dir - get from e config,
962     * then look in the dir itself for a magic dot-file, if not - use theme.
963     * same as currently done for bg & overlay. also add to fm2 the ability
964     * to specify the .edj files to get the list and icon theme stuff from
965     */
966    evas_object_data_set(page->fm_obj, "fm_page", page);
967    evas_object_data_set(page->fm_obj, "page_is_window", page);
968    o = e_widget_scrollframe_pan_add(evas, page->fm_obj,
969                                     e_fm2_pan_set,
970                                     e_fm2_pan_get,
971                                     e_fm2_pan_max_get,
972                                     e_fm2_pan_child_size_get);
973    evas_object_propagate_events_set(page->fm_obj, 0);
974    e_widget_can_focus_set(o, EINA_FALSE);
975    page->scrollframe_obj = o;
976    page->scr = e_widget_scrollframe_object_get(o);
977    e_scrollframe_custom_theme_set(page->scr, "base/theme/fileman",
978                                   "e/fileman/default/scrollframe");
979 //   edje_object_part_swallow(fwin->bg_obj, "e.swallow.content", o);
980    e_widget_list_object_append(page->box, page->scrollframe_obj, 1, 1, 1);
981    evas_object_move(page->box, 0, 0);
982    evas_object_show(page->box);
983
984    if (fileman_config->view.show_toolbar)
985      {
986         page->tbar = e_toolbar_new(evas, "toolbar",
987                                    fwin->win, page->fm_obj);
988         e_toolbar_show(page->tbar);
989      }
990
991    page->fm_op_entry_add_handler =
992      ecore_event_handler_add(E_EVENT_FM_OP_REGISTRY_ADD,
993                              _e_fwin_op_registry_entry_add_cb, page);
994    _e_fwin_op_registry_entry_iter(page);
995    return page;
996 }
997
998 static void
999 _e_fwin_page_free(E_Fwin_Page *page)
1000 {
1001    if (page->fm_obj) evas_object_del(page->fm_obj);
1002    if (page->tbar) e_object_del(E_OBJECT(page->tbar));
1003    if (page->box) evas_object_del(page->box);
1004    else evas_object_del(page->scrollframe_obj);
1005
1006    if (page->fm_op_entry_add_handler)
1007      ecore_event_handler_del(page->fm_op_entry_add_handler);
1008
1009    E_FREE(page);
1010 }
1011
1012 static const char *
1013 _e_fwin_custom_file_path_eval(E_Fwin *fwin,
1014                               Efreet_Desktop *ef,
1015                               const char *prev_path,
1016                               const char *key)
1017 {
1018    char buf[PATH_MAX];
1019    const char *res, *ret = NULL;
1020
1021    /* get a X-something custom tage from the .desktop for the dir */
1022    res = eina_hash_find(ef->x, key);
1023    /* free the old path */
1024    if (prev_path) eina_stringshare_del(prev_path);
1025    /* if there was no key found - return NULL */
1026    if (!res) return NULL;
1027
1028    /* it's a full path */
1029    if (res[0] == '/')
1030      ret = eina_stringshare_add(res);
1031    /* relative path to the dir */
1032    else
1033      {
1034         snprintf(buf, sizeof(buf), "%s/%s",
1035                  e_fm2_real_path_get(fwin->cur_page->fm_obj), res);
1036         ret = eina_stringshare_add(buf);
1037      }
1038    return ret;
1039 }
1040
1041 static Eina_List *
1042 _e_fwin_defaults_apps_get(const char *mime, const char *path)
1043 {
1044    Efreet_Ini *ini;
1045    const char *str;
1046    Eina_List *apps = NULL;
1047    char **array, **itr;
1048
1049    if (!ecore_file_exists(path)) return NULL;
1050
1051    ini = efreet_ini_new(path);
1052    if (!ini) return NULL;
1053
1054    efreet_ini_section_set(ini, "Default Applications");
1055    str = efreet_ini_string_get(ini, mime);
1056    if (!str) goto end;
1057
1058    array = eina_str_split(str, ";", 0);
1059    if (!array) goto end;
1060
1061    for (itr = array; *itr != NULL; itr++)
1062      {
1063         const char *name = *itr;
1064         Efreet_Desktop *desktop;
1065
1066         if (name[0] == '/')
1067           desktop = efreet_desktop_new(name);
1068         else
1069           desktop = efreet_util_desktop_file_id_find(name);
1070
1071         if (!desktop) continue;
1072         if (!desktop->exec)
1073           {
1074              efreet_desktop_free(desktop);
1075              continue;
1076           }
1077
1078         apps = eina_list_append(apps, desktop);
1079      }
1080
1081    free(array[0]);
1082    free(array);
1083  end:
1084    efreet_ini_free(ini);
1085    return apps;
1086 }
1087
1088 static Eina_List *
1089 _e_fwin_suggested_apps_list_sort(const char *mime, Eina_List *desktops, Eina_Bool *has_default)
1090 {
1091    char path[PATH_MAX];
1092    Eina_List *order, *l;
1093    Efreet_Desktop *desktop;
1094
1095    snprintf(path, sizeof(path), "%s/applications/defaults.list",
1096             efreet_data_home_get());
1097    order = _e_fwin_defaults_apps_get(mime, path);
1098
1099    if (!order)
1100      {
1101         const Eina_List *n, *dirs = efreet_data_dirs_get();
1102         const char *d;
1103         EINA_LIST_FOREACH(dirs, n, d)
1104           {
1105              snprintf(path, sizeof(path), "%s/applications/defaults.list", d);
1106              order = _e_fwin_defaults_apps_get(mime, path);
1107              if (order)
1108                break;
1109           }
1110      }
1111
1112    if (!order)
1113      {
1114         if (has_default) *has_default = EINA_FALSE;
1115         return desktops;
1116      }
1117
1118    EINA_LIST_FOREACH(order, l, desktop)
1119      {
1120         Eina_List *node = eina_list_data_find_list(desktops, desktop);
1121         if (!node) continue;
1122         desktops = eina_list_remove_list(desktops, node);
1123         efreet_desktop_free(desktop);
1124      }
1125
1126    if (has_default) *has_default = EINA_TRUE;
1127
1128    return eina_list_merge(order, desktops);
1129 }
1130
1131 static Eina_List *
1132 _e_fwin_suggested_apps_list_get(Eina_List *files,
1133                                 Eina_List **mime_list,
1134                                 Eina_Bool *has_default)
1135 {
1136    E_Fm2_Icon_Info *ici;
1137    Eina_Hash *set_mimes;
1138    Eina_List *apps = NULL, *l;
1139
1140    set_mimes = eina_hash_string_small_new(NULL);
1141    EINA_LIST_FOREACH(files, l, ici)
1142      if (!((ici->link) && (ici->mount)))
1143        {
1144           if (_e_fwin_file_is_exec(ici) == E_FWIN_EXEC_NONE)
1145             {
1146                const char *key = ici->mime;
1147                if (ici->link)
1148                  key = efreet_mime_globs_type_get(ici->link);
1149
1150                if (!eina_hash_find(set_mimes, key))
1151                  eina_hash_direct_add(set_mimes, key, (void *)1);
1152             }
1153        }
1154
1155    if (mime_list) *mime_list = NULL;
1156    if (has_default) *has_default = EINA_FALSE;
1157
1158    if (eina_hash_population(set_mimes) > 0)
1159      {
1160         Eina_Hash *set_apps = eina_hash_pointer_new(NULL);
1161         Eina_Iterator *itr = eina_hash_iterator_key_new(set_mimes);
1162         const char *mime;
1163
1164         EINA_ITERATOR_FOREACH(itr, mime)
1165           {
1166              Eina_List *desktops = efreet_util_desktop_mime_list(mime);
1167              Efreet_Desktop *d;
1168              Eina_Bool hd = EINA_FALSE;
1169
1170              if (mime_list) *mime_list = eina_list_append(*mime_list, mime);
1171
1172              desktops = _e_fwin_suggested_apps_list_sort(mime, desktops, &hd);
1173              if ((hd) && (has_default))
1174                *has_default = EINA_TRUE;
1175
1176              EINA_LIST_FREE(desktops, d)
1177                {
1178                   if (eina_hash_find(set_apps, &d)) efreet_desktop_free(d);
1179                   else
1180                     {
1181                        eina_hash_add(set_apps, &d, (void *)1);
1182                        apps = eina_list_append(apps, d);
1183                     }
1184                }
1185           }
1186         eina_iterator_free(itr);
1187         eina_hash_free(set_apps);
1188      }
1189    eina_hash_free(set_mimes);
1190
1191    return apps;
1192 }
1193
1194 static void
1195 _e_fwin_desktop_run(Efreet_Desktop *desktop,
1196                     E_Fwin_Page *page,
1197                     Eina_Bool skip_history)
1198 {
1199    char pcwd[4096], buf[4096];
1200    Eina_List *selected, *l, *files = NULL;
1201    E_Fwin *fwin = page->fwin;
1202    E_Fm2_Icon_Info *ici;
1203    char *file;
1204    
1205    skip_history = EINA_FALSE;
1206
1207    selected = e_fm2_selected_list_get(page->fm_obj);
1208    if (!selected) return;
1209
1210    getcwd(pcwd, sizeof(pcwd));
1211    chdir(e_fm2_real_path_get(page->fm_obj));
1212
1213    EINA_LIST_FOREACH(selected, l, ici)
1214      {
1215         E_Fwin_Exec_Type ext;
1216
1217         /* this snprintf is silly - but it's here in case i really do
1218          * need to provide full paths (seems silly since we chdir
1219          * into the dir)
1220          */
1221         buf[0] = 0;
1222         ext = _e_fwin_file_is_exec(ici);
1223         if ((ext == E_FWIN_EXEC_NONE) || (desktop))
1224           {
1225              if (!((ici->link) && (ici->mount)))
1226                eina_strlcpy(buf, ici->file, sizeof(buf));
1227           }
1228         else
1229           _e_fwin_file_exec(page, ici, ext);
1230         if (buf[0] != 0)
1231           {
1232              if ((ici->mime) && (desktop) && !(skip_history))
1233                e_exehist_mime_desktop_add(ici->mime, desktop);
1234              files = eina_list_append(files, strdup(ici->file));
1235           }
1236      }
1237    if ((fwin->win) && (desktop))
1238      {
1239         e_exec(fwin->win->border->zone, desktop, NULL, files, "fwin");
1240         ici = selected->data;
1241         if ((ici) && (ici->mime) && (desktop) && !(skip_history))
1242           e_exehist_mime_desktop_add(ici->mime, desktop);
1243      }
1244    else if (fwin->zone && desktop)
1245      e_exec(fwin->zone, desktop, NULL, files, "fwin");
1246
1247    eina_list_free(selected);
1248
1249    EINA_LIST_FREE(files, file) free(file);
1250
1251    chdir(pcwd);
1252 }
1253
1254 static E_Fwin_Exec_Type
1255 _e_fwin_file_is_exec(E_Fm2_Icon_Info *ici)
1256 {
1257    /* special file or dir - can't exec anyway */
1258    if ((S_ISCHR(ici->statinfo.st_mode)) ||
1259        (S_ISBLK(ici->statinfo.st_mode)) ||
1260        (S_ISFIFO(ici->statinfo.st_mode)) ||
1261        (S_ISSOCK(ici->statinfo.st_mode)))
1262      return E_FWIN_EXEC_NONE;
1263    /* it is executable */
1264    if ((ici->statinfo.st_mode & S_IXOTH) ||
1265        ((getgid() == ici->statinfo.st_gid) &&
1266         (ici->statinfo.st_mode & S_IXGRP)) ||
1267        ((getuid() == ici->statinfo.st_uid) &&
1268         (ici->statinfo.st_mode & S_IXUSR)))
1269      {
1270         /* no mimetype */
1271         if (!ici->mime)
1272           return E_FWIN_EXEC_DIRECT;
1273         /* mimetype */
1274         else
1275           {
1276              /* FIXME: - this could be config */
1277              if (!strcmp(ici->mime, "application/x-desktop"))
1278                return E_FWIN_EXEC_DESKTOP;
1279              else if ((!strcmp(ici->mime, "application/x-sh")) ||
1280                       (!strcmp(ici->mime, "application/x-shellscript")) ||
1281                       (!strcmp(ici->mime, "application/x-csh")) ||
1282                       (!strcmp(ici->mime, "application/x-perl")) ||
1283                       (!strcmp(ici->mime, "application/x-shar")) ||
1284                       (!strcmp(ici->mime, "application/x-executable")) ||
1285                       (!strcmp(ici->mime, "text/x-csh")) ||
1286                       (!strcmp(ici->mime, "text/x-python")) ||
1287                       (!strcmp(ici->mime, "text/x-sh"))
1288                       )
1289                {
1290                   return E_FWIN_EXEC_DIRECT;
1291                }
1292           }
1293      }
1294    else
1295      {
1296         /* mimetype */
1297         if (ici->mime)
1298           {
1299              /* FIXME: - this could be config */
1300              if (!strcmp(ici->mime, "application/x-desktop"))
1301                return E_FWIN_EXEC_DESKTOP;
1302              else if ((!strcmp(ici->mime, "application/x-sh")) ||
1303                       (!strcmp(ici->mime, "application/x-shellscript")) ||
1304                       (!strcmp(ici->mime, "text/x-sh"))
1305                       )
1306                {
1307                   return E_FWIN_EXEC_TERMINAL_SH;
1308                }
1309           }
1310         else if ((e_util_glob_match(ici->file, "*.desktop")) ||
1311                  (e_util_glob_match(ici->file, "*.kdelink"))
1312                  )
1313           {
1314              return E_FWIN_EXEC_DESKTOP;
1315           }
1316         else if (e_util_glob_match(ici->file, "*.run"))
1317           return E_FWIN_EXEC_TERMINAL_SH;
1318      }
1319    return E_FWIN_EXEC_NONE;
1320 }
1321
1322 static void
1323 _e_fwin_file_exec(E_Fwin_Page *page,
1324                   E_Fm2_Icon_Info *ici,
1325                   E_Fwin_Exec_Type ext)
1326 {
1327    E_Fwin *fwin = page->fwin;
1328    char buf[4096];
1329    Efreet_Desktop *desktop;
1330
1331    /* FIXME: execute file ici with either a terminal, the shell, or directly
1332     * or open the .desktop and exec it */
1333    switch (ext)
1334      {
1335       case E_FWIN_EXEC_NONE:
1336         break;
1337
1338       case E_FWIN_EXEC_DIRECT:
1339         snprintf(buf, sizeof(buf), "%s/%s", e_fm2_real_path_get(fwin->cur_page->fm_obj), ici->file);
1340         if (fwin->win)
1341           e_exec(fwin->win->border->zone, NULL, buf, NULL, "fwin");
1342         else if (fwin->zone)
1343           e_exec(fwin->zone, NULL, buf, NULL, "fwin");
1344         break;
1345
1346       case E_FWIN_EXEC_SH:
1347         snprintf(buf, sizeof(buf), "/bin/sh %s", e_util_filename_escape(ici->file));
1348         if (fwin->win)
1349           e_exec(fwin->win->border->zone, NULL, buf, NULL, "fwin");
1350         else if (fwin->zone)
1351           e_exec(fwin->zone, NULL, buf, NULL, "fwin");
1352         break;
1353
1354       case E_FWIN_EXEC_TERMINAL_DIRECT:
1355         snprintf(buf, sizeof(buf), "%s %s", e_config->exebuf_term_cmd, e_util_filename_escape(ici->file));
1356         if (fwin->win)
1357           e_exec(fwin->win->border->zone, NULL, buf, NULL, "fwin");
1358         else if (fwin->zone)
1359           e_exec(fwin->zone, NULL, buf, NULL, "fwin");
1360         break;
1361
1362       case E_FWIN_EXEC_TERMINAL_SH:
1363         snprintf(buf, sizeof(buf), "%s /bin/sh %s", e_config->exebuf_term_cmd, e_util_filename_escape(ici->file));
1364         if (fwin->win)
1365           e_exec(fwin->win->border->zone, NULL, buf, NULL, "fwin");
1366         else if (fwin->zone)
1367           e_exec(fwin->zone, NULL, buf, NULL, "fwin");
1368         break;
1369
1370       case E_FWIN_EXEC_DESKTOP:
1371         snprintf(buf, sizeof(buf), "%s/%s", e_fm2_real_path_get(page->fm_obj), ici->file);
1372         desktop = efreet_desktop_new(buf);
1373         if (desktop)
1374           {
1375              if (fwin->win)
1376                e_exec(fwin->win->border->zone, desktop, NULL, NULL, "fwin");
1377              else if (fwin->zone)
1378                e_exec(fwin->zone, desktop, NULL, NULL, "fwin");
1379              e_exehist_mime_desktop_add(ici->mime, desktop);
1380              efreet_desktop_free(desktop);
1381           }
1382         break;
1383
1384       default:
1385         break;
1386      }
1387 }
1388
1389 static void
1390 _e_fwin_config_set(E_Fwin_Page *page)
1391 {
1392    E_Fm2_Config fmc;
1393
1394    memset(&fmc, 0, sizeof(E_Fm2_Config));
1395    if (!page->fwin->zone)
1396      {
1397 #if 0
1398         fmc.view.mode = E_FM2_VIEW_MODE_LIST;
1399         fmc.icon.list.w = 24 * e_scale;
1400         fmc.icon.list.h = 24 * e_scale;
1401         fmc.icon.fixed.w = 1;
1402         fmc.icon.fixed.h = 1;
1403 #else
1404         fmc.view.mode = fileman_config->view.mode;
1405         fmc.icon.icon.w = fileman_config->icon.icon.w * e_scale;
1406         fmc.icon.icon.h = fileman_config->icon.icon.h * e_scale;
1407         fmc.icon.fixed.w = 0;
1408         fmc.icon.fixed.h = 0;
1409 #endif
1410         fmc.view.open_dirs_in_place = fileman_config->view.open_dirs_in_place;
1411      }
1412    else
1413      {
1414 #if 0
1415         fmc.view.mode = E_FM2_VIEW_MODE_LIST;
1416         fmc.icon.list.w = 24 * e_scale;
1417         fmc.icon.list.h = 24 * e_scale;
1418         fmc.icon.fixed.w = 1;
1419         fmc.icon.fixed.h = 1;
1420 #else
1421         fmc.view.mode = page->fwin->path->desktop_mode;
1422         fmc.icon.icon.w = fileman_config->icon.icon.w * e_scale;
1423         fmc.icon.icon.h = fileman_config->icon.icon.h * e_scale;
1424         fmc.icon.fixed.w = 0;
1425         fmc.icon.fixed.h = 0;
1426 #endif
1427         fmc.view.no_typebuf_set = !fileman_config->view.desktop_navigation;
1428         fmc.view.open_dirs_in_place = 0;
1429         fmc.view.fit_custom_pos = 1;
1430      }
1431
1432    fmc.view.selector = 0;
1433    fmc.view.single_click = fileman_config->view.single_click;
1434    fmc.view.no_subdir_jump = 0;
1435    fmc.icon.extension.show = fileman_config->icon.extension.show;
1436    fmc.list.sort.no_case = fileman_config->list.sort.no_case;
1437    fmc.list.sort.extension = fileman_config->list.sort.extension;
1438    fmc.list.sort.mtime = fileman_config->list.sort.mtime;
1439    fmc.list.sort.size = fileman_config->list.sort.size;
1440    fmc.list.sort.dirs.first = fileman_config->list.sort.dirs.first;
1441    fmc.list.sort.dirs.last = fileman_config->list.sort.dirs.last;
1442    fmc.selection.single = fileman_config->selection.single;
1443    fmc.selection.windows_modifiers = fileman_config->selection.windows_modifiers;
1444    e_fm2_config_set(page->fm_obj, &fmc);
1445 }
1446
1447 static void
1448 _e_fwin_window_title_set(E_Fwin_Page *page)
1449 {
1450    char buf[PATH_MAX + sizeof("e_fwin::")];
1451    const char *file;
1452
1453    if (!page) return;
1454    if (page->fwin->zone) return;  //safety
1455
1456    if (fileman_config->view.show_full_path)
1457      file = e_fm2_real_path_get(page->fm_obj);
1458    else
1459      file = ecore_file_file_get(e_fm2_real_path_get(page->fm_obj));
1460
1461    if (file)
1462      {
1463         eina_strlcpy(buf, file, sizeof(buf));
1464         e_win_title_set(page->fwin->win, buf);
1465      }
1466
1467    snprintf(buf, sizeof(buf), "e_fwin::%s", e_fm2_real_path_get(page->fm_obj));
1468    e_win_name_class_set(page->fwin->win, "E", buf);
1469 }
1470
1471 static void
1472 _e_fwin_toolbar_resize(E_Fwin_Page *page)
1473 {
1474    int tx, ty, tw, th, offset = 0;
1475    int x, y, w, h;
1476
1477    w = page->fwin->win->w;
1478    h = page->fwin->win->h;
1479    if (!page->tbar)
1480      {
1481         evas_object_move(page->box, 0, 0);
1482         evas_object_resize(page->box, w, h);
1483         return;
1484      }
1485    switch (page->tbar->gadcon->orient)
1486      {
1487       case E_GADCON_ORIENT_HORIZ:
1488       case E_GADCON_ORIENT_TOP:
1489         tx = 0;
1490         ty = offset;
1491         th = 32;
1492         tw = w;
1493
1494         x = 0;
1495         y = offset + th;
1496         h = (h - offset - th);
1497         break;
1498
1499       case E_GADCON_ORIENT_BOTTOM:
1500         tx = 0;
1501         th = 32;
1502         tw = w;
1503         ty = h - th;
1504
1505         x = 0;
1506         y = offset;
1507         h = (h - offset - th);
1508         break;
1509
1510       case E_GADCON_ORIENT_VERT:
1511       case E_GADCON_ORIENT_LEFT:
1512         tx = 0;
1513         tw = 32;
1514         th = h - offset;
1515         ty = offset;
1516
1517         x = tw;
1518         y = offset;
1519         w = (w - tw);
1520         break;
1521
1522       case E_GADCON_ORIENT_RIGHT:
1523         ty = offset;
1524         tw = 32;
1525         tx = w - tw;
1526         th = h - offset;
1527
1528         x = 0;
1529         y = offset;
1530         w = (w - tw);
1531         break;
1532
1533       default:
1534         return;
1535      }
1536    e_toolbar_move_resize(page->tbar, tx, ty, tw, th);
1537    evas_object_move(page->box, x, y);
1538    evas_object_resize(page->box, w, h);
1539 }
1540
1541 /* fwin callbacks */
1542 static void
1543 _e_fwin_cb_delete(E_Win *win)
1544 {
1545    E_Fwin *fwin;
1546
1547    if (!win) return;  //safety
1548    fwin = win->data;
1549    e_object_del(E_OBJECT(fwin));
1550 }
1551
1552 /* static void
1553  * _e_fwin_geom_save(E_Fwin *fwin)
1554  * {
1555  *    char buf[PATH_MAX];
1556  *    E_Fm2_Custom_File *cf;
1557  *
1558  *    if (!fwin->geom_save_ready) return;
1559  *    snprintf(buf, sizeof(buf), "dir::%s", e_fm2_real_path_get(fwin->cur_page->fm_obj));
1560  *    cf = e_fm2_custom_file_get(buf);
1561  *    if (!cf)
1562  *      {
1563  *  cf = alloca(sizeof(E_Fm2_Custom_File));
1564  *  memset(cf, 0, sizeof(E_Fm2_Custom_File));
1565  *      }
1566  *    cf->geom.x = fwin->win->x;
1567  *    cf->geom.y = fwin->win->y;
1568  *    cf->geom.w = fwin->win->w;
1569  *    cf->geom.h = fwin->win->h;
1570  *    cf->geom.valid = 1;
1571  *    e_fm2_custom_file_set(buf, cf);
1572  * } */
1573
1574 static void
1575 _e_fwin_cb_move(E_Win *win)
1576 {
1577 //   E_Fwin *fwin;
1578
1579    if (!win) return;  //safety
1580 //   fwin = win->data;
1581 /* _e_fwin_geom_save(fwin); */
1582 }
1583
1584 static void
1585 _e_fwin_cb_resize(E_Win *win)
1586 {
1587    E_Fwin *fwin;
1588
1589    if (!win) return;  //safety
1590    fwin = win->data;
1591    if (fwin->bg_obj)
1592      {
1593         if (fwin->win)
1594           evas_object_resize(fwin->bg_obj, fwin->win->w, fwin->win->h);
1595         else if (fwin->zone)
1596           evas_object_resize(fwin->bg_obj, fwin->zone->w, fwin->zone->h);
1597      }
1598    _e_fwin_toolbar_resize(fwin->cur_page);
1599    if (fwin->zone)
1600      evas_object_resize(fwin->cur_page->scrollframe_obj, fwin->zone->w, fwin->zone->h);
1601    /* _e_fwin_geom_save(fwin); */
1602 }
1603
1604 static void
1605 _e_fwin_deleted(void *data,
1606                 Evas_Object *obj __UNUSED__,
1607                 void *event_info __UNUSED__)
1608 {
1609    E_Fwin_Page *page;
1610
1611    page = data;
1612    e_object_del(E_OBJECT(page->fwin));
1613 }
1614
1615 static void
1616 _e_fwin_changed(void *data,
1617                 Evas_Object *obj,
1618                 void *event_info __UNUSED__)
1619 {
1620    E_Fwin *fwin;
1621    E_Fwin_Page *page;
1622    E_Fm2_Config *cfg;
1623    Efreet_Desktop *ef;
1624    const char *dev, *path;
1625    char buf[PATH_MAX];
1626
1627    page = data;
1628    fwin = page->fwin;
1629    if (!fwin) return;  //safety
1630
1631    cfg = e_fm2_config_get(page->fm_obj);
1632    e_fm2_path_get(page->fm_obj, &dev, NULL);
1633    e_user_dir_concat_static(buf, "fileman/favorites");
1634    path = e_fm2_real_path_get(page->fm_obj);
1635    if ((dev && (!strcmp(dev, "favorites"))) || (path && (!strcmp(buf, path))))
1636      cfg->view.link_drop = 1;
1637    else
1638      cfg->view.link_drop = 0;
1639
1640    /* FIXME: first look in E config for a special override for this dir's bg
1641     * or overlay
1642     */
1643    snprintf(buf, sizeof(buf), "%s/.directory.desktop", e_fm2_real_path_get(page->fm_obj));
1644    ef = efreet_desktop_new(buf);
1645    //printf("EF=%p for %s\n", ef, buf);
1646    if (ef)
1647      {
1648         fwin->wallpaper_file = _e_fwin_custom_file_path_eval(fwin, ef, fwin->wallpaper_file, "X-Enlightenment-Directory-Wallpaper");
1649         fwin->overlay_file = _e_fwin_custom_file_path_eval(fwin, ef, fwin->overlay_file, "X-Enlightenment-Directory-Overlay");
1650         fwin->scrollframe_file = _e_fwin_custom_file_path_eval(fwin, ef, fwin->scrollframe_file, "X-Enlightenment-Directory-Scrollframe");
1651         fwin->theme_file = _e_fwin_custom_file_path_eval(fwin, ef, fwin->theme_file, "X-Enlightenment-Directory-Theme");
1652         //printf("fwin->wallpaper_file = %s\n", fwin->wallpaper_file);
1653         efreet_desktop_free(ef);
1654      }
1655    else
1656      {
1657 #define RELEASE_STR(x) if (x) {eina_stringshare_del(x); (x) = NULL; }
1658         RELEASE_STR(fwin->wallpaper_file);
1659         RELEASE_STR(fwin->overlay_file);
1660         RELEASE_STR(fwin->scrollframe_file);
1661         RELEASE_STR(fwin->theme_file);
1662 #undef RELEASE_STR
1663      }
1664    if (fwin->under_obj) evas_object_hide(fwin->under_obj);
1665    if (fwin->wallpaper_file)
1666      {
1667         if (eina_str_has_extension(fwin->wallpaper_file, "edj"))
1668           {
1669              if (!fwin->wallpaper_is_edj)
1670                {
1671                   if (fwin->under_obj) evas_object_del(fwin->under_obj);
1672                   fwin->under_obj = edje_object_add(fwin->win->evas);
1673                   fwin->wallpaper_is_edj = EINA_TRUE;
1674                }
1675              edje_object_file_set(fwin->under_obj, fwin->wallpaper_file, "e/desktop/background");
1676           }
1677         else
1678           {
1679              if (fwin->wallpaper_is_edj) evas_object_del(fwin->under_obj);
1680              fwin->wallpaper_is_edj = EINA_FALSE;
1681              fwin->under_obj = e_icon_add(e_win_evas_get(fwin->win));
1682              e_icon_scale_size_set(fwin->under_obj, 0);
1683              e_icon_fill_inside_set(fwin->under_obj, 0);
1684              e_icon_file_set(fwin->under_obj, fwin->wallpaper_file);
1685           }
1686         if (fwin->under_obj)
1687           {
1688              edje_object_part_swallow(fwin->bg_obj, "e.swallow.bg", fwin->under_obj);
1689              evas_object_pass_events_set(fwin->under_obj, 1);
1690              evas_object_show(fwin->under_obj);
1691           }
1692      }
1693    if (fwin->over_obj)
1694      {
1695         //printf("over obj\n");
1696         evas_object_hide(fwin->over_obj);
1697         if (fwin->overlay_file)
1698           {
1699              edje_object_file_set(fwin->over_obj, fwin->overlay_file, "e/desktop/background");
1700 //             ext = strrchr(fwin->overlay_file, '.');
1701 //             if (ext && !strcasecmp(ext, ".edj"))
1702 //               e_icon_file_edje_set(fwin->over_obj, fwin->overlay_file, "e/desktop/background");
1703 //             else
1704 //               e_icon_file_set(fwin->over_obj, fwin->overlay_file);
1705           }
1706 //        else
1707 //          e_icon_file_edje_set(fwin->over_obj, NULL, NULL);
1708         evas_object_show(fwin->over_obj);
1709      }
1710    if (page->scrollframe_obj)
1711      {
1712         if ((fwin->scrollframe_file) &&
1713             (e_util_edje_collection_exists(fwin->scrollframe_file, "e/fileman/default/scrollframe")))
1714           e_scrollframe_custom_edje_file_set(page->scr,
1715                                              (char *)fwin->scrollframe_file,
1716                                              "e/fileman/default/scrollframe");
1717         else
1718           {
1719              if (fwin->zone)
1720                e_scrollframe_custom_theme_set(page->scr,
1721                                               "base/theme/fileman",
1722                                               "e/fileman/desktop/scrollframe");
1723              else
1724                e_scrollframe_custom_theme_set(page->scr,
1725                                               "base/theme/fileman",
1726                                               "e/fileman/default/scrollframe");
1727           }
1728         e_scrollframe_child_pos_set(page->scr, 0, 0);
1729      }
1730    if ((fwin->theme_file) && (ecore_file_exists(fwin->theme_file)))
1731      e_fm2_custom_theme_set(obj, fwin->theme_file);
1732    else
1733      e_fm2_custom_theme_set(obj, NULL);
1734
1735    _e_fwin_icon_mouse_out(fwin, NULL, NULL);
1736    if (fwin->zone)
1737      {
1738         e_fm2_path_get(page->fm_obj, &dev, &path);
1739         eina_stringshare_replace(&fwin->path->dev, dev);
1740         eina_stringshare_replace(&fwin->path->path, path);
1741         return;
1742      }
1743    _e_fwin_window_title_set(page);
1744    if (page->setting) return;
1745    if (page->flist) e_fm2_deselect_all(page->flist);
1746 }
1747
1748 static void
1749 _e_fwin_favorite_selected(void *data,
1750                  Evas_Object *obj __UNUSED__,
1751                  void *event_info __UNUSED__)
1752 {
1753    E_Fwin_Page *page;
1754    Eina_List *selected;
1755
1756    page = data;
1757    selected = e_fm2_selected_list_get(page->flist);
1758    if (!selected) return;
1759    page->setting = 1;
1760    _e_fwin_file_open_dialog(page, selected, 0);
1761    eina_list_free(selected);
1762    page->setting = 0;
1763 }
1764
1765 static void
1766 _e_fwin_selected(void *data,
1767                  Evas_Object *obj __UNUSED__,
1768                  void *event_info __UNUSED__)
1769 {
1770    E_Fwin_Page *page;
1771    Eina_List *selected;
1772
1773    page = data;
1774    selected = e_fm2_selected_list_get(page->fm_obj);
1775    if (!selected) return;
1776    _e_fwin_file_open_dialog(page, selected, 0);
1777    eina_list_free(selected);
1778 }
1779
1780 static void
1781 _e_fwin_selection_change(void *data,
1782                          Evas_Object *obj,
1783                          void *event_info __UNUSED__)
1784 {
1785    Eina_List *l;
1786    E_Fwin_Page *page;
1787
1788    page = data;
1789    for (l = fwins; l; l = l->next)
1790      {
1791         if (l->data != page->fwin)
1792           e_fwin_all_unsel(l->data);
1793      }
1794    evas_object_focus_set(obj, 1);
1795    _e_fwin_icon_mouse_out(page->fwin, NULL, NULL);
1796 }
1797
1798 static void
1799 _e_fwin_cb_all_change(void *data,
1800                       Evas_Object *obj __UNUSED__)
1801 {
1802    E_Fwin_Apps_Dialog *fad;
1803    Efreet_Desktop *desktop = NULL;
1804
1805    fad = data;
1806    desktop = efreet_util_desktop_file_id_find(fad->app2);
1807    if ((desktop) && (desktop->exec))
1808      e_widget_entry_text_set(fad->o_entry, desktop->exec);
1809    if (desktop)
1810      efreet_desktop_free(desktop);
1811 }
1812
1813 static void
1814 _e_fwin_cb_key_down(void *data,
1815                     Evas *e          __UNUSED__,
1816                     Evas_Object *obj __UNUSED__,
1817                     void *event_info)
1818 {
1819    Evas_Event_Key_Down *ev;
1820    E_Fwin *fwin;
1821    E_Fwin_Page *page;
1822
1823    page = data;
1824    fwin = page->fwin;
1825    ev = event_info;
1826
1827    if (evas_key_modifier_is_set(ev->modifiers, "Control"))
1828      {
1829         if (!strcmp(ev->key, "n"))
1830           {
1831              E_Container *con;
1832              const char *dev, *path;
1833
1834              con = e_container_current_get(e_manager_current_get());
1835              e_fm2_path_get(page->fm_obj, &dev, &path);
1836              e_fwin_new(con, dev, path);
1837              return;
1838           }
1839         if (!strcmp(ev->key, "w"))
1840           {
1841              e_object_del(E_OBJECT(fwin));
1842              return;
1843           }
1844         if (!strcmp(ev->key, "a"))
1845           {
1846              e_fm2_all_sel(page->fm_obj);
1847              return;
1848           }
1849      }
1850 }
1851
1852 static void
1853 _e_fwin_cb_page_obj_del(void *data,
1854                         Evas *evas       __UNUSED__,
1855                         Evas_Object *obj __UNUSED__,
1856                         void *event_info __UNUSED__)
1857 {
1858    E_Fwin_Page *page;
1859
1860    page = data;
1861
1862    evas_object_smart_callback_del(page->fm_obj, "dir_changed",
1863                                   _e_fwin_changed);
1864    evas_object_smart_callback_del(page->fm_obj, "dir_deleted",
1865                                   _e_fwin_deleted);
1866    evas_object_smart_callback_del(page->fm_obj, "selected",
1867                                   _e_fwin_selected);
1868    evas_object_smart_callback_del(page->fm_obj, "selection_change",
1869                                   _e_fwin_selection_change);
1870    evas_object_event_callback_del(page->fm_obj, EVAS_CALLBACK_DEL,
1871                                   _e_fwin_cb_page_obj_del);
1872 }
1873
1874 /* fwin zone callbacks */
1875 static void
1876 _e_fwin_zone_cb_mouse_down(void *data,
1877                            Evas *evas       __UNUSED__,
1878                            Evas_Object *obj __UNUSED__,
1879                            void *event_info __UNUSED__)
1880 {
1881    E_Fwin *fwin;
1882
1883    fwin = data;
1884    if (!fwin) return;
1885    e_fwin_all_unsel(fwin);
1886    e_fm2_typebuf_clear(fwin->cur_page->fm_obj);
1887 }
1888
1889 static void
1890 _e_fwin_zone_focus_out(void *data __UNUSED__,
1891                        Evas *evas       __UNUSED__,
1892                        Evas_Object *obj,
1893                        void *event_info __UNUSED__)
1894 {
1895    evas_object_focus_set(obj, EINA_TRUE);
1896 }
1897
1898 static void
1899 _e_fwin_zone_focus_in(void *data,
1900                        Evas *evas       __UNUSED__,
1901                        void *event_info __UNUSED__)
1902 {
1903    E_Fwin *fwin;
1904
1905    fwin = data;
1906    if (!fwin) return;
1907    evas_object_focus_set(fwin->cur_page->fm_obj, EINA_TRUE);
1908 }
1909
1910 static Eina_Bool
1911 _e_fwin_zone_move_resize(void *data,
1912                          int type,
1913                          void *event)
1914 {
1915    E_Event_Zone_Move_Resize *ev;
1916    E_Fwin *fwin;
1917
1918    if (type != E_EVENT_ZONE_MOVE_RESIZE) return ECORE_CALLBACK_PASS_ON;
1919    fwin = data;
1920    ev = event;
1921    if (!fwin) return ECORE_CALLBACK_PASS_ON;
1922    if (fwin->zone != ev->zone) return ECORE_CALLBACK_PASS_ON;
1923    if (fwin->bg_obj)
1924      {
1925         evas_object_move(fwin->bg_obj, ev->zone->x, ev->zone->y);
1926         evas_object_resize(fwin->bg_obj, ev->zone->w, ev->zone->h);
1927      }
1928    if (fwin->cur_page->scrollframe_obj)
1929      {
1930         int x, y, w, h;
1931         e_zone_useful_geometry_get(ev->zone, &x, &y, &w, &h);
1932         evas_object_move(fwin->cur_page->scrollframe_obj, x, y);
1933         evas_object_resize(fwin->cur_page->scrollframe_obj, w, h);
1934      }
1935    return ECORE_CALLBACK_PASS_ON;
1936 }
1937
1938 static Eina_Bool
1939 _e_fwin_zone_del(void *data,
1940                  int type,
1941                  void *event)
1942 {
1943    E_Event_Zone_Del *ev;
1944    E_Fwin *fwin;
1945
1946    if (type != E_EVENT_ZONE_DEL) return ECORE_CALLBACK_PASS_ON;
1947    fwin = data;
1948    ev = event;
1949    if (!fwin) return ECORE_CALLBACK_PASS_ON;
1950    if (fwin->zone != ev->zone) return ECORE_CALLBACK_PASS_ON;
1951    e_object_del(E_OBJECT(fwin));
1952    return ECORE_CALLBACK_PASS_ON;
1953 }
1954
1955 static int
1956 _e_fwin_cb_dir_handler_test(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const char *path)
1957 {
1958    return ecore_file_is_dir(path);
1959 }
1960
1961 static void
1962 _e_fwin_cb_dir_handler(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const char *path)
1963 {
1964    char buf[PATH_MAX];
1965
1966    if (!getcwd(buf, sizeof(buf))) return;
1967
1968    chdir(path);
1969    e_exec(e_util_zone_current_get(e_manager_current_get()), tdesktop, NULL, NULL, "fileman");
1970    chdir(buf);
1971    /* FIXME: if info != null then check mime type and offer options based
1972     * on that
1973     */
1974 }
1975
1976 static void
1977 _e_fwin_parent(void *data,
1978                E_Menu *m       __UNUSED__,
1979                E_Menu_Item *mi __UNUSED__)
1980 {
1981    e_fm2_parent_go(data);
1982 }
1983
1984 static void
1985 _e_fwin_cb_menu_open_fast(void *data,
1986                           E_Menu *m    __UNUSED__,
1987                           E_Menu_Item *mi)
1988 {
1989    E_Fwin_Page *page;
1990    Efreet_Desktop *desk;
1991
1992    page = data;
1993    desk = e_object_data_get(E_OBJECT(mi));
1994
1995    if ((page) && (desk))
1996      _e_fwin_desktop_run(desk, page, EINA_TRUE);
1997 }
1998
1999 static void
2000 _e_fwin_cb_menu_extend_open_with(void *data,
2001                                  E_Menu *m)
2002 {
2003    Eina_List *selected = NULL, *apps = NULL, *l;
2004    E_Menu_Item *mi;
2005    E_Fwin_Page *page;
2006    Efreet_Desktop *desk = NULL;
2007
2008    page = data;
2009
2010    selected = e_fm2_selected_list_get(page->fm_obj);
2011    if (!selected) return;
2012
2013    apps = _e_fwin_suggested_apps_list_get(selected, NULL, NULL);
2014    EINA_LIST_FOREACH(apps, l, desk)
2015      {
2016         if (!desk) continue;
2017         mi = e_menu_item_new(m);
2018         e_menu_item_label_set(mi, desk->name);
2019         e_util_desktop_menu_item_icon_add(desk, 24, mi);
2020         e_menu_item_callback_set(mi, _e_fwin_cb_menu_open_fast, page);
2021         e_object_data_set(E_OBJECT(mi), desk);
2022      }
2023
2024    if (apps)
2025      {
2026         mi = e_menu_item_new(m);
2027         e_menu_item_separator_set(mi, 1);
2028      }
2029
2030    mi = e_menu_item_new(m);
2031    e_menu_item_label_set(mi, _("Other application..."));
2032    e_util_menu_item_theme_icon_set(mi, "document-open");
2033    e_menu_item_callback_set(mi, _e_fwin_cb_menu_open_with, page);
2034
2035    e_menu_pre_activate_callback_set(m, NULL, NULL);
2036
2037    eina_list_free(apps);
2038    eina_list_free(selected);
2039 }
2040
2041 static void
2042 _e_fwin_path(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
2043 {
2044    const char *path;
2045    E_Fwin_Page *page;
2046    Ecore_X_Window xwin;
2047
2048    path = e_fm2_real_path_get(data);
2049    page = evas_object_data_get(data, "fm_page");
2050    if (page->fwin->win)
2051      xwin = page->fwin->win->border->client.win;
2052    else
2053      xwin = page->fwin->zone->container->event_win;
2054    ecore_x_selection_clipboard_set(xwin, path, strlen(path) + 1);
2055 }
2056
2057 static void
2058 _e_fwin_clone(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
2059 {
2060    E_Fwin *fwin = data;
2061    E_Action *act_fm;
2062
2063    /* path of least resistance! */
2064    act_fm = e_action_find("fileman");
2065    if (!act_fm) return;
2066    act_fm->func.go(NULL, fwin->win->border->client.icccm.class + 8);
2067 }
2068
2069 static void
2070 _e_fwin_cb_menu_extend_start(void *data,
2071                              Evas_Object *obj,
2072                              E_Menu *m,
2073                              E_Fm2_Icon_Info *info __UNUSED__)
2074 {
2075    E_Menu_Item *mi = NULL;
2076    E_Fwin_Page *page;
2077    E_Menu *subm;
2078    Eina_List *selected = NULL;
2079
2080    page = data;
2081
2082    selected = e_fm2_selected_list_get(page->fm_obj);
2083
2084 #ifdef ENABLE_FILES
2085    subm = e_mod_menu_add(m, e_fm2_real_path_get(page->fm_obj));
2086
2087    if (((!page->fwin->zone) || fileman_config->view.desktop_navigation) && e_fm2_has_parent_get(obj))
2088      {
2089         mi = e_menu_item_new_relative(subm, NULL);
2090         e_menu_item_label_set(mi, _("Go To Parent Directory"));
2091         e_menu_item_icon_edje_set(mi,
2092                                   e_theme_edje_file_get("base/theme/fileman",
2093                                                         "e/fileman/default/button/parent"),
2094                                   "e/fileman/default/button/parent");
2095         e_menu_item_callback_set(mi, _e_fwin_parent, obj);
2096      }
2097    if (!page->fwin->zone)
2098      {
2099         mi = e_menu_item_new_relative(subm, mi);
2100         e_menu_item_label_set(mi, _("Clone Window"));
2101         e_util_menu_item_theme_icon_set(mi, "window-duplicate");
2102         e_menu_item_callback_set(mi, _e_fwin_clone, page->fwin);
2103      }
2104
2105    mi = e_menu_item_new_relative(subm, mi);
2106    e_menu_item_label_set(mi, _("Copy Path"));
2107    e_util_menu_item_theme_icon_set(mi, "edit-copy");
2108    e_menu_item_callback_set(mi, _e_fwin_path, obj);
2109
2110    mi = e_menu_item_new_relative(subm, mi);
2111    e_menu_item_separator_set(mi, EINA_TRUE);
2112    
2113    mi = e_menu_item_new(m);
2114    e_menu_item_separator_set(mi, EINA_TRUE);
2115 #endif
2116    if (!selected) return;
2117    mi = e_menu_item_new(m);
2118    e_menu_item_label_set(mi, _("Open"));
2119    e_util_menu_item_theme_icon_set(mi, "document-open");
2120    e_menu_item_callback_set(mi, _e_fwin_cb_menu_open, page);
2121
2122    mi = e_menu_item_new(m);
2123    e_menu_item_label_set(mi, _("Open with..."));
2124    e_util_menu_item_theme_icon_set(mi, "document-open");
2125
2126    subm = e_menu_new();
2127    e_menu_item_submenu_set(mi, subm);
2128    e_menu_pre_activate_callback_set(subm, _e_fwin_cb_menu_extend_open_with, page);
2129
2130    mi = e_menu_item_new(m);
2131    e_menu_item_separator_set(mi, 1);
2132 }
2133
2134 static void
2135 _e_fwin_cb_menu_open(void *data,
2136                      E_Menu *m       __UNUSED__,
2137                      E_Menu_Item *mi __UNUSED__)
2138 {
2139    E_Fwin_Page *page;
2140    Eina_List *selected;
2141
2142    page = data;
2143    selected = e_fm2_selected_list_get(page->fm_obj);
2144    if (!selected) return;
2145    _e_fwin_file_open_dialog(page, selected, 0);
2146    eina_list_free(selected);
2147 }
2148
2149 static void
2150 _e_fwin_cb_menu_open_with(void *data,
2151                           E_Menu *m       __UNUSED__,
2152                           E_Menu_Item *mi __UNUSED__)
2153 {
2154    E_Fwin_Page *page;
2155    Eina_List *selected = NULL;
2156
2157    page = data;
2158    selected = e_fm2_selected_list_get(page->fm_obj);
2159    if (!selected) return;
2160    _e_fwin_file_open_dialog(page, selected, 1);
2161    eina_list_free(selected);
2162 }
2163
2164 static void
2165 _e_fwin_border_set(E_Fwin_Page *page, E_Fwin *fwin, E_Fm2_Icon_Info *ici)
2166 {
2167    Evas_Object *oic;
2168    const char *itype = NULL;
2169    int ix, iy, iw, ih, nx, ny, found = 0;
2170    E_Remember *rem = NULL;
2171    Eina_List *ll;
2172    const char *file = NULL, *group = NULL, *class;
2173    int w, h, zw, zh;
2174    /* E_Fm2_Custom_File *cf; */
2175
2176    if (ici->label)
2177      e_win_title_set(fwin->win, ici->label);
2178    else if (ici->file)
2179      e_win_title_set(fwin->win, ici->file);
2180    oic = e_fm2_icon_get(evas_object_evas_get(ici->fm),
2181                         ici->ic, NULL, NULL, 0, &itype);
2182    if (!oic) return;
2183    if (fwin->win->border->internal_icon)
2184      eina_stringshare_del(fwin->win->border->internal_icon);
2185    fwin->win->border->internal_icon = NULL;
2186    if (fwin->win->border->internal_icon_key)
2187      eina_stringshare_del(fwin->win->border->internal_icon_key);
2188    fwin->win->border->internal_icon_key = NULL;
2189
2190    if (!strcmp(evas_object_type_get(oic), "edje"))
2191      {
2192         edje_object_file_get(oic, &file, &group);
2193         if (file)
2194           {
2195              fwin->win->border->internal_icon =
2196                eina_stringshare_add(file);
2197              if (group)
2198                fwin->win->border->internal_icon_key =
2199                  eina_stringshare_add(group);
2200           }
2201      }
2202    else
2203      {
2204         file = e_icon_file_get(oic);
2205         fwin->win->border->internal_icon =
2206           eina_stringshare_add(file);
2207      }
2208    evas_object_del(oic);
2209    if (fwin->win->border->placed) return;
2210
2211    class = eina_stringshare_printf("e_fwin::%s", e_fm2_real_path_get(fwin->cur_page->fm_obj));
2212    EINA_LIST_FOREACH(e_config->remembers, ll, rem)
2213      if (rem->class && (rem->class == class))
2214        {
2215           found = 1;
2216           break;
2217        }
2218    eina_stringshare_del(class);
2219
2220    if (found) return;
2221
2222    e_zone_useful_geometry_get(fwin->win->border->zone,
2223                               NULL, NULL, &zw, &zh);
2224
2225    /* No custom info, so just put window near icon */
2226    e_fm2_icon_geometry_get(ici->ic, &ix, &iy, &iw, &ih);
2227    nx = (ix + (iw / 2));
2228    ny = (iy + (ih / 2));
2229    if (page->fwin->win)
2230      {
2231         nx += page->fwin->win->x;
2232         ny += page->fwin->win->y;
2233      }
2234
2235    /* checking width and height */
2236    /* TODO add config for preffered
2237       initial size? */
2238    w = DEFAULT_WIDTH;
2239    if (w > zw)
2240      w = zw;
2241
2242    h = DEFAULT_HEIGHT;
2243    if (h > zh)
2244      h = zh;
2245
2246    /* iff going out of zone - adjust to be in */
2247    if ((fwin->win->border->zone->x + fwin->win->border->zone->w) < (w + nx))
2248      nx -= w;
2249    if ((fwin->win->border->zone->y + fwin->win->border->zone->h) < (h + ny))
2250      ny -= h;
2251
2252    e_win_move_resize(fwin->win, nx, ny, w, h);
2253    fwin->win->border->placed = 1;
2254 }
2255
2256 static E_Fwin *
2257 _e_fwin_open(E_Fwin_Page *page, E_Fm2_Icon_Info *ici, Eina_Bool force, int *need_dia)
2258 {
2259    E_Fwin *fwin = NULL;
2260    char buf[PATH_MAX + sizeof("removable:")];
2261    Eina_Bool new_fwin;
2262
2263    new_fwin = (force || ((!fileman_config->view.open_dirs_in_place || page->fwin->zone)));
2264
2265    if ((ici->link) && (ici->mount))
2266      {
2267         if (new_fwin)
2268           {
2269              if (page->fwin->win)
2270                fwin = _e_fwin_new(page->fwin->win->container, ici->link, "/");
2271              else if (page->fwin->zone)
2272                fwin = _e_fwin_new(page->fwin->zone->container, ici->link, "/");
2273           }
2274         else
2275           {
2276              _e_fwin_border_set(page, page->fwin, ici);
2277              e_fm2_path_set(page->fm_obj, ici->link, "/");
2278              return page->fwin;
2279           }
2280      }
2281    else if ((ici->link) && (ici->removable))
2282      {
2283         snprintf(buf, sizeof(buf), "removable:%s", ici->link);
2284         if (new_fwin)
2285           {
2286              if (page->fwin->win)
2287                fwin = _e_fwin_new(page->fwin->win->container, buf, "/");
2288              else if (page->fwin->zone)
2289                fwin = _e_fwin_new(page->fwin->zone->container, buf, "/");
2290           }
2291         else
2292           {
2293              _e_fwin_border_set(page, page->fwin, ici);
2294              e_fm2_path_set(page->fm_obj, buf, "/");
2295              return page->fwin;
2296           }
2297      }
2298    else if (ici->real_link)
2299      {
2300         if (S_ISDIR(ici->statinfo.st_mode))
2301           {
2302              if (new_fwin)
2303                {
2304                   if (page->fwin->win)
2305                     fwin = _e_fwin_new(page->fwin->win->container, NULL, ici->real_link);
2306                   else if (page->fwin->zone)
2307                     fwin = _e_fwin_new(page->fwin->zone->container, NULL, ici->real_link);
2308                }
2309              else
2310                {
2311                   _e_fwin_border_set(page, page->fwin, ici);
2312                   e_fm2_path_set(page->fm_obj, NULL, ici->real_link);
2313                   return page->fwin;
2314                }
2315           }
2316         else
2317           {
2318              if (need_dia) *need_dia = 1;
2319           }
2320      }
2321    else
2322      {
2323         snprintf(buf, sizeof(buf), "%s/%s", e_fm2_real_path_get(page->fm_obj), ici->file);
2324         if (S_ISDIR(ici->statinfo.st_mode))
2325           {
2326              if (new_fwin)
2327                {
2328                   if (page->fwin->win)
2329                     fwin = _e_fwin_new(page->fwin->win->container, NULL, ici->link ?: buf);
2330                   else if (page->fwin->zone)
2331                     fwin = _e_fwin_new(page->fwin->zone->container, NULL, ici->link ?: buf);
2332                }
2333              else
2334                {
2335                   _e_fwin_border_set(page, page->fwin, ici);
2336                   e_fm2_path_set(page->fm_obj, NULL, ici->link ?: buf);
2337                   return page->fwin;
2338                }
2339           }
2340         else
2341           {
2342              if (need_dia) *need_dia = 1;
2343           }
2344      }
2345    if (!fwin) return NULL;
2346    if ((!fwin->win) || (!fwin->win->border))
2347      {
2348         _e_fwin_free(fwin);
2349         return NULL;
2350      }
2351    _e_fwin_border_set(page, fwin, ici);
2352         
2353    return fwin;
2354 }
2355
2356 /* 'open with' dialog*/
2357 static void
2358 _e_fwin_file_open_dialog(E_Fwin_Page *page,
2359                          Eina_List *files,
2360                          int always)
2361 {
2362    E_Fwin *fwin = page->fwin;
2363    E_Dialog *dia;
2364    Evas_Coord mw, mh;
2365    Evas_Object *o, *of, *ol, *ot;
2366    Evas *evas;
2367    Eina_List *l = NULL, *apps = NULL, *mlist = NULL;
2368    Eina_List *cats = NULL;
2369    Efreet_Desktop *desk = NULL;
2370    E_Fwin_Apps_Dialog *fad;
2371    E_Fm2_Icon_Info *ici;
2372    char buf[PATH_MAX + sizeof("removable:")];
2373    Eina_Bool has_default = EINA_FALSE;
2374    int need_dia = 0, n = 0;;
2375
2376    n = eina_list_count(files);
2377
2378    if (fwin->fad)
2379      {
2380         e_object_del(E_OBJECT(fwin->fad->dia));
2381         fwin->fad = NULL;
2382      }
2383    if (!always)
2384      {
2385         if ((fileman_config->view.open_dirs_in_place) && (!page->fwin->zone))
2386           _e_fwin_open(page, eina_list_data_get(files), EINA_FALSE, &need_dia);
2387         else
2388           {
2389              EINA_LIST_FOREACH(files, l, ici)
2390                _e_fwin_open(page, ici, EINA_FALSE, &need_dia);
2391           }
2392         if (!need_dia) return;
2393      }
2394
2395    apps = _e_fwin_suggested_apps_list_get(files, &mlist, &has_default);
2396
2397 //   fprintf(stderr, "GOGOGOGOOGOGOG\n");
2398    if (!always)
2399      {
2400         /* FIXME: well this is simplisitic - if only 1 mime type is being
2401          * opened then look for the previously used app for that mimetype and
2402          * if found, use that.
2403          *
2404          * we could get more sophisitcated.
2405          * 1. find apps for each mimetype in mlist. if all prev used apps are
2406          * the same, then use previously used app.
2407          * OR if this fails
2408          * 2. find all apps for each mimetype. find the one used the most.
2409          * if that app can handle all mimetypes in the list - use that. if not
2410          * find the next most often listed app - if that can handle all apps,
2411          * use it, if not fall back again - and so on - if all apps listed do
2412          * not contain 1 that handles all the mime types - fall back to dialog
2413          */
2414         if ((has_default) || (eina_list_count(mlist) <= 1))
2415           {
2416              char *file;
2417              char pcwd[4096];
2418              Eina_List *files_list = NULL;
2419
2420              need_dia = 1;
2421              //fprintf(stderr, "XXXXX %i %p\n", has_default, apps);
2422              if ((has_default) && (apps)) desk = apps->data;
2423              else if (mlist) desk = e_exehist_mime_desktop_get(mlist->data);
2424              //fprintf(stderr, "mlist = %p\n", mlist);
2425              getcwd(pcwd, sizeof(pcwd));
2426              chdir(e_fm2_real_path_get(page->fm_obj));
2427
2428              files_list = NULL;
2429              EINA_LIST_FOREACH(files, l, ici)
2430                if (_e_fwin_file_is_exec(ici) == E_FWIN_EXEC_NONE)
2431                  files_list = eina_list_append(files_list, strdup(ici->file));
2432              EINA_LIST_FOREACH(files, l, ici)
2433                {
2434                   E_Fwin_Exec_Type ext;
2435
2436                   ext = _e_fwin_file_is_exec(ici);
2437                   if (ext != E_FWIN_EXEC_NONE)
2438                     {
2439                        _e_fwin_file_exec(page, ici, ext);
2440                        need_dia = 0;
2441                     }
2442                }
2443              if (desk)
2444                {
2445                   if (fwin->win)
2446                     {
2447                        if (e_exec(fwin->win->border->zone, desk, NULL, files_list, "fwin"))
2448                          need_dia = 0;
2449                     }
2450                   else if (fwin->zone)
2451                     {
2452                        if (e_exec(fwin->zone, desk, NULL, files_list, "fwin"))
2453                          need_dia = 0;
2454                     }
2455                   if (!need_dia)
2456                     {
2457                        if (mlist)
2458                          e_exehist_mime_desktop_add(mlist->data, desk);
2459                     }
2460                }
2461              EINA_LIST_FREE(files_list, file)
2462                free(file);
2463
2464              chdir(pcwd);
2465              if (!need_dia)
2466                {
2467                   EINA_LIST_FREE(apps, desk) efreet_desktop_free(desk);
2468                   mlist = eina_list_free(mlist);
2469                   return;
2470                }
2471           }
2472      }
2473
2474    fad = E_NEW(E_Fwin_Apps_Dialog, 1);
2475    if (fwin->win)
2476      dia = e_dialog_new(fwin->win->border->zone->container,
2477                         "E", "_fwin_open_apps");
2478    else if (fwin->zone)
2479      dia = e_dialog_new(fwin->zone->container,
2480                         "E", "_fwin_open_apps");
2481    else return;  /* make clang happy */
2482
2483    e_dialog_title_set(dia, _("Open with..."));
2484    e_dialog_resizable_set(dia, 1);
2485    e_dialog_button_add(dia, _("Open"), "document-open",
2486                        _e_fwin_cb_open, fad);
2487    e_dialog_button_add(dia, _("Close"), "window-close",
2488                        _e_fwin_cb_close, fad);
2489
2490    fad->dia = dia;
2491    fad->fwin = fwin;
2492    fwin->fad = fad;
2493    dia->data = fad;
2494    e_object_free_attach_func_set(E_OBJECT(dia), _e_fwin_cb_dialog_free);
2495
2496    evas = e_win_evas_get(dia->win);
2497
2498    ol = e_widget_list_add(evas, 0, 0);
2499
2500    l = eina_list_free(l);
2501
2502 #if 1
2503    o = e_widget_filepreview_add(evas, 96 * e_scale, 96 * e_scale, 1);
2504    fad->o_filepreview = o;
2505    if (n == 1)
2506      {
2507         ici = eina_list_data_get(files);
2508         of = e_widget_framelist_add(evas, ici->file, 0);
2509         snprintf(buf, sizeof(buf), "%s/%s", e_fm2_real_path_get(page->fm_obj), ici->file);
2510         e_widget_filepreview_path_set(o, buf, ici->mime);
2511      }
2512    else
2513      {
2514         snprintf(buf, sizeof(buf), P_("%d file", "%d files", n), n);
2515         of = e_widget_framelist_add(evas, buf, 0);
2516         ot = e_widget_toolbar_add(evas, 24 * e_scale, 24 * e_scale);
2517         e_widget_toolbar_scrollable_set(ot, 1);
2518         EINA_LIST_FOREACH(files, l, ici)
2519           e_widget_toolbar_item_append(ot, NULL, ici->file, _e_fwin_file_open_dialog_preview_set, page, ici);
2520         e_widget_toolbar_item_select(ot, 0);
2521         e_widget_framelist_object_append(of, ot);
2522      }
2523
2524    e_widget_framelist_object_append(of, o);
2525 #else
2526    // Here each file has its own widget, created at start, resulting on a longish time to show the dialog.
2527    // However, this doesn't display artefacts as the previous method, so is kept here for reference.
2528    if (n == 1)
2529      {
2530         ici = eina_list_data_get(files);
2531         of = e_widget_framelist_add(evas, ici->file, 0);
2532         o = e_widget_filepreview_add(evas, 96 * e_scale, 96 * e_scale, 1);
2533         snprintf(buf, sizeof(buf), "%s/%s", e_fm2_real_path_get(page->fm_obj), ici->file);
2534         e_widget_filepreview_path_set(o, buf, ici->mime);
2535         e_widget_framelist_object_append(of, o);
2536      }
2537    else
2538      {
2539         snprintf(buf, sizeof(buf), P_("%d file", "%d files", n), n);
2540         of = e_widget_framelist_add(evas, buf, 0);
2541         ot = e_widget_toolbook_add(evas, 24 * e_scale, 24 * e_scale);
2542         EINA_LIST_FOREACH(files, l, ici)
2543           {
2544              o = e_widget_filepreview_add(evas, 96 * e_scale, 96 * e_scale, 1);
2545              snprintf(buf, sizeof(buf), "%s/%s", e_fm2_real_path_get(page->fm_obj), ici->file);
2546              e_widget_filepreview_path_set(o, buf, ici->mime);
2547              e_widget_toolbook_page_append(ot, NULL, ici->file, o, 1, 1, 1, 1, .5, .5);
2548           }
2549         e_widget_toolbook_page_show(ot, 0);
2550         e_widget_framelist_object_append(of, ot);
2551      }
2552 #endif
2553
2554    e_widget_list_object_append(ol, of, 1, 0, 0.5);
2555
2556    // Make frame with list of applications
2557    of = e_widget_framelist_add(evas, _("Known Applications"), 0);
2558    o = e_widget_ilist_add(evas, 24, 24, &(fad->app2));
2559    e_widget_on_change_hook_set(o, _e_fwin_cb_all_change, fad);
2560    fad->o_all = o;
2561    evas_event_freeze(evas);
2562    edje_freeze();
2563    e_widget_ilist_freeze(o);
2564
2565    // Adding Specific Applications list into widget
2566    if (apps)
2567      e_widget_ilist_header_append(o, NULL, _("Specific Applications"));
2568    mlist = eina_list_free(mlist);
2569    EINA_LIST_FOREACH(apps, l, desk)
2570      {
2571         Evas_Object *icon = NULL;
2572
2573         if (!desk) continue;
2574         icon = e_util_desktop_icon_add(desk, 24, evas);
2575         e_widget_ilist_append(o, icon, desk->name, NULL, NULL,
2576                               efreet_util_path_to_file_id(desk->orig_path));
2577      }
2578
2579    // Building All Applications list
2580    cats = efreet_util_desktop_name_glob_list("*");
2581    cats = eina_list_sort(cats, 0, _e_fwin_dlg_cb_desk_sort);
2582    EINA_LIST_FREE(cats, desk)
2583      {
2584         if (!eina_list_data_find(l, desk) && !eina_list_data_find(apps, desk))
2585           l = eina_list_append(l, desk);
2586         else
2587           efreet_desktop_free(desk);
2588      }
2589    l = eina_list_sort(l, -1, _e_fwin_dlg_cb_desk_list_sort);
2590
2591    // Adding All Applications list into widget
2592    if (l)
2593      e_widget_ilist_header_append(o, NULL, _("All Applications"));
2594    EINA_LIST_FREE(l, desk)
2595      {
2596         Evas_Object *icon = NULL;
2597
2598         if (!desk) continue;
2599         icon = e_util_desktop_icon_add(desk, 24, evas);
2600         e_widget_ilist_append(o, icon, desk->name, NULL, NULL,
2601                               efreet_util_path_to_file_id(desk->orig_path));
2602         efreet_desktop_free(desk);
2603      }
2604
2605    EINA_LIST_FREE(apps, desk)
2606      efreet_desktop_free(desk);
2607
2608    e_widget_ilist_go(o);
2609    e_widget_ilist_thaw(o);
2610    edje_thaw();
2611    evas_event_thaw(evas);
2612    e_widget_size_min_set(o, 160, 160);
2613    e_widget_framelist_object_append(of, o);
2614    e_widget_list_object_append(ol, of, 1, 1, 0.5);
2615
2616    o = e_widget_label_add(evas, _("Custom Command"));
2617    e_widget_list_object_append(ol, o, 1, 0, 0.5);
2618    fad->o_entry = e_widget_entry_add(evas, &(fad->exec_cmd),
2619                                      _e_fwin_cb_exec_cmd_changed, fad, NULL);
2620    e_widget_list_object_append(ol, fad->o_entry, 1, 0, 0.5);
2621
2622    e_widget_size_min_get(ol, &mw, &mh);
2623    e_dialog_content_set(dia, ol, mw, mh);
2624    evas_object_event_callback_add(ol, EVAS_CALLBACK_KEY_DOWN, _e_fwin_file_open_dialog_cb_key_down, page);
2625    e_dialog_show(dia);
2626    e_dialog_border_icon_set(dia, "preferences-applications");
2627    e_widget_focus_steal(fad->o_entry);
2628 }
2629
2630 static void
2631 _e_fwin_file_open_dialog_preview_set(void *data1, void *data2)
2632 {
2633    E_Fwin_Page *page = data1;
2634    E_Fm2_Icon_Info *ici = data2;
2635    char buf[PATH_MAX];
2636
2637    snprintf(buf, sizeof(buf), "%s/%s", e_fm2_real_path_get(page->fm_obj), ici->file);
2638    e_widget_filepreview_path_set(page->fwin->fad->o_filepreview, buf, ici->mime);
2639 }
2640
2641 static void
2642 _e_fwin_file_open_dialog_cb_key_down(void *data,
2643                                      Evas *e        __UNUSED__,
2644                                      Evas_Object *o __UNUSED__,
2645                                      void *event_info)
2646 {
2647    Evas_Event_Key_Down *ev = event_info;
2648    E_Fwin_Page *page = data;
2649    E_Fwin *fwin = page->fwin;
2650
2651    if (!strcmp(ev->keyname, "Escape"))
2652      _e_fwin_cb_close(fwin->fad, fwin->fad->dia);
2653    else if (!strcmp(ev->keyname, "Return"))
2654      _e_fwin_cb_open(fwin->fad, fwin->fad->dia);
2655 }
2656
2657 static int
2658 _e_fwin_dlg_cb_desk_sort(const void *p1,
2659                          const void *p2)
2660 {
2661    Efreet_Desktop *d1, *d2;
2662
2663    d1 = (Efreet_Desktop *)p1;
2664    d2 = (Efreet_Desktop *)p2;
2665
2666    if (!d1->name) return 1;
2667    if (!d2->name) return -1;
2668    return strcmp(d1->name, d2->name);
2669 }
2670
2671 static int
2672 _e_fwin_dlg_cb_desk_list_sort(const void *data1,
2673                               const void *data2)
2674 {
2675    const Efreet_Desktop *d1, *d2;
2676
2677    if (!(d1 = data1)) return 1;
2678    if (!(d2 = data2)) return -1;
2679    return strcmp(d1->name, d2->name);
2680 }
2681
2682 static void
2683 _e_fwin_cb_exec_cmd_changed(void *data,
2684                             void *data2 __UNUSED__)
2685 {
2686    E_Fwin_Apps_Dialog *fad = NULL;
2687    Efreet_Desktop *desktop = NULL;
2688
2689    if (!(fad = data)) return;
2690
2691    if (fad->app2)
2692      desktop = efreet_util_desktop_file_id_find(fad->app2);
2693
2694    if (!desktop) return;
2695    if (strcmp(desktop->exec, fad->exec_cmd))
2696      {
2697         eina_stringshare_del(fad->app2);
2698         fad->app2 = NULL;
2699         if (fad->o_all) e_widget_ilist_unselect(fad->o_all);
2700      }
2701    efreet_desktop_free(desktop);
2702 }
2703
2704 static void
2705 _e_fwin_cb_open(void *data,
2706                 E_Dialog *dia __UNUSED__)
2707 {
2708    E_Fwin_Apps_Dialog *fad;
2709    Efreet_Desktop *desktop = NULL;
2710
2711    fad = data;
2712    if (fad->app2)
2713      desktop = efreet_util_desktop_file_id_find(fad->app2);
2714
2715    if ((!desktop) && (!fad->exec_cmd))
2716      {
2717         if (desktop) efreet_desktop_free(desktop);
2718         return;
2719      }
2720
2721    // Create a fake .desktop for custom command.
2722    if (!desktop)
2723      {
2724         desktop = efreet_desktop_empty_new("");
2725         if (strchr(fad->exec_cmd, '%'))
2726           {
2727              desktop->exec = strdup(fad->exec_cmd);
2728           }
2729         else
2730           {
2731              desktop->exec = malloc(strlen(fad->exec_cmd) + 4);
2732              if (desktop->exec)
2733                snprintf(desktop->exec, strlen(fad->exec_cmd) + 4, "%s %%U", fad->exec_cmd);
2734           }
2735      }
2736
2737    if ((desktop) || (strcmp(fad->exec_cmd, "")))
2738      _e_fwin_desktop_run(desktop, fad->fwin->cur_page, EINA_FALSE);
2739
2740    efreet_desktop_free(desktop);
2741
2742    e_object_del(E_OBJECT(fad->dia));
2743 }
2744
2745 static void
2746 _e_fwin_cb_close(void *data,
2747                  E_Dialog *dia __UNUSED__)
2748 {
2749    E_Fwin_Apps_Dialog *fad;
2750
2751    fad = data;
2752    e_object_del(E_OBJECT(fad->dia));
2753 }
2754
2755 static void
2756 _e_fwin_cb_dialog_free(void *obj)
2757 {
2758    E_Dialog *dia;
2759    E_Fwin_Apps_Dialog *fad;
2760
2761    dia = (E_Dialog *)obj;
2762    fad = dia->data;
2763    eina_stringshare_del(fad->app2);
2764    E_FREE(fad->exec_cmd);
2765    fad->fwin->fad = NULL;
2766    E_FREE(fad);
2767 }
2768
2769 /* scrolling ability */
2770 static void
2771 _e_fwin_pan_set(Evas_Object *obj,
2772                 Evas_Coord x,
2773                 Evas_Coord y)
2774 {
2775    E_Fwin_Page *page;
2776
2777    page = evas_object_data_get(obj, "fm_page");
2778    e_fm2_pan_set(obj, x, y);
2779    if (x > page->fm_pan.max_x) x = page->fm_pan.max_x;
2780    if (y > page->fm_pan.max_y) y = page->fm_pan.max_y;
2781    if (x < 0) x = 0;
2782    if (y < 0) y = 0;
2783    page->fm_pan.x = x;
2784    page->fm_pan.y = y;
2785    _e_fwin_pan_scroll_update(page);
2786 }
2787
2788 static void
2789 _e_fwin_pan_get(Evas_Object *obj,
2790                 Evas_Coord *x,
2791                 Evas_Coord *y)
2792 {
2793    E_Fwin_Page *page;
2794
2795    page = evas_object_data_get(obj, "fm_page");
2796    e_fm2_pan_get(obj, x, y);
2797    page->fm_pan.x = *x;
2798    page->fm_pan.y = *y;
2799 }
2800
2801 static void
2802 _e_fwin_pan_max_get(Evas_Object *obj,
2803                     Evas_Coord *x,
2804                     Evas_Coord *y)
2805 {
2806    E_Fwin_Page *page;
2807
2808    page = evas_object_data_get(obj, "fm_page");
2809    e_fm2_pan_max_get(obj, x, y);
2810    page->fm_pan.max_x = *x;
2811    page->fm_pan.max_y = *y;
2812    _e_fwin_pan_scroll_update(page);
2813 }
2814
2815 static void
2816 _e_fwin_pan_child_size_get(Evas_Object *obj,
2817                            Evas_Coord *w,
2818                            Evas_Coord *h)
2819 {
2820    E_Fwin_Page *page;
2821
2822    page = evas_object_data_get(obj, "fm_page");
2823    e_fm2_pan_child_size_get(obj, w, h);
2824    page->fm_pan.w = *w;
2825    page->fm_pan.h = *h;
2826    _e_fwin_pan_scroll_update(page);
2827 }
2828
2829 static void
2830 _e_fwin_pan_scroll_update(E_Fwin_Page *page)
2831 {
2832    Edje_Message_Int_Set *msg;
2833
2834    if ((page->fm_pan.x == page->fm_pan_last.x) &&
2835        (page->fm_pan.y == page->fm_pan_last.y) &&
2836        (page->fm_pan.max_x == page->fm_pan_last.max_x) &&
2837        (page->fm_pan.max_y == page->fm_pan_last.max_y) &&
2838        (page->fm_pan.w == page->fm_pan_last.w) &&
2839        (page->fm_pan.h == page->fm_pan_last.h)) return;
2840    msg = alloca(sizeof(Edje_Message_Int_Set) -
2841                 sizeof(int) + (6 * sizeof(int)));
2842    msg->count = 6;
2843    msg->val[0] = page->fm_pan.x;
2844    msg->val[1] = page->fm_pan.y;
2845    msg->val[2] = page->fm_pan.max_x;
2846    msg->val[3] = page->fm_pan.max_y;
2847    msg->val[4] = page->fm_pan.w;
2848    msg->val[5] = page->fm_pan.h;
2849 //   printf("SEND MSG %i %i | %i %i | %ix%i\n",
2850 //        page->fm_pan.x, page->fm_pan.y,
2851 //        page->fm_pan.max_x, page->fm_pan.max_y,
2852 //        page->fm_pan.w, page->fm_pan.h);
2853    if (page->fwin->under_obj && page->fwin->wallpaper_is_edj)
2854      edje_object_message_send(page->fwin->under_obj, EDJE_MESSAGE_INT_SET, 1, msg);
2855    if (page->fwin->over_obj)
2856      edje_object_message_send(page->fwin->over_obj, EDJE_MESSAGE_INT_SET, 1, msg);
2857    if (page->scr)
2858      edje_object_message_send(e_scrollframe_edje_object_get(page->scr), EDJE_MESSAGE_INT_SET, 1, msg);
2859    page->fm_pan_last.x = page->fm_pan.x;
2860    page->fm_pan_last.y = page->fm_pan.y;
2861    page->fm_pan_last.max_x = page->fm_pan.max_x;
2862    page->fm_pan_last.max_y = page->fm_pan.max_y;
2863    page->fm_pan_last.w = page->fm_pan.w;
2864    page->fm_pan_last.h = page->fm_pan.h;
2865 }
2866
2867 /* e_fm_op_registry */
2868 static void
2869 _e_fwin_op_registry_listener_cb(void *data,
2870                                 const E_Fm2_Op_Registry_Entry *ere)
2871 {
2872    Evas_Object *o = data;
2873    char buf[4096];
2874    char *total;
2875    int mw, mh;
2876
2877    // Don't show if the operation keep less than 1 second
2878    if (ere->start_time + 1.0 > ecore_loop_time_get()) return;
2879
2880    // Update element
2881    edje_object_part_drag_size_set(o, "e.gauge.bar", ((double)(ere->percent)) / 100, 1.0);
2882    edje_object_size_min_get(o, &mw, &mh);
2883    evas_object_resize(o, mw * e_scale, mh * e_scale);
2884    evas_object_show(o);
2885
2886    // Update icon
2887    switch (ere->op)
2888      {
2889       case E_FM_OP_COPY:
2890         edje_object_signal_emit(o, "e,action,icon,copy", "e");
2891         break;
2892
2893       case E_FM_OP_MOVE:
2894         edje_object_signal_emit(o, "e,action,icon,move", "e");
2895         break;
2896
2897       case E_FM_OP_REMOVE:
2898         edje_object_signal_emit(o, "e,action,icon,delete", "e");
2899         break;
2900
2901       default:
2902         edje_object_signal_emit(o, "e,action,icon,unknow", "e");
2903      }
2904
2905    // Update information text
2906    switch (ere->status)
2907      {
2908       case E_FM2_OP_STATUS_ABORTED:
2909         switch (ere->op)
2910           {
2911            case E_FM_OP_COPY:
2912              snprintf(buf, sizeof(buf), _("Copying is aborted"));
2913              break;
2914
2915            case E_FM_OP_MOVE:
2916              snprintf(buf, sizeof(buf), _("Moving is aborted"));
2917              break;
2918
2919            case E_FM_OP_REMOVE:
2920              snprintf(buf, sizeof(buf), _("Deleting is aborted"));
2921              break;
2922
2923            default:
2924              snprintf(buf, sizeof(buf), _("Unknown operation from slave is aborted"));
2925           }
2926         break;
2927
2928       default:
2929         total = e_util_size_string_get(ere->total);
2930         switch (ere->op)
2931           {
2932            case E_FM_OP_COPY:
2933              if (ere->finished)
2934                snprintf(buf, sizeof(buf), _("Copy of %s done"), total);
2935              else
2936                snprintf(buf, sizeof(buf), _("Copying %s (eta: %s)"), total, e_util_time_str_get(ere->eta));
2937              break;
2938
2939            case E_FM_OP_MOVE:
2940              if (ere->finished)
2941                snprintf(buf, sizeof(buf), _("Move of %s done"), total);
2942              else
2943                snprintf(buf, sizeof(buf), _("Moving %s (eta: %s)"), total, e_util_time_str_get(ere->eta));
2944              break;
2945
2946            case E_FM_OP_REMOVE:
2947              if (ere->finished)
2948                snprintf(buf, sizeof(buf), _("Delete done"));
2949              else
2950                snprintf(buf, sizeof(buf), _("Deleting files..."));
2951              break;
2952
2953            default:
2954              snprintf(buf, sizeof(buf), _("Unknow operation from slave %d"), ere->id);
2955           }
2956         E_FREE(total);
2957      }
2958    edje_object_part_text_set(o, "e.text.info", buf);
2959
2960    if (ere->needs_attention)
2961      edje_object_signal_emit(o, "e,action,set,need_attention", "e");
2962    else
2963      edje_object_signal_emit(o, "e,action,set,normal", "e");
2964 }
2965
2966 static void
2967 _e_fwin_op_registry_free_check(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
2968 {
2969    Ecore_Timer *t;
2970
2971    t = evas_object_data_get(obj, "_e_fwin_op_registry_thingy");
2972    if (!t) return;
2973    ecore_timer_del(t);
2974 }
2975
2976 static Eina_Bool
2977 _e_fwin_op_registry_free_data_delayed(void *data)
2978 {
2979    evas_object_event_callback_del_full(data, EVAS_CALLBACK_FREE, _e_fwin_op_registry_free_check, data);
2980    evas_object_del((Evas_Object *)data);
2981    return ECORE_CALLBACK_CANCEL;
2982 }
2983
2984 static void
2985 _e_fwin_op_registry_free_data(void *data)
2986 {
2987    Ecore_Timer *t;
2988    t = ecore_timer_add(5.0, _e_fwin_op_registry_free_data_delayed, data);
2989    evas_object_data_set(data, "_e_fwin_op_registry_thingy", t);
2990    evas_object_event_callback_add(data, EVAS_CALLBACK_FREE, _e_fwin_op_registry_free_check, data);
2991 }
2992
2993 static Eina_Bool
2994 _e_fwin_op_registry_entry_add_cb(void *data,
2995                                  __UNUSED__ int type,
2996                                  void *event)
2997 {
2998    E_Fm2_Op_Registry_Entry *ere = (E_Fm2_Op_Registry_Entry *)event;
2999    E_Fwin_Page *page = data;
3000    Evas_Object *o;
3001
3002    if (!(ere->op == E_FM_OP_COPY || ere->op == E_FM_OP_MOVE ||
3003          ere->op == E_FM_OP_REMOVE))
3004      return ECORE_CALLBACK_RENEW;
3005
3006    o = edje_object_add(evas_object_evas_get(page->scrollframe_obj));
3007    e_theme_edje_object_set(o, "base/theme/fileman",
3008                            "e/fileman/default/progress");
3009
3010    // Append the element to the box
3011    edje_object_part_box_append(e_scrollframe_edje_object_get(page->scr),
3012                                "e.box.operations", o);
3013    evas_object_size_hint_align_set(o, 1.0, 1.0); //FIXME this should be theme-configurable
3014
3015    // add abort button callback with id of operation in registry
3016    edje_object_signal_callback_add(o, "e,fm,operation,abort", "",
3017                                    _e_fwin_op_registry_abort_cb, (void *)(long)ere->id);
3018
3019    //Listen to progress changes
3020    e_fm2_op_registry_entry_listener_add(ere, _e_fwin_op_registry_listener_cb,
3021                                         o, _e_fwin_op_registry_free_data);
3022
3023    return ECORE_CALLBACK_RENEW;
3024 }
3025
3026 static void
3027 _e_fwin_op_registry_entry_iter(E_Fwin_Page *page)
3028 {
3029    Eina_Iterator *itr;
3030    E_Fm2_Op_Registry_Entry *ere;
3031
3032    itr = e_fm2_op_registry_iterator_new();
3033    EINA_ITERATOR_FOREACH(itr, ere)
3034      _e_fwin_op_registry_entry_add_cb(page, 0, ere);
3035    eina_iterator_free(itr);
3036 }
3037
3038 static void
3039 _e_fwin_op_registry_abort_cb(void *data,
3040                              Evas_Object *obj     __UNUSED__,
3041                              const char *emission __UNUSED__,
3042                              const char *source   __UNUSED__)
3043 {
3044    int id;
3045
3046    id = (long)data;
3047    if (!id) return;
3048    e_fm2_operation_abort(id);
3049 }
3050