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