legacy/experimental/ecdb/trunk/src/ecdb_filelist_custom.c

435 lines
12 KiB
C

/* 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);
/* This entire thing here is 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);
ewl_widget_configure(EWL_FILELIST(w)->controller);
/* End hack stuff */
// 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);
}