This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch master
in repository efm2.
View the commit online.
commit 90609d695442a602066c67651eb023536ebebf00
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
AuthorDate: Wed Apr 9 15:57:08 2025 +0100
implement ln as an op (need to use alt when dropping for ask menu)
---
src/backends/default/cp.c | 14 ++--
src/backends/default/fs.c | 3 +-
src/backends/default/ln.c | 177 +++++++++++++++++++++++++++++++++++++++
src/backends/default/meson.build | 14 +++-
src/backends/default/open.c | 3 +-
src/efm/efm_dnd.c | 29 ++++---
src/efm/efm_util.c | 1 +
7 files changed, 218 insertions(+), 23 deletions(-)
diff --git a/src/backends/default/cp.c b/src/backends/default/cp.c
index c8832c3..4c76ffe 100644
--- a/src/backends/default/cp.c
+++ b/src/backends/default/cp.c
@@ -45,7 +45,7 @@ file_set_add(Eina_List *files, const char *src, const char *dst)
int
main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
-{ // mv [src] [dstdir]
+{ // cp [src] [dstdir]
const char *fname, *home_dir;
Eina_Strbuf *buf = NULL;
Eina_List *files = NULL, *l;
@@ -108,7 +108,7 @@ main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
status_begin();
status_op("cp");
- // build up a list of all files to mv and scan them to find how much
+ // build up a list of all files to cp and scan them to find how much
EINA_LIST_FOREACH(files, l, fs)
{
struct stat stsrc, stdst;
@@ -175,7 +175,7 @@ main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
if ((!src) || (!srctmpdir) || (!dst) || (!dsttmpdir) || (!dsttmpfile))
mem_abort();
- // can we modify the meta files in the src? (like mv/rm them?)
+ // can we modify the meta files in the src? (like cp/rm them?)
src_can_write = meta_path_can_write(src);
dst_can_write = meta_path_can_write(dst);
@@ -191,7 +191,7 @@ main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
}
umask(prev_umask);
- // mv the file to a tmp file: mv /srcdir/filename /dstdir/.efm/filename.tmp
+ // cp the file to a tmp file: cp /srcdir/filename /dstdir/.efm/filename.tmp
if (fs_cp(src, dsttmpfile, EINA_TRUE))
{ // it worked so deal with meta/thumbs
char *src_meta, *dst_meta;
@@ -220,7 +220,7 @@ main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
status_count(1, src_meta);
fs_cp(src_meta, dst_meta, EINA_FALSE);
// fix up the oprig stat info to match so thub is valid
- // get stat info of new mv'd file
+ // get stat info of new cp'd file
if (stat(dsttmpfile, &st) == 0)
{
Eet_File *ef;
@@ -243,7 +243,7 @@ main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
free(src_meta);
free(dst_meta);
- // rename atomically the tmp mv'd file to its dest now thumb and meta
+ // rename atomically the tmp cp'd file to its dest now thumb and meta
// are ok/valid. i.e.
// mv /dstdir/.efm/filename.tmp /distdir/filename
ret = rename(dsttmpfile, dst);
@@ -282,4 +282,4 @@ err:
eet_shutdown();
eina_shutdown();
return 0;
-}
\ No newline at end of file
+}
diff --git a/src/backends/default/fs.c b/src/backends/default/fs.c
index 5028f92..0aa89ae 100644
--- a/src/backends/default/fs.c
+++ b/src/backends/default/fs.c
@@ -471,7 +471,8 @@ fs_cp(const char *src, const char *dst, Eina_Bool report_err)
return res;
}
-Eina_Bool fs_ln(const char *src, const char *dst, Eina_Bool report_err)
+Eina_Bool
+fs_ln(const char *src, const char *dst, Eina_Bool report_err)
{ // ln -s /path/to/src/filename /path/to/dst/filename
Eina_Bool res = EINA_TRUE;
const char *op = "Symlink";
diff --git a/src/backends/default/ln.c b/src/backends/default/ln.c
new file mode 100644
index 0000000..8599876
--- /dev/null
+++ b/src/backends/default/ln.c
@@ -0,0 +1,177 @@
+#include <Eina.h>
+#include <Ecore.h>
+#include <Ecore_File.h>
+#include <Efreet.h>
+#include <Efreet_Mime.h>
+#include <Eet.h>
+
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "meta.h"
+#include "status.h"
+#include "fs.h"
+#include "esc.h"
+#include "sha.h"
+
+static const char *config_dir = NULL;
+
+typedef struct _File_Set
+{
+ const char *src, *dst;
+} File_Set;
+
+static void
+mem_abort(void)
+{
+ fprintf(stderr, "Out of memory!\n");
+ abort();
+}
+
+static Eina_List *
+file_set_add(Eina_List *files, const char *src, const char *dst)
+{
+ File_Set *fs = calloc(1, sizeof(File_Set));
+ if (!fs) mem_abort();
+ fs->src = ""
+ fs->dst = eina_stringshare_add(dst);
+ if ((!fs->src) || (!fs->dst)) mem_abort();
+ files = eina_list_append(files, fs);
+ return files;
+}
+
+int
+main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
+{ // ln [src] [dstdir]
+ const char *fname, *home_dir;
+ Eina_Strbuf *buf = NULL;
+ Eina_List *files = NULL, *l;
+ File_Set *fs;
+ size_t sz;
+ char *src = ""
+ char *dst = NULL, *dstfile = NULL;
+ char sbuf[PATH_MAX + 256];
+ int ret;
+ struct stat st;
+
+ eina_init();
+ eet_init();
+ ecore_init();
+ efreet_init();
+
+ for (;;)
+ { // read stdin of key=val\n ... or end\n
+ if (!fgets(sbuf, sizeof(sbuf), stdin)) break;
+ sz = strlen(sbuf);
+ if (sz < 1) break; // too small
+ if (sbuf[sz - 1] == '\n') sbuf[sz - 1] = '\0'; // remove \n if there
+ if (!strncmp(sbuf, "src="" 4))
+ {
+ if (src) free(src);
+ src = "" + 4);
+ }
+ else if (!strncmp(sbuf, "dst=", 4))
+ {
+ if (dst) free(dst);
+ dst = unescape(sbuf + 4);
+ if ((src) && (dst)) files = file_set_add(files, src, dst);
+ if (src) free(src);
+ if (dst) free(dst);
+ src = ""
+ dst = NULL;
+ }
+ else if (!strcmp(sbuf, "end")) break;
+ }
+ if (src) free(src);
+ if (dst) free(dst);
+ src = "" = NULL;
+
+ config_dir = getenv("E_HOME_DIR");
+ home_dir = getenv("HOME");
+ if (!home_dir) return 77; // no $HOME? definitely an error!
+ if (!config_dir)
+ {
+ snprintf(sbuf, sizeof(sbuf), "%s/.e/e", home_dir);
+ config_dir = eina_stringshare_add(sbuf);
+ }
+ meta_init(config_dir);
+
+ buf = eina_strbuf_new();
+ if (!buf) goto err;
+
+ // set up status files for the op
+ status_begin();
+ status_op("ln");
+
+ // build up a list of all files to cp and scan them to find how much
+ EINA_LIST_FOREACH(files, l, fs)
+ {
+ struct stat stsrc, stdst;
+
+ if (strlen(fs->src) < 1) goto err2;
+ if (lstat(fs->src, &stsrc) != 0) break;
+ if (lstat(fs->dst, &stdst) != 0) break;
+ if (stsrc.st_dev == stdst.st_dev) status_count(1, fs->src);
+ else if (!fs_scan(fs->src)) goto err2;
+ }
+
+ EINA_LIST_FOREACH(files, l, fs)
+ {
+ fname = ecore_file_file_get(fs->src);
+ if (!fname) break;
+ // when monitoring/watching a status file dst dst=xxx allows you to place
+ // progress in the right dst dir
+ status_dst(fs->dst);
+ ret = stat(fs->dst, &st);
+ if (ret != 0)
+ { // if we can't stat the dstdir then we have issues
+ status_error(fs->src, fs->dst, "Cannot stat destination");
+ break;
+ }
+
+ // free up previous loop stuff
+ free(dstfile);
+ src = "" = NULL;
+
+ src = ""
+
+ eina_strbuf_reset(buf);
+ eina_strbuf_append(buf, fs->dst);
+ eina_strbuf_append(buf, "/");
+ eina_strbuf_append(buf, fname);
+ dstfile = strdup(eina_strbuf_string_get(buf));
+ if ((!dstfile)) mem_abort();
+
+ // ln the file with full path - that's just what we will do
+ if (fs_ln(src, dstfile, EINA_TRUE))
+ { // it worked
+ status_count(1, src);
+ }
+ else break;
+ }
+err2:
+ status_end();
+ // free up leftover strings from loop
+ free(src);
+ free(dstfile);
+
+err:
+ if (buf) eina_strbuf_free(buf);
+ EINA_LIST_FREE(files, fs)
+ {
+ eina_stringshare_del(fs->src);
+ eina_stringshare_del(fs->dst);
+ free(fs);
+ }
+
+ meta_shutdown();
+
+ efreet_shutdown();
+ ecore_shutdown();
+ eet_shutdown();
+ eina_shutdown();
+ return 0;
+}
diff --git a/src/backends/default/meson.build b/src/backends/default/meson.build
index 10bfec4..53972f9 100644
--- a/src/backends/default/meson.build
+++ b/src/backends/default/meson.build
@@ -63,4 +63,16 @@ executable('cp', [
dependencies: deps,
install: true,
install_dir: dir)
-
\ No newline at end of file
+executable('ln', [
+ '../../shared/sha.c',
+ '../../shared/esc.c',
+ '../../shared/util.c',
+ 'fs.c',
+ 'ln.c',
+ 'meta.c',
+ 'status.c'
+ ],
+ include_directories: inc,
+ dependencies: deps,
+ install: true,
+ install_dir: dir)
diff --git a/src/backends/default/open.c b/src/backends/default/open.c
index 6ff7a6b..492dcce 100644
--- a/src/backends/default/open.c
+++ b/src/backends/default/open.c
@@ -1346,7 +1346,8 @@ _handle_drop_paste(const char *over, const char *action, Eina_List *files)
_op_run("mv", files, mondir);
}
else if (!strcmp(action, "link"))
- { // XXX: implement
+ {
+ _op_run("ln", files, mondir);
}
else // "ask", "list", "description", or anything else
{ // actully we should never get this
diff --git a/src/efm/efm_dnd.c b/src/efm/efm_dnd.c
index a98d397..6bfb638 100644
--- a/src/efm/efm_dnd.c
+++ b/src/efm/efm_dnd.c
@@ -157,15 +157,18 @@ _dnd_drop_handle(Smart_Data *sd, char *urilist, Elm_Xdnd_Action act)
fprintf(stderr, "XXX: LINK\n");
cmd_strbuf_append(buf, "action", "link");
break;
- /* here for documentation but not used
- case ELM_XDND_ACTION_ASK:
- break;
- case ELM_XDND_ACTION_LIST:
- break;
- case ELM_XDND_ACTION_DESCRIPTION:
- break;
- */
+ // should not see ask as it should have been handled already, but others
+ // are possivble, but not supported
+ case ELM_XDND_ACTION_ASK: // for documentation
+ // fallthrough
+ case ELM_XDND_ACTION_LIST: // for documentation
+ // fallthrough
+ case ELM_XDND_ACTION_DESCRIPTION: // for documentation
+ // fallthrough
default:
+ if (act == ELM_XDND_ACTION_ASK) fprintf(stderr, "XXX: ASK\n");
+ else if (act == ELM_XDND_ACTION_LIST) fprintf(stderr, "XXX: LIST\n");
+ else if (act == ELM_XDND_ACTION_DESCRIPTION) fprintf(stderr, "XXX: DESCRIPTION\n");
eina_strbuf_free(buf);
sd->drop_over = NULL;
return;
@@ -362,15 +365,15 @@ _cb_drop(void *data, Evas_Object *o EINA_UNUSED, Elm_Selection_Data *ev)
memcpy(tmp, ev->data, ev->len);
tmp[ev->len] = 0;
if (act == ELM_XDND_ACTION_ASK)
- {
- // XXX: store tmp as urilist and pop up ask menu
+ { // store tmp as urilist and pop up ask menu
Efm_Menu *m
= _efm_menu_add("What to do?", NULL, _cb_menu_dnd_ask_done, sd, NULL);
- _efm_menu_it_normal(m, "Copy", NULL, _cb_menu_dnd_drop_copy, sd, NULL);
- _efm_menu_it_normal(m, "Move", NULL, _cb_menu_dnd_drop_move, sd, NULL);
- _efm_menu_it_normal(m, "Link", NULL, _cb_menu_dnd_drop_link, sd, NULL);
+ _efm_menu_it_normal(m, "Copy", "std:folder-copy", _cb_menu_dnd_drop_copy, sd, NULL);
+ _efm_menu_it_normal(m, "Move", "std:folder-move", _cb_menu_dnd_drop_move, sd, NULL);
+ _efm_menu_it_normal(m, "Link", "std:insert-link", _cb_menu_dnd_drop_link, sd, NULL);
_efm_menu_show(sd->o_smart, m, sd->dnd_x, sd->dnd_y);
sd->dnd_drop_data = tmp;
+ printf("XXX: drop action modified to ask by modifier key\n");
}
else
{ // handle dnd here as we know the action
diff --git a/src/efm/efm_util.c b/src/efm/efm_util.c
index fb2b57b..6c0858b 100644
--- a/src/efm/efm_util.c
+++ b/src/efm/efm_util.c
@@ -1355,6 +1355,7 @@ _cb_icon_mouse_move(void *data, Evas *e EINA_UNUSED,
// XXX: this "except to/from removable drive" is bad/inconsistent imho
if (ev->buttons & (1 << 2)) // right mouse pressed
action = ""
+ printf("XXX: ASK = %i\n", action == EFM_ACTION_ASK);
_drag_start(icon, action);
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.