X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=form%2Ffrm_driver.c;h=b07ca7cdd5899f46a7185efeb356578bb579568d;hp=160fdeb7cc85cc940cb8828eca4162086f9ea37f;hb=9208e1bde56ebb9cc550fd93034f1d4650518b11;hpb=c6f54649ed4bf49ec27a522816984d2290201438 diff --git a/form/frm_driver.c b/form/frm_driver.c index 160fdeb7..b07ca7cd 100644 --- a/form/frm_driver.c +++ b/form/frm_driver.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2013,2014 Free Software Foundation, Inc. * + * Copyright (c) 1998-2017,2018 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 * @@ -32,7 +32,7 @@ #include "form.priv.h" -MODULE_ID("$Id: frm_driver.c,v 1.114 2014/07/26 20:46:51 tom Exp $") +MODULE_ID("$Id: frm_driver.c,v 1.126 2018/04/28 19:03:36 Leon.Winter Exp $") /*---------------------------------------------------------------------------- This is the core module of the form library. It contains the majority @@ -99,9 +99,9 @@ Perhaps at some time we will make this configurable at runtime. #define GROW_IF_NAVIGATE (1) #if USE_WIDEC_SUPPORT -#define myADDNSTR(w, s, n) wadd_wchnstr(w, s, n) -#define myINSNSTR(w, s, n) wins_wchnstr(w, s, n) -#define myINNSTR(w, s, n) fix_wchnstr(w, s, n) +#define myADDNSTR(w, s, n) wide_waddnstr(w, s, n) +#define myINSNSTR(w, s, n) wide_winsnstr(w, s, n) +#define myINNSTR(w, s, n) wide_winnstr(w, s, n) #define myWCWIDTH(w, y, x) cell_width(w, y, x) #else #define myADDNSTR(w, s, n) waddnstr(w, s, n) @@ -239,9 +239,29 @@ check_pos(FORM *form, int lineno) Wide-character special functions --------------------------------------------------------------------------*/ #if USE_WIDEC_SUPPORT -/* like winsnstr */ +/* add like waddnstr, but using cchar_t* rather than char* + */ +static int +wide_waddnstr(WINDOW *w, const cchar_t *s, int n) +{ + int rc = OK; + + while (n-- > 0) + { + if ((rc = wadd_wch(w, s)) != OK) + break; + ++s; + } + return rc; +} + +/* insert like winsnstr, but using cchar_t* rather than char* + * + * X/Open Curses has no close equivalent; inserts are done only with wchar_t + * strings. + */ static int -wins_wchnstr(WINDOW *w, cchar_t *s, int n) +wide_winsnstr(WINDOW *w, const cchar_t *s, int n) { int code = ERR; int y, x; @@ -257,11 +277,13 @@ wins_wchnstr(WINDOW *w, cchar_t *s, int n) return code; } -/* win_wchnstr is inconsistent with winnstr, since it returns OK rather than - * the number of items transferred. +/* retrieve like winnstr, but using cchar_t*, rather than char*. + * + * X/Open Curses' closest equivalent, win_wchnstr(), is inconsistent with + * winnstr(), since it returns OK rather than the number of items transferred. */ static int -fix_wchnstr(WINDOW *w, cchar_t *s, int n) +wide_winnstr(WINDOW *w, cchar_t *s, int n) { int x; @@ -808,6 +830,7 @@ _nc_Position_Form_Cursor(FORM *form) { FIELD *field; WINDOW *formwin; + int row, col; if (!form) return (E_BAD_ARGUMENT); @@ -818,14 +841,17 @@ _nc_Position_Form_Cursor(FORM *form) field = form->current; formwin = Get_Form_Window(form); - wmove(form->w, form->currow, form->curcol); + col = Field_Has_Option(field, O_PUBLIC) ? form->curcol : form->begincol; + row = Field_Has_Option(field, O_PUBLIC) ? form->currow : form->toprow; + + wmove(form->w, row, col); if (Has_Invisible_Parts(field)) { /* in this case fieldwin isn't derived from formwin, so we have to move the cursor in formwin by hand... */ wmove(formwin, - field->frow + form->currow - form->toprow, - field->fcol + form->curcol - form->begincol); + field->frow + row - form->toprow, + field->fcol + col - form->begincol); wcursyncup(formwin); } else @@ -844,6 +870,7 @@ _nc_Position_Form_Cursor(FORM *form) | E_BAD_ARGUMENT - invalid form pointer | E_SYSTEM_ERROR - general error +--------------------------------------------------------------------------*/ +static bool move_after_insert = true; NCURSES_EXPORT(int) _nc_Refresh_Current_Field(FORM *form) { @@ -875,7 +902,8 @@ _nc_Refresh_Current_Field(FORM *form) else { if (form->curcol >= (form->begincol + field->cols)) - form->begincol = form->curcol - field->cols + 1; + form->begincol = form->curcol - field->cols + + (move_after_insert ? 1 : 0); } copywin(form->w, formwin, @@ -979,7 +1007,9 @@ Perform_Justification(FIELD *field, WINDOW *win) int len; int col = 0; - bp = Get_Start_Of_Data(field->buf, Buffer_Length(field)); + bp = (Field_Has_Option(field, O_NO_LEFT_STRIP) + ? field->buf + : Get_Start_Of_Data(field->buf, Buffer_Length(field))); len = (int)(After_End_Of_Data(field->buf, Buffer_Length(field)) - bp); if (len > 0) @@ -1021,9 +1051,14 @@ static void Undo_Justification(FIELD *field, WINDOW *win) { FIELD_CELL *bp; + int y, x; int len; - bp = Get_Start_Of_Data(field->buf, Buffer_Length(field)); + getyx(win, y, x); + + bp = (Field_Has_Option(field, O_NO_LEFT_STRIP) + ? field->buf + : Get_Start_Of_Data(field->buf, Buffer_Length(field))); len = (int)(After_End_Of_Data(field->buf, Buffer_Length(field)) - bp); if (len > 0) @@ -1032,6 +1067,7 @@ Undo_Justification(FIELD *field, WINDOW *win) wmove(win, 0, 0); myADDNSTR(win, bp, len); } + wmove(win, y, x); } /*--------------------------------------------------------------------------- @@ -1271,7 +1307,8 @@ _nc_Synchronize_Attributes(FIELD *field) copywin(form->w, formwin, 0, 0, field->frow, field->fcol, - field->rows - 1, field->cols - 1, 0); + field->frow + field->rows - 1, + field->fcol + field->cols - 1, 0); wsyncup(formwin); Buffer_To_Window(field, form->w); SetStatus(field, _NEWTOP); /* fake refresh to paint all */ @@ -1391,6 +1428,57 @@ _nc_Synchronize_Options(FIELD *field, Field_Options newopts) returnCode(res); } +/* + * Removes the focus from the current field of the form. + */ +void +_nc_Unset_Current_Field(FORM *form) +{ + FIELD *field = form->current; + + _nc_Refresh_Current_Field(form); + if (Field_Has_Option(field, O_PUBLIC)) + { + if (field->drows > field->rows) + { + if (form->toprow == 0) + ClrStatus(field, _NEWTOP); + else + SetStatus(field, _NEWTOP); + } + else + { + if (Justification_Allowed(field)) + { + Window_To_Buffer(form, field); + werase(form->w); + Perform_Justification(field, form->w); + if (Field_Has_Option(field, O_DYNAMIC_JUSTIFY) && + (form->w->_parent == 0)) + { + copywin(form->w, + Get_Form_Window(form), + 0, + 0, + field->frow, + field->fcol, + field->frow, + field->cols + field->fcol - 1, + 0); + wsyncup(Get_Form_Window(form)); + } + else + { + wsyncup(form->w); + } + } + } + } + delwin(form->w); + form->w = (WINDOW *)0; + form->current = 0; +} + /*--------------------------------------------------------------------------- | Facility : libnform | Function : int _nc_Set_Current_Field(FORM * form, @@ -1411,7 +1499,7 @@ _nc_Set_Current_Field(FORM *form, FIELD *newfield) T((T_CALLED("_nc_Set_Current_Field(%p,%p)"), (void *)form, (void *)newfield)); - if (!form || !newfield || !form->current || (newfield->form != form)) + if (!form || !newfield || (newfield->form != form)) returnCode(E_BAD_ARGUMENT); if ((form->status & _IN_DRIVER)) @@ -1425,51 +1513,10 @@ _nc_Set_Current_Field(FORM *form, FIELD *newfield) if ((field != newfield) || !(form->status & _POSTED)) { - if ((form->w) && + if (field && (form->w) && (Field_Has_Option(field, O_VISIBLE)) && (field->form->curpage == field->page)) - { - _nc_Refresh_Current_Field(form); - if (Field_Has_Option(field, O_PUBLIC)) - { - if (field->drows > field->rows) - { - if (form->toprow == 0) - ClrStatus(field, _NEWTOP); - else - SetStatus(field, _NEWTOP); - } - else - { - if (Justification_Allowed(field)) - { - Window_To_Buffer(form, field); - werase(form->w); - Perform_Justification(field, form->w); - if (Field_Has_Option(field, O_DYNAMIC_JUSTIFY) && - (form->w->_parent == 0)) - { - copywin(form->w, - Get_Form_Window(form), - 0, - 0, - field->frow, - field->fcol, - field->frow, - field->cols + field->fcol - 1, - 0); - wsyncup(Get_Form_Window(form)); - } - else - { - wsyncup(form->w); - } - } - } - } - delwin(form->w); - form->w = (WINDOW *)0; - } + _nc_Unset_Current_Field(form); field = newfield; @@ -4030,7 +4077,7 @@ Data_Entry_w(FORM *form, wchar_t c) cchar_t temp_ch; given[0] = c; - given[1] = 1; + given[1] = 0; setcchar(&temp_ch, given, 0, 0, (void *)0); if ((Field_Has_Option(field, O_BLANK)) && First_Position_In_Current_Field(form) && @@ -4143,6 +4190,12 @@ Data_Entry(FORM *form, int c) bool End_Of_Field = (((field->drows - 1) == form->currow) && ((field->dcols - 1) == form->curcol)); + if (Field_Has_Option(field, O_EDGE_INSERT_STAY)) + move_after_insert = !!(form->curcol + - form->begincol + - field->cols + + 1); + SetStatus(form, _WINDOW_MODIFIED); if (End_Of_Field && !Growable(field) && (Field_Has_Option(field, O_AUTOSKIP))) result = Inter_Field_Navigation(FN_Next_Field, form); @@ -4307,12 +4360,14 @@ form_driver(FORM *form, int c) const Binding_Info *BI = (Binding_Info *) 0; int res = E_UNKNOWN_COMMAND; + move_after_insert = true; + T((T_CALLED("form_driver(%p,%d)"), (void *)form, c)); if (!form) RETURN(E_BAD_ARGUMENT); - if (!(form->field)) + if (!(form->field) || !(form->current)) RETURN(E_NOT_CONNECTED); assert(form->page); @@ -4924,7 +4979,7 @@ _nc_Widen_String(char *source, int *lengthp) { if (pass) { - result[need] = source[passed]; + result[need] = (wchar_t)source[passed]; } ++need; ++passed;