lynx-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

lynx-dev patch (textarea handling, mostly) - textarea_fix.diff


From: Klaus Weide
Subject: lynx-dev patch (textarea handling, mostly) - textarea_fix.diff
Date: Sun, 31 Oct 1999 12:25:14 -0600 (CST)

I also put a copy in <http://enteract.com/~kweide/lynx/>.
The patch should be applied on top of the other patches there.

* Another tweak for display refreshing when text previously displayed
  had UTF-8 (for ncurses) - a check in display_page was missing.
* Corrected stupid problem in LYGetFileInfo - invalid memory access.
* Corrected and extended handling for textarea INSERTFILE and EDITTEXTAREA
  (or DWIMEDIT), the previous patch wasn't quite right:
  - Now really truncate very long lines as intended for INSERTFILE, instead
    of wrapping with loss of one character.
  - For EDITTEXTAREA (DWIMEDIT), implement wrapping instead of truncation
    (Rationale for the difference: user's editing work shouldn't be lost
    if we can avoid it; it is only temporarily stored in a file which may
    be unrecoverable, different from the typical INSERTFILE case.)
    If, upon returning from the external editor, lines are encountered that
    don't fit in the displayed width of the textarea fields, the user may be
    given the option to wrap to that width.  (This prompt may not be given
    when the first such line has no suitable spaces for breaking - the file
    may be binary garbage after all, not worth fixing up too much.)  Line
    breaking is attempted at spaces if possible (using isspace() for
    checking), but not if the only available spaces are close to the beginning
    of a line.  An attempt is made to join the wrapped part of a line (if not
    too long) with the next line if it is not indented, by suppressing the
    next line break (if not too far away).  Some other heuristics are used
    that work reasonably well for normal text paragraphs.
    If the above mechanisms fail, or the user did not confirm wrapping when
    prompted, very long lines will still be wrapped to fit into the buffer
    size (around 1024 chars).

[ The wrapping works quite nicely in "normal" cases - please try it! ]

[ There should be some comments in the code - will try to add them later. ]

    Klaus


Index: 2.16/WWW/Library/Implementation/HTFile.c
--- 2.16/WWW/Library/Implementation/HTFile.c Mon, 25 Oct 1999 16:08:27 -0500
+++ 2.16(w)/WWW/Library/Implementation/HTFile.c Fri, 29 Oct 1999 23:05:58 -0500
@@ -1129,7 +1129,7 @@
        HTFormat format;
        HTAtom * myEnc = NULL;
        HTParentAnchor *file_anchor;
-       CONST char *file_csname = file_anchor->charset;
+       CONST char *file_csname;
        int file_cs;
 
        /*
@@ -1817,7 +1817,7 @@
 #ifndef DISP_PARTIAL
                if (num_of_entries_output % HTMAX(display_lines,10) == 0) {
                    if (HTCheckForInterrupt()) {
-                       _HTProgress ("Data transfer interrupted.");
+                       _HTProgress (TRANSFER_INTERRUPTED);
                        status = HT_PARTIAL_CONTENT;
                        break;
                    }
Index: 2.16/src/GridText.c
--- 2.16/src/GridText.c Wed, 27 Oct 1999 21:44:23 -0500
+++ 2.16(w)/src/GridText.c Sat, 30 Oct 1999 23:32:00 -0500
@@ -2097,7 +2097,7 @@
     }
 #endif /* DISP_PARTIAL */
 
-    if (text->has_utf8) {
+    if (text->has_utf8 || text->had_utf8) {
        /*
         *  For other than ncurses, repainting is taken care of
         *  by touching lines in display_line and highlight. - kw 1999-10-07
@@ -11764,6 +11764,7 @@
     TextAnchor *start_anchor  = NULL;
     TextAnchor *end_anchor    = NULL;
     BOOLEAN    firstanchor   = TRUE;
+    BOOLEAN wrapalert = FALSE;
 
     char       ed_offset[10];
     int                start_line    = 0;
@@ -11785,7 +11786,10 @@
     char       *cp;
     int         match_tag = 0;
     int                newlines  = 0;
-    int                len;
+    int                len, len0, len_in;
+    int                wanted_fieldlen_wrap = -1; /* not yet asked; 0 means 
don't. */
+    char       *skip_at = NULL;
+    int                skip_num = 0, i;
 
     CTRACE((tfp, "GridText: entered HText_ExtEditForm()\n"));
 
@@ -11941,24 +11945,111 @@
        outofmem(__FILE__, "HText_ExtEditForm");
 
     anchor_ptr = start_anchor;
+    if (anchor_ptr->input_field->size <= 4 ||
+       anchor_ptr->input_field->size >= MAX_LINE)
+       wanted_fieldlen_wrap = 0;
 
-    len = 0;
+    len = len_in = 0;
     lp  = ebuf;
 
     while ((line_cnt <= orig_cnt) || (*lp) || ((len != 0) && (*lp == '\0'))) {
 
+       if (skip_at) {
+           len0 = skip_at - lp;
+           strncpy(line, lp, len0);
+           line[len0] = '\0';
+           lp = skip_at + skip_num;
+           skip_at = NULL;
+           skip_num = 0;
+       } else {
+           len0 = 0;
+       }
+       line[len0] = '\0';
+
        if ((cp = strchr (lp, '\n')) != 0)
-          len = cp - lp;
+          len = len_in = cp - lp;
        else
-          len = strlen (lp);
+          len = len_in = strlen (lp);
 
-       if (len >= MAX_LINE - 1)
-           len = MAX_LINE - 1;
 
-       strncpy (line, lp, len);
-       *(line + len) = '\0';
+       if (wanted_fieldlen_wrap < 0 && !wrapalert &&
+           len0+len >= anchor_ptr->input_field->size &&
+           (cp = strchr(lp, ' ')) != NULL &&
+           (cp-lp) < anchor_ptr->input_field->size - 1) {
+           LYFixCursesOn("ask for confirmation:");
+           erase();            /* don't show previous state */
+           if (HTConfirmDefault(gettext("Wrap lines to fit displayed area?"),
+                                NO)) {
+               wanted_fieldlen_wrap = anchor_ptr->input_field->size - 1;
+           } else {
+               wanted_fieldlen_wrap = 0;
+           }
+       }
+       if (wanted_fieldlen_wrap > 0 && len0+len > wanted_fieldlen_wrap) {
+           for (i = wanted_fieldlen_wrap-len0;
+                i+len0 >= wanted_fieldlen_wrap/4; i--) {
+               if (isspace((unsigned char)lp[i])) {
+                   len = i + 1;
+                   cp = lp + i;
+                   if (cp[1] != '\n' &&
+                       isspace((unsigned char)cp[1]) &&
+                       !isspace((unsigned char)cp[2])) {
+                       len++;
+                       cp++;
+                   }
+                   if (!isspace((unsigned char)cp[1])) {
+                       while (*cp && *cp != '\r' && *cp != '\n' &&
+                              (cp - lp) <= len + (3 * wanted_fieldlen_wrap/4))
+                           cp++;       /* search for next line break */
+                       if (*cp == '\r' && cp[1] == '\n')
+                           cp++;
+                       if (*cp == '\n' &&
+                           (cp[1] == '\r' || cp[1] == '\n' ||
+                            !isspace((unsigned char)cp[1]))) {
+                           *cp = ' ';
+                           while (isspace((unsigned char)*(cp-1))) {
+                               skip_num++;
+                               cp--;
+                           }
+                           skip_at = cp;
+                       }
+                   }
+                   break;
+               }
+           }
+       }
+       if (wanted_fieldlen_wrap > 0 && len0+len > wanted_fieldlen_wrap) {
+           i = len-1;
+           while (len0+i+1 > wanted_fieldlen_wrap &&
+                  isspace((unsigned char)lp[i]))
+               i--;
+           if (len0+i+1 > wanted_fieldlen_wrap)
+               len = wanted_fieldlen_wrap - len0;
+       }
+
+       if (len0+len >= MAX_LINE) {
+           if (!wrapalert) {
+               LYFixCursesOn("show alert:");
+               HTAlert(gettext("Very long lines have been wrapped!"));
+               wrapalert = TRUE;
+           }
+           /*
+            *  First try to find a space character for wrapping - kw
+            */
+           for (i = MAX_LINE - len0 - 1; i > 0; i--) {
+               if (isspace((unsigned char)lp[i])) {
+                   len = i;
+                   break;
+               }
+           }
+           if (len0+len >= MAX_LINE)
+               len = MAX_LINE - len0 - 1;
+       }
+
+       strncat (line, lp, len);
+       *(line + len0+len) = '\0';
 
-       cleanup_line_for_textarea (line, len);
+       cleanup_line_for_textarea (line, len0+len);
 
        /*
         *  If there are more lines in the edit buffer than were in the
@@ -11980,7 +12071,7 @@
         *  Keep track of 1st blank line in any trailing blank lines, for
         *  later cursor repositioning.
         */
-       if (len > 0)
+       if (len0+len > 0)
            exit_line = 0;
        else if (exit_line == 0)
            exit_line = anchor_ptr->line_num;
@@ -11989,7 +12080,7 @@
         *  And do the next line of edited text, for the next anchor ...
         */
        lp += len;
-       if (*lp) lp++;
+       if (*lp && isspace((unsigned char)*lp)) lp++;
 
        end_anchor = anchor_ptr;
        anchor_ptr = anchor_ptr->next;
@@ -12388,10 +12479,12 @@
 
        if (len >= MAX_LINE) {
            if (!truncalert) {
-               HTAlert(gettext("Long lines have been truncated!"));
+               HTAlert(gettext("Very long lines have been truncated!"));
                truncalert = TRUE;
            }
            len = MAX_LINE - 1;
+           if (lp[len])
+               lp[len+1] = '\0'; /* prevent next iteration */
        }
        strncpy (line, lp, len);
        *(line + len) = '\0';


reply via email to

[Prev in Thread] Current Thread [Next in Thread]