legacy/experimental/ecdb/trunk/src/ecdb_filelist_custom.c
2008-08-04 22:18:34 +00:00

384 lines
9.3 KiB
C

#include "ecdb.h"
static void free_file(Ewl_Filelist_File *file);
static void ecdb_custom_filelist_cb_clicked(Ewl_Widget *w, void *ev,
void *data);
static Ewl_Widget *ecdb_custom_filelist_view_widget_fetch(void *data,
unsigned int row, unsigned int column);
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)
{
const char *dnd_types[] = {"text/uri-list", NULL};
Ewl_Widget *ret;
ret = ewl_filelist_new();
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_fetch_set(EWL_FILELIST(ret)->view,
ecdb_custom_filelist_view_widget_fetch);
ewl_callback_append(ret, EWL_CALLBACK_DND_DATA_RECEIVED,
ecdb_custom_filelist_dnd_dropped_cb, NULL);
ewl_dnd_accepted_types_set(ret, dnd_types);
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);
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, "source");
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);
}
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), "source", 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, ECORE_FREE_CB(free_file));
ecore_list_free_cb_set(dirs, ECORE_FREE_CB(free_file));
if (!parent)
return NULL;
/* No up for now */
while ((src = parent->children[i]))
{
file = calloc(1, sizeof(Ewl_Filelist_File));
file->name = ecore_string_instance(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++;
}
/* Oops */
i++;
}
dir = calloc(1, sizeof(Ewl_Filelist_Directory));
dir->files = ecore_list_new();
dir->dirs = ecore_list_new();
dir->rfiles = files;
dir->rdirs = dirs;
dir->num_dirs = nd;
dir->num_files = nf;
ecdb_custom_filelist_model_filter(dir);
return dir;
}
static void
free_file(Ewl_Filelist_File *file)
{
ecore_string_release(file->name);
FREE(file);
}
static void
ecdb_custom_filelist_model_filter(Ewl_Filelist_Directory *dir)
{
Ewl_Filelist_File *file;
int nd, nf;
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 (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 (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_clicked(Ewl_Widget *w, void *ev, void *data)
{
Ewl_Event_Mouse_Down *md;
char *file;
int i = 0;
Ewl_Widget *c;
Ewl_Filelist *fl;
Ecdb_Source *parent, *child;
md = ev;
fl = data;
if (!ewl_mvc_selected_count_get(EWL_MVC(fl->controller)))
return;
if (md->clicks != 2)
{
ewl_filelist_selected_files_change_notify(fl);
return;
}
c = ewl_container_child_at_recursive_get(EWL_CONTAINER(fl),
md->base.x, md->base.y);
while (c && c->parent)
{
if (!ewl_widget_internal_is(c))
{
i = 1;
break;
}
c = c->parent;
}
if (!i)
return;
file = ecdb_custom_filelist_selected_file_get(fl);
parent = ewl_widget_data_get(EWL_WIDGET(fl), "source");
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_view_widget_fetch(void *data, unsigned int row __UNUSED__,
unsigned int column)
{
Ewl_Widget *ret;
const char *img = NULL, *stock, *filename;
/* Create icon */
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);
/* Get and set data into icon */
if (column == 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(ret), img, NULL);
filename = ecore_file_file_get(data);
ewl_icon_label_set(EWL_ICON(ret), filename);
}
else
ewl_icon_label_set(EWL_ICON(ret), data);
FREE(data);
return ret;
}