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