]> git.neil.brown.name Git - edlib.git/blobdiff - doc-email.c
TODO: clean out done items.
[edlib.git] / doc-email.c
index 67c96e75483cc86455c09e75a5d6ac8b50b60ce2..58d44cbb914fb817e1c2ecd6cc48035f94daeecb 100644 (file)
@@ -24,7 +24,7 @@
  *   etc).
  *
  * The middle part has attributes set on the document which can be
- * accessed form the spacer using "multipart-prev:"
+ * accessed from the spacer using "multipart-prev:"
  * - email:path identify the part in the nexted multipart struture
  *   e.g. "header", "body", "body,multipart/mixed:0,mulitpart/alternate:1"
  * - email:actions a ':' separated list of buttons. "hide:save:view"
 #include <wctype.h>
 #include <ctype.h>
 #include <stdio.h>
+
+#define PANE_DATA_TYPE struct email_view
+#define DOC_NEXT email_next
+#define DOC_PREV email_prev
 #include "core.h"
 #include "misc.h"
 
+struct email_view {
+       int     parts;
+       char    *invis;
+};
+
+#include "core-pane.h"
+
 static inline bool is_orig(int p)
 {
        return p >= 0 && p % 3 == 0;
@@ -78,7 +89,7 @@ static bool handle_rfc822(struct pane *email safe,
 static bool cond_append(struct buf *b safe, char *txt safe, char *tag safe,
                        int offset, int *pos safe)
 {
-       char *tagf = "active-tag:email-";
+       char *tagf = "action-activate:email-";
        int prelen = 1 + strlen(tagf) + strlen(tag) + 1 + 1;
        int postlen = 1 + 3;
        int len = prelen + strlen(txt) + postlen;
@@ -325,7 +336,7 @@ DEF_CMD(email_select_extras)
        hdrdoc = call_ret(pane, "doc:multipart:get-part", ci->focus, 1);
        if (!headers || !hdrdoc)
                return Einval;
-       point = vmark_new(hdrdoc, MARK_POINT, NULL);
+       point = point_new(hdrdoc);
        if (point) {
                char *file;
 
@@ -640,7 +651,7 @@ static bool handle_text(struct pane *p safe, char *type, char *xfer, char *disp,
  * Return 1 if a terminal boundary is found (trailing --)
  * Return -1 if nothing is found.
  */
-#define is_lws(c) ({int __c2 = c; __c2 == ' ' || __c2 == '\t' || is_eol(__c2); })
+#define is_lws(c) ({int _c2 = c; _c2 == ' ' || _c2 == '\t' || is_eol(_c2); })
 static int find_boundary(struct pane *p safe,
                         struct mark *start safe, struct mark *end safe,
                         struct mark *pos,
@@ -816,12 +827,12 @@ static bool handle_rfc822(struct pane *email safe,
        if (!hdrdoc)
                goto out;
        call("doc:set:autoclose", hdrdoc, 1);
-       point = vmark_new(hdrdoc, MARK_POINT, NULL);
+       point = point_new(hdrdoc);
        if (!point)
                goto out;
 
        /* copy some headers to the header temp document */
-       home_call(h2, "get-header", hdrdoc, 0, point, "From", 1);
+       home_call(h2, "get-header", hdrdoc, 0, point, "From", 1, NULL, "list");
        home_call(h2, "get-header", hdrdoc, 0, point, "Date", 1);
        home_call(h2, "get-header", hdrdoc, 0, point, "Subject", 1, NULL, "text");
        home_call(h2, "get-header", hdrdoc, 0, point, "To", 1, NULL, "list");
@@ -916,7 +927,7 @@ DEF_CMD(open_email)
        attr_set_str(&p->attrs, "email:which", "spacer");
        call("doc:set:autoclose", p, 1);
        spacer = p;
-       point = vmark_new(p, MARK_POINT, NULL);
+       point = point_new(p);
        call("doc:set-ref", p, 1, point);
        call("doc:set-attr", p, 1, point, "markup:func", 0,
             NULL, "doc:email:render-spacer");
@@ -947,17 +958,12 @@ out:
        return Efail;
 }
 
-struct email_view {
-       int     parts;
-       char    *invis safe;
-};
-
-DEF_CMD(email_view_free)
+DEF_CMD_CLOSED(email_view_close)
 {
        struct email_view *evi = ci->home->data;
 
        free(evi->invis);
-       unalloc(evi, pane);
+       evi->invis = NULL;
        return 1;
 }
 
@@ -976,80 +982,63 @@ static int count_buttons(struct pane *p safe, struct mark *m safe)
        return cnt;
 }
 
-static int email_step(struct pane *home safe, struct mark *mark safe,
-                     int forward, int move)
+static inline wint_t email_next(struct pane *p safe, struct mark *m safe,
+                               struct doc_ref *r safe, bool bytes)
 {
-       struct pane *p = home;
        struct email_view *evi = p->data;
+       bool move = r == &m->ref;
        wint_t ret;
        int n = -1;
 
-       if (forward) {
-               ret = home_call(p->parent, "doc:char", home,
-                               move ? 1 : 0,
-                               mark, evi->invis,
-                               move ? 0 : 1);
-               n = get_part(p->parent, mark);
-               if (move && is_spacer(n)) {
-                       /* Moving in a spacer, If after valid buttons,
-                        * move to end
-                        */
-                       wint_t c;
-                       unsigned int buttons;
-                       buttons = count_buttons(p, mark);
-                       while ((c = doc_following(p->parent, mark)) != WEOF
-                              && iswdigit(c) && (c - '0') >= buttons)
-                                       doc_next(p->parent, mark);
-               }
-       } else {
-               ret = home_call(p->parent, "doc:char", home,
-                               move ? -1 : 0,
-                               mark, evi->invis,
-                               move ? 0 : -1);
-               n = get_part(p->parent, mark);
-               if (is_spacer(n) && move &&
-                   ret != CHAR_RET(WEOF) && iswdigit(ret & 0x1fffff)) {
-                       /* Just stepped back over the 9 at the end of a spacer,
-                        * Maybe step further if there aren't 10 buttons.
-                        */
-                       unsigned int buttons = count_buttons(p, mark);
-                       wint_t c = ret & 0x1fffff;
-
-                       while (c != WEOF && iswdigit(c) && c - '0' >= buttons)
-                               c = doc_prev(p->parent, mark);
-                       ret = CHAR_RET(c);
-               }
+       ret = home_call(p->parent, "doc:char", p,
+                       move ? 1 : 0,
+                       m, evi->invis,
+                       move ? 0 : 1);
+       n = get_part(p->parent, m);
+       if (move && is_spacer(n)) {
+               /* Moving in a spacer.  IF after valid buttons,
+                * move to end.
+                */
+               wint_t c;
+               unsigned int buttons = count_buttons(p, m);
+               while ((c = doc_following(p->parent, m)) != WEOF &&
+                      iswdigit(c) && (c-'0') >= buttons)
+                       doc_next(p->parent, m);
        }
        return ret;
 }
 
-DEF_CMD(email_char)
+static inline wint_t email_prev(struct pane *p safe, struct mark *m safe,
+                               struct doc_ref *r safe, bool bytes)
 {
-       struct mark *m = ci->mark;
-       struct mark *end = ci->mark2;
-       int steps = ci->num;
-       int forward = steps > 0;
-       int ret = Einval;
+       struct email_view *evi = p->data;
+       bool move = r == &m->ref;
+       wint_t ret;
+       int n = -1;
 
-       if (!m)
-               return Enoarg;
-       if (end && mark_same(m, end))
-               return 1;
-       if (end && (end->seq < m->seq) != (steps < 0))
-               /* Can never cross 'end' */
-               return Einval;
-       while (steps && ret != CHAR_RET(WEOF) && (!end || !mark_same(m, end))) {
-               ret = email_step(ci->home, m, forward, 1);
-               steps -= forward*2 - 1;
+       ret = home_call(p->parent, "doc:char", p,
+                       move ? -1 : 0,
+                       m, evi->invis,
+                       move ? 0 : -1);
+       n = get_part(p->parent, m);
+       if (is_spacer(n) && move &&
+           ret != CHAR_RET(WEOF) && iswdigit(ret & 0x1fffff)) {
+               /* Just stepped back over the 9 at the end of a spacer,
+                * Maybe step further if there aren't 10 buttons.
+                */
+               unsigned int buttons = count_buttons(p, m);
+               wint_t c = ret & 0x1fffff;
+
+               while (c != WEOF && iswdigit(c) && c - '0' >= buttons)
+                       c = doc_prev(p->parent, m);
+               ret = c;
        }
-       if (end)
-               return 1 + (forward ? ci->num - steps : steps - ci->num);
-       if (ret == CHAR_RET(WEOF) || ci->num2 == 0)
-               return ret;
-       if (ci->num &&(ci->num2 < 0) == forward)
-               return ret;
-       /* Want the 'next' char */
-       return email_step(ci->home, m, ci->num2 > 0, 0);
+       return ret;
+}
+
+DEF_CMD(email_char)
+{
+       return do_char_byte(ci);
 }
 
 DEF_CMD(email_content)
@@ -1108,6 +1097,8 @@ DEF_CMD(email_view_get_attr)
                p = to_orig(p);
                if (p < 0 || p >= evi->parts)
                        v = "none";
+               else if (!evi->invis)
+                       v = "none";
                else if (evi->invis[p] != 'i')
                        v = "orig";
                else if (evi->invis[p+1] != 'i')
@@ -1118,6 +1109,14 @@ DEF_CMD(email_view_get_attr)
                return comm_call(ci->comm2, "callback", ci->focus, 0, ci->mark,
                                 v, 0, NULL, ci->str);
        }
+       if (strcmp(ci->str, "email:image") == 0) {
+               char im[100];
+
+               p = get_part(ci->home->parent, ci->mark);
+               sprintf(im, "comm:doc:multipart-%d-doc:get-bytes", to_orig(p));
+               return comm_call(ci->comm2, "cb", ci->focus, 0, ci->mark,
+                                im, 0, NULL, ci->str);
+       }
        return Efallthrough;
 }
 
@@ -1135,7 +1134,7 @@ DEF_CMD(email_view_set_attr)
                p = get_part(ci->home->parent, ci->mark);
                /* only parts can be invisible, not separators */
                p = to_orig(p);
-               if (p < 0 || p >= evi->parts)
+               if (p < 0 || p >= evi->parts || !evi->invis)
                        return Efail;
 
                m1 = mark_dup(ci->mark);
@@ -1206,7 +1205,10 @@ DEF_CMD(attach_email_view)
        if (n <= 0 || n > 1000 )
                return Einval;
 
-       alloc(evi, pane);
+       p = pane_register(ci->focus, 0, &email_view_handle.c);
+       if (!p)
+               return Efail;
+       evi = p->data;
        evi->parts = n;
        evi->invis = calloc(n+1, sizeof(char));
        for (i = 0; i < n; i++) {
@@ -1220,11 +1222,6 @@ DEF_CMD(attach_email_view)
                        /* Everything else default to invisible */
                        evi->invis[i] = 'i';
        }
-       p = pane_register(ci->focus, 0, &email_view_handle.c, evi);
-       if (!p) {
-               free(evi);
-               return Efail;
-       }
        p2 = call_ret(pane, "attach-line-count", p);
        if (p2)
                p = p2;
@@ -1235,7 +1232,7 @@ DEF_CMD(attach_email_view)
 static void email_init_map(void)
 {
        email_view_map = key_alloc();
-       key_add(email_view_map, "Free", &email_view_free);
+       key_add(email_view_map, "Close", &email_view_close);
        key_add(email_view_map, "doc:char", &email_char);
        key_add(email_view_map, "doc:content", &email_content);
        key_add(email_view_map, "doc:content-bytes", &email_content);