/* vim: set sw=3 ts=3 sts=3 expandtab: */ #include "ecdb.h" static void free_file(void *data); static void ecdb_custom_filelist_cb_clicked(Ewl_Widget *w, void *ev, void *data); static void ecdb_custom_filelist_cb_key_down(Ewl_Widget *w, void *ev, void *data); static Ewl_Widget *ecdb_custom_filelist_cb_widget_fetch(unsigned int col, void *pr_data); static void ecdb_custom_filelist_cb_widget_assign(Ewl_Widget *w, void *data, unsigned int row, unsigned int col, void *pr_data); static void *ecdb_custom_filelist_model_data_fetch(void *data, unsigned int row, unsigned int column); static void ecdb_custom_filelist_model_filter(Ewl_Filelist_Directory *dir); static unsigned int ecdb_custom_filelist_model_data_unref(void *data); static Ewl_Filelist_Directory *ecdb_custom_filelist_directory_new (Ecdb_Source *src); static void ecdb_custom_filelist_dnd_dropped_cb(Ewl_Widget *w, void *ev, void *data); Ewl_Widget * ecdb_custom_filelist_new(void) { Ewl_Widget *ret; ret = ewl_filelist_new(); if (!ret) { EINA_ERROR_PWARN("ecdb_custom_filelist_new: NULL return!\n"); return NULL; } /* Ouch, this took forever to find */ ewl_model_data_unref_set(EWL_FILELIST(ret)->model, ecdb_custom_filelist_model_data_unref); ewl_model_data_fetch_set(EWL_FILELIST(ret)->model, ecdb_custom_filelist_model_data_fetch); ewl_view_widget_constructor_set(EWL_FILELIST(ret)->view, ecdb_custom_filelist_cb_widget_fetch); ewl_view_widget_assign_set(EWL_FILELIST(ret)->view, ecdb_custom_filelist_cb_widget_assign); ewl_callback_append(ret, EWL_CALLBACK_DND_DATA_RECEIVED, ecdb_custom_filelist_dnd_dropped_cb, NULL); em->ewl_dnd_candidates = eina_list_append(em->ewl_dnd_candidates, ret); ewl_callback_del_type(EWL_FILELIST(ret)->controller, EWL_CALLBACK_CLICKED); ewl_callback_prepend(EWL_FILELIST(ret)->controller, EWL_CALLBACK_CLICKED, ecdb_custom_filelist_cb_clicked, ret); ewl_callback_append(EWL_FILELIST(ret)->controller, EWL_CALLBACK_KEY_DOWN, ecdb_custom_filelist_cb_key_down, ret); return ret; } static void ecdb_custom_filelist_dnd_dropped_cb(Ewl_Widget *w, void *ev, void *data__UNUSED__) { int i; Ewl_Event_Dnd_Data_Received *dnd = ev; char **files = dnd->data; Ecdb_Source *parent, *child; Efreet_Uri *uri; /* Get the parent, find the path of the file(s) dropped * and add them as children to parent */ parent = ewl_widget_data_get(w, "src"); for (i = 0; i < dnd->len; i++) { uri = efreet_uri_decode(files[i]); if (!ecore_file_exists(uri->path)) { efreet_uri_free(uri); continue; } child = ecdb_source_new(); ecdb_source_data_set(child, uri->path); ecdb_source_child_append(parent, child); efreet_uri_free(uri); } ecdb_custom_filelist_directory_set(EWL_FILELIST(w), parent); /* And filter it here -- a bit of a hack */ ewl_filelist_model_data_sort(ewl_mvc_data_get (EWL_MVC(EWL_FILELIST(w)->controller)), 0, EWL_SORT_DIRECTION_ASCENDING); ewl_mvc_dirty_set(EWL_MVC(EWL_FILELIST(w)->controller), TRUE); // Send out this event so that we can get notified on size changes // and update the capacity measure ewl_callback_call_with_event_data(w, ECDB_FILELIST_SIZE_CHANGED, parent); } void ecdb_custom_filelist_directory_set(Ewl_Filelist *fl, Ecdb_Source *src) { if (src) { Ewl_Filelist_Directory *data; Ewl_Event_Action_Response ev_data; data = ewl_mvc_data_get(EWL_MVC(fl->controller)); if (data) { ecdb_custom_filelist_model_data_unref(data); } data = ecdb_custom_filelist_directory_new(src); ewl_mvc_data_set(EWL_MVC(fl->controller), data); ev_data.response = EWL_FILELIST_EVENT_DIR_CHANGE; ewl_callback_call_with_event_data(EWL_WIDGET(fl), EWL_CALLBACK_VALUE_CHANGED, &ev_data); /* Set the source as needed for file operations */ ewl_widget_data_set(EWL_WIDGET(fl), "src", src); } } static Ewl_Filelist_Directory * ecdb_custom_filelist_directory_new(Ecdb_Source *parent) { Ecdb_Source *src; Ewl_Filelist_Directory *dir; Ewl_Filelist_File *file; struct stat st; int nf = 0, nd = 0, i = 0; Ecore_List *files, *dirs; files = ecore_list_new(); dirs = ecore_list_new(); ecore_list_free_cb_set(files, free_file); ecore_list_free_cb_set(dirs, free_file); if (!parent) { return NULL; } while ((src = parent->children[i])) { file = calloc(1, sizeof(Ewl_Filelist_File)); file->name = eina_stringshare_add(src->dst); stat(src->dst, &st); file->size = st.st_size; file->modtime = st.st_mtime; file->mode = st.st_mode; file->groupname = st.st_gid; file->username = st.st_uid; file->is_dir = src->dir; file->readable = ecore_file_can_read(src->dst); file->writeable = ecore_file_can_write(src->dst); if (src->dir) { ecore_list_append(dirs, file); nd++; } else { ecore_list_append(files, file); nf++; } i++; } dir = calloc(1, sizeof(Ewl_Filelist_Directory)); dir->rfiles = files; dir->rdirs = dirs; dir->files = ecore_list_new(); dir->dirs = ecore_list_new(); dir->num_dirs = nd; dir->num_files = nf; ecdb_custom_filelist_model_filter(dir); return dir; } static void free_file(void *data) { Ewl_Filelist_File *file; file = data; eina_stringshare_del(file->name); FREE(file); } static void ecdb_custom_filelist_model_filter(Ewl_Filelist_Directory *dir) { Ewl_Filelist_File *file; int nd, nf; if (!dir->files || !dir->dirs) return; ecore_list_clear(dir->files); ecore_list_clear(dir->dirs); nd = nf = 0; if (!dir->show_dot) { ecore_list_first_goto(dir->rfiles); while ((file = ecore_list_next(dir->rfiles))) { if ((file->name) && (ecore_file_file_get(file->name)[0] != '.')) { ecore_list_append(dir->files, file); nf++; } } ecore_list_first_goto(dir->rdirs); while ((file = ecore_list_next(dir->rdirs))) { if ((file->name) && (ecore_file_file_get(file->name)[0] != '.')) { ecore_list_append(dir->dirs, file); nd++; } } } else { ecore_list_first_goto(dir->rfiles); while ((file = ecore_list_next(dir->rfiles))) { ecore_list_append(dir->files, file); nf++; } ecore_list_first_goto(dir->rdirs); while ((file = ecore_list_next(dir->rdirs))) { ecore_list_append(dir->dirs, file); nd++; } } dir->num_dirs = nd; dir->num_files = nf; } static unsigned int ecdb_custom_filelist_model_data_unref(void *data) { Ewl_Filelist_Directory *dir; dir = data; ecore_list_destroy(dir->files); ecore_list_destroy(dir->dirs); ecore_list_destroy(dir->rfiles); ecore_list_destroy(dir->rdirs); FREE(dir); return TRUE; } static void * ecdb_custom_filelist_model_data_fetch(void *data, unsigned int row, unsigned int column) { Ewl_Filelist_Directory *fld; Ewl_Filelist_File *file; int i; void *ret; fld = data; /* Check if in dirs or files list */ if (row < fld->num_dirs) { file = ecore_list_index_goto(fld->dirs, row); } else { i = row - fld->num_dirs; file = ecore_list_index_goto(fld->files, i); } if (column == 1) ret = ewl_filelist_size_get(file->size); else if (column == 2) ret = ewl_filelist_perms_get(file->mode); else if (column == 3) ret = ewl_filelist_username_get(file->username); else if (column == 4) ret = ewl_filelist_groupname_get(file->groupname); else if (column == 5) ret = ewl_filelist_modtime_get(file->modtime); else ret = strdup(file->name); /* ret needs to be freed by the view or with model_data_free_set */ return ret; } static void ecdb_custom_filelist_cb_key_down(Ewl_Widget *w, void *ev, void *data) { Ewl_Event_Key_Down *kd; Ewl_Filelist *fl; char *file; int i; Ecdb_Source *parent, *child; kd = ev; fl = data; if (!ewl_mvc_selected_count_get(EWL_MVC(w))) { return; } if (!strcmp(kd->base.keyname, "Delete")) { file = ecdb_custom_filelist_selected_file_get(fl); parent = ewl_widget_data_get(EWL_WIDGET(fl), "src"); for (i = 0; (child = parent->children[i]); i++) { if (!strcmp(child->dst, file)) { ecdb_source_child_remove(parent, child); ecdb_source_destroy(child); ecdb_custom_filelist_directory_set(fl, parent); ewl_callback_call_with_event_data(EWL_WIDGET(fl), ECDB_FILELIST_SIZE_CHANGED, parent); break; } } } } static void ecdb_custom_filelist_cb_clicked(Ewl_Widget *w, void *ev, void *data) { Ewl_Event_Mouse_Down *md; char *file; int i = 0; Ewl_Filelist *fl; Ecdb_Source *parent, *child; md = ev; fl = data; if ((!ewl_mvc_selected_count_get(EWL_MVC(w))) || (md->clicks != 2)) { ewl_filelist_selected_files_change_notify(fl); return; } file = ecdb_custom_filelist_selected_file_get(fl); parent = ewl_widget_data_get(EWL_WIDGET(fl), "src"); i = 0; while ((child = parent->children[i])) { if ((child->dir) && (!strcmp(child->dst, file))) { ecdb_custom_filelist_directory_set(fl, child); FREE(file); return; } i++; } ewl_filelist_selected_files_change_notify(fl); FREE(file); } char * ecdb_custom_filelist_selected_file_get(Ewl_Filelist *fl) { Ewl_Filelist_Directory *data; Ewl_Filelist_File *file; Ewl_Selection_Idx *idx; int i; idx = ewl_mvc_selected_get(EWL_MVC(fl->controller)); data = EWL_SELECTION(idx)->data; if (idx->row < data->num_dirs) { file = ecore_list_index_goto(data->dirs, idx->row); } else { i = (idx->row - data->num_dirs); file = ecore_list_index_goto(data->files, i); } FREE(idx); return strdup(file->name); } static Ewl_Widget *ecdb_custom_filelist_cb_widget_fetch( unsigned int col __UNUSED__, void *pr_data __UNUSED__) { Ewl_Widget *ret; ret = ewl_icon_simple_new(); ewl_icon_constrain_set(EWL_ICON(ret), EWL_ICON_SIZE_MEDIUM); ewl_box_orientation_set(EWL_BOX(ret), EWL_ORIENTATION_HORIZONTAL); ewl_object_alignment_set(EWL_OBJECT(ret), EWL_FLAG_ALIGN_LEFT); return ret; } static void ecdb_custom_filelist_cb_widget_assign(Ewl_Widget *w, void *data, unsigned int row __UNUSED__, unsigned int col, void *pr_data) { const char *img = NULL, *stock, *filename; if (col == 0) { stock = ewl_filelist_stock_icon_get(data); img = ewl_icon_theme_icon_path_get(stock, EWL_ICON_SIZE_MEDIUM); if (img) { ewl_icon_image_set(EWL_ICON(w), img, NULL); } filename = ecore_file_file_get(data); ewl_icon_label_set(EWL_ICON(w), filename); } else { ewl_icon_label_set(EWL_ICON(w), data); } FREE(data); }