diff --git a/Makefile b/Makefile index 52e4ab6..2f1c36a 100644 --- a/Makefile +++ b/Makefile @@ -108,6 +108,7 @@ dist: $(PACKAGE)-$(VERSION)/src/plugins/subversion.c \ $(PACKAGE)-$(VERSION)/src/plugins/template.c \ $(PACKAGE)-$(VERSION)/src/plugins/trash.c \ + $(PACKAGE)-$(VERSION)/src/plugins/undelete.c \ $(PACKAGE)-$(VERSION)/src/plugins/volumes.c \ $(PACKAGE)-$(VERSION)/src/plugins/Makefile \ $(PACKAGE)-$(VERSION)/src/plugins/common.c \ diff --git a/src/plugins/Makefile b/src/plugins/Makefile index 61ae15e..3280850 100644 --- a/src/plugins/Makefile +++ b/src/plugins/Makefile @@ -1,4 +1,4 @@ -TARGETS = $(OBJDIR)backup.so $(OBJDIR)cvs.so $(OBJDIR)dirtree.so $(OBJDIR)favorites.so $(OBJDIR)git.so $(OBJDIR)make.so $(OBJDIR)preview.so $(OBJDIR)properties.so $(OBJDIR)selection.so $(OBJDIR)subversion.so $(OBJDIR)template.so $(OBJDIR)trash.so $(OBJDIR)volumes.so +TARGETS = $(OBJDIR)backup.so $(OBJDIR)cvs.so $(OBJDIR)dirtree.so $(OBJDIR)favorites.so $(OBJDIR)git.so $(OBJDIR)make.so $(OBJDIR)preview.so $(OBJDIR)properties.so $(OBJDIR)selection.so $(OBJDIR)subversion.so $(OBJDIR)template.so $(OBJDIR)trash.so $(OBJDIR)undelete.so $(OBJDIR)volumes.so OBJDIR = PREFIX = /usr/local DESTDIR = @@ -104,6 +104,13 @@ trash_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) $(OBJDIR)trash.so: $(trash_OBJS) $(CCSHARED) -o $(OBJDIR)trash.so $(trash_OBJS) $(trash_LDFLAGS) +undelete_OBJS = $(OBJDIR)undelete.o +undelete_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS) +undelete_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) + +$(OBJDIR)undelete.so: $(undelete_OBJS) + $(CCSHARED) -o $(OBJDIR)undelete.so $(undelete_OBJS) $(undelete_LDFLAGS) + volumes_OBJS = $(OBJDIR)volumes.o volumes_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS) volumes_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) @@ -147,11 +154,14 @@ $(OBJDIR)template.o: template.c ../../include/Browser.h $(OBJDIR)trash.o: trash.c ../../include/Browser.h $(CC) $(trash_CFLAGS) -o $(OBJDIR)trash.o -c trash.c +$(OBJDIR)undelete.o: undelete.c ../../include/Browser.h + $(CC) $(undelete_CFLAGS) -o $(OBJDIR)undelete.o -c undelete.c + $(OBJDIR)volumes.o: volumes.c ../../include/Browser.h $(CC) $(volumes_CFLAGS) -o $(OBJDIR)volumes.o -c volumes.c clean: - $(RM) -- $(backup_OBJS) $(cvs_OBJS) $(dirtree_OBJS) $(favorites_OBJS) $(git_OBJS) $(make_OBJS) $(preview_OBJS) $(properties_OBJS) $(selection_OBJS) $(subversion_OBJS) $(template_OBJS) $(trash_OBJS) $(volumes_OBJS) + $(RM) -- $(backup_OBJS) $(cvs_OBJS) $(dirtree_OBJS) $(favorites_OBJS) $(git_OBJS) $(make_OBJS) $(preview_OBJS) $(properties_OBJS) $(selection_OBJS) $(subversion_OBJS) $(template_OBJS) $(trash_OBJS) $(undelete_OBJS) $(volumes_OBJS) distclean: clean $(RM) -- $(TARGETS) diff --git a/src/plugins/project.conf b/src/plugins/project.conf index 9c82127..ca11d93 100644 --- a/src/plugins/project.conf +++ b/src/plugins/project.conf @@ -1,4 +1,4 @@ -targets=backup,cvs,dirtree,favorites,git,make,preview,properties,selection,subversion,template,trash,volumes +targets=backup,cvs,dirtree,favorites,git,make,preview,properties,selection,subversion,template,trash,undelete,volumes cppflags_force=-I ../../include cppflags= cflags_force=-W `pkg-config --cflags libDesktop` @@ -101,6 +101,13 @@ install=$(LIBDIR)/Browser/plugins [trash.c] depends=../../include/Browser.h +[undelete] +type=plugin +sources=undelete.c + +[undelete.c] +depends=../../include/Browser.h + [volumes] type=plugin sources=volumes.c diff --git a/src/plugins/undelete.c b/src/plugins/undelete.c new file mode 100644 index 0000000..345a15a --- /dev/null +++ b/src/plugins/undelete.c @@ -0,0 +1,203 @@ +/* $Id$ */ +/* Copyright (c) 2015 Pierre Pronchery */ +/* This file is part of DeforaOS Desktop Browser */ +/* This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + + + +#include +#include +#include +#include +#include +#include +#include "Browser.h" +#define _(string) gettext(string) +#define N_(string) (string) + + +/* Undelete */ +/* private */ +/* types */ +enum _UndeleteColumn +{ + UC_ICON, + UC_FILENAME +}; +#define UC_LAST UC_FILENAME +#define UC_COUNT (UC_LAST + 1) + +typedef struct _BrowserPlugin +{ + BrowserPluginHelper * helper; + + guint source; + + /* refresh */ + char * selection; + int fd; + + /* widgets */ + GtkWidget * window; + GtkListStore * store; + GtkWidget * view; +} Undelete; + + +/* prototypes */ +/* plug-in */ +static Undelete * _undelete_init(BrowserPluginHelper * helper); +static void _undelete_destroy(Undelete * undelete); +static GtkWidget * _undelete_get_widget(Undelete * undelete); +static void _undelete_refresh(Undelete * undelete, GList * selection); + +/* callbacks */ +static gboolean _undelete_on_idle(gpointer data); + + +/* public */ +/* variables */ +BrowserPluginDefinition plugin = +{ + N_("Undelete"), + "image-missing", + NULL, + _undelete_init, + _undelete_destroy, + _undelete_get_widget, + _undelete_refresh +}; + + +/* private */ +/* functions */ +/* undelete_init */ +static Undelete * _undelete_init(BrowserPluginHelper * helper) +{ + Undelete * undelete; + GtkCellRenderer * renderer; + GtkTreeViewColumn * column; + + if((undelete = object_new(sizeof(*undelete))) == NULL) + return NULL; + undelete->helper = helper; + undelete->source = 0; + undelete->selection = NULL; + undelete->fd = -1; + undelete->window = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(undelete->window), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + undelete->store = gtk_list_store_new(UC_COUNT, + GDK_TYPE_PIXBUF, /* UC_ICON */ + G_TYPE_STRING); /* UC_FILENAME */ + undelete->view = gtk_tree_view_new_with_model(GTK_TREE_MODEL( + undelete->store)); + gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(undelete->view), TRUE); + /* icon */ + renderer = gtk_cell_renderer_pixbuf_new(); + column = gtk_tree_view_column_new_with_attributes(NULL, renderer, + "pixbuf", UC_ICON, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(undelete->view), column); + /* filename */ + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Filename"), + renderer, "text", UC_FILENAME, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(undelete->view), column); + gtk_container_add(GTK_CONTAINER(undelete->window), undelete->view); + gtk_widget_show_all(undelete->window); + return undelete; +} + + +/* undelete_destroy */ +static void _undelete_destroy(Undelete * undelete) +{ + if(undelete->source != 0) + g_source_remove(undelete->source); + if(undelete->fd >= 0) + close(undelete->fd); + string_delete(undelete->selection); + object_delete(undelete); +} + + +/* undelete_get_widget */ +static GtkWidget * _undelete_get_widget(Undelete * undelete) +{ + return undelete->window; +} + + +/* undelete_refresh */ +static void _undelete_refresh(Undelete * undelete, GList * selection) +{ + if(undelete->source != 0) + g_source_remove(undelete->source); + if(undelete->fd >= 0) + close(undelete->fd); + undelete->fd = -1; + string_delete(undelete->selection); + undelete->selection = NULL; + if(selection == NULL + || selection->data == NULL + || (undelete->selection = string_new(selection->data)) + == NULL) + undelete->source = 0; + else + undelete->source = g_idle_add(_undelete_on_idle, undelete); +} + + +/* callbacks */ +/* undelete_on_idle */ +static gboolean _undelete_on_idle(gpointer data) +{ + Undelete * undelete = data; + char buf[65536]; + int i; + int j; + struct dirent de; + + if(undelete->fd < 0) + { + if((undelete->fd = open(undelete->selection, O_RDONLY)) < 0) + { + undelete->helper->error(undelete->helper->browser, + undelete->selection, 1); + undelete->source = 0; + return FALSE; + } + return TRUE; + } + if((i = getdents(undelete->fd, buf, sizeof(buf))) < 0) + undelete->helper->error(undelete->helper->browser, + undelete->selection, 1); + else if(i > 0) + { + for(j = 0; j + (int)sizeof(de) < i; j += de.d_reclen) + { + memcpy(&de, &buf[j], sizeof(de)); + if(strncmp(de.d_name, ".", 1) == 0 && de.d_namlen == 1) + continue; + if(strncmp(de.d_name, "..", 2) == 0 && de.d_namlen == 2) + continue; + /* FIXME implement */ + } + return TRUE; + } + close(undelete->fd); + string_delete(undelete->selection); + undelete->selection = NULL; + undelete->source = 0; + return FALSE; +}