1656 lines
39 KiB
C
1656 lines
39 KiB
C
//
|
|
// Copyright (C) 2002,2001, 2000, 1999, Rildo Pragana, Jim Noeth,
|
|
// Andrew Cameron, David Essex.
|
|
// Copyright (C) 1993, 1991 Rildo Pragana.
|
|
//
|
|
// This library is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU Lesser General Public License
|
|
// as published by the Free Software Foundation; either version 2.1,
|
|
// or (at your option) any later version.
|
|
//
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
// License along with this library; see the file COPYING.LIB. If
|
|
// not, write to the Free Software Foundation, Inc., 59 Temple Place,
|
|
// Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
|
//
|
|
// Cobol Compiler Run Time Library
|
|
// Curses Screen I/O Functions - Screen frontedn
|
|
//
|
|
|
|
#include "htcoblib.h"
|
|
#include "mwindows.h"
|
|
|
|
#if defined(SunOS)
|
|
#include <curses.h>
|
|
#else
|
|
# if defined(__CYGWIN__)
|
|
# include <ncurses/ncurses.h>
|
|
# else
|
|
# if defined(__MINGW32__)
|
|
# include <curses.h> //# include <pdcurses.h>
|
|
# else
|
|
# include <curses.h>
|
|
# endif
|
|
# endif
|
|
#endif
|
|
|
|
#include "screenio.h"
|
|
#include "rterrors.h"
|
|
#include "config.h"
|
|
/* PDcurses 2.4 does not have the following defenetion */
|
|
#ifndef KEY_CODE_YES
|
|
#define KEY_CODE_YES 0x100 /* A wchar_t contains a key code */
|
|
#endif
|
|
|
|
static short fore_color; // Actual fore and back colors
|
|
static short back_color;
|
|
|
|
static int cursor_x = 0; // Actual screen position for dinamically
|
|
static int cursor_y = 0; // calculate +/- line/col
|
|
extern int bDecimalComma;
|
|
|
|
static struct KeyBinding *keyBindings;
|
|
int tcob_isZNum(char *p); // walter
|
|
//
|
|
// Initialize curses
|
|
//
|
|
int tcob_scr_init(){
|
|
int i;
|
|
initscr();
|
|
noecho();
|
|
cbreak();
|
|
keypad(stdscr,TRUE);
|
|
scrollok(stdscr,FALSE); //walter: turn off scroll possibility
|
|
nonl();
|
|
//raw();
|
|
noecho();
|
|
//walter 03-01-06 if (has_colors())
|
|
//walter 03-01-06 start_color();
|
|
|
|
keyBindings = tcob_get_keybindings();
|
|
// pair_content(0,&fore_color,&back_color); walter: pair_content first argument must be between 1 and COLOR_PAIRS-1
|
|
attrset(A_NORMAL);
|
|
|
|
//
|
|
// This is needed for pdcurses, that has all the pairs to 0-7
|
|
//
|
|
//walter 03-01-06 for(i=0;i<COLOR_PAIRS;i++)
|
|
//walter 03-01-06 init_pair(i,0,0);
|
|
if(has_colors()) { // temos suporte a cores
|
|
start_color();
|
|
}
|
|
attrset(A_NORMAL);
|
|
for(i = 0; i < COLOR_PAIRS; i++)
|
|
init_pair(i, i%COLORS, i/COLORS);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
//
|
|
// Close curses
|
|
//
|
|
void tcob_scr_finish(){
|
|
if(!isendwin())
|
|
endwin();
|
|
}
|
|
//
|
|
// Set len positions to c
|
|
//
|
|
static void tcob_scr_setchar(char c, unsigned int len){
|
|
unsigned int i;
|
|
for (i=0; i<len; i++)
|
|
addch(c);
|
|
}
|
|
//
|
|
// Get actual cursos position on the screen
|
|
//
|
|
int tcob_scr_getx(){
|
|
return cursor_x;
|
|
}
|
|
int tcob_scr_gety(){
|
|
return cursor_y;
|
|
}
|
|
|
|
/* Scroll screen up by one line, if needed, and
|
|
return if actually scrolled or not */
|
|
int tcob_scr_scrl() {
|
|
if (cursor_y >= (LINES-1)) {
|
|
scrollok(stdscr,TRUE); //walter: turn on scroll possibility
|
|
scrl(1); // scroll 1 line
|
|
scrollok(stdscr,FALSE); //walter: turn off scroll possibility
|
|
move(cursor_y,0);
|
|
cursor_x=0;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// Set cursos position on the screen
|
|
//
|
|
void tcob_scr_setyx(int y, int x){
|
|
move(y,x);
|
|
getyx(stdscr,cursor_y,cursor_x);
|
|
}
|
|
void tcob_scr_setx(int x){
|
|
tcob_scr_setyx(tcob_scr_gety(),x);
|
|
}
|
|
void tcob_scr_sety(int y){
|
|
tcob_scr_setyx(y,tcob_scr_getx());
|
|
}
|
|
//
|
|
// Get the status of keyboard.
|
|
//
|
|
// return TRUE if there is a char in the buffer and FALSE if not
|
|
//
|
|
int tcob_scr_kbdstatus(){
|
|
int c;
|
|
nodelay(stdscr,TRUE);
|
|
c=getch();
|
|
nodelay(stdscr,FALSE);
|
|
if (c==ERR) {
|
|
return 0;
|
|
}
|
|
ungetch(c);
|
|
return 1;
|
|
}
|
|
/*-------------------------------------------------------------------------*\
|
|
| |
|
|
| tcob_scr_action_for_key |
|
|
| Looks in the table which is the action to return for the key passed. |
|
|
| If exists the SCREEN STATUS field moves the value in the table to it. |
|
|
| |
|
|
\*-------------------------------------------------------------------------*/
|
|
|
|
int tcob_scr_action_for_key(int key,int *status) {
|
|
struct KeyBinding *binding=NULL;
|
|
struct KeyBinding *pbindings;
|
|
|
|
|
|
for(pbindings=keyBindings; pbindings->keyCode!=0; pbindings++) {
|
|
if (pbindings->keyCode == key) {
|
|
binding=pbindings;
|
|
break;
|
|
}
|
|
}
|
|
if (binding==NULL) {
|
|
return EDIT_NOP;
|
|
}
|
|
*status = binding->screenStatus;
|
|
return binding->action;
|
|
|
|
}
|
|
|
|
/*
|
|
check the configuration for "auto clean all" setting
|
|
*/
|
|
int tcob_autocleanall() {
|
|
struct KeyBinding *binding=NULL;
|
|
struct KeyBinding *pbindings;
|
|
|
|
for(pbindings=keyBindings; pbindings->keyCode!=0; pbindings++) {
|
|
if (pbindings->keyCode == TCOBKEY_AUTOCLEANALL) {
|
|
binding=pbindings;
|
|
break;
|
|
}
|
|
}
|
|
if (binding==NULL) {
|
|
return 0;
|
|
}
|
|
return binding->screenStatus;
|
|
}
|
|
|
|
//
|
|
// Returns the curses color code from the cobol color number
|
|
//
|
|
static int get_curses_color(int cobol_color) {
|
|
|
|
unsigned int colour = COLOR_BLACK;
|
|
// switch(cobol_color % 8) {
|
|
switch(cobol_color % COLORS) {
|
|
case TC_BLUE:
|
|
colour = COLOR_BLUE;
|
|
break;
|
|
case TC_GREEN:
|
|
colour = COLOR_GREEN;
|
|
break;
|
|
case TC_CYAN:
|
|
colour = COLOR_CYAN;
|
|
break;
|
|
case TC_RED:
|
|
colour = COLOR_RED;
|
|
break;
|
|
case TC_MAGENTA:
|
|
colour = COLOR_MAGENTA;
|
|
break;
|
|
case TC_YELLOW:
|
|
colour = COLOR_YELLOW;
|
|
break;
|
|
case TC_WHITE:
|
|
colour = COLOR_WHITE;
|
|
break;
|
|
case TC_BLACK:
|
|
default:
|
|
break;
|
|
}
|
|
return colour;
|
|
}
|
|
|
|
/*static int get_curses_color(int cobol_color) {
|
|
// Color numbers from standard
|
|
//
|
|
// 0 - black
|
|
// 1 - blue
|
|
// 2 - green
|
|
// 3 - cyan
|
|
// 4 - red
|
|
// 5 - magenta
|
|
// 6 - brown/yellow
|
|
// 7 - white
|
|
//
|
|
// Curses colors
|
|
// #define COLOR_BLACK 0
|
|
// #define COLOR_RED 1
|
|
// #define COLOR_GREEN 2
|
|
// #define COLOR_YELLOW 3
|
|
// #define COLOR_BLUE 4
|
|
// #define COLOR_MAGENTA 5
|
|
// #define COLOR_CYAN 6
|
|
// #define COLOR_WHITE 7
|
|
//
|
|
|
|
//switch(cobol_color % 8) {
|
|
switch(cobol_color % COLORS) {
|
|
case TC_BLACK: return COLOR_BLACK;
|
|
case TC_BLUE: return COLOR_BLUE;
|
|
case TC_GREEN: return COLOR_GREEN;
|
|
case TC_CYAN: return COLOR_CYAN;
|
|
case TC_RED: return COLOR_RED;
|
|
case TC_MAGENTA:return COLOR_MAGENTA;
|
|
case TC_YELLOW: return COLOR_YELLOW;
|
|
case TC_WHITE: return COLOR_WHITE;
|
|
default:return 0;
|
|
}
|
|
|
|
}*/
|
|
//
|
|
// sets the color for the next display
|
|
//
|
|
static void set_colors(){
|
|
int i;
|
|
// short fore,back;
|
|
/*walter 03-01-06
|
|
for(i = 0; i < COLOR_PAIRS; ++i) {
|
|
pair_content(i,&fore,&back);
|
|
if ((fore == fore_color) && (back == back_color)) {
|
|
break;
|
|
}
|
|
if ((fore == 0) && (back == 0)) {
|
|
init_pair(i,fore_color,back_color);
|
|
break;
|
|
}
|
|
}
|
|
*/
|
|
i=(back_color*8)+fore_color;
|
|
if (i != COLOR_PAIRS)
|
|
{
|
|
#ifdef CURSES_HAS_COLOR_SET
|
|
color_set(i,NULL);
|
|
#else
|
|
attrset(COLOR_PAIR(i));
|
|
#endif
|
|
bkgdset(COLOR_PAIR(i));
|
|
|
|
} else {
|
|
attrset(A_NORMAL);
|
|
}
|
|
|
|
}
|
|
/*-------------------------------------------------------------------------*\
|
|
| |
|
|
| set_attributes |
|
|
| |
|
|
\*-------------------------------------------------------------------------*/
|
|
static void set_atributes(struct ScrFld *pFld) {
|
|
attr_t iAttr=0;
|
|
chtype pos; // walter
|
|
short color; // walter
|
|
|
|
attrset(A_NORMAL);
|
|
|
|
if (pFld->iAttributes != -1)
|
|
{
|
|
if ((pFld->iAttributes & SCR_HIGHLIGHT) == SCR_HIGHLIGHT)
|
|
iAttr |= A_BOLD;
|
|
|
|
if ((pFld->iAttributes & SCR_LOWLIGHT) == SCR_LOWLIGHT)
|
|
iAttr |= A_DIM;
|
|
|
|
if ((pFld->iAttributes & SCR_UNDERLINE) == SCR_UNDERLINE)
|
|
iAttr |= A_UNDERLINE;
|
|
|
|
if ((pFld->iAttributes & SCR_REVERSE_VIDEO) == SCR_REVERSE_VIDEO)
|
|
iAttr |= A_REVERSE;
|
|
|
|
if ((pFld->iAttributes & SCR_BLINK) == SCR_BLINK) {
|
|
iAttr |= A_BLINK;
|
|
}
|
|
|
|
if ((pFld->iAttributes & SCR_BELL) == SCR_BELL)
|
|
beep();
|
|
|
|
if ((pFld->iAttributes & SCR_BLANK_SCREEN) == SCR_BLANK_SCREEN) {
|
|
clear();
|
|
tcob_scr_setyx(tcob_scr_gety(),tcob_scr_getx());
|
|
}
|
|
attron(iAttr);
|
|
}
|
|
|
|
if (has_colors() == TRUE) {
|
|
fore_color=COLOR_WHITE;
|
|
back_color=COLOR_BLACK;
|
|
pos = mvinch(pFld->iLine, pFld->iCol);
|
|
color = ( pos & A_COLOR ) / 256;
|
|
if (pFld->iFgColor != -1){
|
|
fore_color=get_curses_color(pFld->iFgColor);
|
|
} else { // walter, get the foreground color in screen
|
|
if(color)
|
|
fore_color=color % 8;
|
|
} // fim walter
|
|
if (pFld->iBgColor != -1) {
|
|
back_color=get_curses_color(pFld->iBgColor);
|
|
} else { // walter, get the background color in screen
|
|
if(color)
|
|
back_color=color / 8;
|
|
}
|
|
set_colors();
|
|
}
|
|
/*
|
|
|
|
|
|
chtype pos; // walter
|
|
unsigned int color; // walter
|
|
if (pFld->iAttributes != -1)
|
|
{
|
|
if (pFld->iAttributes & SCR_HIGHLIGHT) attron(A_BOLD);
|
|
else attroff(A_BOLD);
|
|
|
|
if (pFld->iAttributes & SCR_LOWLIGHT) attron(A_DIM);
|
|
else attroff(A_DIM);
|
|
|
|
if(pFld->iAttributes & SCR_UNDERLINE) attron(A_UNDERLINE);
|
|
else attroff(A_UNDERLINE);
|
|
|
|
if(pFld->iAttributes & SCR_REVERSE_VIDEO) attron(A_REVERSE);
|
|
else attroff(A_REVERSE);
|
|
|
|
if(pFld->iAttributes & SCR_BLINK) attron(A_BLINK);
|
|
else attroff(A_BLINK);
|
|
|
|
if(pFld->iAttributes & SCR_BELL)
|
|
beep();
|
|
if(pFld->iAttributes & SCR_BLANK_SCREEN) {
|
|
clear();
|
|
tcob_scr_setyx(tcob_scr_gety(),tcob_scr_getx());
|
|
}
|
|
}
|
|
if (pFld->iFgColor != -1){
|
|
fore_color=get_curses_color(pFld->iFgColor);
|
|
} else { // walter, get the foreground color in screen
|
|
pos = mvinch(pFld->iLine, pFld->iCol);
|
|
color = ( pos & A_COLOR ) / 256;
|
|
fore_color=color % 8;
|
|
} // fim walter
|
|
if (pFld->iBgColor != -1){
|
|
back_color=get_curses_color(pFld->iBgColor);
|
|
} else { // walter, get the background color in screen
|
|
pos = mvinch(pFld->iLine, pFld->iCol);
|
|
color = ( pos & A_COLOR ) / 256;
|
|
back_color=color / 8;
|
|
if(fore_color == 0 && back_color == 0)
|
|
fore_color = 7;
|
|
}
|
|
set_colors();
|
|
*/
|
|
}
|
|
/*-------------------------------------------------------------------------*\
|
|
| |
|
|
| _DisplayField |
|
|
| |
|
|
\*-------------------------------------------------------------------------*/
|
|
static void _DisplayField(struct ScrFld *pFld) {
|
|
set_atributes(pFld);
|
|
tcob_scr_setyx(pFld->iLine, pFld->iCol);
|
|
|
|
if(pFld->iAttributes & SCR_BLANK_LINE){ // erase all the current line
|
|
move(tcob_scr_gety(),0);
|
|
clrtoeol();
|
|
tcob_scr_setyx(tcob_scr_gety(),tcob_scr_getx());
|
|
}
|
|
if(pFld->iAttributes & SCR_ERASE_EOL) // erase to end of line
|
|
clrtoeol();
|
|
if(pFld->iAttributes & SCR_ERASE_EOS) // erase to end of screen
|
|
clrtobot();
|
|
if(pFld->iAttributes & SCR_BELL)
|
|
beep();
|
|
if(pFld->iAttributes & SCR_BLANK_SCREEN){
|
|
clear();
|
|
tcob_scr_setyx(tcob_scr_gety(),tcob_scr_getx());
|
|
}
|
|
|
|
if(pFld->iAttributes & SCR_SECURE) {
|
|
tcob_scr_setchar('*', pFld->fldScr.len);
|
|
} else {
|
|
if((pFld->iAttributes & SCR_BLANK_WHEN_ZERO) != SCR_BLANK_WHEN_ZERO) {
|
|
addnstr(pFld->caScr, pFld->fldScr.len);
|
|
} else {
|
|
unsigned int i, sign;
|
|
tcob_scr_setyx(pFld->iLine, pFld->iCol);
|
|
sign = tcob_extract_sign(&pFld->fldWk, pFld->caWk);
|
|
for(i = 0; i < pFld->fldWk.len; ++i) {
|
|
if(pFld->caWk[i] != '0')
|
|
break;
|
|
}
|
|
tcob_put_sign(&pFld->fldWk, pFld->caWk, sign);
|
|
if(i == pFld->fldWk.len)
|
|
tcob_scr_setchar(' ', pFld->fldScr.len);
|
|
else
|
|
addnstr(pFld->caScr, pFld->fldScr.len);
|
|
}
|
|
}
|
|
}
|
|
/*-------------------------------------------------------------------------*\
|
|
| |
|
|
| _DisplayForAccept |
|
|
| |
|
|
\*-------------------------------------------------------------------------*/
|
|
static void _DisplayForAccept(struct ScrFld *pFld) {
|
|
|
|
set_atributes(pFld);
|
|
tcob_scr_setyx(pFld->iLine, pFld->iCol);
|
|
|
|
if(pFld->iAttributes & SCR_BLANK_LINE)
|
|
clrtoeol();
|
|
|
|
if(pFld->iAttributes & SCR_SECURE)
|
|
tcob_scr_setchar('*', pFld->fldScr.len);
|
|
else if(pFld->iAttributes & SCR_NOECHO)
|
|
tcob_scr_setchar(' ', pFld->fldScr.len);
|
|
else
|
|
addnstr(pFld->caScr, pFld->fldScr.len);
|
|
}
|
|
void tcob_scr_display_field(struct ScrFld *pFld){
|
|
_DisplayField(pFld);
|
|
}
|
|
void tcob_scr_display_for_input(struct ScrFld *pFld){
|
|
_DisplayForAccept(pFld);
|
|
}
|
|
void tcob_scr_display(struct ScrFld *fields){
|
|
struct ScrFld *pFld;
|
|
|
|
for(pFld=fields; pFld; pFld=pFld->pNext) {
|
|
// if(pFld->fldFrom) { /* if we have a from field */
|
|
// tcob_move(pFld->fldFrom, pFld->caFrom, &(pFld->fldScr), pFld->caScr);
|
|
// }
|
|
tcob_scr_display_field(pFld);
|
|
tcob_scr_setx(tcob_scr_getx() + pFld->fldScr.len);
|
|
}
|
|
}
|
|
|
|
static int full_field(struct ScrFld *pFld) {
|
|
return ((pFld->charCount - pFld->decimals) >= (pFld->len - pFld->decimals));
|
|
}
|
|
|
|
static int first_pos(struct ScrFld *pFld) {
|
|
int t = pFld->fldScr.len - 1;
|
|
int pos = 0;
|
|
|
|
if (NUMERICFIELD(pFld->fldScr.type)) {
|
|
while (pos < t && pFld->caScr[pos] == ' ')
|
|
pos++;
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
static int last_pos(struct ScrFld *pFld) {
|
|
unsigned int b = (pFld->decimalPointPosition <= pFld->iScrPos);
|
|
int full = full_field(pFld);
|
|
int pos;
|
|
|
|
if (NUMERICFIELD(pFld->fldScr.type)) {
|
|
pos = pFld->fldScr.len - 1;
|
|
if (!b && !full) { /* cursor wasn't already over the decimal point */
|
|
if (pFld->decimalPointPosition >= 0)
|
|
pos = pFld->decimalPointPosition;
|
|
}
|
|
}
|
|
else {
|
|
pos = pFld->charCount;
|
|
if (pos == pFld->fldScr.len) pos--;
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*\
|
|
| |
|
|
| move_cursor_first |
|
|
| move_cursor_last |
|
|
| move_cursor_left |
|
|
| move_cursor_right |
|
|
| |
|
|
| This are helper functions for cob_accept_screen to help moving inside a |
|
|
| field. |
|
|
\*-------------------------------------------------------------------------*/
|
|
static void move_cursor_first(struct ScrFld *pFld) {
|
|
pFld->iScrPos = first_pos(pFld);
|
|
pFld->iFldPos = 0;
|
|
}
|
|
|
|
static void move_cursor_last(struct ScrFld *pFld) {
|
|
pFld->iScrPos = last_pos(pFld);
|
|
}
|
|
|
|
static int move_cursor_left(struct ScrFld *pFld) {
|
|
char cWk;
|
|
int p = first_pos(pFld);
|
|
int full = full_field(pFld);
|
|
|
|
if(pFld->iScrPos > p) {
|
|
--pFld->iFldPos;
|
|
--pFld->iScrPos;
|
|
if(pFld->iScrPos > p && EDITEDFIELD(pFld->fldScr.type)) {
|
|
while(pFld->iScrPos > p) {
|
|
if (DECIMALPOINT && !full) break;
|
|
cWk = pFld->caScr[pFld->iScrPos];
|
|
if((cWk != '.')
|
|
&& (cWk != ',')
|
|
&& (cWk != '/')
|
|
&& (cWk != '-'))
|
|
break;
|
|
--pFld->iScrPos;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
static int move_cursor_right(struct ScrFld *pFld) {
|
|
char cWk;
|
|
int full = full_field(pFld);
|
|
int l = last_pos(pFld);
|
|
int f = first_pos(pFld);
|
|
|
|
if (pFld->iScrPos < l) {
|
|
++pFld->iScrPos;
|
|
++pFld->iFldPos;
|
|
if (EDITEDFIELD(pFld->fldScr.type)) {
|
|
while(pFld->iScrPos < l) {
|
|
if (DECIMALPOINT && !full) break;
|
|
cWk = pFld->caScr[pFld->iScrPos];
|
|
if((cWk != '.')
|
|
&& (cWk != ',')
|
|
&& (cWk != '/')
|
|
&& (cWk != '-'))
|
|
break;
|
|
++pFld->iScrPos;
|
|
}
|
|
}
|
|
if (pFld->iScrPos < f)
|
|
pFld->iScrPos = f;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*static void shift_right(char *source, int pos, int len) {
|
|
char *p = source + pos;
|
|
|
|
len--;
|
|
memmove(p+1, p, len);
|
|
*p = ' ';
|
|
}*/
|
|
|
|
static void shift_left(char *source, int pos, int len) {
|
|
char *p = source + pos;
|
|
|
|
len--;
|
|
memcpy(p, p+1, len);
|
|
*(p+len) = ' ';
|
|
}
|
|
|
|
static void calculate_charcount(struct ScrFld *pFld) {
|
|
int j, k, l;
|
|
char c;
|
|
|
|
if (!NUMERICFIELD(pFld->fldScr.type)) {
|
|
k = pFld->fldWk.len;
|
|
j = pFld->iScrPos;
|
|
while (--k > j && pFld->caWk[k] == ' ');
|
|
if (k >= pFld->charCount)
|
|
pFld->charCount = k + 1;
|
|
}
|
|
else if DISPLAYFIELD(pFld->fldScr.type){
|
|
j = -1;
|
|
k = pFld->fldWk.len;
|
|
while (++j < k && pFld->caWk[j] == '0');
|
|
pFld->charCount = k- j;
|
|
}
|
|
else { /* edited */
|
|
k = pFld->fldScr.len;
|
|
j = -1;
|
|
l = 0;
|
|
while (++j < k) {
|
|
c = pFld->caScr[j];
|
|
if (c >= '0' && c <= '9') l++;
|
|
pFld->charCount = l;
|
|
}
|
|
}
|
|
}
|
|
|
|
static int createdRoomToField; /* true if you need shift the field
|
|
to alocate space to a digit */
|
|
|
|
static void display_field(struct ScrFld *pFld) {
|
|
int j, k;
|
|
|
|
tcob_move(&pFld->fldScr, pFld->caScr, &pFld->fldWk, pFld->caWk);
|
|
tcob_move(&pFld->fldWk, pFld->caWk, &pFld->fldScr, pFld->caScr);
|
|
calculate_charcount(pFld);
|
|
createdRoomToField = 0;
|
|
/* RP -- we never get a DISPLAYFIELD here, as it is being faked as EDITED!! */
|
|
if (DISPLAYFIELD(pFld->fldScr.type)) {
|
|
j = -1;
|
|
k = pFld->fldWk.len;
|
|
while (++j < k && pFld->caScr[j] == '0')
|
|
pFld->caScr[j] = ' ';
|
|
if (pFld->charCount < pFld->fldWk.len) { /* we need room to the cursor */
|
|
shift_left(pFld->caScr, 0, pFld->fldScr.len);
|
|
createdRoomToField = 1;
|
|
}
|
|
}
|
|
else
|
|
if (EDITEDFIELD(pFld->fldScr.type)
|
|
&& !HASDECIMALPOINT
|
|
&& !HASSIGN
|
|
&& pFld->charCount < pFld->fldWk.len) { /* we need room to the cursor */
|
|
shift_left(pFld->caScr, 0, pFld->fldScr.len);
|
|
createdRoomToField = 1;
|
|
}
|
|
|
|
_DisplayForAccept(pFld);
|
|
}
|
|
|
|
static void remove_char(struct ScrFld *pFld) {
|
|
if (NUMERICFIELD(pFld->fldScr.type)) {
|
|
pFld->caScr[pFld->iScrPos] = ' ';
|
|
display_field(pFld);
|
|
if (!createdRoomToField || pFld->iScrPos < first_pos(pFld))
|
|
move_cursor_right(pFld);
|
|
}
|
|
else {
|
|
shift_left(pFld->caScr, pFld->iScrPos, (pFld->fldScr.len - pFld->iScrPos));
|
|
display_field(pFld);
|
|
}
|
|
}
|
|
|
|
static void process_special_char(struct ScrFld *pFld, int iKey) {
|
|
int j;
|
|
|
|
if (iKey == CDECIMALPOINT) {
|
|
if (pFld->decimalPointPosition < 0) {
|
|
beep();
|
|
return;
|
|
}
|
|
pFld->iScrPos = pFld->decimalPointPosition + 1;
|
|
return;
|
|
}
|
|
if (iKey == CTHOUSANDSEPARATOR) {
|
|
j = pFld->iScrPos;
|
|
while (j < pFld->fldScr.len && pFld->caScr[j] != CTHOUSANDSEPARATOR)
|
|
j++;
|
|
j++;
|
|
if (j >= pFld->fldScr.len) {
|
|
beep();
|
|
return;
|
|
}
|
|
pFld->iScrPos = j;
|
|
return;
|
|
}
|
|
if (iKey == '-' || iKey == '+') {
|
|
if (pFld->signPosition < 0) {
|
|
beep();
|
|
return;
|
|
}
|
|
pFld->caScr[pFld->signPosition] = (char)iKey;
|
|
return;
|
|
}
|
|
}
|
|
|
|
static int fill_field(struct ScrFld *pFld, int iKey) {
|
|
int ret = 0;
|
|
int l;
|
|
int digit;
|
|
|
|
if(pFld->fldWk.type != DTYPE_ALPHANUMERIC) { // numeric input
|
|
digit = ((iKey >= '0') && (iKey <= '9'));
|
|
if (!digit &&
|
|
(iKey != '-') &&
|
|
(iKey != '+') &&
|
|
(iKey != CTHOUSANDSEPARATOR) &&
|
|
(iKey != CDECIMALPOINT)) {
|
|
beep();
|
|
iKey = 0;
|
|
}
|
|
else
|
|
if (!digit) {
|
|
process_special_char(pFld, iKey);
|
|
display_field(pFld);
|
|
iKey = 0;
|
|
}
|
|
else
|
|
if (pFld->iScrPos == pFld->signPosition) {
|
|
if (full_field(pFld)) {
|
|
beep();
|
|
iKey = 0;
|
|
}
|
|
else {
|
|
shift_left(pFld->caScr, 0, pFld->iScrPos);
|
|
}
|
|
}
|
|
}
|
|
if ( iKey ) {
|
|
int k;
|
|
/* upper & lower */
|
|
if (pFld->iAttributes & SCR_UPPER)
|
|
iKey=toupper(iKey);
|
|
if (pFld->iAttributes & SCR_LOWER)
|
|
iKey=tolower(iKey);
|
|
|
|
k = pFld->iScrPos;
|
|
if (DECIMALPOINT) {
|
|
shift_left(pFld->caScr, 0, pFld->decimalPointPosition);
|
|
k--;
|
|
}
|
|
pFld->caScr[k] = (char)iKey;
|
|
l = pFld->charCount;
|
|
display_field(pFld);
|
|
k = full_field(pFld);
|
|
if (pFld->charCount < l)
|
|
move_cursor_first(pFld);
|
|
else
|
|
if (!DECIMALPOINT || k)
|
|
ret = move_cursor_right(pFld);
|
|
ret = (pFld->charCount == pFld->fldWk.len) &&
|
|
(pFld->iScrPos == pFld->fldScr.len - 1) && !ret;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/* compute offset in screen field from digit position
|
|
pix -- the expanded picture for the screen field
|
|
pos -- position in the digits array
|
|
(something with pic like 9(n)V9(m))
|
|
*/
|
|
int scr_pos(char *pix, int pos) {
|
|
int n=0;
|
|
while (1) {
|
|
if (strchr("9ZXA",*(pix+n))) {
|
|
if (!pos) break;
|
|
pos--;
|
|
}
|
|
n++;
|
|
}
|
|
return n;
|
|
}
|
|
|
|
/* make sure no positions in the field are nonsense */
|
|
void fixField( int len, char *str, char *pix, char hasSign ) {
|
|
int found=0;
|
|
char *s=str;
|
|
if (hasSign) {
|
|
if (*s != '-' && *s != '+')
|
|
*s='+';
|
|
s++;
|
|
len--;
|
|
}
|
|
while (len) {
|
|
switch (*pix) {
|
|
case '9':
|
|
if (!isdigit(*s)) *s='0';
|
|
break;
|
|
case 'Z':
|
|
if (found) {
|
|
if (!isdigit(*s))
|
|
*s='0';
|
|
} else {
|
|
if (!isdigit(*s))
|
|
*s=' ';
|
|
else
|
|
found=1;
|
|
}
|
|
break;
|
|
case 'X':
|
|
case 'A':
|
|
if (((unsigned)*s) > 0x7f || ((unsigned)*s) < 0x20) {
|
|
*s = ' ';
|
|
}
|
|
break;
|
|
default:
|
|
pix++;
|
|
continue;
|
|
}
|
|
s++;
|
|
pix++;
|
|
len--;
|
|
}
|
|
}
|
|
|
|
/* check if a number has all digits filled */
|
|
int filledNum( char *s, char *pic ) {
|
|
while (*pic != '9' && *pic != 'Z') {
|
|
s++;
|
|
pic += 2;
|
|
}
|
|
return ((*s >= '1') && (*s <= '9'));
|
|
}
|
|
|
|
/* accept display (numeric) field */
|
|
int tcob_scr_accept_number(struct ScrFld *pFld,int *status){
|
|
int j, k, iKey,action,pos;
|
|
int maxpos,dpos,dp=0;
|
|
int blank=0,moved=0,hasz=0,is9edited=0,isZNum=0,atdp=0,hs=0;
|
|
char *pix;
|
|
char *s;
|
|
int tmppos,scr_corr,chk_ov=0;
|
|
int insmode=0;
|
|
|
|
/* if the accepted field is a refmod, don't auto-clean */
|
|
if (pFld->iAttributes & SCR_IS_REFMOD)
|
|
moved++;
|
|
|
|
//if (pFld->fldTo->type == DTYPE_EDITED) {
|
|
if (pFld->fldScr.type == DTYPE_EDITED) {
|
|
isZNum = tcob_isZNum(pFld->fldScr.pic);
|
|
if (!isZNum) {
|
|
if (tcob_hasZ(pFld->fldScr.pic))
|
|
hasz++;
|
|
else
|
|
is9edited++;
|
|
}
|
|
}
|
|
pix=tcob_picExpand( &(pFld->fldScr) );
|
|
s=pFld->caWk;
|
|
maxpos=pFld->fldWk.len-1;
|
|
dpos=pFld->fldWk.len-pFld->fldWk.decimals;
|
|
dp=pFld->fldWk.decimals;
|
|
if (*(pFld->fldWk.pic) == 'S') {
|
|
hs=1;
|
|
s++;
|
|
dpos--;
|
|
maxpos--;
|
|
}
|
|
/* Correct the discrepancy between the Wk field size
|
|
and the requested data field (why in the earth it is like this?!).
|
|
Anyway, we must align fields by the decimal point.*/
|
|
scr_corr = tcob_picEditedCompLength(&(pFld->fldScr))-pFld->fldWk.len+hs;
|
|
//scr_corr = 0;
|
|
|
|
tcob_move(&pFld->fldScr, pFld->caScr, &pFld->fldWk, pFld->caWk);
|
|
fixField(pFld->fldWk.len,pFld->caWk,pix,hs);
|
|
pos = 0;
|
|
if (hasz && !tcob_autocleanall()) {
|
|
moved++;
|
|
} else {
|
|
if (!is9edited) {
|
|
while (pos < maxpos && pos < (dpos-1)
|
|
&& (*(s+pos) == '0' || *(s+pos) == ' ')) pos++;
|
|
} else {
|
|
while (pos < maxpos && pos < (dpos-1)
|
|
&& (*(s+pos) == ' ')) pos++;
|
|
}
|
|
if (isZNum && pos==(dpos-1) && dp)
|
|
atdp=1;
|
|
}
|
|
while(1) {
|
|
tcob_move(&pFld->fldWk, pFld->caWk, &pFld->fldScr, pFld->caScr);
|
|
if (chk_ov) {
|
|
chk_ov=0;
|
|
if (*pFld->caScr != '0' && *pFld->caScr != ' ') {
|
|
pos++;
|
|
atdp=0;
|
|
}
|
|
}
|
|
tmppos=scr_pos(pix,pos+scr_corr);
|
|
if (blank && *(pFld->caScr+tmppos) == '0') {
|
|
*(pFld->caScr+tmppos)=' ';
|
|
}
|
|
_DisplayForAccept(pFld);
|
|
if (atdp) tmppos++;
|
|
tcob_scr_setyx(pFld->iLine, pFld->iCol + tmppos);
|
|
refresh();
|
|
iKey = getch();
|
|
if(iKey == 8) // walter
|
|
iKey = 0x107;
|
|
*status=0;
|
|
if ((iKey >= '0') && (iKey <= '9')) {
|
|
blank=0;
|
|
if (!moved) {
|
|
if (hs) *(pFld->caWk)='+';
|
|
memset(s,'0',pFld->fldWk.len);
|
|
if (!is9edited) {
|
|
if (!dp)
|
|
pos = maxpos;
|
|
else
|
|
pos = (dpos?dpos-1:dpos);
|
|
} else {
|
|
pos = 0;
|
|
}
|
|
moved=1;
|
|
}
|
|
if (!dp) {
|
|
/* integer numbers */
|
|
if (pos == maxpos &&
|
|
pos && (*s == '0' || *s == ' ')) {
|
|
*(s+pos) = iKey;
|
|
if (!is9edited) {
|
|
memmove(s,s+1,pos);
|
|
*(s+pos) = '0';
|
|
blank=1;
|
|
} else if (pFld->iAttributes & SCR_AUTO) {
|
|
return EDIT_DOWN_FIELD;
|
|
}
|
|
} else {
|
|
if (insmode) {
|
|
if (!hasz) {
|
|
memmove(s+pos+1,s+pos,maxpos-pos);
|
|
*(s+pos) = iKey;
|
|
} else {
|
|
if (pos) {
|
|
memmove(s,s+1,pos);
|
|
*(s+pos-1) = iKey;
|
|
}
|
|
}
|
|
if (pos == maxpos && (pFld->iAttributes & SCR_AUTO)) {
|
|
return EDIT_DOWN_FIELD;
|
|
}
|
|
} else {
|
|
*(s+pos) = iKey;
|
|
if (pos < maxpos) {
|
|
pos++;
|
|
} else if (pFld->iAttributes & SCR_AUTO) {
|
|
return EDIT_DOWN_FIELD;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
/* numbers with fractional contents -- insert mode */
|
|
if (insmode || atdp) {
|
|
//if (pos && pos < dpos) {
|
|
if (pos < dpos) {
|
|
if (atdp) {
|
|
/*if (*s == '0') {*/
|
|
if (*pFld->caScr == '0' ||
|
|
*pFld->caScr == ' ') {
|
|
memmove(s,s+1,pos+1);
|
|
*(s+pos) = iKey;
|
|
chk_ov=1;
|
|
/*if (*s!='0') {
|
|
pos++;
|
|
atdp=0;
|
|
}*/
|
|
} else {
|
|
atdp=0;
|
|
if (pos < maxpos) {
|
|
pos++;
|
|
} else if (pFld->iAttributes & SCR_AUTO) {
|
|
return EDIT_DOWN_FIELD;
|
|
}
|
|
}
|
|
} else {
|
|
if (isZNum) {
|
|
if (pos) {
|
|
memmove(s,s+1,pos);
|
|
*(s+pos-1) = iKey;
|
|
}
|
|
} else {
|
|
memmove(s,s+1,pos);
|
|
*(s+pos-1) = iKey;
|
|
}
|
|
}
|
|
} else if (pos >= dpos) {
|
|
if (pos < maxpos) {
|
|
memmove(s+pos+1,s+pos,maxpos-dpos);
|
|
}
|
|
*(s+pos) = iKey;
|
|
if (pos < maxpos) {
|
|
pos++;
|
|
} else if (pFld->iAttributes & SCR_AUTO) {
|
|
return EDIT_DOWN_FIELD;
|
|
}
|
|
}
|
|
/* fractional numbers -- replace mode */
|
|
} else {
|
|
if (atdp && *s == '0') {
|
|
continue;
|
|
}
|
|
*(s+pos) = iKey;
|
|
if (isZNum) {
|
|
atdp=0;
|
|
if (pos < maxpos) {
|
|
if (pos == (dpos-1)) {
|
|
if (*s!='0') {
|
|
pos++;
|
|
atdp=0;
|
|
} else {
|
|
atdp = 1;
|
|
}
|
|
} else {
|
|
pos++;
|
|
}
|
|
}
|
|
} else {
|
|
if (pos < maxpos) {
|
|
pos++;
|
|
} else if (pFld->iAttributes & SCR_AUTO) {
|
|
return EDIT_DOWN_FIELD;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else if (iKey == '+') {
|
|
if (hs) {
|
|
*(pFld->caWk)='+';
|
|
moved=1;
|
|
}
|
|
} else if (iKey == '-') {
|
|
if (hs) {
|
|
*(pFld->caWk)='-';
|
|
moved=1;
|
|
}
|
|
} else { // non data key pressed
|
|
action = tcob_scr_action_for_key(iKey,status);
|
|
switch(action) {
|
|
case EDIT_LEFT: /* move cursor to left */
|
|
if (isZNum) {
|
|
if (atdp) {
|
|
atdp=0;
|
|
} else if (pos+scr_corr) {
|
|
pos--;
|
|
if (pos==(dpos-1))
|
|
atdp=1;
|
|
}
|
|
} else {
|
|
if (!dp && blank && pos==maxpos && *(s+pos) == '0') {
|
|
memmove(s+1,s,pos);
|
|
*s='0';
|
|
} else if (pos+scr_corr) {
|
|
pos--;
|
|
}
|
|
}
|
|
blank=0;
|
|
moved=1;
|
|
break;
|
|
case EDIT_RIGHT: /* move cursor to right */
|
|
blank=0;
|
|
if (isZNum) {
|
|
if (atdp) {
|
|
atdp=0;
|
|
if (pos < maxpos)
|
|
pos++;
|
|
} else {
|
|
if (pos==(dpos-1)) {
|
|
atdp=1;
|
|
} else {
|
|
if (pos < maxpos)
|
|
pos++;
|
|
}
|
|
}
|
|
} else {
|
|
if (!is9edited && !dp && pos==maxpos &&
|
|
(*s == '0' || *s == ' ')) {
|
|
memmove(s,s+1,pos);
|
|
*(s+pos) = '0';
|
|
blank=1;
|
|
} else if (pos < maxpos) {
|
|
pos++;
|
|
}
|
|
}
|
|
moved=1;
|
|
break;
|
|
case EDIT_FIRST:
|
|
blank=0;
|
|
pos=0;
|
|
while (*(pFld->caScr+pos) == ' ') pos++;
|
|
break;
|
|
case EDIT_LAST:
|
|
blank=0;
|
|
pos = maxpos;
|
|
break;
|
|
case EDIT_BACKSPACE:
|
|
if (!insmode) {
|
|
if (pos && (pos < dpos || pos > dpos)) {
|
|
if (pos != (dpos-1)) {
|
|
pos--;
|
|
*(s+pos)='0';
|
|
} else {
|
|
if (blank) {
|
|
memmove(s+1,s,pos-1);
|
|
*s='0';
|
|
} else {
|
|
if (atdp) {
|
|
memmove(s+1,s,pos);
|
|
*s='0';
|
|
} else {
|
|
*(s+pos-1)='0';
|
|
pos--;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (pos) {
|
|
pos--;
|
|
*(s+pos)='0';
|
|
}
|
|
}
|
|
} else {
|
|
if ((dp && pos < dpos) || !dp) {
|
|
if (pos+scr_corr) {
|
|
if (atdp) {
|
|
memmove(s+1,s,pos);
|
|
*s='0';
|
|
} else if (pos-1) {
|
|
memmove(s+1,s,pos-1);
|
|
*s='0';
|
|
}
|
|
}
|
|
} else {
|
|
if (pos > dpos && (pos+scr_corr)) {
|
|
if (insmode) {
|
|
memmove(s+pos-1,s+pos,maxpos-pos+1);
|
|
*(s+maxpos)='0';
|
|
} else {
|
|
*(s+pos-1)='0';
|
|
pos--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case EDIT_DELETE:
|
|
if (blank && pos == maxpos) {
|
|
continue;
|
|
}
|
|
blank=0;
|
|
if (pos < dpos) {
|
|
if (pos+scr_corr) {
|
|
memmove(s+1,s,pos);
|
|
*(s+scr_corr) = '0';
|
|
if (pos < maxpos)
|
|
pos++;
|
|
}
|
|
} else if (dp) {
|
|
memmove(s+pos,s+pos+1,maxpos-pos);
|
|
*(s+maxpos)='0';
|
|
}
|
|
break;
|
|
case EDIT_INSERT: /* toggle insert mode */
|
|
if (insmode)
|
|
insmode=0;
|
|
else
|
|
insmode=1;
|
|
moved=1;
|
|
break;
|
|
case EDIT_CLEAR: /* clear the current field */
|
|
blank=0;
|
|
memset(pFld->caScr,' ',pFld->fldScr.len);
|
|
break;
|
|
case EDIT_CLEAR_TOEND: /* Clear to the end of field */
|
|
blank=0;
|
|
j = pFld->fldScr.len - pFld->iFldPos - 1;
|
|
k = pFld->iFldPos;
|
|
memset(pFld->caScr + k,' ',j);
|
|
break;
|
|
case EDIT_DECIMALPT:
|
|
if (dp && pos < dpos && !atdp) {
|
|
memmove(s+dpos-pos,s,pos);
|
|
memset(s,'0',dpos-pos);
|
|
pos=dpos;
|
|
}
|
|
if (atdp)
|
|
pos=dpos;
|
|
atdp=0;
|
|
moved=1;
|
|
break;
|
|
default:
|
|
tcob_move(&pFld->fldScr, pFld->caScr,
|
|
&pFld->fldWk, pFld->caWk);
|
|
free(pix);
|
|
return action;
|
|
}
|
|
}
|
|
}
|
|
free(pix);
|
|
return EDIT_TERMINATE;
|
|
}
|
|
|
|
/* verify if character is valid against picture mask char */
|
|
static int valid_char(int c, int picc) {
|
|
switch (picc) {
|
|
case '9':
|
|
case 'Z':
|
|
if (isdigit(c))
|
|
return 1;
|
|
else
|
|
break;
|
|
case 'A':
|
|
if (isalpha(c))
|
|
return 1;
|
|
else
|
|
break;
|
|
case 'X':
|
|
if (c <= 0xff && c >= 0x20)
|
|
return 1;
|
|
else
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* clean a field following its picture mask */
|
|
static void clean_field(char *s, char *pix) {
|
|
while (*pix) {
|
|
if (*pix == '9') {
|
|
*s++ = '0';
|
|
} else if (*pix == 'A' || *pix == 'X' || *pix == 'Z') {
|
|
*s++ = ' ';
|
|
}
|
|
pix++;
|
|
}
|
|
}
|
|
|
|
int tcob_scr_accept_edited(struct ScrFld *pFld,int *status){
|
|
int j, k, iKey,action,pos;
|
|
int maxpos=0;
|
|
int moved=0;
|
|
char *pix;
|
|
char *s;
|
|
int tmppos;
|
|
int insmode=0;
|
|
|
|
insmode=0;
|
|
if (pFld->iAttributes & SCR_IS_REFMOD) {
|
|
pix=tcob_picExpand( &(pFld->fldWk) );
|
|
} else {
|
|
pix=tcob_picExpand( &(pFld->fldScr) );
|
|
}
|
|
s=pFld->caWk;
|
|
maxpos=pFld->fldWk.len-1;
|
|
|
|
/* if the accepted field is a refmod, don't auto-clean */
|
|
if (pFld->iAttributes & SCR_IS_REFMOD)
|
|
moved++;
|
|
|
|
pos = 0;
|
|
if (pFld->fldScr.type != 'X' && pFld->fldScr.type != 'D') {
|
|
while (pos < maxpos && *(s+pos) == ' ') pos++;
|
|
} else {
|
|
if (!tcob_autocleanall())
|
|
moved++;
|
|
}
|
|
|
|
while(1) {
|
|
tcob_move(&pFld->fldWk, pFld->caWk, &pFld->fldScr, pFld->caScr);
|
|
tmppos=scr_pos(pix,pos);
|
|
_DisplayForAccept(pFld);
|
|
tcob_scr_setyx(pFld->iLine, pFld->iCol + tmppos);
|
|
refresh();
|
|
iKey = getch();
|
|
if(iKey == 8) // walter
|
|
iKey = 0x107;
|
|
//walter garrote
|
|
/* upper & lower */
|
|
if (pFld->iAttributes & SCR_UPPER)
|
|
iKey=toupper(iKey);
|
|
if (pFld->iAttributes & SCR_LOWER)
|
|
iKey=tolower(iKey);
|
|
//fim
|
|
*status=0;
|
|
if (valid_char(iKey,*(pix+scr_pos(pix,pos)))) {
|
|
if (!moved) {
|
|
clean_field(s,pix);
|
|
//memset(s,' ',pFld->fldWk.len);
|
|
pos = 0;
|
|
moved=1;
|
|
if (pFld->fldWk.type != 'X') {
|
|
while (pos < maxpos && *(s+pos) == ' ') pos++;
|
|
}
|
|
}
|
|
if (insmode) {
|
|
if (pos < maxpos)
|
|
memmove(s+pos+1,s+pos,maxpos-pos);
|
|
*(s+pos) = iKey;
|
|
if (pos < maxpos) {
|
|
pos++;
|
|
} else if (pFld->iAttributes & SCR_AUTO) {
|
|
return EDIT_DOWN_FIELD;
|
|
}
|
|
} else {
|
|
*(s+pos) = iKey;
|
|
if (pos < maxpos) {
|
|
pos++;
|
|
} else if ((pFld->iAttributes & SCR_AUTO) &&
|
|
(*s != ' ')) {
|
|
return EDIT_DOWN_FIELD;
|
|
} else if (*s == ' ') {
|
|
memmove(s,s+1,maxpos);
|
|
if (pFld->fldWk.type == '9') // walter estava com =
|
|
*(s+maxpos) = '0';
|
|
else
|
|
*(s+maxpos) = ' ';
|
|
}
|
|
}
|
|
} else if (iKey > 0x7f || iKey < 0x20) { // non data key pressed
|
|
action = tcob_scr_action_for_key(iKey,status);
|
|
switch(action) {
|
|
case EDIT_LEFT: /* move cursor to left */
|
|
if (pos) {
|
|
pos--;
|
|
}
|
|
moved=1;
|
|
break;
|
|
case EDIT_RIGHT: /* move cursor to right */
|
|
if (pos < maxpos) {
|
|
pos++;
|
|
}
|
|
moved=1;
|
|
break;
|
|
case EDIT_FIRST:
|
|
pos=0;
|
|
while (*(pFld->caScr+pos) == ' ') pos++;
|
|
break;
|
|
case EDIT_LAST:
|
|
pos = maxpos;
|
|
break;
|
|
case EDIT_BACKSPACE:
|
|
if (!insmode) {
|
|
if (*(pix+scr_pos(pix,pos)) == '9')
|
|
*(s+pos)='0';
|
|
else
|
|
*(s+pos)=' ';
|
|
if (pos) { // walter inverti
|
|
pos--;
|
|
}
|
|
} else {
|
|
if (pos) {
|
|
memmove(s+pos-1,s+pos,maxpos-pos+1);
|
|
if (*(pix+scr_pos(pix,maxpos)) == '9')
|
|
*(s+maxpos)='0';
|
|
else
|
|
*(s+maxpos)=' ';
|
|
pos--;
|
|
}
|
|
}
|
|
break;
|
|
case EDIT_DELETE:
|
|
if (pos < maxpos) {
|
|
/*memmove(s+1,s,pos);
|
|
if (*(pix+scr_pos(pix,0)) == '9')
|
|
*(s) = '0';
|
|
else
|
|
*(s) = ' ';
|
|
pos++;*/
|
|
memmove(s+pos,s+pos+1,maxpos-pos);
|
|
*(s+maxpos) = ' ';
|
|
} else {
|
|
if (*(pix+scr_pos(pix,maxpos)) == '9')
|
|
*(s+maxpos) = '0';
|
|
else
|
|
*(s+maxpos) = ' ';
|
|
|
|
}
|
|
break;
|
|
case EDIT_INSERT: /* toggle insert mode */
|
|
if (insmode)
|
|
insmode=0;
|
|
else
|
|
insmode=1;
|
|
moved=1;
|
|
break;
|
|
case EDIT_CLEAR: /* clear the current field */
|
|
memset(pFld->caScr,' ',pFld->fldScr.len);
|
|
break;
|
|
case EDIT_CLEAR_TOEND: /* Clear to the end of field */
|
|
j = pFld->fldScr.len - pFld->iFldPos - 1;
|
|
k = pFld->iFldPos;
|
|
memset(pFld->caScr + k,' ',j);
|
|
break;
|
|
default:
|
|
free(pix);
|
|
return action;
|
|
}
|
|
}
|
|
}
|
|
free(pix);
|
|
return EDIT_TERMINATE;
|
|
}
|
|
|
|
//
|
|
// Accept one field
|
|
//
|
|
//
|
|
//
|
|
int tcob_scr_accept_field(struct ScrFld *pFld,int *status){
|
|
int j, k, iKey,bAtEnd,action;
|
|
//char type=pFld->fldScr.type;
|
|
|
|
if (pFld->fldTo->type == DTYPE_DISPLAY ||
|
|
(pFld->fldTo->type == DTYPE_EDITED &&
|
|
tcob_isNumEdit(pFld->fldScr.pic))) {
|
|
return (tcob_scr_accept_number(pFld,status));
|
|
}
|
|
//if (pFld->fldTo->type == DTYPE_EDITED) {
|
|
return (tcob_scr_accept_edited(pFld,status));
|
|
//}
|
|
|
|
pFld->charCount = -1;
|
|
display_field(pFld);
|
|
//_DisplayForAccept(pFld);
|
|
move_cursor_first(pFld);
|
|
set_atributes(pFld);
|
|
while(1) {
|
|
tcob_scr_setyx(pFld->iLine, pFld->iCol + pFld->iScrPos);
|
|
refresh();
|
|
iKey = getch();
|
|
*status=0;
|
|
if(!(iKey & KEY_CODE_YES) && !(iKey < ' ')) { // data key pressed
|
|
bAtEnd = fill_field(pFld, iKey);
|
|
if((bAtEnd) && (pFld->iAttributes & SCR_AUTO)) {
|
|
return EDIT_DOWN_FIELD;
|
|
}
|
|
} else { // non data key pressed
|
|
action = tcob_scr_action_for_key(iKey,status);
|
|
switch(action) {
|
|
case EDIT_LEFT: /* move cursor to left */
|
|
if (!(move_cursor_left(pFld))) {
|
|
beep();
|
|
}
|
|
break;
|
|
case EDIT_RIGHT: /* move cursor to right */
|
|
if (!(move_cursor_right(pFld))) {
|
|
beep();
|
|
}
|
|
break;
|
|
case EDIT_FIRST:
|
|
move_cursor_first(pFld);
|
|
break;
|
|
case EDIT_LAST:
|
|
move_cursor_last(pFld);
|
|
break;
|
|
case EDIT_BACKSPACE:
|
|
if(pFld->iScrPos > first_pos(pFld)) {
|
|
pFld->iScrPos--;
|
|
if (!EDITEDFIELD(pFld->fldScr.type))
|
|
remove_char(pFld);
|
|
else {
|
|
int k = pFld->iScrPos;
|
|
while (!isdigit(pFld->caScr[k]) && --k >= 0);
|
|
if (k >= 0) {
|
|
pFld->iScrPos = k;
|
|
remove_char(pFld);
|
|
}
|
|
else {
|
|
beep();
|
|
}
|
|
}
|
|
} else {
|
|
beep();
|
|
}
|
|
break;
|
|
case EDIT_DELETE: /* delete character under cursor */
|
|
if (pFld->iScrPos != pFld->signPosition)
|
|
remove_char(pFld);
|
|
else beep();
|
|
break;
|
|
case EDIT_INSERT: /* insert a character before cursor */
|
|
j = pFld->fldScr.len - pFld->iFldPos - 1;
|
|
k = pFld->iFldPos;
|
|
memmove(pFld->caWk+k+1, pFld->caWk+k, j);
|
|
pFld->caWk[k] = ' ';
|
|
_DisplayForAccept(pFld);
|
|
break;
|
|
case EDIT_CLEAR: /* clear the current field */
|
|
memset(pFld->caWk,' ',pFld->fldWk.len);
|
|
_DisplayForAccept(pFld);
|
|
break;
|
|
case EDIT_CLEAR_TOEND: /* Clear to the end of field */
|
|
j = pFld->fldWk.len - pFld->iFldPos - 1;
|
|
k = pFld->iFldPos;
|
|
memset(pFld->caWk + k,' ',j);
|
|
_DisplayForAccept(pFld);
|
|
break;
|
|
default: // replace character under cursor
|
|
return action;
|
|
}
|
|
}
|
|
}
|
|
return EDIT_TERMINATE;
|
|
}
|
|
|
|
//
|
|
// Accept all the fields until finish of function key pressed
|
|
// Return the value for the screen_status
|
|
//
|
|
int tcob_scr_accept(struct ScrFld *fields) {
|
|
int key_status,action;
|
|
struct ScrFld *pFld;
|
|
struct ScrFld *pFirst=NULL;
|
|
struct ScrFld *pLast=NULL;
|
|
struct ScrFld *pPrev=NULL;
|
|
char *pix,*s,*d;
|
|
int i;
|
|
|
|
for (pFld=fields; pFld; pFld=pFld->pNext) {
|
|
if(pFld->fldTo) { // cursor stop
|
|
if(!pFirst)
|
|
pFirst = pFld;
|
|
pLast = pFld;
|
|
}
|
|
}
|
|
|
|
if(!pFirst)
|
|
return 0;
|
|
|
|
for(pFld=pFirst;pFld;) { //main accept loop
|
|
if(pFld->fldTo) {
|
|
/* this don't work with all fields types:
|
|
prepare_input_field(pFld);*/
|
|
|
|
if (pFld->fldTo->type == '9') {
|
|
memmove(pFld->caWk,pFld->caScr,pFld->fldScr.len);
|
|
//pFld->fldWk.len = pFld->fldTo->len;
|
|
} else {
|
|
/* make our work copy have the significant characters */
|
|
if (pFld->iAttributes & SCR_IS_REFMOD) {
|
|
pix=tcob_picExpand( &(pFld->fldWk) );
|
|
} else {
|
|
pix=tcob_picExpand( &(pFld->fldScr) );
|
|
}
|
|
d = pFld->caWk;
|
|
s = pFld->caScr;
|
|
for (i=0;i<pFld->fldScr.len;i++) {
|
|
if (strchr("9ZXA",*(pix+i))) {
|
|
*d++ = *s++;
|
|
} else {
|
|
s++;
|
|
}
|
|
}
|
|
}
|
|
/*tcob_move(&pFld->fldWk, pFld->caWk, &pFld->fldScr,
|
|
pFld->caScr);*/
|
|
}
|
|
|
|
tcob_scr_display_for_input(pFld);
|
|
|
|
if (pFld != pPrev) { // if new field, put the cursor on position
|
|
// and display the last accepted
|
|
if (pPrev)
|
|
tcob_scr_display_field(pPrev);
|
|
|
|
}
|
|
|
|
pPrev = pFld;
|
|
action = tcob_scr_accept_field(pFld,&key_status);
|
|
tcob_move(&pFld->fldWk, pFld->caWk, &pFld->fldScr, pFld->caScr);
|
|
|
|
switch(action) {
|
|
case EDIT_FIRST_FIELD: /* move to first input field */
|
|
pFld = pFirst;
|
|
break;
|
|
case EDIT_LAST_FIELD: /* move to last input field */
|
|
pFld = pLast;
|
|
break;
|
|
case EDIT_DOWN_FIELD: /* move cursor to next input field */
|
|
/* find next input field in chain */
|
|
pFld = get_next_input_field(pFld);
|
|
break;
|
|
case EDIT_UP_FIELD: /* move cursor to prev input field */
|
|
/* find prev input field in chain */
|
|
pFld = get_prev_input_field(pFld);
|
|
break;
|
|
case EDIT_NEXT_FIELD: /* move cursor to next input field */
|
|
pFld = get_next_input_field(pFld);
|
|
if(!pFld) /* if last field rotate */
|
|
pFld = pFirst;
|
|
break;
|
|
case EDIT_PREV_FIELD: /* move cursor to prev input field */
|
|
/* find prev input field in chain */
|
|
pFld = get_prev_input_field(pFld);
|
|
if(!pFld) /* if last field rotate */
|
|
pFld = pLast;
|
|
break;
|
|
case EDIT_TERMINATE: /* we're done */
|
|
pFld = NULL;
|
|
break;
|
|
} // switch
|
|
} // main loop
|
|
if(pPrev)
|
|
tcob_scr_display_field(pPrev); // Display last accepted field
|
|
refresh();
|
|
return key_status;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* scr_curses.c */
|