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 bafceaf95678b2b37c092300b9742109cc3779b9
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
AuthorDate: Sun Oct 1 12:19:13 2023 +0100
add sample table backend with detail text view and custom dir backends
---
src/backends/default/open.c | 49 ++++++++++++++++++++
src/backends/meson.build | 1 +
src/backends/table/meson.build | 5 ++
src/backends/table/open | 103 +++++++++++++++++++++++++++++++++++++++++
src/efm/efm.c | 16 +++++++
src/efm/efm_back_end.c | 71 +++++++++++++++++++++++++---
src/efm/efm_private.h | 4 ++
src/efm/efm_structs.h | 1 +
src/efm/efm_util.c | 9 ++--
src/efm/main.c | 48 ++++++++++---------
src/shared/common/cmd.c | 54 +++++++--------------
11 files changed, 292 insertions(+), 69 deletions(-)
diff --git a/src/backends/default/open.c b/src/backends/default/open.c
index 5d1474f..5638025 100644
--- a/src/backends/default/open.c
+++ b/src/backends/default/open.c
@@ -856,15 +856,64 @@ _cb_mon(void *data EINA_UNUSED, Ecore_File_Monitor *em EINA_UNUSED,
else if (event == ECORE_FILE_EVENT_DELETED_SELF) _dir_del(path);
}
+static Eina_Bool
+_backend_check(const char *backend)
+{
+ const char *s;
+
+ if (!backend) return EINA_FALSE;
+ for (s = backend; *s; s++)
+ {
+ if (!(((*s >= 'a') && (*s <= 'z')) ||
+ ((*s >= 'A') && (*s <= 'Z')) ||
+ ((*s >= '0') && (*s <= '9')) ||
+ (*s >= '-') ||
+ (*s >= '_') ||
+ (*s >= '.')))
+ return EINA_FALSE;
+ }
+ return EINA_TRUE;
+}
+
static void
_monitor(const char *path)
{
Eina_Iterator *it;
Eina_File_Direct_Info *info;
Eina_Strbuf *strbuf;
+ Efreet_Ini *ini;
+ Eina_Bool abort_list = EINA_FALSE;
if (mon) return;
+ // is it a custom backend in this dir? XXX this is a security issue to
+ // solve in future (front end?)
+ strbuf = eina_strbuf_new();
+ eina_strbuf_append(strbuf, path);
+ eina_strbuf_append(strbuf, ".efm/.efm");
+ ini = efreet_ini_new(eina_strbuf_string_get(strbuf));
+ if (ini)
+ {
+ if ((ini->data) && (efreet_ini_section_set(ini, "Efm Dir")))
+ {
+ const char *backend = eina_hash_find(ini->section, "backend");
+
+ if (_backend_check(backend))
+ {
+ eina_strbuf_free(strbuf);
+ strbuf = cmd_strbuf_new("backend-set");
+ cmd_strbuf_append(strbuf, "backend", backend);
+ cmd_strbuf_print_consume(strbuf);
+ strbuf = NULL;
+ abort_list = EINA_TRUE;
+ }
+ }
+ efreet_ini_free(ini);
+ }
+ if (strbuf) eina_strbuf_free(strbuf);
+
+ if (abort_list) return;
+
// tell the front end out listing is beginning
strbuf = cmd_strbuf_new("list-begin");
cmd_strbuf_print_consume(strbuf);
diff --git a/src/backends/meson.build b/src/backends/meson.build
index 7cd9a71..aeb7a53 100644
--- a/src/backends/meson.build
+++ b/src/backends/meson.build
@@ -1 +1,2 @@
subdir('default')
+subdir('table')
diff --git a/src/backends/table/meson.build b/src/backends/table/meson.build
new file mode 100644
index 0000000..23e9fef
--- /dev/null
+++ b/src/backends/table/meson.build
@@ -0,0 +1,5 @@
+dir = join_paths(dir_lib, 'efm', 'backends', 'default')
+install_data('open',
+ install_dir : dir,
+ install_mode : 'rwxr-xr-x'
+ )
diff --git a/src/backends/table/open b/src/backends/table/open
new file mode 100755
index 0000000..556723c
--- /dev/null
+++ b/src/backends/table/open
@@ -0,0 +1,103 @@
+#!/bin/bash
+
+# global state
+DIR=""
+
+function err() {
+ >&2 echo $@
+}
+
+function val_unescape() {
+ local -n V=$1
+ read <<< ${2}
+ V=$( echo -e ${REPLY//%/\\x} );
+}
+
+function val_escape() {
+ local -n V=$1
+ local STR=${2}
+ local STRLEN=${#STR}
+ local NEWSTR=""
+ local I CHR OUT
+
+ for (( I=0; I<$STRLEN; I++ )); do
+ CHR=${STR:$I:1}
+ case "$CHR" in
+ [-/.a-zA-Z0-9] ) OUT="${CHR}" ;;
+ * ) printf -v OUT '%%%02x' "'$CHR"
+ esac
+ NEWSTR+="${OUT}"
+ done
+ V=${NEWSTR}
+}
+
+function line_read() {
+ local -n V=${1}
+ local PIFS="$IFS"
+ IFS=" "
+ read -a V
+ IFS="$PIFS"
+# check command line starts with CMD
+ if [ ${V[0]} != "CMD" ]; then return 1; fi
+ return 0
+}
+
+function handle_cmd_dir_set() {
+ echo "CMD viewmode-set mode=list_detailed"
+ echo "CMD detail-header-set col=0 label=nomnom"
+ echo "CMD detail-header-set col=1 label=h-one"
+ echo "CMD detail-header-set col=2 label=h-two"
+ echo "CMD detail-header-set col=3 label=h-three"
+ echo "CMD detail-header-set col=4 label=h-four"
+ echo "CMD detail-header-set col=5 label=h-five"
+ echo "CMD detail-header-set col=6 label=h-six"
+ echo "CMD list-begin"
+ D="detailtext=yes detail1=one detail2=two detail3=three detail4=four detail5=five detail6=six"
+ val_escape F ${DIR}"abba"
+ val_escape M ${DIR}"ic.jpg"
+ M="type=file icon="${M}
+ err "CMD file-add path="${F}" "${M}" "${D}
+ echo "CMD file-add path="${F}" "${M}" "${D}
+ val_escape F ${DIR}"boopy__==!@#$%^&*();"
+ echo "CMD file-add path="${F}" "${M}" "${D}
+ val_escape F ${DIR}"g h i"
+ echo "CMD file-add path="${F}" "${M}" "${D}
+ val_escape F ${DIR}"z~"
+ echo "CMD file-add path="${F}" "${M}" "${D}
+ echo "CMD list-end"
+}
+
+function handle_cmd() {
+ local -n ARGS=${1}
+ local ARGSLEN=${#ARGS[@]}
+ CMD=${2}
+ case "$CMD" in
+ dir-set )
+ echo "dir set ["${ARGS[0]}"] len="${ARGSLEN}
+ if [ ${ARGS[0]} = "path" ]; then
+ DIR=${ARGS[1]}
+ handle_cmd_dir_set ${DIR}
+ fi
+ ;;
+ esac
+}
+
+# loop parsing input lines
+while [ 1 ]; do
+ if line_read LINE; then
+ CMD=${LINE[1]}
+ ARGS=("${LINE[@]:2}")
+ ARGSLEN=${#LINE[@]}
+ NEWARGS=()
+ for (( I=0; I<$ARGSLEN; I++ )); do
+ PIFS="$IFS"; IFS="="
+ read -a A <<< ${ARGS[$I]}
+ IFS="$PIFS"
+ KEY=${A[0]}
+ val_unescape VAL ${A[1]}
+ NEWARGS+=(${KEY})
+ NEWARGS+=(${VAL})
+ done
+ handle_cmd NEWARGS "$CMD"
+ fi
+done
diff --git a/src/efm/efm.c b/src/efm/efm.c
index 81c29bc..d9ca4a4 100644
--- a/src/efm/efm.c
+++ b/src/efm/efm.c
@@ -54,6 +54,15 @@ static void _cb_canvas_resize(void *data, Evas *e,
static void _reposition_detail_header_items(Smart_Data *sd);
static void _recalc(Smart_Data *sd);
+static void
+_cb_header_change(void *data)
+{
+ Smart_Data *sd = data;
+
+ sd->header_change_job = NULL;
+ evas_object_smart_callback_call(sd->o_smart, "header_change", NULL);
+}
+
static void
_cb_lost_selection(void *data, Elm_Sel_Type selection EINA_UNUSED)
{
@@ -836,6 +845,11 @@ _smart_del(Evas_Object *obj)
ecore_job_del(sd->size_max_update_job);
sd->size_max_update_job = NULL;
}
+ if (sd->header_change_job)
+ {
+ ecore_job_del(sd->header_change_job);
+ sd->header_change_job = NULL;
+ }
if (sd->drag_icon)
{
if (sd->o_scroller) elm_drag_cancel(sd->o_scroller);
@@ -1776,6 +1790,8 @@ efm_path_view_mode_set(Evas_Object *obj, Efm_View_Mode mode)
evas_object_show(sd->o_list_detail[i]);
else evas_object_hide(sd->o_list_detail[i]);
}
+ if (sd->header_change_job) ecore_job_del(sd->header_change_job);
+ sd->header_change_job = ecore_job_add(_cb_header_change, sd);
_reset(sd);
}
diff --git a/src/efm/efm_back_end.c b/src/efm/efm_back_end.c
index cf686aa..5accd9c 100644
--- a/src/efm/efm_back_end.c
+++ b/src/efm/efm_back_end.c
@@ -422,6 +422,71 @@ _cb_thread_notify(void *data, Ecore_Thread *th EINA_UNUSED, void *msg)
sd->listing_done_reblock = EINA_TRUE;
CMD_DONE;
}
+ else if (!strcmp(c->command, "backend-set"))
+ { // *** must call before list-begin
+ const char *backend = cmd_key_find(c, "backend");
+
+ if (backend)
+ {
+ eina_stringshare_replace(&(sd->config.backend), backend);
+ _reset(sd);
+ }
+ CMD_DONE;
+ }
+ else if (!strcmp(c->command, "viewmode-set"))
+ { // *** must call before list-begin
+ const char *mode = cmd_key_find(c, "mode");
+
+ if (mode)
+ {
+ Efm_View_Mode view_mode = sd->config.view_mode;
+
+ if (!strcmp(mode, "icons"))
+ view_mode = EFM_VIEW_MODE_ICONS;
+ else if (!strcmp(mode, "icons_custom"))
+ view_mode = EFM_VIEW_MODE_ICONS_CUSTOM;
+ else if (!strcmp(mode, "list"))
+ view_mode = EFM_VIEW_MODE_LIST;
+ else if (!strcmp(mode, "list_detailed"))
+ view_mode = EFM_VIEW_MODE_LIST_DETAILED;
+ if (view_mode != sd->config.view_mode)
+ {
+ int i;
+
+ sd->config.view_mode = view_mode;
+ for (i = 0; i < 6; i++)
+ {
+ if (sd->config.view_mode == EFM_VIEW_MODE_LIST_DETAILED)
+ evas_object_show(sd->o_list_detail[i]);
+ else evas_object_hide(sd->o_list_detail[i]);
+ }
+ if (sd->header_change_job)
+ ecore_job_del(sd->header_change_job);
+ sd->header_change_job = ecore_job_add(_cb_header_change, sd);
+ }
+ }
+ CMD_DONE;
+ }
+ else if (!strcmp(c->command, "detail-header-set"))
+ { // *** must call before list-begin
+ const char *col = cmd_key_find(c, "col");
+ const char *label = cmd_key_find(c, "label");
+
+ if ((col) && (label))
+ {
+ int colnum = atoi(col);
+
+ if ((colnum >= 0) && (colnum <= 6))
+ {
+ eina_stringshare_replace
+ (&(sd->config.detail_heading[colnum]), label);
+ if (sd->o_detail_header_item[colnum])
+ elm_object_text_set(sd->o_detail_header_item[colnum],
+ sd->config.detail_heading[colnum]);
+ }
+ }
+ CMD_DONE;
+ }
// below commands all send a path for a specific file
file = cmd_key_find(c, "path");
@@ -594,12 +659,6 @@ _cb_thread_notify(void *data, Ecore_Thread *th EINA_UNUSED, void *msg)
cmd_free(c);
c = NULL;
}
- else if (!strcmp(c->command, "viewmode-set"))
- { // *** must call before list-begin
- }
- else if (!strcmp(c->command, "detail-header-set"))
- { // *** must call before list-begin
- }
cprev = c;
}
eina_list_free(batch);
diff --git a/src/efm/efm_private.h b/src/efm/efm_private.h
index 86cb5ab..a1198c0 100644
--- a/src/efm/efm_private.h
+++ b/src/efm/efm_private.h
@@ -1,5 +1,7 @@
// functions used between the split up parts of the efm view
+static void _cb_header_change(void *data);
+
static void _listing_do(Smart_Data *sd);
static void _listing_done(Smart_Data *sd);
static double _scale_get(Smart_Data *sd);
@@ -28,3 +30,5 @@ static void _cb_reblock(void *data);
static void _drag_start(Icon *icon);
static void _icon_custom_data_free(Smart_Data *sd);
+
+static void _reset(Smart_Data *sd);
diff --git a/src/efm/efm_structs.h b/src/efm/efm_structs.h
index dfce3f4..777725b 100644
--- a/src/efm/efm_structs.h
+++ b/src/efm/efm_structs.h
@@ -51,6 +51,7 @@ struct _Smart_Data
Ecore_Job *refocus_job;
Ecore_Job *size_bars_update_job;
Ecore_Job *size_max_update_job;
+ Ecore_Job *header_change_job;
Icon *last_selected;
Icon *last_focused_before;
Icon *last_focused;
diff --git a/src/efm/efm_util.c b/src/efm/efm_util.c
index 883cbe0..17167f0 100644
--- a/src/efm/efm_util.c
+++ b/src/efm/efm_util.c
@@ -58,8 +58,8 @@ _strbuf_escape_append(Eina_Strbuf *strbuf, const char *str)
for (s = str; *s; s++)
{
- if ((*s < -',') || (*s == '%') || ((*s >= ':') && (*s <= '@'))
- || ((*s >= '[') && (*s <= ' ')) || (*s >= '{'))
+ if ((*s <= ',') || (*s == '%') || ((*s >= ':') && (*s <= '@'))
+ || ((*s >= '[') && (*s <= '`')) || (*s >= '{'))
{
eina_strbuf_append_char(strbuf, '%');
eina_strbuf_append_char(strbuf, hex[(*s >> 4) & 0xf]);
@@ -1228,8 +1228,8 @@ _icon_object_add(Icon *icon, Smart_Data *sd, Evas *e,
{
for (i = 0; i < 6; i++)
{
- snprintf(buf, sizeof(buf), "detail%i", i + 1);
- s = cmd_key_find(icon->cmd, buf);
+ snprintf(buf2, sizeof(buf2), "detail%i", i + 1);
+ s = cmd_key_find(icon->cmd, buf2);
snprintf(buf2, sizeof(buf2), "e.text.detail%i", i + 1);
if (!s) s = "";
edje_object_part_text_set(icon->o_base, buf2, s);
@@ -1416,6 +1416,7 @@ _icon_object_add(Icon *icon, Smart_Data *sd, Evas *e,
edje_object_signal_callback_add(o, "e,action,label,click", "e",
_cb_icon_label_longpress, icon);
icon->edje = EINA_FALSE;
+ printf("[%s %s %s]\n", icon_group, icon_file, icon_thumb);
if ((!icon_group) && (icon_file))
{ // image file
icon->o_icon = o = efm_icon_add(o);
diff --git a/src/efm/main.c b/src/efm/main.c
index a7b3c2b..2d833b8 100644
--- a/src/efm/main.c
+++ b/src/efm/main.c
@@ -11,11 +11,6 @@ _cb_icons(void *data, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
efm_path_view_mode_set(data, EFM_VIEW_MODE_ICONS);
- if (o_detail_header)
- {
- evas_object_del(o_detail_header);
- o_detail_header = NULL;
- }
}
static void
@@ -23,39 +18,45 @@ _cb_icons_custom(void *data, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
efm_path_view_mode_set(data, EFM_VIEW_MODE_ICONS_CUSTOM);
- if (o_detail_header)
- {
- evas_object_del(o_detail_header);
- o_detail_header = NULL;
- }
}
static void
_cb_list(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
efm_path_view_mode_set(data, EFM_VIEW_MODE_LIST);
- if (o_detail_header)
- {
- evas_object_del(o_detail_header);
- o_detail_header = NULL;
- }
}
static void
_cb_list_detailed(void *data, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
- Evas_Object *o;
-
efm_path_view_mode_set(data, EFM_VIEW_MODE_LIST_DETAILED);
+}
- if (!o_detail_header)
+static void
+_cb_header_change(void *data, Evas_Object *obj EINA_UNUSED,
+ void *event_info EINA_UNUSED)
+{
+ if (efm_path_view_mode_get(data) == EFM_VIEW_MODE_LIST_DETAILED)
+ {
+ if (!o_detail_header)
+ {
+ Evas_Object *o;
+
+ o_detail_header = o = efm_detail_header_get(data);
+ evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
+ elm_box_pack_end(o_detail_header_box, o);
+ evas_object_show(o);
+ }
+ }
+ else
{
- o_detail_header = o = efm_detail_header_get(data);
- evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
- evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
- elm_box_pack_end(o_detail_header_box, o);
- evas_object_show(o);
+ if (o_detail_header)
+ {
+ evas_object_del(o_detail_header);
+ o_detail_header = NULL;
+ }
}
}
@@ -135,6 +136,7 @@ elm_main(int argc, char **argv)
efm = o = efm_add(win);
evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_smart_callback_add(o, "header_change", _cb_header_change, efm);
elm_object_content_set(sc, o);
efm_scroller_set(o, sc);
efm_path_set(o, path);
diff --git a/src/shared/common/cmd.c b/src/shared/common/cmd.c
index 08ece5c..de848f1 100644
--- a/src/shared/common/cmd.c
+++ b/src/shared/common/cmd.c
@@ -54,43 +54,25 @@ cmd_parse(const char *cmd)
// parse up to space - handle escapes
while ((*s) && (!isspace(*s)))
{
- if (*s == '\\')
+ if (*s == '%')
{
s++;
- if (*s == 'x')
+ if (s[0] && s[1])
{
- s++;
- if (s[0] && s[1])
- {
- int hex1 = 0, hex2 = 0;
- if ((s[0] >= '0') && (s[0] <= '9')) hex1 = s[0] - '0';
- if ((s[0] >= 'a') && (s[0] <= 'f'))
- hex1 = 10 + s[0] - 'a';
- if ((s[0] >= 'A') && (s[0] <= 'F'))
- hex1 = 10 + s[0] - 'A';
- if ((s[1] >= '0') && (s[1] <= '9')) hex2 = s[1] - '0';
- if ((s[1] >= 'a') && (s[1] <= 'f'))
- hex2 = 10 + s[1] - 'a';
- if ((s[1] >= 'A') && (s[1] <= 'F'))
- hex2 = 10 + s[1] - 'A';
- *b++ = (hex1 << 4) | hex2;
- s += 2;
- }
+ int hex1 = 0, hex2 = 0;
+ if ((s[0] >= '0') && (s[0] <= '9')) hex1 = s[0] - '0';
+ if ((s[0] >= 'a') && (s[0] <= 'f'))
+ hex1 = 10 + s[0] - 'a';
+ if ((s[0] >= 'A') && (s[0] <= 'F'))
+ hex1 = 10 + s[0] - 'A';
+ if ((s[1] >= '0') && (s[1] <= '9')) hex2 = s[1] - '0';
+ if ((s[1] >= 'a') && (s[1] <= 'f'))
+ hex2 = 10 + s[1] - 'a';
+ if ((s[1] >= 'A') && (s[1] <= 'F'))
+ hex2 = 10 + s[1] - 'A';
+ *b++ = (hex1 << 4) | hex2;
+ s += 2;
}
- else if (*s == ' ') *b++ = ' ';
- else if (*s == 'a') *b++ = '\a';
- else if (*s == 'b') *b++ = '\b';
- else if (*s == 't') *b++ = '\t';
- else if (*s == 'n') *b++ = '\n';
- else if (*s == 'v') *b++ = '\v';
- else if (*s == 'f') *b++ = '\f';
- else if (*s == 'r') *b++ = '\r';
- else if (*s == '`') *b++ = '`';
- else if (((*s >= '>') && (*s <= '*'))
- || ((*s >= ';') && (*s <= '?'))
- || ((*s >= '[') && (*s <= ']'))
- || ((*s >= '{') && (*s <= '~')))
- *b++ = *s++;
}
else *b++ = *s++;
}
@@ -183,13 +165,13 @@ cmd_strbuf_append(Eina_Strbuf *strbuf, const char *key, const char *val)
eina_strbuf_append_char(strbuf, '=');
for (s = val; *s; s++)
{
- if ((*s <= '*') || ((*s >= ';') && (*s <= '?'))
- || ((*s >= '[') && (*s <= ']')) || (*s == '`') || (*s >= '{'))
+ if ((*s <= ',') || (*s == '%') || ((*s >= ':') && (*s <= '@'))
+ || ((*s >= '[') && (*s <= '`')) || (*s >= '{'))
{
unsigned char tmp;
tmp = s[0];
- eina_strbuf_append_printf(strbuf, "\\x%02x", tmp);
+ eina_strbuf_append_printf(strbuf, "%%%02x", tmp);
}
else eina_strbuf_append_char(strbuf, *s);
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.