You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

3389 lines
111 KiB

#include "e_mod_main.h"
/* FIXME: fwin - the fm2 filemanager wrapped with a window and scrollframe.
* primitive BUT enough to test generic dnd and fm stuff more easily. don't
* play with this unless u want to help with it. NOT COMPLETE! BEWARE!
*/
/* FIXME: multiple selected files across different fwins - you can only dnd the
* ones in the 1 window src - not all selected ones. also selecting a new file
* in a new fwin doesn't deseclect other selections in other fwin's (unless
* multi-selecting)
*/
#define DEFAULT_WIDTH 600
#define DEFAULT_HEIGHT 350
#define MINIMUM_WIDTH 360
#define MINIMUM_HEIGHT 250
typedef struct _E_Fwin E_Fwin;
typedef struct _E_Fwin_Page E_Fwin_Page;
typedef struct _E_Fwin_Apps_Dialog E_Fwin_Apps_Dialog;
#define E_FWIN_TYPE 0xE0b0101f
struct _E_Fwin
{
E_Object e_obj_inherit;
Evas_Object *win;
E_Zone *zone;
Fileman_Path *path; /* not freed with fwin, actually attached to config */
Evas_Object *bg_obj;
E_Fwin_Apps_Dialog *fad;
E_Fwin_Page *cur_page;
Evas_Object *under_obj;
Evas_Object *over_obj;
const char *wallpaper_file;
Eina_Bool wallpaper_is_edj E_BITFIELD;
const char *overlay_file;
const char *scrollframe_file;
const char *theme_file;
const char *over_file;
Ecore_Timer *popup_timer;
Ecore_Job *popup_del_job;
Ecore_Job *object_del_job;
Eina_List *popup_handlers;
Evas_Object *popup;
Ecore_Timer *spring_timer;
Ecore_Timer *spring_close_timer;
E_Fwin *spring_parent;
E_Fwin *spring_child;
Ecore_Event_Handler *zone_handler;
Ecore_Event_Handler *zone_del_handler;
};
struct _E_Fwin_Page
{
E_Fwin *fwin;
Ecore_Event_Handler *fm_op_entry_add_handler;
Evas_Object *flist;
Evas_Object *flist_frame;
Evas_Object *scrollframe_obj;
Evas_Object *scr;
Evas_Object *fm_obj;
E_Toolbar *tbar;
struct
{
Evas_Coord x, y, max_x, max_y, w, h;
} fm_pan, fm_pan_last;
int index;
Eina_Bool setting E_BITFIELD;
};
struct _E_Fwin_Apps_Dialog
{
E_Dialog *dia;
E_Fwin *fwin;
const char *app2;
Evas_Object *o_filepreview;
Evas_Object *o_all;
Evas_Object *o_entry;
char *exec_cmd;
};
typedef enum
{
E_FWIN_EXEC_NONE,
E_FWIN_EXEC_DIRECT,
E_FWIN_EXEC_SH,
E_FWIN_EXEC_TERMINAL_DIRECT,
E_FWIN_EXEC_TERMINAL_SH,
E_FWIN_EXEC_DESKTOP
} E_Fwin_Exec_Type;
typedef enum
{
E_FWIN_WIN_AUTO,
E_FWIN_WIN_FORCE_INLINE,
E_FWIN_WIN_FORCE_WIN
} E_Fwin_Win_Mode;
/* local subsystem prototypes */
static int _e_fwin_cb_dir_handler_test(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *path);
static void _e_fwin_cb_dir_handler(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *path);
static void _e_fwin_page_favorites_add(E_Fwin_Page *page);
static void _e_fwin_icon_mouse_out(void *data, Evas_Object *obj EINA_UNUSED, void *event_info);
static void _e_fwin_icon_mouse_in(void *data, Evas_Object *obj EINA_UNUSED, void *event_info);
static E_Fwin *_e_fwin_open(E_Fwin_Page *page, E_Fm2_Icon_Info *ici, E_Fwin_Win_Mode win_mode, int *need_dia);
static E_Fwin *_e_fwin_new(const char *dev, const char *path);
static void _e_fwin_free(E_Fwin *fwin);
static E_Fwin_Page *_e_fwin_page_create(E_Fwin *fwin);
static void _e_fwin_page_free(E_Fwin_Page *page);
static void _e_fwin_cb_delete(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _e_fwin_cb_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _e_fwin_deleted(void *data,
Evas_Object *obj,
void *event_info);
static const char *_e_fwin_custom_file_path_eval(E_Fwin *fwin,
Efreet_Desktop *ef,
const char *prev_path,
const char *key);
static void _e_fwin_desktop_run(Efreet_Desktop *desktop,
E_Fwin_Page *page,
Eina_Bool skip_history);
static Eina_List *_e_fwin_suggested_apps_list_get(Eina_List *files,
Eina_List **mime_list,
Eina_Bool *has_default);
static void _e_fwin_changed(void *data,
Evas_Object *obj,
void *event_info);
static void _e_fwin_favorite_selected(void *data,
Evas_Object *obj,
void *event_info);
static void _e_fwin_selected(void *data,
Evas_Object *obj,
void *event_info);
static void _e_fwin_selection_change(void *data,
Evas_Object *obj,
void *event_info);
static void _e_fwin_cb_menu_extend_open_with(void *data,
E_Menu *m);
static void _e_fwin_cb_menu_open_fast(void *data,
E_Menu *m,
E_Menu_Item *mi);
static void _e_fwin_parent(void *data,
E_Menu *m,
E_Menu_Item *mi);
static void _e_fwin_cb_key_down(void *data,
Evas *e,
Evas_Object *obj,
void *event_info);
static void _e_fwin_cb_menu_extend_start(void *data,
Evas_Object *obj,
E_Menu *m,
E_Fm2_Icon_Info *info);
static void _e_fwin_cb_menu_open(void *data,
E_Menu *m,
E_Menu_Item *mi);
static void _e_fwin_cb_menu_open_with(void *data,
E_Menu *m,
E_Menu_Item *mi);
static void _e_fwin_cb_all_change(void *data,
Evas_Object *obj);
static void _e_fwin_cb_exec_cmd_changed(void *data,
void *data2);
static void _e_fwin_cb_open(void *data,
E_Dialog *dia);
static void _e_fwin_cb_close(void *data,
E_Dialog *dia);
static void _e_fwin_cb_dialog_free(void *obj);
static E_Fwin_Exec_Type _e_fwin_file_is_exec(E_Fm2_Icon_Info *ici);
static void _e_fwin_file_exec(E_Fwin_Page *page,
E_Fm2_Icon_Info *ici,
E_Fwin_Exec_Type ext);
static void _e_fwin_file_open_dialog(E_Fwin_Page *page,
Eina_List *files,
int always);
static void _e_fwin_file_open_dialog_preview_set(void *data1,
void *data2);
static void _e_fwin_file_open_dialog_cb_key_down(void *data,
Evas *e,
Evas_Object *obj,
void *event_info);
static void _e_fwin_pan_set(Evas_Object *obj,
Evas_Coord x,
Evas_Coord y);
static void _e_fwin_pan_get(Evas_Object *obj,
Evas_Coord *x,
Evas_Coord *y);
static void _e_fwin_pan_max_get(Evas_Object *obj,
Evas_Coord *x,
Evas_Coord *y);
static void _e_fwin_pan_child_size_get(Evas_Object *obj,
Evas_Coord *w,
Evas_Coord *h);
static void _e_fwin_pan_scroll_update(E_Fwin_Page *page);
static void _e_fwin_cb_page_obj_del(void *data, Evas *evas,
Evas_Object *obj, void *event_info);
static void _e_fwin_zone_cb_mouse_down(void *data,
Evas *evas,
Evas_Object *obj,
void *event_info);
static Eina_Bool _e_fwin_zone_move_resize(void *data,
int type,
void *event);
static Eina_Bool _e_fwin_zone_del(void *data,
int type,
void *event);
static void _e_fwin_config_set(E_Fwin_Page *page);
static void _e_fwin_window_title_set(E_Fwin_Page *page);
static void _e_fwin_toolbar_resize(E_Fwin_Page *page);
static int _e_fwin_dlg_cb_desk_sort(const void *p1,
const void *p2);
static int _e_fwin_dlg_cb_desk_list_sort(const void *data1,
const void *data2);
static void _e_fwin_op_registry_listener_cb(void *data,
const E_Fm2_Op_Registry_Entry *ere);
static Eina_Bool _e_fwin_op_registry_entry_add_cb(void *data,
int type,
void *event);
static void _e_fwin_op_registry_entry_iter(E_Fwin_Page *page);
static void _e_fwin_op_registry_abort_cb(void *data,
Evas_Object *obj,
const char *emission,
const char *source);
static E_Fwin *drag_fwin = NULL;
static E_Client_Hook *focus_out_hook = NULL;
/* local subsystem globals */
static Eina_List *fwins = NULL;
static E_Fm2_Mime_Handler *dir_handler = NULL;
static Efreet_Desktop *tdesktop = NULL;
static Eina_Stringshare *fwin_class = NULL;
static void
_e_fwin_client_hook_focus_unset(void *d EINA_UNUSED, E_Client *ec)
{
E_Fwin *fwin;
/* if there is no new focused, set focus to zone fwin */
if (e_client_focused_get() ||
(!e_client_util_ignored_get(e_desk_client_top_visible_get(e_desk_current_get(ec->zone))))) return;
if (e_comp_util_kbd_grabbed()) return;
fwin = e_fwin_zone_find(ec->zone);
if (fwin)
evas_object_focus_set(fwin->cur_page->fm_obj, 1);
}
typedef struct _E_Fwin_Mime_Handler
{
const char *mime;
Efreet_Desktop *desktop;
E_Fm2_Mime_Handler *handler;
} E_Fwin_Mime_Handler;
static Ecore_Event_Handler *_e_fwin_efreet_desktop_update_handler = NULL;
static Eina_List *_e_fwin_mime_all_handlers_list = NULL;
static int
_e_fwin_cb_dir_mime_handler_test(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *path)
{
if (ecore_file_is_dir(path)) return 1;
if (e_fm2_real_path_get(obj))
{
evas_object_data_set(obj, "fileman_terminal_realpath", (void*)1);
return 1;
}
return 0;
}
static void
_e_fwin_cb_dir_mime_handler(void *data, Evas_Object *obj EINA_UNUSED, const char *path)
{
E_Fwin_Mime_Handler *h = data;
Eina_Stringshare *rp;
Eina_List *files = NULL;
rp = e_fm2_real_path_get(obj);
if (rp && (rp != path) && (evas_object_data_del(obj, "fileman_terminal_realpath"))) //icon menu; use rp
path = rp;
files = eina_list_append(files, path);
e_exec(e_zone_current_get(), h->desktop, NULL, files, "fileman");
eina_list_free(files);
}
static void
_e_fwin_mime_all_handlers_fill(void)
{
E_Fwin_Mime_Handler *h;
Eina_List *desktops;
Efreet_Desktop *desktop;
desktops = efreet_util_desktop_name_glob_list("*");
EINA_LIST_FREE(desktops, desktop)
{
const char *mime = eina_hash_find
(desktop->x, "X-Enlightenment-Action-Mime");
if (!mime) continue;
h = calloc(1, sizeof(E_Fwin_Mime_Handler));
if (!h) continue;
h->mime = eina_stringshare_add(mime);
h->desktop = desktop;
efreet_desktop_ref(desktop);
h->handler = e_fm2_mime_handler_new
(desktop->name, desktop->icon,
_e_fwin_cb_dir_mime_handler, h,
_e_fwin_cb_dir_mime_handler_test, h);
e_fm2_mime_handler_mime_add(h->handler, h->mime);
_e_fwin_mime_all_handlers_list =
eina_list_append(_e_fwin_mime_all_handlers_list, h);
}
}
static void
_e_fwin_mime_all_handlers_clear(void)
{
E_Fwin_Mime_Handler *h;
EINA_LIST_FREE(_e_fwin_mime_all_handlers_list, h)
{
efreet_desktop_free(h->desktop);
e_fm2_mime_handler_mime_del(h->handler, h->mime);
e_fm2_mime_handler_free(h->handler);
eina_stringshare_del(h->mime);
free(h);
}
}
static Eina_Bool
_e_fwin_cb_efreet_cache_update(void *data EINA_UNUSED, int type EINA_UNUSED, void *ev EINA_UNUSED)
{
_e_fwin_mime_all_handlers_clear();
_e_fwin_mime_all_handlers_fill();
return ECORE_CALLBACK_RENEW;
}
static void
_e_fwin_mime_all_handlers_init(void)
{
_e_fwin_efreet_desktop_update_handler =
ecore_event_handler_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE,
_e_fwin_cb_efreet_cache_update, NULL);
_e_fwin_mime_all_handlers_fill();
}
static void
_e_fwin_mime_all_handlers_shutdown(void)
{
_e_fwin_mime_all_handlers_clear();
ecore_event_handler_del(_e_fwin_efreet_desktop_update_handler);
}
/* externally accessible functions */
int
e_fwin_init(void)
{
focus_out_hook = e_client_hook_add(E_CLIENT_HOOK_FOCUS_UNSET, _e_fwin_client_hook_focus_unset, NULL);
fwin_class = eina_stringshare_add("e_fwin");
_e_fwin_mime_all_handlers_init();
tdesktop = e_util_terminal_desktop_get();
if (!tdesktop) return 1;
dir_handler = e_fm2_mime_handler_new(_("Open Terminal here"),
tdesktop->icon,
_e_fwin_cb_dir_handler, NULL,
_e_fwin_cb_dir_handler_test, NULL);
e_fm2_mime_handler_mime_add(dir_handler, "inode/directory");
return 1;
}
int
e_fwin_shutdown(void)
{
E_Fwin *fwin;
EINA_LIST_FREE(fwins, fwin)
e_object_del(E_OBJECT(fwin));
if (dir_handler)
{
e_fm2_mime_handler_mime_del(dir_handler, "inode/directory");
e_fm2_mime_handler_free(dir_handler);
dir_handler = NULL;
}
if (tdesktop)
{
efreet_desktop_free(tdesktop);
tdesktop = NULL;
}
_e_fwin_mime_all_handlers_shutdown();
eina_stringshare_replace(&fwin_class, NULL);
if (focus_out_hook)
{
e_client_hook_del(focus_out_hook);
focus_out_hook = NULL;
}
return 1;
}
/* FIXME: this opens a new window - we need a way to inherit a zone as the
* "fwin" window
*/
void
e_fwin_new(const char *dev,
const char *path)
{
_e_fwin_new(dev, path);
}
static Eina_Bool
_e_fwin_spring_cb(E_Fwin *fwin)
{
E_Fm2_Icon_Info *ici;
E_Fwin *f;
if (fwin->spring_child)
_e_fwin_free(fwin->spring_child);
ici = e_fm2_drop_icon_get(fwin->cur_page->fm_obj);
if (!ici)
ici = e_fm2_drop_icon_get(fwin->cur_page->flist);
while (ici)
{
/* FIXME: could use an animation here */
f = _e_fwin_open(fwin->cur_page, ici, E_FWIN_WIN_FORCE_WIN, NULL);
if (!f) break;
f->spring_parent = fwin;
fwin->spring_child = f;
break;
}
if (fwin->spring_timer) ecore_timer_del(fwin->spring_timer);
fwin->spring_timer = NULL;
return EINA_FALSE;
}
/* called on the drop source */
static void
_e_fwin_dnd_end_cb(E_Fwin *fwin, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
if (fwin->spring_timer) ecore_timer_del(fwin->spring_timer);
fwin->spring_timer = NULL;
if (!drag_fwin) return;
if (drag_fwin->spring_timer) ecore_timer_del(drag_fwin->spring_timer);
drag_fwin->spring_timer = NULL;
/* NOTE: closing the drop target window here WILL break things */
fwin = drag_fwin->spring_parent;
if (!fwin)
{
if (!drag_fwin->zone) return;
//dragging from desktop, we'll never have a parent here
if (drag_fwin->spring_child)
_e_fwin_free(drag_fwin->spring_child);
return;
}
fwin->spring_child->spring_parent = NULL;
fwin->spring_child = NULL;
while (fwin->spring_parent)
{
/* FIXME: needs closing animation? */
fwin = fwin->spring_parent;
_e_fwin_free(fwin->spring_child);
}
drag_fwin = NULL;
}
static void
_e_fwin_dnd_change_cb(E_Fwin *fwin, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
drag_fwin = fwin;
if (fwin->spring_timer)
ecore_timer_loop_reset(fwin->spring_timer);
else
fwin->spring_timer = ecore_timer_loop_add(fileman_config->view.spring_delay, (Ecore_Task_Cb)_e_fwin_spring_cb, fwin);
}
static void
_e_fwin_dnd_enter_cb(E_Fwin *fwin, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
if (drag_fwin == fwin) return;
if (fwin->spring_timer) ecore_timer_del(fwin->spring_timer);
fwin->spring_timer = NULL;
if (fwin->spring_child && (drag_fwin == fwin->spring_child)) _e_fwin_free(fwin->spring_child);
drag_fwin = fwin;
if (fwin->spring_close_timer) ecore_timer_del(fwin->spring_close_timer);
fwin->spring_close_timer = NULL;
}
static Eina_Bool
_e_fwin_dnd_close_cb(E_Fwin *fwin)
{
_e_fwin_free(fwin);
return EINA_FALSE;
}
static void
_e_fwin_dnd_leave_cb(E_Fwin *fwin, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
if (fwin->spring_timer) ecore_timer_del(fwin->spring_timer);
fwin->spring_timer = NULL;
if (fwin->spring_parent && (!fwin->spring_child))
{
if (!fwin->spring_close_timer)
fwin->spring_close_timer = ecore_timer_loop_add(0.01, (Ecore_Task_Cb)_e_fwin_dnd_close_cb, fwin);
}
drag_fwin = NULL;
}
static void
_e_fwin_dnd_begin_cb(E_Fwin *fwin EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
drag_fwin = NULL;
}
static void
_e_fwin_zone_shutdown(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
E_Fwin *fwin = data;
const char *dev, *path;
fwin->path->desktop_mode = e_fm2_view_mode_get(obj);
e_fm2_path_get(obj, &dev, &path);
eina_stringshare_replace(&fwin->path->dev, dev);
eina_stringshare_replace(&fwin->path->path, path);
e_object_del(E_OBJECT(fwin));
}
void
e_fwin_zone_new(E_Zone *zone, void *p)
{
E_Fwin *fwin;
Fileman_Path *path = p;
E_Fwin_Page *page;
Evas_Object *o;
int x, y, w, h;
fwin = E_OBJECT_ALLOC(E_Fwin, E_FWIN_TYPE, _e_fwin_free);
if (!fwin) return;
fwin->zone = zone;
page = E_NEW(E_Fwin_Page, 1);
page->fwin = fwin;
fwin->path = path;
/* Add Event Handler for zone move/resize & del */
fwin->zone_handler =
ecore_event_handler_add(E_EVENT_ZONE_USEFUL_GEOMETRY_CHANGED,
_e_fwin_zone_move_resize, fwin);
fwin->zone_del_handler =
ecore_event_handler_add(E_EVENT_ZONE_DEL,
_e_fwin_zone_del, fwin);
/* Trap the mouse_down on zone so we can unselect */
evas_object_event_callback_add(zone->bg_event_object,
EVAS_CALLBACK_MOUSE_DOWN,
_e_fwin_zone_cb_mouse_down, fwin);
fwins = eina_list_append(fwins, fwin);
o = e_fm2_add(e_comp->evas);
evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_fwin_zone_shutdown, fwin);
page->fm_obj = o;
_e_fwin_config_set(page);
e_fm2_custom_theme_content_set(o, "desktop");
evas_object_smart_callback_add(o, "changed",
_e_fwin_icon_mouse_out, fwin);
evas_object_smart_callback_add(o, "dir_changed",
_e_fwin_changed, page);
evas_object_smart_callback_add(o, "dir_deleted",
_e_fwin_deleted, page);
evas_object_smart_callback_add(o, "selected",
_e_fwin_selected, page);
evas_object_smart_callback_add(o, "selection_change",
_e_fwin_selection_change, page);
evas_object_event_callback_add(o, EVAS_CALLBACK_DEL,
_e_fwin_cb_page_obj_del, page);
evas_object_smart_callback_add(o, "dnd_enter", (Evas_Smart_Cb)_e_fwin_dnd_enter_cb, fwin);
evas_object_smart_callback_add(o, "dnd_leave", (Evas_Smart_Cb)_e_fwin_dnd_leave_cb, fwin);
evas_object_smart_callback_add(o, "dnd_changed", (Evas_Smart_Cb)_e_fwin_dnd_change_cb, fwin);
evas_object_smart_callback_add(o, "dnd_begin", (Evas_Smart_Cb)_e_fwin_dnd_begin_cb, fwin);
evas_object_smart_callback_add(o, "dnd_end", (Evas_Smart_Cb)_e_fwin_dnd_end_cb, fwin);
evas_object_smart_callback_add(o, "icon_mouse_in", (Evas_Smart_Cb)_e_fwin_icon_mouse_in, fwin);
evas_object_smart_callback_add(o, "icon_mouse_out", (Evas_Smart_Cb)_e_fwin_icon_mouse_out, fwin);
e_fm2_icon_menu_start_extend_callback_set(o, _e_fwin_cb_menu_extend_start, page);
e_fm2_underlay_hide(o);
evas_object_focus_set(o, !e_client_focused_get());
evas_object_show(o);
o = e_scrollframe_add(e_comp->evas);
e_scrollframe_custom_theme_set(o, "base/theme/fileman",
"e/fileman/desktop/scrollframe");
/* FIXME: this theme object will have more versions and options later
* for things like swallowing widgets/buttons ot providing them - a
* gadcon for starters for fm widgets. need to register the owning
* e_object of the gadcon so gadcon clients can get it and thus do
* things like find out what dirs/path the fwin is for etc. this will
* probably be how you add optional gadgets to fwin views like empty/full
* meters for disk usage, and other dir info/stats or controls. also it
* might be possible that we can have custom frames per dir later so need
* a way to set an edje file directly
*/
/* FIXME: allow specialised scrollframe obj per dir - get from e config,
* then look in the dir itself for a magic dot-file, if not - use theme.
* same as currently done for bg & overlay. also add to fm2 the ability
* to specify the .edj files to get the list and icon theme stuff from
*/
evas_object_data_set(page->fm_obj, "fm_page", page);
evas_object_data_set(page->fm_obj, "page_is_zone", page);
e_scrollframe_extern_pan_set(o, page->fm_obj,
_e_fwin_pan_set,
_e_fwin_pan_get,
_e_fwin_pan_max_get,
_e_fwin_pan_child_size_get);
evas_object_propagate_events_set(page->fm_obj, 0);
e_widget_can_focus_set(o, 0);
evas_object_name_set(o, "zone_fwin");
e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
evas_object_move(o, x, y);
evas_object_resize(o, w, h);
evas_object_show(o);
evas_object_layer_set(o, E_LAYER_DESKTOP);
evas_object_lower(o);
page->scrollframe_obj = page->scr = o;
e_fm2_window_object_set(page->fm_obj, E_OBJECT(fwin->zone));
e_fm2_path_set(page->fm_obj, path->dev, path->path);
fwin->cur_page = page;
}
void
e_fwin_all_unsel(void *data)
{
E_Fwin *fwin;
fwin = data;
E_OBJECT_CHECK(fwin);
E_OBJECT_TYPE_CHECK(fwin, E_FWIN_TYPE);
e_fm2_all_unsel(fwin->cur_page->fm_obj);
}
void
e_fwin_zone_shutdown(E_Zone *zone)
{
Eina_List *f, *fn;
E_Fwin *fwin;
EINA_LIST_FOREACH_SAFE(fwins, f, fn, fwin)
{
if (fwin->zone != zone) continue;
_e_fwin_zone_shutdown(fwin, NULL, fwin->cur_page->fm_obj, NULL);
fwin = NULL;
}
}
static void
_e_fwin_cb_toolbar_del(void *obj)
{
E_Fwin_Page *page = e_object_data_get(obj);
page->tbar = NULL;
}
void
e_fwin_reload_all(void)
{
const Eina_List *l, *ll;
E_Fwin *fwin;
E_Zone *zone;
/* Reload/recreate zones cause of property changes */
EINA_LIST_FOREACH_SAFE(fwins, l, ll, fwin)
{
if (!fwin) continue; //safety
if (fwin->zone)
e_fwin_zone_shutdown(fwin->zone);
else
{
_e_fwin_config_set(fwin->cur_page);
if (fileman_config->view.show_toolbar)
{
if (!fwin->cur_page->tbar)
{
fwin->cur_page->tbar = e_toolbar_new
(evas_object_evas_get(fwin->win), "toolbar",
fwin->win, fwin->cur_page->fm_obj);
e_toolbar_orient(fwin->cur_page->tbar, fileman_config->view.toolbar_orient);
e_object_data_set(E_OBJECT(fwin->cur_page->tbar), fwin->cur_page);
E_OBJECT_DEL_SET(fwin->cur_page->tbar, _e_fwin_cb_toolbar_del);
}
}
else
{
if (fwin->cur_page->tbar)
{
fileman_config->view.toolbar_orient = fwin->cur_page->tbar->gadcon->orient;
e_object_del(E_OBJECT(fwin->cur_page->tbar));
fwin->cur_page->tbar = NULL;
}
}
if (fileman_config->view.show_sidebar)
{
if (!fwin->cur_page->flist_frame)
{
_e_fwin_page_favorites_add(fwin->cur_page);
edje_object_signal_emit(fwin->bg_obj, "e,favorites,enabled", "e");
edje_object_message_signal_process(fwin->bg_obj);
}
}
else
{
if (fwin->cur_page->flist_frame)
{
evas_object_del(fwin->cur_page->flist_frame);
fwin->cur_page->flist_frame = fwin->cur_page->flist = NULL;
edje_object_signal_emit(fwin->bg_obj, "e,favorites,disabled", "e");
edje_object_message_signal_process(fwin->bg_obj);
}
}
_e_fwin_window_title_set(fwin->cur_page);
_e_fwin_cb_resize(fwin, NULL, NULL, NULL);
_e_fwin_toolbar_resize(fwin->cur_page);
e_fm2_refresh(fwin->cur_page->fm_obj);
}
}
/* Hook into zones */
EINA_LIST_FOREACH(e_comp->zones, l, zone)
{
if (e_fwin_zone_find(zone)) continue;
if (e_config->show_desktop_icons)
e_fwin_zone_new(zone, e_mod_fileman_path_find(zone));
}
}
void *
e_fwin_zone_find(E_Zone *zone)
{
Eina_List *f;
E_Fwin *fwin;
EINA_LIST_FOREACH(fwins, f, fwin)
if (fwin->zone == zone) return fwin;
return NULL;
}
Eina_Bool
e_fwin_show(const char *dev, const char *path)
{
Eina_List *f;
E_Fwin *fwin;
EINA_LIST_FOREACH(fwins, f, fwin)
{
const char *d, *p;
e_fm2_path_get(fwin->cur_page->fm_obj, &d, &p);
if ((d) && (!strcmp(dev, d)) && (p) && (!strcmp(path, p)))
{
elm_win_activate(fwin->win);
return EINA_TRUE;
}
}
return EINA_FALSE;
}
/* local subsystem functions */
static void
_e_fwin_bg_mouse_down(E_Fwin *fwin, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
int x, y, w, h, zx, zy, zw, zh, cx, cy, cw, ch;
E_Client *ec;
ec = e_win_client_get(fwin->win);
if (ec->maximized) e_client_unmaximize(ec, ec->maximized);
if (ec->fullscreen) e_client_unfullscreen(ec);
e_zone_useful_geometry_get(ec->zone, &zx, &zy, &zw, &zh);
x = ec->x, y = ec->y;
if (!e_fm2_optimal_size_calc(fwin->cur_page->fm_obj, MINIMUM_WIDTH, zw + zx - x, zh + zy - y, &w, &h)) return;
evas_object_geometry_get(fwin->cur_page->fm_obj, &cx, &cy, &cw, &ch);
if (x + w > zx + zw)
w = zx + zw - x;
if (y + h > zy + zh)
h = zy + zh - y;
w = w + cx;
h = h + cy;
evas_object_resize(fwin->win, MAX(w, MINIMUM_WIDTH), MAX(h, MINIMUM_HEIGHT));
}
static void
_e_fwin_cb_focus(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
E_Fwin *fwin = data;
if (!e_fm2_icon_editing_get(fwin->cur_page->fm_obj))
evas_object_focus_set(fwin->cur_page->fm_obj, 1);
}
static E_Fwin *
_e_fwin_new(const char *dev,
const char *path)
{
E_Fwin *fwin;
E_Fwin_Page *page;
Evas_Object *o;
E_Zone *zone;
fwin = E_OBJECT_ALLOC(E_Fwin, E_FWIN_TYPE, _e_fwin_free);
if (!fwin) return NULL;
fwin->win = elm_win_add(NULL, NULL, ELM_WIN_BASIC);
if (!fwin->win)
{
free(fwin);
return NULL;
}
fwins = eina_list_append(fwins, fwin);
evas_object_event_callback_add(fwin->win, EVAS_CALLBACK_FOCUS_IN, _e_fwin_cb_focus, fwin);
evas_object_event_callback_add(fwin->win, EVAS_CALLBACK_DEL, _e_fwin_cb_delete, fwin);
evas_object_event_callback_add(fwin->win, EVAS_CALLBACK_RESIZE, _e_fwin_cb_resize, fwin);
o = edje_object_add(evas_object_evas_get(fwin->win));
elm_win_resize_object_add(fwin->win, o);
e_theme_edje_object_set(o, "base/theme/fileman",
"e/fileman/default/window/main");
evas_object_show(o);
fwin->bg_obj = o;
page = _e_fwin_page_create(fwin);
fwin->cur_page = page;
/*
o = edje_object_add(evas_object_evas_get(fwin->win));
// o = e_icon_add(evas_object_evas_get(fwin->win));
// e_icon_scale_size_set(o, 0);
// e_icon_fill_inside_set(o, 0);
edje_object_part_swallow(fwin->bg_obj, "e.swallow.bg", o);
evas_object_pass_events_set(o, 1);
fwin->under_obj = o;
*/
o = edje_object_add(evas_object_evas_get(fwin->win));
// o = e_icon_add(evas_object_evas_get(fwin->win));
// e_icon_scale_size_set(o, 0);
// e_icon_fill_inside_set(o, 0);
edje_object_part_swallow(e_scrollframe_edje_object_get(page->scr),
"e.swallow.overlay", o);
evas_object_pass_events_set(o, 1);
fwin->over_obj = o;
e_fm2_path_set(page->fm_obj, dev, path);
_e_fwin_window_title_set(page);
evas_object_size_hint_min_set(fwin->win, MINIMUM_WIDTH, MINIMUM_HEIGHT);
zone = e_zone_current_get();
if ((zone) && (zone->w < DEFAULT_WIDTH))
{
int w, h;
e_zone_useful_geometry_get(zone, NULL, NULL, &w, &h);
evas_object_resize(fwin->win, w, h);
}
else
evas_object_resize(fwin->win, DEFAULT_WIDTH, DEFAULT_HEIGHT);
evas_object_show(fwin->win);
if (elm_win_window_id_get(fwin->win))
e_drop_xdnd_register_set(elm_win_window_id_get(fwin->win), 1);
e_win_client_icon_set(fwin->win, "system-file-manager");
return fwin;
}
static Eina_Bool
_e_fwin_icon_popup_handler(void *data)
{
E_Fwin *fwin = data;
E_FREE_FUNC(fwin->popup_timer, ecore_timer_del);
if (fwin->popup)
{
evas_object_hide(fwin->popup);
E_FREE_FUNC(fwin->popup, evas_object_del);
}
if (fwin->win)
{
evas_object_event_callback_del(fwin->win, EVAS_CALLBACK_MOUSE_IN, (void *)_e_fwin_icon_popup_handler);
evas_object_event_callback_del(fwin->win, EVAS_CALLBACK_MOUSE_OUT, (void *)_e_fwin_icon_popup_handler);
}
E_FREE_LIST(fwin->popup_handlers, ecore_event_handler_del);
if (fwin->over_file) eina_stringshare_del(fwin->over_file);
fwin->over_file = NULL;
return ECORE_CALLBACK_RENEW;
}
static void
_e_fwin_free(E_Fwin *fwin)
{
if (!fwin) return; //safety
_e_fwin_page_free(fwin->cur_page);
if (fwin->zone)
evas_object_event_callback_del(fwin->zone->bg_event_object,
EVAS_CALLBACK_MOUSE_DOWN,
_e_fwin_zone_cb_mouse_down);
if (fwin->zone_handler)
ecore_event_handler_del(fwin->zone_handler);
if (fwin->zone_del_handler)
ecore_event_handler_del(fwin->zone_del_handler);
if (fwin->spring_timer) ecore_timer_del(fwin->spring_timer);
fwin->spring_timer = NULL;
if (fwin->spring_close_timer) ecore_timer_del(fwin->spring_close_timer);
fwin->spring_close_timer = NULL;
fwins = eina_list_remove(fwins, fwin);
if (fwin->wallpaper_file) eina_stringshare_del(fwin->wallpaper_file);
if (fwin->overlay_file) eina_stringshare_del(fwin->overlay_file);
if (fwin->scrollframe_file) eina_stringshare_del(fwin->scrollframe_file);
if (fwin->theme_file) eina_stringshare_del(fwin->theme_file);
if (fwin->over_file) eina_stringshare_del(fwin->over_file);
if (fwin->fad)
{
e_object_del(E_OBJECT(fwin->fad->dia));
fwin->fad = NULL;
}
if (fwin->popup_del_job) ecore_job_del(fwin->popup_del_job);
if (fwin->popup)
{
evas_object_hide(fwin->popup);
evas_object_del(fwin->popup);
fwin->popup = NULL;
}
if (fwin->object_del_job) ecore_job_del(fwin->object_del_job);
fwin->object_del_job = NULL;
if (fwin->popup_timer) ecore_timer_del(fwin->popup_timer);
fwin->popup_timer = NULL;
if (fwin->win)
{
evas_object_event_callback_del(fwin->win, EVAS_CALLBACK_MOUSE_IN, (void *)_e_fwin_icon_popup_handler);
evas_object_event_callback_del(fwin->win, EVAS_CALLBACK_MOUSE_OUT, (void *)_e_fwin_icon_popup_handler);
}
E_FREE_LIST(fwin->popup_handlers, ecore_event_handler_del);
if (fwin->spring_parent) fwin->spring_parent->spring_child = NULL;
if (fwin->win)
{
evas_object_event_callback_del_full(fwin->win, EVAS_CALLBACK_DEL, _e_fwin_cb_delete, fwin);
evas_object_del(fwin->win);
}
free(fwin);
}
static void
_e_fwin_icon_hints(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
int x, y, w, h, mw, mh, fx, fy, px, py;
E_Zone *zone;
Evas_Object *edje;
E_Fwin *fwin = data;
E_Fm2_Icon_Info *popup_icon;
popup_icon = e_fm2_icon_file_get(fwin->cur_page->fm_obj, fwin->over_file);
if (!popup_icon) return;
e_fm2_icon_geometry_get(popup_icon->ic, &x, &y, &w, &h);
if (fwin->zone)
{
zone = fwin->zone;
evas_object_geometry_get(popup_icon->fm, &fx, &fy, NULL, NULL);
fx -= zone->x, fy -= zone->y;
}
else
{
E_Client *ec = e_win_client_get(fwin->win);
fx = ec->x, fy = ec->y;
zone = ec->zone;
}
edje = evas_object_smart_parent_get(obj);
/* failing to unswallow here causes edje to fail its min size calculations */
edje_object_part_unswallow(edje, obj);
edje_object_part_swallow(edje, "e.swallow.content", obj);
edje_object_size_min_calc(edje, &mw, &mh);
/* prefer tooltip left of icon */
px = (fx + x) - mw - 3;
/* if it's offscreen, try right of icon */
if (px < zone->x) px = (fx + x + w) + 3;
/* fuck this, stick it right on the icon */
if (px + mw + 3 > zone->x + zone->w)
px = (x + w / 2) - (mw / 2);
/* give up */
if (px < zone->x) px = zone->x;
/* prefer tooltip above icon */
py = (fy + y) - mh - 3;
/* if it's offscreen, try below icon */
if (py < zone->y) py = (fy + y + h) + 3;
/* fuck this, stick it right on the icon */
if (py + mh + 3 > zone->x + zone->h)
py = (y + h / 2) - (mh / 2);
/* give up */
if (py < zone->y) py = zone->y;
evas_object_geometry_set(fwin->popup, px, py, mw, mh);
}
static void
_e_fwin_popup_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
evas_object_event_callback_del(data, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _e_fwin_icon_hints);
}
static Eina_Bool
_e_fwin_icon_popup(void *data)
{
E_Fwin *fwin = data;
Evas_Object *bg, *list, *o;
E_Zone *zone;
char buf[4096];
int mw, mh;
E_Fm2_Icon_Info *popup_icon;
struct stat st;
fwin->popup_timer = NULL;
popup_icon = e_fm2_icon_file_get(fwin->cur_page->fm_obj, fwin->over_file);
if (!popup_icon) return EINA_FALSE;
snprintf(buf, sizeof(buf), "%s/%s", e_fm2_real_path_get(fwin->cur_page->fm_obj), popup_icon->file);
if (!ecore_file_can_read(buf)) return EINA_FALSE;
if (stat(buf, &st) < 0) return EINA_FALSE;
if (S_ISFIFO(st.st_mode)) return EINA_FALSE;
if (fwin->popup)
{
evas_object_hide(fwin->popup);
evas_object_del(fwin->popup);
}
zone = fwin->zone ?: e_comp_object_util_zone_get(fwin->win);
bg = edje_object_add(e_comp->evas);
e_theme_edje_object_set(bg, "base/theme/fileman",
"e/fileman/popup/default");
mw = zone->w * fileman_config->tooltip.size / 100.0;
mh = zone->h * fileman_config->tooltip.size / 100.0;
edje_object_part_text_set(bg, "e.text.title",
popup_icon->label ?
popup_icon->label : popup_icon->file);
list = e_widget_list_add(e_comp->evas, 0, 0);
if (fwin->win)
evas_object_event_callback_add(fwin->win, EVAS_CALLBACK_DEL, _e_fwin_popup_del, list);
o = e_widget_filepreview_add(e_comp->evas, mw, mh, 0);
e_widget_filepreview_clamp_video_set(o, fileman_config->tooltip.clamp_size);
e_widget_filepreview_path_set(o, buf, popup_icon->mime);
e_widget_list_object_append(list, o, 1, 0, 0.5);
edje_object_part_swallow(bg, "e.swallow.content", list);
_e_fwin_icon_hints(fwin, NULL, list, NULL);
evas_object_event_callback_add(list, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _e_fwin_icon_hints, fwin);
fwin->popup = e_comp_object_util_add(bg, E_COMP_OBJECT_TYPE_POPUP);
evas_object_layer_set(fwin->popup, E_LAYER_POPUP);
e_comp_object_util_del_list_append(fwin->popup, list);
e_comp_object_util_del_list_append(fwin->popup, o);
evas_object_pass_events_set(fwin->popup, 1);
#ifndef HAVE_WAYLAND_ONLY
if (!fwin->popup_handlers)
{
evas_object_event_callback_add(fwin->win, EVAS_CALLBACK_MOUSE_IN, (void *)_e_fwin_icon_popup_handler, fwin);
evas_object_event_callback_add(fwin->win, EVAS_CALLBACK_MOUSE_OUT, (void *)_e_fwin_icon_popup_handler, fwin);
if (e_comp_util_has_x())
E_LIST_HANDLER_APPEND(fwin->popup_handlers, ECORE_X_EVENT_XDND_POSITION, (void *)_e_fwin_icon_popup_handler, fwin);
E_LIST_HANDLER_APPEND(fwin->popup_handlers, ECORE_EVENT_MOUSE_BUTTON_DOWN, (void *)_e_fwin_icon_popup_handler, fwin);
}
#endif
evas_object_show(fwin->popup);
return EINA_FALSE;
}
static void
_e_fwin_icon_popup_del(E_Fwin *fwin)
{
evas_object_hide(fwin->popup);
E_FREE_FUNC(fwin->popup, evas_object_del);
fwin->popup_del_job = NULL;
}
static void
_e_fwin_icon_mouse_out(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
E_Fwin *fwin = data;
E_FREE_FUNC(fwin->popup_timer, ecore_timer_del);
if (!fwin->popup_del_job) fwin->popup_del_job = ecore_job_add((Ecore_Cb)_e_fwin_icon_popup_del, fwin);
}
static void
_e_fwin_icon_mouse_in(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
{
E_Fwin *fwin = data;
E_Fm2_Icon_Info *ici = event_info;
if (fwin->popup_timer) ecore_timer_del(fwin->popup_timer);
fwin->popup_timer = NULL;
if (!fileman_config->tooltip.enable) return;
fwin->popup_timer = ecore_timer_loop_add(fileman_config->tooltip.delay, _e_fwin_icon_popup, fwin);
if (fwin->over_file) eina_stringshare_del(fwin->over_file);
fwin->over_file = NULL;
if (ici->file) fwin->over_file = eina_stringshare_add(ici->file);
#ifndef HAVE_WAYLAND_ONLY
if (!fwin->popup_handlers)
{
if (fwin->win)
{
evas_object_event_callback_add(fwin->win, EVAS_CALLBACK_MOUSE_IN, (void *)_e_fwin_icon_popup_handler, fwin);
evas_object_event_callback_add(fwin->win, EVAS_CALLBACK_MOUSE_OUT, (void *)_e_fwin_icon_popup_handler, fwin);
}
if (e_comp_util_has_x())
E_LIST_HANDLER_APPEND(fwin->popup_handlers, ECORE_X_EVENT_XDND_POSITION, (void *)_e_fwin_icon_popup_handler, fwin);
E_LIST_HANDLER_APPEND(fwin->popup_handlers, ECORE_EVENT_MOUSE_BUTTON_DOWN, (void *)_e_fwin_icon_popup_handler, fwin);
}
#endif
}
static void
_e_fwin_page_favorites_add(E_Fwin_Page *page)
{
E_Fm2_Config fmc;
Evas_Object *o;
Evas *evas = evas_object_evas_get(page->fwin->bg_obj);
o = e_fm2_add(evas);
evas_object_data_set(o, "fm_page", page);
page->flist = o;
memset(&fmc, 0, sizeof(E_Fm2_Config));
fmc.view.mode = E_FM2_VIEW_MODE_LIST;
fmc.view.open_dirs_in_place = 1;
fmc.view.selector = 1;
fmc.view.single_click = 1;
fmc.view.no_subdir_jump = 1;
fmc.view.link_drop = 1;
fmc.icon.list.w = 24;
fmc.icon.list.h = 24;
fmc.icon.fixed.w = 1;
fmc.icon.fixed.h = 1;
fmc.icon.extension.show = 0;
fmc.icon.key_hint = NULL;
fmc.list.sort.no_case = 1;
fmc.list.sort.dirs.first = 0;
fmc.list.sort.dirs.last = 0;
fmc.selection.single = 1;
fmc.selection.windows_modifiers = 0;
fmc.view.no_click_rename = 1;
e_fm2_config_set(o, &fmc);
e_fm2_icon_menu_flags_set(o, E_FM2_MENU_NO_NEW | E_FM2_MENU_NO_ACTIVATE_CHANGE | E_FM2_MENU_NO_VIEW_CHANGE);
evas_object_smart_callback_add(o, "selected", _e_fwin_favorite_selected, page);
evas_object_smart_callback_add(o, "dnd_enter", (Evas_Smart_Cb)_e_fwin_dnd_enter_cb, page->fwin);
evas_object_smart_callback_add(o, "dnd_leave", (Evas_Smart_Cb)_e_fwin_dnd_leave_cb, page->fwin);
evas_object_smart_callback_add(o, "dnd_changed", (Evas_Smart_Cb)_e_fwin_dnd_change_cb, page->fwin);
evas_object_smart_callback_add(o, "dnd_begin", (Evas_Smart_Cb)_e_fwin_dnd_begin_cb, page->fwin);
evas_object_smart_callback_add(o, "dnd_end", (Evas_Smart_Cb)_e_fwin_dnd_end_cb, page->fwin);
e_fm2_path_set(o, "favorites", "/");
o = e_widget_scrollframe_pan_add(evas, page->flist,
e_fm2_pan_set,
e_fm2_pan_get,
e_fm2_pan_max_get,
e_fm2_pan_child_size_get);
e_scrollframe_custom_theme_set(e_widget_scrollframe_object_get(o),
"base/theme/fileman",
"e/fileman/default/scrollframe");
evas_object_propagate_events_set(page->flist, 0);
e_widget_can_focus_set(o, EINA_FALSE);
e_fm2_window_set(page->flist, page->fwin->win);
e_widget_scrollframe_focus_object_set(o, page->flist);
page->flist_frame = o;
evas_object_size_hint_min_set(o, 128 * e_scale, 0);
edje_object_part_swallow(page->fwin->bg_obj, "e.swallow.favorites", o);
}
static E_Fwin_Page *
_e_fwin_page_create(E_Fwin *fwin)
{
Evas_Object *o;
E_Fwin_Page *page;
Evas *evas;
page = E_NEW(E_Fwin_Page, 1);
page->fwin = fwin;
evas = evas_object_evas_get(fwin->win);
if (fileman_config->view.show_sidebar)
{
_e_fwin_page_favorites_add(page);
edje_object_signal_emit(fwin->bg_obj, "e,favorites,enabled", "e");
edje_object_message_signal_process(fwin->bg_obj);
}
o = e_fm2_add(evas);
page->fm_obj = o;
e_fm2_view_flags_set(o, E_FM2_VIEW_DIR_CUSTOM);
// low priority to be called last... after e_fm's own cb's
evas_object_event_callback_priority_add(o, EVAS_CALLBACK_KEY_DOWN,
1000, _e_fwin_cb_key_down, page);
evas_object_smart_callback_add(o, "changed", _e_fwin_icon_mouse_out, fwin);
evas_object_smart_callback_add(o, "dir_changed",
_e_fwin_changed, page);
evas_object_smart_callback_add(o, "dir_deleted",
_e_fwin_deleted, page);
evas_object_smart_callback_add(o, "selected",
_e_fwin_selected, page);
evas_object_smart_callback_add(o, "selection_change",
_e_fwin_selection_change, page);
evas_object_event_callback_add(o, EVAS_CALLBACK_DEL,
_e_fwin_cb_page_obj_del, page);
evas_object_smart_callback_add(o, "dnd_enter", (Evas_Smart_Cb)_e_fwin_dnd_enter_cb, fwin);
evas_object_smart_callback_add(o, "dnd_leave", (Evas_Smart_Cb)_e_fwin_dnd_leave_cb, fwin);
evas_object_smart_callback_add(o, "dnd_changed", (Evas_Smart_Cb)_e_fwin_dnd_change_cb, fwin);
evas_object_smart_callback_add(o, "dnd_begin", (Evas_Smart_Cb)_e_fwin_dnd_begin_cb, fwin);
evas_object_smart_callback_add(o, "dnd_end", (Evas_Smart_Cb)_e_fwin_dnd_end_cb, fwin);
evas_object_smart_callback_add(o, "double_clicked", (Evas_Smart_Cb)_e_fwin_bg_mouse_down, fwin);
evas_object_smart_callback_add(o, "icon_mouse_in", (Evas_Smart_Cb)_e_fwin_icon_mouse_in, fwin);
evas_object_smart_callback_add(o, "icon_mouse_out", (Evas_Smart_Cb)_e_fwin_icon_mouse_out, fwin);
e_fm2_icon_menu_start_extend_callback_set(o, _e_fwin_cb_menu_extend_start, page);
e_fm2_window_set(o, fwin->win);
evas_object_focus_set(o, 1);
_e_fwin_config_set(page);
/* FIXME: this theme object will have more versions and options later
* for things like swallowing widgets/buttons ot providing them - a
* gadcon for starters for fm widgets. need to register the owning
* e_object of the gadcon so gadcon clients can get it and thus do
* things like find out what dirs/path the fwin is for etc. this will
* probably be how you add optional gadgets to fwin views like empty/full
* meters for disk usage, and other dir info/stats or controls. also it
* might be possible that we can have custom frames per dir later so need
* a way to set an edje file directly
*/
/* FIXME: allow specialised scrollframe obj per dir - get from e config,
* then look in the dir itself for a magic dot-file, if not - use theme.
* same as currently done for bg & overlay. also add to fm2 the ability
* to specify the .edj files to get the list and icon theme stuff from
*/
evas_object_data_set(page->fm_obj, "fm_page", page);
evas_object_data_set(page->fm_obj, "page_is_window", page);
o = e_widget_scrollframe_pan_add(evas, page->fm_obj,
e_fm2_pan_set,
e_fm2_pan_get,
e_fm2_pan_max_get,
e_fm2_pan_child_size_get);
evas_object_propagate_events_set(page->fm_obj, 0);
e_widget_can_focus_set(o, EINA_FALSE);
page->scrollframe_obj = o;
page->scr = e_widget_scrollframe_object_get(o);
e_scrollframe_key_navigation_set(o, EINA_FALSE);
e_scrollframe_custom_theme_set(o, "base/theme/fileman",
"e/fileman/default/scrollframe");
edje_object_part_swallow(fwin->bg_obj, "e.swallow.content", o);
e_widget_scrollframe_focus_object_set(o, page->fm_obj);
if (fileman_config->view.show_toolbar)
{
page->tbar = e_toolbar_new(evas, "toolbar",
fwin->win, page->fm_obj);
e_toolbar_orient(page->tbar, fileman_config->view.toolbar_orient);
e_object_data_set(E_OBJECT(page->tbar), page);
E_OBJECT_DEL_SET(page->tbar, _e_fwin_cb_toolbar_del);
}
page->fm_op_entry_add_handler =
ecore_event_handler_add(E_EVENT_FM_OP_REGISTRY_ADD,
_e_fwin_op_registry_entry_add_cb, page);
_e_fwin_op_registry_entry_iter(page);
_e_fwin_toolbar_resize(page);
return page;
}
static void
_e_fwin_page_free(E_Fwin_Page *page)
{
evas_object_del(page->flist);
evas_object_del(page->flist_frame);
if (page->tbar)
{
fileman_config->view.toolbar_orient = page->tbar->gadcon->orient;
E_OBJECT_DEL_SET(E_OBJECT(page->tbar), NULL);
e_object_del(E_OBJECT(page->tbar));
}
else evas_object_del(page->scrollframe_obj);
if (page->fm_obj) evas_object_del(page->fm_obj);
if (page->fm_op_entry_add_handler)
ecore_event_handler_del(page->fm_op_entry_add_handler);
E_FREE(page);
}
static const char *
_e_fwin_custom_file_path_eval(E_Fwin *fwin,
Efreet_Desktop *ef,
const char *prev_path,
const char *key)
{
char buf[PATH_MAX];
const char *res, *ret = NULL;
/* get a X-something custom stage from the .desktop for the dir */
res = efreet_desktop_x_field_get(ef, key);
/* free the old path */
if (prev_path) eina_stringshare_del(prev_path);
/* if there was no key found - return NULL */
if (!res) return NULL;
/* it's a full path */
if (res[0] == '/')
return res;
/* relative path to the dir */
snprintf(buf, sizeof(buf), "%s/%s",
e_fm2_real_path_get(fwin->cur_page->fm_obj), res);
ret = eina_stringshare_add(buf);
eina_stringshare_del(res);
return ret;
}
static Eina_List *
_e_fwin_defaults_apps_get(const char *mime, const char *path)
{
Efreet_Ini *ini;
const char *str;
Eina_List *apps = NULL;
char **array, **itr;
if (!ecore_file_exists(path)) return NULL;
ini = efreet_ini_new(path);
if (!ini) return NULL;
efreet_ini_section_set(ini, "Default Applications");
str = efreet_ini_string_get(ini, mime);
if (!str) goto end;
array = eina_str_split(str, ";", 0);
if (!array) goto end;
for (itr = array; *itr != NULL; itr++)
{
const char *name = *itr;
Efreet_Desktop *desktop;
if (name[0] == '/')
desktop = efreet_desktop_new(name);
else
desktop = efreet_util_desktop_file_id_find(name);
if (!desktop) continue;
if (!desktop->exec)
{
efreet_desktop_free(desktop);
continue;
}
apps = eina_list_append(apps, desktop);
}
free(array[0]);
free(array);
end:
efreet_ini_free(ini);
return apps;
}
Eina_List *
e_fwin_suggested_apps_list_sort(const char *mime, Eina_List *desktops, Eina_Bool *has_default)
{
char path[PATH_MAX];
Eina_List *order, *l;
Efreet_Desktop *desktop;
snprintf(path, sizeof(path), "%s/mimeapps.list",
efreet_config_home_get());
order = _e_fwin_defaults_apps_get(mime, path);
if (!order)
{
const Eina_List *n, *dirs = efreet_data_dirs_get();
const char *d;
EINA_LIST_FOREACH(dirs, n, d)
{
snprintf(path, sizeof(path), "%s/applications/defaults.list", d);
order = _e_fwin_defaults_apps_get(mime, path);
if (order)
break;
}
}
if (!order)
{
if (has_default) *has_default = EINA_FALSE;
return desktops;
}
EINA_LIST_FOREACH(order, l, desktop)
{
Eina_List *node = eina_list_data_find_list(desktops, desktop);
if (!node) continue;
desktops = eina_list_remove_list(desktops, node);
efreet_desktop_free(desktop);
}
if (has_default) *has_default = EINA_TRUE;
return eina_list_merge(order, desktops);
}
static Eina_List *
_e_fwin_suggested_apps_list_get(Eina_List *files,
Eina_List **mime_list,
Eina_Bool *has_default)
{
E_Fm2_Icon_Info *ici;
Eina_Hash *set_mimes;
Eina_List *apps = NULL, *l;
set_mimes = eina_hash_string_small_new(NULL);
EINA_LIST_FOREACH(files, l, ici)
if (!((ici->link) && (ici->mount)))
{
if (_e_fwin_file_is_exec(ici) == E_FWIN_EXEC_NONE)
{
const char *key = ici->mime;
if (ici->link)
key = efreet_mime_globs_type_get(ici->link);
if (!eina_hash_find(set_mimes, key))
eina_hash_direct_add(set_mimes, key, (void *)1);
}
}
if (mime_list) *mime_list = NULL;
if (has_default) *has_default = EINA_FALSE;
if (eina_hash_population(set_mimes) > 0)
{
Eina_Hash *set_apps = eina_hash_pointer_new(NULL);
Eina_Iterator *itr = eina_hash_iterator_key_new(set_mimes);
const char *mime;
EINA_ITERATOR_FOREACH(itr, mime)
{
Eina_List *desktops = efreet_util_desktop_mime_list(mime);
Efreet_Desktop *d;
Eina_Bool hd = EINA_FALSE;
if (mime_list) *mime_list = eina_list_append(*mime_list, mime);
desktops = e_fwin_suggested_apps_list_sort(mime, desktops, &hd);
if ((hd) && (has_default))
*has_default = EINA_TRUE;
EINA_LIST_FREE(desktops, d)
{
if (eina_hash_find(set_apps, &d)) efreet_desktop_free(d);
else
{
eina_hash_add(set_apps, &d, (void *)1);
apps = eina_list_append(apps, d);
}
}
}
eina_iterator_free(itr);
eina_hash_free(set_apps);
}
eina_hash_free(set_mimes);
return apps;
}
static void
_e_fwin_desktop_run(Efreet_Desktop *desktop,
E_Fwin_Page *page,
Eina_Bool skip_history)
{
char pcwd[4096], buf[4096];
Eina_List *selected, *l, *files = NULL;
E_Fwin *fwin = page->fwin;
E_Fm2_Icon_Info *ici;
char *file;
skip_history = EINA_FALSE;
selected = e_fm2_selected_list_get(page->fm_obj);
if (!selected) return;
if (!getcwd(pcwd, sizeof(pcwd))) return;
if (chdir(e_fm2_real_path_get(page->fm_obj)) < 0) return;
EINA_LIST_FOREACH(selected, l, ici)
{
E_Fwin_Exec_Type ext;
/* this snprintf is silly - but it's here in case i really do
* need to provide full paths (seems silly since we chdir
* into the dir)
*/
buf[0] = 0;
ext = _e_fwin_file_is_exec(ici);
if ((ext == E_FWIN_EXEC_NONE) || (desktop))
{
if (!((ici->link) && (ici->mount)))
eina_strlcpy(buf, ici->file, sizeof(buf));
}
else
_e_fwin_file_exec(page, ici, ext);
if (buf[0] != 0)
{
if ((ici->mime) && (desktop) && !(skip_history))
e_exehist_mime_desktop_add(ici->mime, desktop);
files = eina_list_append(files, strdup(ici->file));
}
}
if ((fwin->win) && (desktop))
{
e_exec(e_comp_object_util_zone_get(fwin->win), desktop, NULL, files, "fwin");
ici = selected->data;
if ((ici) && (ici->mime) && (desktop) && !(skip_history))
e_exehist_mime_desktop_add(ici->mime, desktop);
}
else if (fwin->zone && desktop)
e_exec(fwin->zone, desktop, NULL, files, "fwin");
eina_list_free(selected);
EINA_LIST_FREE(files, file) free(file);
if (chdir(pcwd) < 0) perror("chdir");
}
static E_Fwin_Exec_Type
_e_fwin_file_is_exec(E_Fm2_Icon_Info *ici)
{
/* special file or dir - can't exec anyway */
if ((S_ISCHR(ici->statinfo.st_mode)) ||
(S_ISBLK(ici->statinfo.st_mode)) ||
(S_ISFIFO(ici->statinfo.st_mode)) ||
(S_ISSOCK(ici->statinfo.st_mode)))
return E_FWIN_EXEC_NONE;
/* it is executable */
if ((ici->statinfo.st_mode & S_IXOTH) ||
((getgid() == ici->statinfo.st_gid) &&
(ici->statinfo.st_mode & S_IXGRP)) ||
((getuid() == ici->statinfo.st_uid) &&
(ici->statinfo.st_mode & S_IXUSR)))
{
/* no mimetype */
if (!ici->mime)
return E_FWIN_EXEC_DIRECT;
/* mimetype */
else
{
/* FIXME: - this could be config */
if (!strcmp(ici->mime, "application/x-desktop"))
return E_FWIN_EXEC_DESKTOP;
else if ((!strcmp(ici->mime, "application/x-sh")) ||
(!strcmp(ici->mime, "application/x-shellscript")) ||
(!strcmp(ici->mime, "application/x-csh")) ||
(!strcmp(ici->mime, "application/x-perl")) ||
(!strcmp(ici->mime, "application/x-shar")) ||
(!strcmp(ici->mime, "application/x-executable")) ||
(!strcmp(ici->mime, "text/x-csh")) ||
(!strcmp(ici->mime, "text/x-python")) ||
(!strcmp(ici->mime, "text/x-sh"))
)
{
return E_FWIN_EXEC_DIRECT;
}
}
}
else
{
/* mimetype */
if (ici->mime)
{
/* FIXME: - this could be config */
if (!strcmp(ici->mime, "application/x-desktop"))
return E_FWIN_EXEC_DESKTOP;
else if ((!strcmp(ici->mime, "application/x-sh")) ||
(!strcmp(ici->mime, "application/x-shellscript")) ||
(!strcmp(ici->mime, "text/x-sh"))
)
{
return E_FWIN_EXEC_TERMINAL_SH;
}
}
else if ((e_util_glob_match(ici->file, "*.desktop")) ||
(e_util_glob_match(ici->file, "*.kdelink"))
)
{
return E_FWIN_EXEC_DESKTOP;
}
else if (e_util_glob_match(ici->file, "*.run"))
return E_FWIN_EXEC_TERMINAL_SH;
}
return E_FWIN_EXEC_NONE;
}
static void
_e_fwin_file_exec(E_Fwin_Page *page,
E_Fm2_Icon_Info *ici,
E_Fwin_Exec_Type ext)
{
E_Fwin *fwin = page->fwin;
char buf[4096];
Efreet_Desktop *desktop;
/* FIXME: execute file ici with either a terminal, the shell, or directly
* or open the .desktop and exec it */
switch (ext)
{
case E_FWIN_EXEC_NONE:
break;
case E_FWIN_EXEC_DIRECT:
snprintf(buf, sizeof(buf), "%s/%s", e_fm2_real_path_get(fwin->cur_page->fm_obj), ici->file);
// XXX: exec verify buf
if (fwin->win)
e_exec(e_comp_object_util_zone_get(fwin->win), NULL, buf, NULL, "fwin");
else if (fwin->zone)
e_exec(fwin->zone, NULL, buf, NULL, "fwin");
break;
case E_FWIN_EXEC_SH:
snprintf(buf, sizeof(buf), "/bin/sh %s", e_util_filename_escape(ici->file));
// XXX: exec verify buf
if (fwin->win)
e_exec(e_comp_object_util_zone_get(fwin->win), NULL, buf, NULL, "fwin");
else if (fwin->zone)
e_exec(fwin->zone, NULL, buf, NULL, "fwin");
break;
case E_FWIN_EXEC_TERMINAL_DIRECT:
snprintf(buf, sizeof(buf), "%s %s", e_config->exebuf_term_cmd, e_util_filename_escape(ici->file));
// XXX: exec verify buf
if (fwin->win)
e_exec(e_comp_object_util_zone_get(fwin->win), NULL, buf, NULL, "fwin");
else if (fwin->zone)
e_exec(fwin->zone, NULL, buf, NULL, "fwin");
break;
case E_FWIN_EXEC_TERMINAL_SH:
snprintf(buf, sizeof(buf), "%s /bin/sh %s", e_config->exebuf_term_cmd, e_util_filename_escape(ici->file));
// XXX: exec verify buf
if (fwin->win)
e_exec(e_comp_object_util_zone_get(fwin->win), NULL, buf, NULL, "fwin");
else if (fwin->zone)
e_exec(fwin->zone, NULL, buf, NULL, "fwin");
break;
case E_FWIN_EXEC_DESKTOP:
snprintf(buf, sizeof(buf), "%s/%s", e_fm2_real_path_get(page->fm_obj), ici->file);
// XXX: exec verify buf
desktop = efreet_desktop_new(buf);
if (desktop)
{
if (fwin->win)
e_exec(e_comp_object_util_zone_get(fwin->win), desktop, NULL, NULL, "fwin");
else if (fwin->zone)
e_exec(fwin->zone, desktop, NULL, NULL, "fwin");
efreet_desktop_free(desktop);
}
break;
default:
break;
}
}
static void
_e_fwin_config_set(E_Fwin_Page *page)
{
E_Fm2_Config fmc;
memset(&fmc, 0, sizeof(E_Fm2_Config));
if (!page->fwin->zone)
{
#if 0
fmc.view.mode = E_FM2_VIEW_MODE_LIST;
fmc.icon.list.w = 24 * e_scale;
fmc.icon.list.h = 24 * e_scale;
fmc.icon.fixed.w = 1;
fmc.icon.fixed.h = 1;
#else
fmc.view.mode = fileman_config->view.mode;
fmc.icon.icon.w = fileman_config->icon.icon.w * e_scale;
fmc.icon.icon.h = fileman_config->icon.icon.h * e_scale;
fmc.icon.fixed.w = 0;
fmc.icon.fixed.h = 0;
#endif
fmc.view.open_dirs_in_place = fileman_config->view.open_dirs_in_place;
}
else
{
#if 0
fmc.view.mode = E_FM2_VIEW_MODE_LIST;
fmc.icon.list.w = 24 * e_scale;
fmc.icon.list.h = 24 * e_scale;
fmc.icon.fixed.w = 1;
fmc.icon.fixed.h = 1;
#else
fmc.view.mode = page->fwin->path->desktop_mode;
fmc.icon.icon.w = fileman_config->icon.icon.w * e_scale;
fmc.icon.icon.h = fileman_config->icon.icon.h * e_scale;
fmc.icon.fixed.w = 0;
fmc.icon.fixed.h = 0;
#endif
fmc.view.no_typebuf_set = !fileman_config->view.desktop_navigation;
fmc.view.open_dirs_in_place = 0;
fmc.view.fit_custom_pos = 1;
}
fmc.view.selector = 0;
fmc.view.single_click = fileman_config->view.single_click;
fmc.view.no_subdir_jump = 0;
fmc.icon.max_thumb_size = fileman_config->icon.max_thumb_size;
fmc.icon.extension.show = fileman_config->icon.extension.show;
fmc.list.sort.no_case = fileman_config->list.sort.no_case;
fmc.list.sort.extension = fileman_config->list.sort.extension;
fmc.list.sort.mtime = fileman_config->list.sort.mtime;
fmc.list.sort.size = fileman_config->list.sort.size;
fmc.list.sort.dirs.first = fileman_config->list.sort.dirs.first;
fmc.list.sort.dirs.last = fileman_config->list.sort.dirs.last;
fmc.selection.single = fileman_config->selection.single;
fmc.selection.windows_modifiers = fileman_config->selection.windows_modifiers;
e_fm2_config_set(page->fm_obj, &fmc);
}
static void
_e_fwin_window_title_set(E_Fwin_Page *page)
{
char buf[PATH_MAX + sizeof("e_fwin::")];
const char *file;
if (!page) return;
if (page->fwin->zone) return; //safety
if (fileman_config->view.show_full_path)
file = e_fm2_real_path_get(page->fm_obj);
else
file = ecore_file_file_get(e_fm2_real_path_get(page->fm_obj));
if (file)
elm_win_title_set(page->fwin->win, file);
if (e_config->remember_internal_fm_windows_globally)
ecore_evas_name_class_set(e_win_ee_get(page->fwin->win), "E", fwin_class);
else
{
snprintf(buf, sizeof(buf), "e_fwin::%s", e_fm2_real_path_get(page->fm_obj));
ecore_evas_name_class_set(e_win_ee_get(page->fwin->win), "E", buf);
}
}
static void
_e_fwin_toolbar_resize(E_Fwin_Page *page)
{
if (!page->tbar)
{
edje_object_signal_emit(page->fwin->bg_obj, "e,toolbar,disabled", "e");
return;
}
switch (page->tbar->gadcon->orient)
{
case E_GADCON_ORIENT_HORIZ:
case E_GADCON_ORIENT_TOP:
evas_object_size_hint_min_set(page->tbar->o_base, 0, page->tbar->minh);
edje_object_part_swallow(page->fwin->bg_obj, "e.swallow.toolbar", page->tbar->o_base);
edje_object_signal_emit(page->fwin->bg_obj, "e,toolbar,top", "e");
break;
case E_GADCON_ORIENT_BOTTOM:
evas_object_size_hint_min_set(page->tbar->o_base, 0, page->tbar->minh);
edje_object_part_swallow(page->fwin->bg_obj, "e.swallow.toolbar", page->tbar->o_base);
edje_object_signal_emit(page->fwin->bg_obj, "e,toolbar,bottom", "e");
break;
case E_GADCON_ORIENT_VERT:
case E_GADCON_ORIENT_LEFT:
evas_object_size_hint_min_set(page->tbar->o_base, page->tbar->minw, 0);
edje_object_part_swallow(page->fwin->bg_obj, "e.swallow.toolbar", page->tbar->o_base);
edje_object_signal_emit(page->fwin->bg_obj, "e,toolbar,left", "e");
break;
case E_GADCON_ORIENT_RIGHT:
evas_object_size_hint_min_set(page->tbar->o_base, page->tbar->minw, 0);
edje_object_part_swallow(page->fwin->bg_obj, "e.swallow.toolbar", page->tbar->o_base);
edje_object_signal_emit(page->fwin->bg_obj, "e,toolbar,right", "e");
break;
default:
break;
}
edje_object_message_signal_process(page->fwin->bg_obj);
}
/* fwin callbacks */
static void
_e_fwin_cb_delete(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
e_object_del(data);
}
/* static void
* _e_fwin_geom_save(E_Fwin *fwin)
* {
* char buf[PATH_MAX];
* E_Fm2_Custom_File *cf;
*
* if (!fwin->geom_save_ready) return;
* snprintf(buf, sizeof(buf), "dir::%s", e_fm2_real_path_get(fwin->cur_page->fm_obj));
* cf = e_fm2_custom_file_get(buf);
* if (!cf)
* {
* cf = alloca(sizeof(E_Fm2_Custom_File));
* memset(cf, 0, sizeof(E_Fm2_Custom_File));
* }
* cf->geom.x = fwin->win->x;
* cf->geom.y = fwin->win->y;
* cf->geom.w = fwin->win->w;
* cf->geom.h = fwin->win->h;
* cf->geom.valid = 1;
* e_fm2_custom_file_set(buf, cf);
* } */
static void
_e_fwin_cb_resize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
E_Fwin *fwin = data;
if (fwin->bg_obj)
{
if (fwin->zone)
evas_object_resize(fwin->bg_obj, fwin->zone->w, fwin->zone->h);
}
_e_fwin_toolbar_resize(fwin->cur_page);
if (fwin->zone)
evas_object_resize(fwin->cur_page->scrollframe_obj, fwin->zone->w, fwin->zone->h);
/* _e_fwin_geom_save(fwin); */
}
static void
_e_fwin_deleted(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
E_Fwin_Page *page;
page = data;
e_object_del(E_OBJECT(page->fwin));
}
static void
_e_fwin_changed(void *data,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
E_Fwin *fwin;
E_Fwin_Page *page;
E_Fm2_Config *cfg;
Efreet_Desktop *ef;
const char *dev, *path;
char buf[PATH_MAX];
Eina_Bool need_free = EINA_TRUE;
page = data;
fwin = page->fwin;
if (!fwin) return; //safety
_e_fwin_icon_mouse_out(fwin, NULL, NULL);
cfg = e_fm2_config_get(page->fm_obj);
e_fm2_path_get(page->fm_obj, &dev, NULL);
e_user_dir_concat_static(buf, "fileman/favorites");
path = e_fm2_real_path_get(page->fm_obj);
if ((dev && (!strcmp(dev, "favorites"))) || (path && (!strcmp(buf, path))))
cfg->view.link_drop = 1;
else
cfg->view.link_drop = 0;
/* FIXME: first look in E config for a special override for this dir's bg
* or overlay
*/
ef = e_fm2_desktop_get(page->fm_obj);
if (ef) need_free = EINA_FALSE;
else
{
snprintf(buf, sizeof(buf), "%s/.directory.desktop", e_fm2_real_path_get(page->fm_obj));
ef = efreet_desktop_new(buf);
}
//printf("EF=%p for %s\n", ef, buf);
if (ef)
{
fwin->wallpaper_file = _e_fwin_custom_file_path_eval(fwin, ef, fwin->wallpaper_file, "X-Enlightenment-Directory-Wallpaper");
fwin->overlay_file = _e_fwin_custom_file_path_eval(fwin, ef, fwin->overlay_file, "X-Enlightenment-Directory-Overlay");
fwin->scrollframe_file = _e_fwin_custom_file_path_eval(fwin, ef, fwin->scrollframe_file, "X-Enlightenment-Directory-Scrollframe");
fwin->theme_file = _e_fwin_custom_file_path_eval(fwin, ef, fwin->theme_file, "X-Enlightenment-Directory-Theme");
//printf("fwin->wallpaper_file = %s\n", fwin->wallpaper_file);
if (need_free) efreet_desktop_free(ef);
}
else
{
eina_stringshare_replace(&fwin->wallpaper_file, NULL);
eina_stringshare_replace(&fwin->overlay_file, NULL);
eina_stringshare_replace(&fwin->scrollframe_file, NULL);
eina_stringshare_replace(&fwin->theme_file, NULL);
}
if (page->scrollframe_obj)
{
if ((fwin->scrollframe_file) &&
(e_util_edje_collection_exists(fwin->scrollframe_file,
"e/fileman/default/scrollframe")))
e_scrollframe_custom_edje_file_set(page->scr,
(char *)fwin->scrollframe_file,
"e/fileman/default/scrollframe");
else
{
if (fwin->zone)
e_scrollframe_custom_theme_set(page->scr,
"base/theme/fileman",
"e/fileman/desktop/scrollframe");
else
e_scrollframe_custom_theme_set(page->scr,
"base/theme/fileman",
"e/fileman/default/scrollframe");
}
e_scrollframe_child_pos_set(page->scr, 0, 0);
}
if ((fwin->theme_file) && (ecore_file_exists(fwin->theme_file)))
e_fm2_custom_theme_set(obj, fwin->theme_file);
else
e_fm2_custom_theme_set(obj, NULL);
if (fwin->wallpaper_file)
{
if (eina_str_has_extension(fwin->wallpaper_file, "edj"))
{
if (!fwin->wallpaper_is_edj)
{
if (fwin->under_obj) evas_object_del(fwin->under_obj);
fwin->under_obj = edje_object_add(evas_object_evas_get(fwin->win));
fwin->wallpaper_is_edj = EINA_TRUE;
}
edje_object_file_set(fwin->under_obj, fwin->wallpaper_file, "e/desktop/background");
}
else
{
if (fwin->wallpaper_is_edj) evas_object_del(fwin->under_obj);
fwin->wallpaper_is_edj = EINA_FALSE;
fwin->under_obj = e_icon_add(evas_object_evas_get(fwin->win));
e_icon_scale_size_set(fwin->under_obj, 0);
e_icon_fill_inside_set(fwin->under_obj, 0);
e_icon_file_set(fwin->under_obj, fwin->wallpaper_file);
}
if (fwin->under_obj)
{
edje_object_part_swallow(e_scrollframe_edje_object_get(page->scr),
"e.swallow.bg", fwin->under_obj);
evas_object_pass_events_set(fwin->under_obj, 1);
evas_object_show(fwin->under_obj);
}
}
else
{
edje_object_part_swallow(e_scrollframe_edje_object_get(page->scr),
"e.swallow.bg", NULL);
if (fwin->under_obj) evas_object_hide(fwin->under_obj);
}
if (fwin->over_obj)
{
//printf("over obj\n");
evas_object_hide(fwin->over_obj);
if (fwin->overlay_file)
{
edje_object_file_set(fwin->over_obj, fwin->overlay_file,
"e/desktop/background");
// ext = strrchr(fwin->overlay_file, '.');
// if (ext && !strcasecmp(ext, ".edj"))
// e_icon_file_edje_set(fwin->over_obj, fwin->overlay_file, "e/desktop/background");
// else
// e_icon_file_set(fwin->over_obj, fwin->overlay_file);
}
// else
// e_icon_file_edje_set(fwin->over_obj, NULL, NULL);
evas_object_show(fwin->over_obj);
}
_e_fwin_icon_mouse_out(fwin, NULL, NULL);
if (fwin->zone)
{
e_fm2_path_get(page->fm_obj, &dev, &path);
eina_stringshare_replace(&fwin->path->dev, dev);
eina_stringshare_replace(&fwin->path->path, path);
return;
}
_e_fwin_window_title_set(page);
if (page->setting) return;
if (page->flist) e_fm2_deselect_all(page->flist);
}
static void
_e_fwin_favorite_selected(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
E_Fwin_Page *page;
Eina_List *selected;
page = data;
selected = e_fm2_selected_list_get(page->flist);
if (!selected) return;
page->setting = 1;
_e_fwin_file_open_dialog(page, selected, -1);
eina_list_free(selected);
page->setting = 0;
}
static void
_e_fwin_selected(void *data,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
E_Fwin_Page *page;
Eina_List *selected;
page = data;
selected = e_fm2_selected_list_get(page->fm_obj);
if (!selected) return;
_e_fwin_file_open_dialog(page, selected, 0);
eina_list_free(selected);
}
static void
_e_fwin_selection_change(void *data,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
Eina_List *l;
E_Fwin_Page *page;
page = data;
for (l = fwins; l; l = l->next)
{
if (l->data != page->fwin)
e_fwin_all_unsel(l->data);
}
evas_object_focus_set(obj, 1);
}
static void
_e_fwin_cb_all_change(void *data,
Evas_Object *obj EINA_UNUSED)
{
E_Fwin_Apps_Dialog *fad;
Efreet_Desktop *desktop = NULL;
fad = data;
desktop = efreet_util_desktop_file_id_find(fad->app2);
if ((desktop) && (desktop->exec))
e_widget_entry_text_set(fad->o_entry, desktop->exec);
if (desktop)
efreet_desktop_free(desktop);
else
e_widget_entry_text_set(fad->o_entry, fad->app2);
}
static void
_e_fwin_cb_delay_del_job(void *data)
{
E_Fwin *fwin = data;
fwin->object_del_job = NULL;
e_object_del(E_OBJECT(fwin));
}
static void
_e_fwin_cb_key_down(void *data,
Evas *e EINA_UNUSED,
Evas_Object *obj EINA_UNUSED,
void *event_info)
{
Evas_Event_Key_Down *ev;
E_Fwin *fwin;
E_Fwin_Page *page;
page = data;
fwin = page->fwin;
ev = event_info;
if (evas_key_modifier_is_set(ev->modifiers, "Control"))
{
if (!strcmp(ev->key, "n"))
{
const char *dev, *path;
e_fm2_path_get(page->fm_obj, &dev, &path);
e_fwin_new(dev, path);
}
else if (!strcmp(ev->key, "a"))
{
e_fm2_all_sel(page->fm_obj);
}
else if (!strcmp(ev->key, "w"))
{
if (fwin->object_del_job) ecore_job_del(fwin->object_del_job);
fwin->object_del_job = ecore_job_add(_e_fwin_cb_delay_del_job, fwin);
}
}
}
static void
_e_fwin_cb_page_obj_del(void *data EINA_UNUSED,
Evas *evas EINA_UNUSED,
Evas_Object *obj,
void *event_info EINA_UNUSED)
{
evas_object_smart_callback_del(obj, "dir_changed",
_e_fwin_changed);
evas_object_smart_callback_del(obj, "dir_deleted",
_e_fwin_deleted);
evas_object_smart_callback_del(obj, "selected",
_e_fwin_selected);
evas_object_smart_callback_del(obj, "selection_change",
_e_fwin_selection_change);
evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL,
_e_fwin_cb_page_obj_del);
}
/* fwin zone callbacks */
static void
_e_fwin_zone_cb_mouse_down(void *data,
Evas *evas EINA_UNUSED,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
E_Fwin *fwin;
fwin = data;
if (!fwin) return;
e_fwin_all_unsel(fwin);
e_fm2_typebuf_clear(fwin->cur_page->fm_obj);
}
static Eina_Bool
_e_fwin_zone_move_resize(void *data, int type EINA_UNUSED, void *event)
{
E_Event_Zone_Move_Resize *ev = event;
E_Fwin *fwin = data;
int x, y, w, h, sx, sy, sw, sh;
if (!fwin) return ECORE_CALLBACK_PASS_ON;
if (fwin->zone != ev->zone) return ECORE_CALLBACK_PASS_ON;
if (!fwin->cur_page->scrollframe_obj) return ECORE_CALLBACK_RENEW;
e_zone_useful_geometry_get(ev->zone, &x, &y, &w, &h);
evas_object_geometry_get(fwin->cur_page->scrollframe_obj, &sx, &sy, &sw, &sh);
/* if same, do nothing */
if ((sx == x) && (sy == y) && (sw == w) && (sh == h)) return ECORE_CALLBACK_RENEW;
evas_object_geometry_set(fwin->cur_page->scrollframe_obj, x, y, w, h);
e_fm2_refresh(fwin->cur_page->fm_obj);
return ECORE_CALLBACK_RENEW;
}
static Eina_Bool
_e_fwin_zone_del(void *data,
int type,
void *event)
{
E_Event_Zone_Del *ev;
E_Fwin *fwin;
if (type != E_EVENT_ZONE_DEL) return ECORE_CALLBACK_PASS_ON;
fwin = data;
ev = event;
if (!fwin) return ECORE_CALLBACK_PASS_ON;
if (fwin->zone != ev->zone) return ECORE_CALLBACK_PASS_ON;
e_object_del(E_OBJECT(fwin));
return ECORE_CALLBACK_PASS_ON;
}
static int
_e_fwin_cb_dir_handler_test(void *data EINA_UNUSED, Evas_Object *obj, const char *path)
{
if (ecore_file_is_dir(path)) return 1;
if (e_fm2_real_path_get(obj))
{
evas_object_data_set(obj, "fileman_terminal_realpath", (void*)1);
return 1;
}
return 0;
}
static void
_e_fwin_cb_dir_handler(void *data EINA_UNUSED, Evas_Object *obj, const char *path)
{
char buf[PATH_MAX];
Eina_Stringshare *rp;
if (!getcwd(buf, sizeof(buf))) return;
rp = e_fm2_real_path_get(obj);
if (rp && (rp != path) && (evas_object_data_del(obj, "fileman_terminal_realpath"))) //icon menu; use rp
path = rp;
if (chdir(path) < 0) perror("chdir");
e_exec(e_zone_current_get(), tdesktop, NULL, NULL, "fileman");
if (chdir(buf) < 0) perror("chdir");
/* FIXME: if info != null then check mime type and offer options based
* on that
*/
}
static void
_e_fwin_parent(void *data,
E_Menu *m EINA_UNUSED,
E_Menu_Item *mi EINA_UNUSED)
{
e_fm2_parent_go(data);
}
static void
_e_fwin_cb_menu_open_fast(void *data,
E_Menu *m EINA_UNUSED,
E_Menu_Item *mi)
{
E_Fwin_Page *page;
Efreet_Desktop *desk;
page = data;
desk = e_object_data_get(E_OBJECT(mi));
if ((page) && (desk))
_e_fwin_desktop_run(desk, page, EINA_TRUE);
}
static void
_e_fwin_cb_menu_extend_open_with(void *data,
E_Menu *m)
{
Eina_List *selected = NULL, *apps = NULL, *l;
E_Menu_Item *mi;
E_Fwin_Page *page;
Efreet_Desktop *desk = NULL;
page = data;
selected = e_fm2_selected_list_get(page->fm_obj);
if (!selected) return;
apps = _e_fwin_suggested_apps_list_get(selected, NULL, NULL);
EINA_LIST_FOREACH(apps, l, desk)
{