]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - test/edit_field.c
ncurses 6.2 - patch 20200321
[ncurses.git] / test / edit_field.c
index 5ac096dcfb7b59aba8c1a9b3ab690d79a978128e..b2b2084593576ad08907c41a8777fab74b350303 100644 (file)
@@ -1,5 +1,6 @@
 /****************************************************************************
- * Copyright (c) 2003-2006,2008 Free Software Foundation, Inc.              *
+ * Copyright 2019,2020 Thomas E. Dickey                                     *
+ * Copyright 2003-2014,2017 Free Software Foundation, Inc.                  *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
  * authorization.                                                           *
  ****************************************************************************/
 /*
- * $Id: edit_field.c,v 1.15 2008/12/20 19:23:01 tom Exp $
+ * $Id: edit_field.c,v 1.31 2020/02/02 23:34:34 tom Exp $
  *
  * A wrapper for form_driver() which keeps track of the user's editing changes
- * for each field, and makes the result available as a null-terminated string
- * in field_buffer(field,1).
+ * for each field, and makes the resulting length available as a
+ * null-terminated string in field_buffer(field,1).
  *
  * Thomas Dickey - 2003/4/26.
  */
@@ -40,6 +41,7 @@
 #if USE_LIBFORM
 
 #include <edit_field.h>
+#include <popup_msg.h>
 
 static struct {
     int code;
@@ -169,149 +171,117 @@ static struct {
     }
 };
 
-static WINDOW *old_window;
-
-static void
-begin_popup(void)
-{
-    doupdate();
-    old_window = dupwin(curscr);
-}
-
-static void
-end_popup(void)
-{
-    touchwin(old_window);
-    wnoutrefresh(old_window);
-    doupdate();
-    delwin(old_window);
-}
-
 /*
  * Display a temporary window listing the keystroke-commands we recognize.
  */
 void
 help_edit_field(void)
 {
-    int x0 = 4;
-    int y0 = 2;
-    int y1 = 0;
-    int y2 = 0;
-    int wide = COLS - ((x0 + 1) * 2);
-    int high = LINES - ((y0 + 1) * 2);
-    WINDOW *help = newwin(high, wide, y0, x0);
-    WINDOW *data = newpad(2 + SIZEOF(commands), wide - 4);
+    int used = 0;
     unsigned n;
-    int ch = ERR;
+    char **msgs = typeCalloc(char *, 3 + SIZEOF(commands));
 
-    begin_popup();
-
-    keypad(help, TRUE);
-    keypad(data, TRUE);
-    waddstr(data, "Defined form edit/traversal keys:\n");
+    msgs[used++] = strdup("Defined form edit/traversal keys:");
     for (n = 0; n < SIZEOF(commands); ++n) {
+       char *msg;
        const char *name;
+       const char *code = keyname(commands[n].code);
+       size_t need = 5;
 #ifdef NCURSES_VERSION
        if ((name = form_request_name(commands[n].result)) == 0)
 #endif
            name = commands[n].help;
-       wprintw(data, "%s -- %s\n",
-               keyname(commands[n].code),
-               name != 0 ? name : commands[n].help);
+       need = 5 + strlen(code) + strlen(name);
+       msg = typeMalloc(char, need);
+       _nc_SPRINTF(msg, _nc_SLIMIT(need) "%s -- %s", code, name);
+       msgs[used++] = msg;
+    }
+    msgs[used++] =
+       strdup("Arrow keys move within a field as you would expect.");
+    msgs[used] = 0;
+    popup_msg2(stdscr, msgs);
+    for (n = 0; msgs[n] != 0; ++n) {
+       free(msgs[n]);
     }
-    waddstr(data, "Arrow keys move within a field as you would expect.");
-    y2 = getcury(data);
+    free(msgs);
+}
 
-    do {
-       switch (ch) {
-       case KEY_HOME:
-           y1 = 0;
-           break;
-       case KEY_END:
-           y1 = y2;
-           break;
-       case KEY_PREVIOUS:
-       case KEY_PPAGE:
-           if (y1 > 0) {
-               y1 -= high / 2;
-               if (y1 < 0)
-                   y1 = 0;
-           } else {
-               beep();
-           }
-           break;
-       case KEY_NEXT:
-       case KEY_NPAGE:
-           if (y1 < y2) {
-               y1 += high / 2;
-               if (y1 >= y2)
-                   y1 = y2;
-           } else {
-               beep();
-           }
-           break;
-       case CTRL('P'):
-       case KEY_UP:
-           if (y1 > 0)
-               --y1;
-           else
-               beep();
-           break;
-       case CTRL('N'):
-       case KEY_DOWN:
-           if (y1 < y2)
-               ++y1;
-           else
-               beep();
-           break;
-       default:
-           beep();
-           break;
-       case ERR:
-           break;
-       }
-       werase(help);
-       box(help, 0, 0);
-       wnoutrefresh(help);
-       pnoutrefresh(data, y1, 0, y0 + 1, x0 + 1, high, wide);
-       doupdate();
-    } while ((ch = wgetch(data)) != ERR && ch != QUIT && ch != ESCAPE);
-    werase(help);
-    wrefresh(help);
-    delwin(help);
-    delwin(data);
+static int
+offset_in_field(FORM *form)
+{
+    FIELD *field = current_field(form);
+    int currow, curcol;
+
+    form_getyx(form, currow, curcol);
+    return curcol + currow * (int) field->dcols;
+}
+
+static void
+inactive_field(FIELD *f)
+{
+    set_field_back(f, field_attrs(f)->background);
+}
 
-    end_popup();
+FieldAttrs *
+field_attrs(FIELD *f)
+{
+    return (FieldAttrs *) field_userptr(f);
 }
 
 static int
-offset_in_field(FORM * form)
+buffer_length(FIELD *f)
 {
-    FIELD *field = current_field(form);
-    return form->curcol + form->currow * field->dcols;
+    return field_attrs(f)->row_lengths[0];
 }
 
 static void
-inactive_field(FIELD * f)
+set_buffer_length(FIELD *f, int length)
 {
-    FieldAttrs *ptr = (FieldAttrs *) field_userptr(f);
-    set_field_back(f, ptr->background);
+    field_attrs(f)->row_lengths[0] = length;
+}
+
+/*
+ * The userptr is used in edit_field.c's inactive_field(), as well as for
+ * keeping track of the actual lengths of lines in a multiline field.
+ */
+void
+init_edit_field(FIELD *f, char *value)
+{
+    char empty[1];
+    FieldAttrs *ptr = field_attrs(f);
+    if (ptr == 0) {
+       int rows, cols, frow, fcol, nrow, nbuf;
+
+       ptr = typeCalloc(FieldAttrs, (size_t) 1);
+       ptr->background = field_back(f);
+       if (field_info(f, &rows, &cols, &frow, &fcol, &nrow, &nbuf) == E_OK) {
+           ptr->row_count = nrow;
+           ptr->row_lengths = typeCalloc(int, (size_t) nrow + 1);
+       }
+    }
+    if (value == 0) {
+       value = empty;
+       *value = '\0';
+    }
+    set_field_userptr(f, (void *) ptr);
+    set_field_buffer(f, 0, value);     /* will be formatted */
+    set_field_buffer(f, 1, value);     /* will be unformatted */
+    set_buffer_length(f, (int) strlen(value));
 }
 
 int
-edit_field(FORM * form, int *result)
+edit_field(FORM *form, int *result)
 {
     int ch = wgetch(form_win(form));
     int status;
     FIELD *before;
     unsigned n;
-    char lengths[80];
     int length;
-    char *buffer;
-    int before_row = form->currow;
-    int before_col = form->curcol;
+    int before_row;
+    int before_col;
     int before_off = offset_in_field(form);
 
+    form_getyx(form, before_row, before_col);
     before = current_field(form);
     set_field_back(before, A_NORMAL);
     if (ch <= KEY_MAX) {
@@ -333,9 +303,7 @@ edit_field(FORM * form, int *result)
     if (status == E_OK) {
        bool modified = TRUE;
 
-       length = 0;
-       if ((buffer = field_buffer(before, 1)) != 0)
-           length = atoi(buffer);
+       length = buffer_length(before);
        if (length < before_off)
            length = before_off;
        switch (*result) {
@@ -343,7 +311,7 @@ edit_field(FORM * form, int *result)
            length = before_off;
            break;
        case REQ_CLR_EOL:
-           if (before_row + 1 == before->rows)
+           if ((int) (before_row + 1) == (int) (before->rows))
                length = before_off;
            break;
        case REQ_CLR_FIELD:
@@ -358,12 +326,12 @@ edit_field(FORM * form, int *result)
                if (before_col > 0) {
                    --length;
                } else if (before_row > 0) {
-                   length -= before->cols + before_col;
+                   length -= (int) before->cols + before_col;
                }
            }
            break;
        case REQ_NEW_LINE:
-           length += before->cols;
+           length += (int) before->cols;
            break;
 #if 0
            /* FIXME: finish these */
@@ -441,14 +409,23 @@ edit_field(FORM * form, int *result)
            < MIN_FORM_COMMAND)
            ++length;
 
-       sprintf(lengths, "%d", length);
-       set_field_buffer(before, 1, lengths);
+       set_buffer_length(before, length);
     }
 
     if (current_field(form) != before)
        inactive_field(before);
     return status;
 }
+
+void
+free_edit_field(FIELD *f)
+{
+    FieldAttrs *ptr = field_attrs(f);
+    if (ptr != 0) {
+       free(ptr->row_lengths);
+       free(ptr);
+    }
+}
 #else
 
 extern void no_edit_field(void);