lynx-dev
[Top][All Lists]
Advanced

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

lynx-dev [PATCH 2.8.4dev.18] better pasting


From: Ilya Zakharevich
Subject: lynx-dev [PATCH 2.8.4dev.18] better pasting
Date: Tue, 20 Feb 2001 01:20:28 -0500
User-agent: Mutt/1.2.5i

This patch removes arbitrary restrictions on the size of text to be
pasted.  It also makes a quadratic algo into a linear one.  Also: it
may remove many bugs with when the text to paste contains
non-printable chars.

I have no possibility to test this with Unicode and on Win*.  Other
branches are tested.

Enjoy,
Ilya

--- ./src/LYForms.c-pre-grab    Wed Feb 14 01:47:34 2001
+++ ./src/LYForms.c     Mon Feb 19 22:12:12 2001
@@ -6,9 +6,9 @@
 #include <GridText.h>
 #include <LYCharSets.h>
 #include <UCAux.h>
-#include <LYUtils.h>
 #include <LYStructs.h>  /* includes HTForms.h */
 #include <LYGlobalDefs.h>
+#include <LYUtils.h>
 #include <LYStrings.h>
 #include <LYKeymap.h>
 #include <LYClean.h>
@@ -601,53 +601,60 @@ again:
        }
 
 #ifdef CAN_CUT_AND_PASTE       /* 1998/10/01 (Thu) 19:19:22 */
-
-#define FORM_PASTE_MAX 8192
-
        if (action == LYE_PASTE) {
-           unsigned char buff[FORM_PASTE_MAX];
-           int i, len;
+           unsigned char *s = get_clip_grab(), *e;
+           char *buf = NULL;
+           int len;
 
-           len = get_clip(buff, FORM_PASTE_MAX);
+           if (!s)
+               break;
+           len = strlen(s);
+           e = s + len;
 
            if (len > 0) {
-               i = 0;
-               while ((ch = buff[i]) != '\0') {
-
-                   if (ch == '\r') {
-                       i++;
-                       continue;
-                   }
-                   if (ch == '\n') {
-                       i++;
-                       len = strlen(buff + i);
-                       if (len > 0) {
-                           put_clip(buff + i);
-                       }
-                       break;
-                   }
+               unsigned char *e1 = s;
 
-                   LYLineEdit(&MyEdit, ch, TRUE);
-
-                   if (MyEdit.strlen >= max_length) {
-                       HaveMaxlength = TRUE;
-                   } else if (HaveMaxlength &&
-                              MyEdit.strlen < max_length) {
-                       HaveMaxlength = FALSE;
-                       _statusline(ENTER_TEXT_ARROWS_OR_TAB);
-                   }
-                   i++;
+               while (e1 < e) {
+                   if (*e1 < ' ') { /* Stop here? */
+                       if (e1 > s)
+                           LYEditInsert(&MyEdit, s, e1 - s, -1, TRUE);
+                       s = e1;
+                       if (*e1 == '\t') { /* Replace by space */
+                           LYEditInsert(&MyEdit, " ", 1, -1, TRUE);
+                           s = ++e1;
+                       } else
+                           break;
+                   } else
+                       ++e1;
+               }
+               if (e1 > s)
+                   LYEditInsert(&MyEdit, s, e1 - s, -1, TRUE);
+               while (e1 < e && *e1 == '\r')
+                   e1++;
+               if (e1 + 1 < e && *e1 == '\n')
+                   StrAllocCopy(buf, e1 + 1);  /* Survive _release() */
+               get_clip_release();
+               if (MyEdit.strlen >= max_length) {
+                   HaveMaxlength = TRUE;
+               } else if (HaveMaxlength &&
+                          MyEdit.strlen < max_length) {
+                   HaveMaxlength = FALSE;
+                   _statusline(ENTER_TEXT_ARROWS_OR_TAB);
                }
                if (strcmp(value, MyEdit.buffer) != 0) {
                    Edited = TRUE;
                }
+               if (buf) {
+                   put_clip(buf);
+                   FREE(buf);
+                   ch = '\n';          /* Sometimes moves to the next line */
+                   break;
+               }
                LYRefreshEdit(&MyEdit);
-
            } else {
                HTInfoMsg("Clipboard empty or Not text data.");
-               return(DO_NOTHING);
+               continue;
            }
-           break;
        }
 #endif
 #ifndef WIN_EX
--- ./src/LYStrings.c-pre-grab  Wed Feb 14 01:46:12 2001
+++ ./src/LYStrings.c   Mon Feb 19 22:05:14 2001
@@ -1,8 +1,8 @@
 #include <HTUtils.h>
 #include <HTCJK.h>
 #include <UCAux.h>
-#include <LYUtils.h>
 #include <LYGlobalDefs.h>
+#include <LYUtils.h>
 #include <LYStrings.h>
 #include <GridText.h>
 #include <LYKeymap.h>
@@ -2661,6 +2661,121 @@ PRIVATE int prev_pos ARGS2(
 }
 #endif /* SUPPORT_MULTIBYTE_EDIT */
 
+#ifdef EXP_KEYBOARD_LAYOUT
+static int map_active = 0;
+#endif
+
+PUBLIC int LYEditInsert ARGS5(
+       EDREC *,        edit,
+       unsigned char *,s,
+       int,            len,
+       int,            map,
+       BOOL,           maxMessage)
+{
+    int length = strlen(Buf);
+    int remains = MaxLen - (length + len);
+    int edited = 0, overflow = 0;
+
+    /*
+     *  ch is (presumably) printable character.
+     */
+    if (remains < 0) {
+       overflow = 1;
+       len = 0;
+       if (MaxLen > length)    /* Insert as much as we can */
+           len = MaxLen - length;
+       else
+           goto finish;
+    }
+    Buf[length + len] = '\0';
+    for(; length >= Pos; length--)    /* Make room */
+       Buf[length + len] = Buf[length];
+#ifdef EXP_KEYBOARD_LAYOUT
+    if (map < 0)
+       map = map_active;
+    if (map && LYCharSet_UC[current_char_set].enc == UCT_ENC_UTF8) {
+       unsigned char *e = s + len, *t = Buf + Pos;
+       char *tail = 0;
+
+       while (s < e) {
+           char utfbuf[8];
+           int l = 1;
+
+           utfbuf[0] = *s;
+           if ( *s < 128 && LYKbLayouts[current_layout][*s] ) {
+               UCode_t ucode = LYKbLayouts[current_layout][*s];
+
+               if (ucode > 127) {
+                   if (UCConvertUniToUtf8(ucode, utfbuf)) {
+                       l = strlen(utfbuf);
+                       remains -= l - 1;
+                       if (remains < 0) {
+                           if (tail)
+                               strcpy(t, tail);
+                           FREE(tail);
+                           len = (char*)t - Buf;
+                           overflow = 1;
+                           goto finish;
+                       }
+                       if (l > 1 && !tail)
+                           StrAllocCopy((char*)tail, Buf + Pos + len);
+                   } else
+                       utfbuf[0] = '?';
+               } else
+                   utfbuf[0] = UCH(ucode);
+           }
+           strncpy(t, utfbuf, l);
+           edited = 1;
+           t += l;
+           s++;
+       }
+       if (tail)
+           strcpy(t, tail);
+       len = (char*)t - (Buf + Pos);
+       FREE(tail);
+    } else if (map) {
+       unsigned char *e = s + len, *t = Buf + Pos;
+
+       while (s < e) {
+           int ch;
+
+           if ( *s < 128 && LYKbLayouts[current_layout][*s] ) {
+               ch = UCTransUniChar(LYKbLayouts[current_layout][*s],
+                                   current_char_set);
+               if (ch < 0)
+                   ch = '?';
+           } else
+               ch = *s;
+           *t = UCH(ch);
+           t++, s++;
+       }
+       edited = 1;
+    }
+    else
+#endif /* defined EXP_KEYBOARD_LAYOUT */
+       {
+           strncpy(Buf + Pos, s, len);
+           edited = 1;
+       }
+    
+  finish:
+    Pos += len;
+    StrLen += len;
+    if (edited)
+       edit->dirty = TRUE;
+    if (overflow && maxMessage)
+       _statusline(MAXLEN_REACHED_DEL_OR_MOV);
+#ifdef ENHANCED_LINEEDIT
+    if (Mark > Pos)
+       Mark += len;
+    else if (Mark < -1 - Pos)
+       Mark -= len;
+    if (Mark >= 0)
+       Mark = -1 - Mark;               /* Disable it */
+#endif
+    return edited;
+}
+
 PUBLIC int LYEdit1 ARGS4(
        EDREC *,        edit,
        int,            ch,
@@ -2672,9 +2787,6 @@ PUBLIC int LYEdit1 ARGS4(
      */
     int i;
     int length;
-#ifdef EXP_KEYBOARD_LAYOUT
-    static int map_active = 0;
-#endif
 
     if (MaxLen <= 0)
        return(0); /* Be defensive */
@@ -2703,64 +2815,13 @@ PUBLIC int LYEdit1 ARGS4(
            return(ch);
        /* FALLTHRU */
 #endif
-    case LYE_CHAR:
-#ifdef EXP_KEYBOARD_LAYOUT
-       if (map_active && ch < 128 && ch >= 0 &&
-           LYKbLayouts[current_layout][ch]) {
-           UCode_t ucode = LYKbLayouts[current_layout][ch];
-           if (LYCharSet_UC[current_char_set].enc == UCT_ENC_UTF8) {
-               if (ucode > 127) {
-                   char utfbuf[8];
-                   utfbuf[0] = 0;
-                   if (UCConvertUniToUtf8(ucode, utfbuf)) {
-                       int ulen = strlen(utfbuf);
-                       i = 0;
-                       if (ulen > 1) {
-                           if (Pos + ulen - 1 <= (MaxLen) &&
-                               StrLen + ulen - 1 < (MaxLen)) {
-                               for (i = 0; i < ulen-1; i++)
-                                   LYEdit1(edit, utfbuf[i], LYE_CHAR, FALSE);
-                               length = strlen(&Buf[0]);
-                               StrLen = length;
-                           } else {
-                               if (maxMessage)
-                                   _statusline(MAXLEN_REACHED_DEL_OR_MOV);
-                               return 0;
-                           }
-                       }
-                       ch = UCH(utfbuf[i]);
-                   }
-               } else {
-                   ch = UCH(ucode);
-               }
-           } else {
-               ch = UCTransUniChar(ucode, current_char_set);
-               if (ch < 0)
-                   ch = '?';
-           }
-       }
-#endif
-       /*
-        *  ch is (presumably) printable character.
-        */
-       if (Pos <= (MaxLen) && StrLen < (MaxLen)) {
-#ifdef ENHANCED_LINEEDIT
-           if (Mark > Pos)
-               Mark++;
-           else if (Mark < -1 - Pos)
-               Mark--;
-           if (Mark >= 0)
-               Mark = -1 - Mark;               /* Disable it */
-#endif
-           for(i = length; i >= Pos; i--)    /* Make room */
-               Buf[i+1] = Buf[i];
-           Buf[length+1]='\0';
-           Buf[Pos] = UCH(ch);
-           Pos++;
-       } else if (maxMessage) {
-           _statusline(MAXLEN_REACHED_DEL_OR_MOV);
-       }
-       break;
+    case LYE_CHAR: {
+       unsigned char uch = UCH(ch);
+       
+       LYEditInsert(edit, &uch, 1, map_active, maxMessage);
+       return 0;                       /* All changes already registered */
+    }
+    break;
 
     case LYE_C1CHAR:
        /*
@@ -4691,25 +4752,36 @@ again:
 #ifdef CAN_CUT_AND_PASTE
        /* 1998/10/01 (Thu) 15:05:49 */
 
-#define PASTE_MAX      512
-
        case LYE_PASTE:
            {
-               unsigned char buff[PASTE_MAX];
-               int i, len;
+               unsigned char *s = get_clip_grab(), *e;
+               int len;
 
-               len = get_clip(buff, PASTE_MAX);
+               if (!s)
+                   break;
+               len = strlen(s);
+               e = s + len;
 
                if (len > 0) {
-                   i = 0;
-                   while ((ch = buff[i]) != '\0') {
-                       if (ch == '\r' || ch == '\n')
-                           break;
-                       if (ch >= ' ')
-                           LYLineEdit(&MyEdit, ch, FALSE);
-                       i++;
+                   unsigned char *e1 = s;
+
+                   while (e1 < e) {
+                       if (*e1 < ' ') { /* Stop here? */
+                           if (e1 > s)
+                               LYEditInsert(&MyEdit, s, e1 - s, map_active, 
TRUE);
+                           s = e1;
+                           if (*e1 == '\t') { /* Replace by space */
+                               LYEditInsert(&MyEdit, " ", 1, map_active, TRUE);
+                               s = ++e1;
+                           } else
+                               break;
+                       } else
+                           ++e1;
                    }
+                   if (e1 > s)
+                       LYEditInsert(&MyEdit, s, e1 - s, map_active, TRUE);
                }
+               get_clip_release();
                break;
            }
 #endif
--- ./src/LYStrings.h-pre-grab  Wed Feb 14 00:30:14 2001
+++ ./src/LYStrings.h   Mon Feb 19 21:16:04 2001
@@ -344,4 +344,6 @@ extern int escape_bound;
 /* Dummy initializer for LYEditmap.c */
 extern int LYEditmapDeclared NOPARAMS;
 
+int LYEditInsert PARAMS((EditFieldData *edit, unsigned char *s,        int 
len, int map_active, BOOL maxMessage));
+
 #endif /* LYSTRINGS_H */
--- ./src/LYUtils.c-pre-grab    Wed Feb 14 02:49:46 2001
+++ ./src/LYUtils.c     Sun Feb 18 17:27:00 2001
@@ -6,9 +6,9 @@
 #include <HTAlert.h>
 #include <LYCurses.h>
 #include <LYHistory.h>
-#include <LYUtils.h>
 #include <LYStrings.h>
 #include <LYGlobalDefs.h>
+#include <LYUtils.h>
 #include <LYSignal.h>
 #include <GridText.h>
 #include <LYClean.h>
@@ -7840,37 +7840,48 @@ PUBLIC int put_clip ARGS1(char *, s)
     return 0;
 }
 
-PUBLIC int get_clip ARGS2(char *, szBuffer, int, size)
+static int clip_open;
+
+/* get_clip_grab() returns a pointer to the string in the system area.
+   get_clip_release() should be called ASAP after this. */
+
+PUBLIC char* get_clip_grab NOARGS
 {
     char *ClipData;
     ULONG ulFormat;
     int sz;
-    int ret = 0;
 
-    if(!size)
-        return 0;
     morph_PM();
     if(!hab)
         return 0;
+    if (clip_open)
+       get_clip_release();
 
     WinQueryClipbrdFmtInfo(hab, CF_TEXT, &ulFormat);
-    if(ulFormat != CFI_POINTER)
-        goto finish;
+    if(ulFormat != CFI_POINTER) {
+       unmorph_PM();
+       return 0;
+    }
     WinOpenClipbrd(hab);
+    clip_open = 1;
     ClipData = (char *)WinQueryClipbrdData(hab, CF_TEXT);
     sz = strlen(ClipData);
-    if(!ClipData || sz >= size)
-        goto fail;
-    memcpy(szBuffer, ClipData, sz + 1);
-    ret = sz;
-  fail:
+    if(!ClipData || !sz) {
+        get_clip_release();
+       return 0;
+    }
+    return ClipData;
+}
+
+PUBLIC void get_clip_release NOARGS
+{
+    if (!clip_open)
+       return;
     WinCloseClipbrd(hab);
-  finish:
+    clip_open = 0;
     unmorph_PM();
-    return ret;
 }
 
-
 #endif
 
 #if defined(WIN_EX)    /* 1997/10/16 (Thu) 20:13:28 */
@@ -7926,10 +7937,15 @@ PUBLIC int put_clip(char *szBuffer)
     return 0;
 }
 
-PUBLIC int get_clip(char *szBuffer, int size)
+static HANDLE m_hLogData;
+static int m_locked;
+
+/* get_clip_grab() returns a pointer to the string in the system area.
+   get_clip_release() should be called ASAP after this. */
+
+PUBLIC char* get_clip_grab()
 {
     HANDLE hWnd;
-    HANDLE m_hLogData;
     LPTSTR pLogData;
     int val;
 
@@ -7942,24 +7958,23 @@ PUBLIC int get_clip(char *szBuffer, int 
     m_hLogData = GetClipboardData(CF_TEXT);
 
     if (m_hLogData == NULL) {
-       val = 0;
-    } else {
-       pLogData = (LPTSTR) GlobalLock(m_hLogData);
+       CloseClipboard();
+       m_locked = 0;
+       return 0;
+    }
+    pLogData = (LPTSTR) GlobalLock(m_hLogData);
 
-       val = strlen((LPTSTR) pLogData);
-       if (size > val)
-           lstrcpy(szBuffer, (LPTSTR) pLogData);
-       else {
-           val = size - 1;
-           lstrcpyn(szBuffer, (LPTSTR) pLogData, val);
-           szBuffer[val] = '\0';
-       }
+    m_locked = 1;
+    return pLogData;
+}
 
-       GlobalUnlock(m_hLogData);
-    }
+PUBLIC void get_clip_release()
+{
+    if (!m_locked)
+       return;
+    GlobalUnlock(m_hLogData);
     CloseClipboard();
-
-    return val;
+    m_locked = 0;
 }
 
 
--- ./src/LYUtils.h-pre-grab    Wed Feb 14 01:22:28 2001
+++ ./src/LYUtils.h     Sun Feb 18 17:26:36 2001
@@ -176,7 +176,10 @@ extern void LYUIPages_free NOPARAMS;
 
 #ifdef CAN_CUT_AND_PASTE
 extern int put_clip(char *szBuffer);
-extern int get_clip(char *szBuffer, int size);
+/* get_clip_grab() returns a pointer to the string in the system area.
+   get_clip_release() should be called ASAP after this. */
+extern char* get_clip_grab(void);
+extern void  get_clip_release(void);
 #  ifdef WIN_EX
 #    define size_clip()        8192
 #  else

; To UNSUBSCRIBE: Send "unsubscribe lynx-dev" to address@hidden

reply via email to

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