As requested per irc I have composed a new efreet patch that make the trash 
implementation a separate lib (like efreet_mime is). This new patch also use 
the new ecore_file_dir_is_empty(), so 
you need a fresh ecore to test it.
I'm not really sure about the autotools modification I'have made... please 
review it well :P

You can find the new patch attached or you can download it from:
http://www.gurumeditation.it/blog/wp-content/uploads/efreet_trash_support_02.patch

Thanks 
Dave





----- "Dave Andreoli" <[EMAIL PROTECTED]> ha scritto:

> ----- "Nick Hughart" <[EMAIL PROTECTED]> ha scritto:
> 
> > While this is somewhat neat, it might be best to implement this
> into
> > efm 
> > itself.  Having it on a shelf seems a bit strange to me, but it does
> 
> > make things a bit easier.  The only issue I see is it requires a
> dnd
> > and 
> > will not come into play if something deletes a file normally in efm.
> 
> 
> I have done the part in efreet so that we can use it in the fm
> 
> > 
> > Also, I'd drop the internal dnd and just do xdnd for everything. 
> > Since 
> > efm supports xdnd there isn't much need to even deal with internal
> > dnd.  
> 
> xdnd works on top of ednd, I don't know a way to use
> xdnd without the e one ;)
> 
> > Also, you may meet some resistance getting it into efreet.  Even
> > though 
> > it seems to be a haven for FDO specs, some of the authors feel it's
> 
> > scope is a bit smaller then that.  Just a warning :)
> > 
> > Anyway, this is good work and will be helpful.  If there is any way
> to
> > 
> > better tie it into efm that would be good.  I believe adding items
> to
> > 
> > the bottom of the right click context menu is possible by matching
> > with 
> > a glob or mimetype.  So you could just match on every file and it
> > would 
> > add a Trash item to the list.
> 
> and then the fm must also show you the content of the trash. I'm
> waiting 
> to see what append to the fm in the SoC and then we can make the fm
> trash
> compliant.
> 
> 
> > 
> > Dave Andreoli wrote:
> > > HI all !
> > > I have a new module available, it's full freedesktop.org
> compliant
> > trash and as some cool animations.
> > > You can download from
> > > http://www.gurumeditation.it/blog/?page_id=90
> > >
> > > The trash implementation is done in a clean efreet patch that is
> > (IMO) ready for cvs. It include also a simple URI implementation.
> > >
> > > The module (if placed on a shelf) will accept dnd from the efm
> > (internal dnd) and from 
> > > any other application (xdnd). But the xdnd will not work unless
> you
> > do at least one internal dnd (from efm or from a border). Dunno
> why,
> > If someone have idea please let me know.
> > >
> > > Files that are not on the local filesystem can't be trashed and
> the
> > module will ask you if you want to delete permanently those files.
> > >
> > > ...happy testing
> > > Dave
> > >
> > >
> > >
> > >
> > >
> >
> -------------------------------------------------------------------------
> > > Check out the new SourceForge.net Marketplace.
> > > It's the best place to buy or sell services for
> > > just about anything Open Source.
> > > http://sourceforge.net/services/buy/index.php
> > > _______________________________________________
> > > enlightenment-devel mailing list
> > > enlightenment-devel@lists.sourceforge.net
> > > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
> > >
> 
> -------------------------------------------------------------------------
> Check out the new SourceForge.net Marketplace.
> It's the best place to buy or sell services for
> just about anything Open Source.
> http://sourceforge.net/services/buy/index.php
> _______________________________________________
> enlightenment-devel mailing list
> enlightenment-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
Index: configure.in
===================================================================
RCS file: /cvs/e/e17/libs/efreet/configure.in,v
retrieving revision 1.21
diff -u -u -r1.21 configure.in
--- configure.in	19 May 2008 00:07:11 -0000	1.21
+++ configure.in	22 Jun 2008 19:08:20 -0000
@@ -1,6 +1,6 @@
 rm -f config.cache
 
-AC_INIT(efreet, 0.5.0.043, enlightenment-devel@lists.sourceforge.net)
+AC_INIT(efreet, 0.5.0.044, enlightenment-devel@lists.sourceforge.net)
 AC_PREREQ(2.52)
 AC_CONFIG_SRCDIR(configure.in)
 AC_CANONICAL_BUILD
@@ -69,6 +69,7 @@
 efreet.spec
 efreet.pc
 efreet-mime.pc
+efreet-trash.pc
 Makefile
 src/Makefile
 src/lib/Makefile
Index: efreet-trash.pc.in
===================================================================
RCS file: efreet-trash.pc.in
diff -N efreet-trash.pc.in
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ efreet-trash.pc.in	22 Jun 2008 19:08:20 -0000
@@ -0,0 +1,11 @@
[EMAIL PROTECTED]@
[EMAIL PROTECTED]@
[EMAIL PROTECTED]@
[EMAIL PROTECTED]@
+
+Name: efreet-trash
+Description: Freedesktop Shared Trash implementation for the EFL
+Requires: @requirements@
+Version: @VERSION@
+Libs: -L${libdir} -lefreet_trash
+Cflags: -I${includedir}/efreet
Index: doc/head.html
===================================================================
RCS file: /cvs/e/e17/libs/efreet/doc/head.html,v
retrieving revision 1.3
diff -u -u -r1.3 head.html
--- doc/head.html	6 Dec 2007 16:58:41 -0000	1.3
+++ doc/head.html	22 Jun 2008 19:08:20 -0000
@@ -23,6 +23,7 @@
     <table border="0" cellpadding="0" cellspacing="4px">
      <tr>
       <td class='nav'><a class='nav' href="index.html">Main&nbsp;Page</a></td>
+      <td class='nav'><a class='nav' href="modules.html">Modules</a></td>
       <td class="nav"><a class="nav" href="annotated.html">Data&nbsp;Structures</a></td>
       <td class="nav"><a class="nav" href="classes.html">Index</a></td>
      </tr>
Index: src/lib/Efreet.h
===================================================================
RCS file: /cvs/e/e17/libs/efreet/src/lib/Efreet.h,v
retrieving revision 1.4
diff -u -u -r1.4 Efreet.h
--- src/lib/Efreet.h	4 Nov 2007 09:32:35 -0000	1.4
+++ src/lib/Efreet.h	22 Jun 2008 19:08:20 -0000
@@ -22,6 +22,7 @@
  * @li Icon Theme Specification
  * @li Desktop Entry Specification
  * @li Desktop Menu Specification
+ * @li Trash Specification
  */
 
 #ifdef EAPI
Index: src/lib/Efreet_Trash.h
===================================================================
RCS file: src/lib/Efreet_Trash.h
diff -N src/lib/Efreet_Trash.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/lib/Efreet_Trash.h	22 Jun 2008 19:08:20 -0000
@@ -0,0 +1,82 @@
+/* vim: set sw=4 ts=4 sts=4 et: */
+#ifndef EFREET_TRASH_H
+#define EFREET_TRASH_H
+
+/**
+ * @file efreet_trash.h
+ * @brief Contains the methods used to support the FDO trash specification.
+ * @addtogroup Efreet_Trash Efreet_Trash: The XDG Trash Specification
+ * Some better explanation here...
+ * @{
+ */
+
+#ifdef EAPI
+#undef EAPI
+#endif
+#ifdef _MSC_VER
+# ifdef BUILDING_DLL
+#  define EAPI __declspec(dllexport)
+# else
+#  define EAPI __declspec(dllimport)
+# endif
+#else
+# ifdef __GNUC__
+#  if __GNUC__ >= 4
+#   define EAPI __attribute__ ((visibility("default")))
+#  else
+#   define EAPI
+#  endif
+# else
+#  define EAPI
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @{
+ */
+
+/**
+ * Efreet_Uri
+ */
+typedef struct Efreet_Uri Efreet_Uri;
+
+/**
+ * Efreet_Uri
+ * @brief Contains a simple rappresentation of an uri. The string don't have 
+ * special chars escaped.
+ */
+struct Efreet_Uri
+{
+    const char *protocol;   /**< The name of the host if any, or NULL */
+    const char *hostname;   /**< The name of the host if any, or NULL */
+    const char *path;       /**< The full file path whitout protocol nor host*/
+};
+
+
+EAPI const char *efreet_uri_escape(Efreet_Uri *uri);
+EAPI Efreet_Uri *efreet_uri_parse(const char *val);
+EAPI void        efreet_uri_free(Efreet_Uri *uri);
+
+int              efreet_trash_init(void);
+void             efreet_trash_shutdown(void);
+
+EAPI const char *efreet_trash_dir_get(void);
+EAPI int         efreet_trash_delete_uri(Efreet_Uri *uri, int force_delete);
+EAPI Ecore_List *efreet_trash_ls(void);
+EAPI int         efreet_trash_is_empty(void);
+EAPI int         efreet_trash_empty_trash(void);
+   
+   
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: src/lib/Makefile.am
===================================================================
RCS file: /cvs/e/e17/libs/efreet/src/lib/Makefile.am,v
retrieving revision 1.10
diff -u -u -r1.10 Makefile.am
--- src/lib/Makefile.am	4 Nov 2007 10:28:23 -0000	1.10
+++ src/lib/Makefile.am	22 Jun 2008 19:08:20 -0000
@@ -6,7 +6,7 @@
 -I$(top_srcdir) \
 @ECORE_CFLAGS@
 
-lib_LTLIBRARIES = libefreet.la libefreet_mime.la
+lib_LTLIBRARIES = libefreet.la libefreet_mime.la libefreet_trash.la
 
 EFREETHEADERS = \
 Efreet.h \
@@ -43,10 +43,23 @@
 libefreet_mime_la_SOURCES = \
 $(EFREETMIMESOURCES)
 
+
+EFREETTRASHHEADERS = \
+Efreet_Trash.h
+
+EFREETTRASHSOURCES = \
+efreet_trash.c \
+$(EFREETTRASHHEADERS)
+
+libefreet_trash_la_SOURCES = \
+$(EFREETTRASHSOURCES)
+
+
 installed_headersdir = $(prefix)/include/efreet
-installed_headers_DATA = $(EFREETHEADERS) $(EFREETMIMEHEADERS)
+installed_headers_DATA = $(EFREETHEADERS) $(EFREETMIMEHEADERS) $(EFREETTRASHHEADERS)
 
 libefreet_la_LIBADD = @ECORE_LIBS@
 libefreet_la_LDFLAGS = -version-info @version_info@
 
 libefreet_mime_la_LIBADD = @ECORE_LIBS@ libefreet.la
+libefreet_trash_la_LIBADD = @ECORE_LIBS@ libefreet.la
Index: src/lib/efreet_trash.c
===================================================================
RCS file: src/lib/efreet_trash.c
diff -N src/lib/efreet_trash.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/lib/efreet_trash.c	22 Jun 2008 19:08:20 -0000
@@ -0,0 +1,318 @@
+/* vim: set sw=4 ts=4 sts=4 et: */
+#include <errno.h>
+#include <time.h>
+#include "Efreet.h"
+#include "Efreet_Trash.h"
+#include "efreet_private.h"
+
+static const char *efreet_trash_dir = NULL;
+
+/**
+ * @internal
+ * @return Returns 1 on success or 0 on failure
+ * @brief Initializes the efreet trash system
+ */
+int
+efreet_trash_init(void)
+{
+    return 1;
+}
+
+/**
+ * @internal
+ * @return Returns no value
+ * @brief Cleans up the efreet trash system
+ */
+void
+efreet_trash_shutdown(void)
+{
+    IF_RELEASE(efreet_trash_dir);
+}
+
+/**
+ * @return Returns the XDG Trash local directory or NULL on errors
+ * @brief Retrieves the XDG Trash local directory
+ */
+EAPI const char*
+efreet_trash_dir_get(void)
+{
+    char buf[PATH_MAX];
+
+    if (efreet_trash_dir && ecore_file_exists(efreet_trash_dir))
+        return efreet_trash_dir;
+
+    snprintf(buf, sizeof(buf), "%s/Trash", efreet_data_home_get());
+    if (!ecore_file_exists(buf) && !ecore_file_mkpath(buf))
+        return NULL;
+
+    IF_RELEASE(efreet_trash_dir);
+    efreet_trash_dir = ecore_string_instance(buf);
+
+    snprintf(buf, sizeof(buf), "%s/files", efreet_trash_dir);
+    if (!ecore_file_exists(buf) && !ecore_file_mkpath(buf))
+        return NULL;
+
+    snprintf(buf, sizeof(buf), "%s/info", efreet_trash_dir);
+    if (!ecore_file_exists(buf) && !ecore_file_mkpath(buf))
+        return NULL;
+
+    return efreet_trash_dir;
+}
+
+/**
+ * @param uri: The local uri to move in the trash
+ * @param force_delete: If you set this to 1 than files on different filesystems
+ * will be deleted permanently
+ * @return Return 1 on success, 0 on failure or -1 in case the uri is not on the
+ * same filesystem and force_delete is not set.
+ * @brief This function try to move the given uri to the trash. Files on 
+ * different filesystem can't be moved to trash. If force_delete
+ * is 0 than non-local files will be ignored and -1 is returned, if you set
+ * force_delete to 1 non-local files will be deleted without asking.
+ */
+EAPI int
+efreet_trash_delete_uri(Efreet_Uri *uri, int force_delete)
+{
+    char dest[PATH_MAX];
+    char times[64];
+    const char *fname;
+    const char *escaped;
+    int i = 1;
+    time_t now;
+    FILE *f;
+
+    if (!uri || !uri->path || !ecore_file_can_write(uri->path)) return 0;
+
+    fname = ecore_file_file_get(uri->path);
+    snprintf(dest, PATH_MAX, "%s/files/%s", efreet_trash_dir_get(), fname);
+
+    /* search for a free filename */
+    while (ecore_file_exists(dest))
+        snprintf(dest, PATH_MAX, "%s/files/%s$%d",
+                 efreet_trash_dir_get(), fname, i++);
+    fname = ecore_file_file_get(dest);
+
+    /* move file to trash dir */
+    if (rename(uri->path, dest))
+    {
+        if (errno == EXDEV)
+        {
+            if (!force_delete) return -1;
+            if (!ecore_file_recursive_rm(uri->path))
+            {
+                printf("EFREET TRASH ERROR: Can't delete file.\n");
+                return 0; 
+            }
+        }
+        else
+        {
+            printf("EFREET TRASH ERROR: Can't move file to trash.\n");
+            return 0;
+        }
+    }
+   
+      
+    /* create info file */
+    snprintf(dest, PATH_MAX, "%s/info/%s.trashinfo",
+             efreet_trash_dir_get(), fname);
+
+    if (f = fopen(dest, "w"))
+    {
+        fputs("[Trash Info]\n", f); //TODO is '\n' right?? (or \r\c??)
+
+        fputs("Path=", f);
+        escaped = efreet_uri_escape(uri);
+        fputs(escaped + 7, f); // +7 == don't write 'file://'
+        IF_RELEASE(escaped);
+
+        time(&now);
+        strftime(times, sizeof(times), "%Y-%m-%dT%H:%M:%S", localtime(&now));
+        fputs("\nDeletionDate=", f);
+        fputs(times, f);
+        fputs("\n", f);
+        fclose(f);
+    }
+    else
+    {
+        printf("EFREET TRASH ERROR: Can't create trash info file.\n");
+        return 0;
+    }
+
+    return 1;
+}
+
+/**
+ * @return Return 1 if the trash is empty or 0 if some file are in.
+ * @brief Check if the trash is currently empty
+ */
+EAPI int
+efreet_trash_is_empty(void)
+{
+    char buf[PATH_MAX];
+    snprintf(buf, PATH_MAX, "%s/files", efreet_trash_dir_get());
+   
+    /* TODO Check also trash in other filesystems */
+    return ecore_file_dir_is_empty(buf);
+}
+
+/**
+ * @return Return 1 on success or 0 on failure
+ * @brief Delete all the files inside the trash.
+ */
+EAPI int
+efreet_trash_empty_trash(void)
+{
+    char buf[PATH_MAX];
+
+    snprintf(buf, PATH_MAX, "%s/info", efreet_trash_dir_get());
+    if (!ecore_file_recursive_rm(buf)) return 0;
+    ecore_file_mkdir(buf);
+
+    snprintf(buf, PATH_MAX, "%s/files", efreet_trash_dir_get());
+    if (!ecore_file_recursive_rm(buf)) return 0;
+    ecore_file_mkdir(buf);
+
+    /* TODO Empty also trash in other filesystems */
+    return 1;
+}
+
+/**
+ * @return Return a list of strings with filename (remember to free the list
+ * when you don't need anymore)
+ * @brief List all the files and directory currently inside the trash.
+ */
+EAPI Ecore_List*
+efreet_trash_ls(void)
+{
+    char *infofile;
+    char buf[PATH_MAX];
+    Ecore_List *files;
+
+    // NOTE THIS FUNCTION NOW IS NOT COMPLETE AS I DON'T NEED IT
+    // TODO read the name from the infofile instead of the filename
+
+    snprintf(buf, PATH_MAX, "%s/files", efreet_trash_dir_get());
+    files = ecore_file_ls(buf);
+
+    while (infofile = ecore_list_next(files))
+    {
+        printf("FILE: %s\n", infofile);
+    }
+
+    return files;
+}
+
+
+/**
+ * @param val: a valid uri string to parse
+ * @return Return The corresponding Efreet_Uri structure. Or NULL on errors.
+ * @brief Parse a single uri and return an Efreet_Uri struct. If there's no
+ * hostname in the uri then the hostname parameter is NULL. All the uri escaped
+ * chars will be converted back.
+ */
+EAPI Efreet_Uri *
+efreet_uri_parse(const char *val)
+{
+    Efreet_Uri *uri;
+    const char *p;
+    char protocol[64], hostname[PATH_MAX], path[PATH_MAX];
+    int i = 0;
+
+    /* An uri should be in the form <protocol>://<hostname>/<path> */
+    p = strstr(val, "://");
+    if (!p) return NULL;
+
+    memset(protocol, 0, 64);
+    memset(hostname, 0, PATH_MAX);
+    memset(path, 0, PATH_MAX);
+
+    /* parse protocol */
+    p = val;
+    for (i = 0; *p != ':' && *p != '\0' && i < _POSIX_HOST_NAME_MAX; p++, i++)
+         protocol[i] = *p;
+    protocol[i] = '\0';
+
+    /* parse hostname */
+    p += 3;
+    if (*p != '/')
+    {
+        for (i = 0; *p != '/' && *p != '\0' && i < _POSIX_HOST_NAME_MAX; p++, i++)
+            hostname[i] = *p;
+        hostname[i] = '\0';
+    }
+    else
+        hostname[0] = '\0';
+
+    /* parse path */
+    /* See http://www.faqs.org/rfcs/rfc1738.html for the escaped chars */
+    for (i = 0; *p != '\0' && i < PATH_MAX; i++, p++)
+    {
+        if (*p == '%')
+        {
+            path[i] = *(++p);
+            path[i+1] = *(++p);
+            path[i] = (char)strtol(&(path[i]), NULL, 16);
+            path[i+1] = '\0';
+        }
+        else
+            path[i] = *p;
+    }
+
+    uri = NEW(Efreet_Uri, 1);
+    if (!uri) return NULL;
+
+    uri->protocol = ecore_string_instance(protocol);
+    uri->hostname = ecore_string_instance(hostname);
+    uri->path = ecore_string_instance(path);
+
+    return uri;
+}
+
+/**
+ * @param uri: The uri structure to escape
+ * @return The string rapresentation of an uri (ex: 'file:///home/my%20name')
+ * @brief Get the string rapresentation of the given uri struct escaping
+ * illegal caracters. The resulting string will contain the protocol but not the
+ * hostname, as many apps doesn't handle it.
+ */
+EAPI const char *
+efreet_uri_escape(Efreet_Uri *uri)
+{
+    char dest[PATH_MAX * 3 + 4];
+    const char *p;
+    int i;
+
+    if (!uri || !uri->path || !uri->protocol) return NULL;
+    memset(dest, 0, PATH_MAX * 3 + 4);
+    snprintf(dest, strlen(uri->protocol)+4, "%s://", uri->protocol);
+
+
+    /* Most app doesn't handle the hostname in the uri so it's put to NULL */
+    for (i = strlen(uri->protocol) + 3, p = uri->path; *p != '\0'; p++, i++)
+    {
+        if (isalnum(*p) || strchr("/$-_.+!*'()", *p))
+            dest[i] = *p;
+        else
+        {
+            snprintf(&(dest[i]), 4, "%%%02X", *p);
+            i += 2;
+        }
+    }
+
+    return ecore_string_instance(dest);
+}
+
+/**
+ * @param uri: The uri to free
+ * @brief Free the given uri structure.
+ */
+EAPI void
+efreet_uri_free(Efreet_Uri *uri)
+{
+    if (!uri) return;
+    IF_RELEASE(uri->protocol);
+    IF_RELEASE(uri->path);
+    IF_RELEASE(uri->hostname);
+    free(uri);
+    uri = NULL;
+}
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to