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.

Reply via email to