📄 winp.c
字号:
if(cform->cfield->fconv=='9') {
deci_left(cform,cform->pbuf);
disp_field(cform,NULL,1);
temp=cform->cfield;
while(!cform->decimal&&cform->cfield==temp)
next_pos(cform);
break;
}
/* fall through to default */
default:
/* if conditional update feature is on, check to see if */
/* an editing key has been pressed. if it has not, */
/* then erase field and position cursor at beginning */
if(cform->cfield->mode==2) {
if(!edit) {
beg_pos(cform);
del_field(cform,cform->pbuf,1);
}
}
/* break keycode down to just the ASCII code portion. if */
/* ASCII code is zero, then it must be an extended key */
ch=(char)xch;
if(!isprint(ch)) break;
/* if lower, mixed, or upper case conversion */
/* was specified, then do the conversion */
if(*cform->pformat=='M' || cform->cfield->fconv=='M')
ch=touplow(cform->cfield->buf,cform->pbuf,ch);
else if(*cform->pformat=='U' || cform->cfield->fconv=='U')
ch=toupper(ch);
else if(*cform->pformat=='L' || cform->cfield->fconv=='L')
ch=tolower(ch);
/* see if current format string character is the left angle */
/* bracket (start of set inclusion). if so, search through */
/* the set of characters for the character matching */
/* keypress. if a matching character wasn't found, then the */
/* input character is invalid. */
if(*cform->pformat=='<') {
valid=NO;
p=cform->pformat;
cform->pformat++;
while(*cform->pformat!='>') {
if(ch==*cform->pformat) valid=YES;
cform->pformat++;
}
if(!valid) cform->pformat=p;
}
/* see if current format string character is the left square */
/* bracket (start of set exclusion). if so, search through */
/* the set of characters for the character matching */
/* keypress. if a matching character wasn't found, then the */
/* input character is valid. */
else {
if(*cform->pformat=='[') {
valid=YES;
p=cform->pformat;
cform->pformat++;
while(*cform->pformat!=']') {
if(ch==*cform->pformat) valid=NO;
cform->pformat++;
}
if(!valid) cform->pformat=p;
}
/* see if input character is a valid character */
/* of the current format character type */
else {
valid=cvaltype(ch,*cform->pformat);
}
}
/* if input character is a space, then even */
/* if it's not valid, make it valid for now */
if(ch==' ') valid=YES;
/* if input character is valid, display it */
if(valid) {
/* if at last position of last field, don't wrap-around */
if((cform->pbuf==(cform->cfield->buf+cform->cfield->lenbuf
-1))&&(cform->cfield==last_rec(cform))) {
valid=NO;
end_pos(cform);
}
temp=cform->cfield;
disp_char(cform,ch,valid);
if(!valid&&cform->cfield->fconv=='9') beg_pos(cform);
if(temp!=cform->cfield)
if((edit=cond_update(cform))==NO) continue;
/* if field is numeric, and we just passed the decimal */
/* point, right justify, space fill the left side of it */
if(valid) {
if(cform->cfield->fconv=='9'&&cform->decimal) {
deci_left(cform,cform->cfield->buf+
cform->cfield->decpos-1);
disp_field(cform,NULL,1);
}
}
}
}
/* turn on edit mode */
edit=YES;
}
}
/*---------------------------------------------------------------------------*/
/* this function will start the cursor at the 1st position in */
/* the field and advance it until we are at specified column */
static void adv_column(struct _form_t *cform,int col)
{
struct _field_t *temp;
temp=cform->cfield;
beg_pos(cform);
while(cform->cwcol<col) next_pos(cform);
if(cform->cfield!=temp) while(cform->cfield!=temp) prev_pos(cform);
}
/*---------------------------------------------------------------------------*/
/* this function takes care of a couple tasks to do after editing a field */
static void after_edit(struct _form_t *cform)
{
/* redisplay current field in field attribute */
disp_field(cform,NULL,0);
/* if an 'after' function was defined, call it */
call_func(cform->cfield->after);
/* turn off Insert mode */
cform->insert=OFF;
smcursor();
}
/*---------------------------------------------------------------------------*/
/* this function does a destructive backspace */
static void back_space(struct _form_t *cform)
{
/* decrement buffer pointer */
cform->pbuf--;
/* if buffer pointer is less than start of buffer, then validate */
/* field, display field, and go to previous field, end of line */
/* otherwise, decrement column, format string */
/* pointer, and back up one position */
if( cform->pbuf < cform->cfield->buf ) {
if(!goto_field(cform,FLD_PR)) end_line(cform);
}
else {
cform->cwcol--;
cform->pformat--;
prev_fchar(cform);
}
/* if insert mode is on, delete character under cursor */
/* otherwise, replace character with a space */
if(cform->insert)
del_char(cform);
else {
wprintc(cform->cwrow,cform->cwcol,cform->textattr,' ');
*cform->pbuf=' ';
}
}
/*---------------------------------------------------------------------------*/
/* this function sets current position to the beginning of the field */
static void beg_pos(struct _form_t *cform)
{
struct _field_t *cfield;
cfield = cform->cfield;
cform->cwrow = cfield->wrow;
cform->cwcol = cfield->wcol;
cform->pbuf = cfield->buf;
cform->pformat = cfield->format;
next_fchar(cform);
}
/*---------------------------------------------------------------------------*/
/* this function calls the given function, then checks all */
/* fields to see if any of their redisplay flags have been */
/* set. If so, then the field will be redisplayed. */
static void call_func(void (*func)(void))
{
register int err;
if(func!=NULL) {
err=whelpush();
(*func)();
if(!err) whelpop();
check_redisp(_winfo.active->form);
}
}
/*---------------------------------------------------------------------------*/
/* this function checks syntax of format string, returns length of field */
static void check_format(char *format,int *lenfld,int *lenbuf,int *decpos)
{
char *p,ch;
int valid=YES,deccount=0;
*lenbuf=0;
*lenfld=0;
*decpos=0;
p=format;
/* do while not end of string and string still valid */
while(*p && valid) {
/* test current character */
switch(*p) {
case '\"':
case '\'':
/* search for matching quote */
ch=*p++;
while(*p!=ch) {
/* check for premature end of string */
if(!*p) {
valid=NO;
break;
}
(*lenfld)++;
p++;
}
p++;
break;
case ' ':
/* skip spaces, they are used for readability */
p++;
break;
case '<': /* left angle bracket (start of inclusion set) */
/* search for matching angle bracket */
p++;
while(*p!='>') {
/* check for premature end of string */
if(!*p) {
valid=NO;
break;
}
p++;
}
(*lenfld)++;
(*lenbuf)++;
p++;
break;
case '[': /* left square bracket (start of exclusion set) */
/* search for matching square bracket */
p++;
while(*p!=']') {
/* check for premature end of string */
if(!*p) {
valid=NO;
break;
}
p++;
}
(*lenfld)++;
(*lenbuf)++;
p++;
break;
case '.': /* decimal point */
/* mark decimal position */
*decpos=(*lenbuf)+1;
(*lenfld)++;
p++;
/* make sure there is only 1 decimal point */
deccount++;
if(deccount>1) valid=NO;
break;
default:
/* see if character is a valid format character type */
if( cvaltype(0,*p) == -1 ) {
valid=NO;
break;
}
(*lenfld)++;
(*lenbuf)++;
p++;
}
}
/* if no decimal was found, "position" it at end of field */
if(!(*decpos)) *decpos=(*lenbuf)+1;
if(!valid) {
*lenbuf=0;
*lenfld=0;
*decpos=0;
}
}
/*---------------------------------------------------------------------------*/
static void check_redisp(struct _form_t *cform)
{
struct _field_t *test,*cfield;
/* search all fields in linked list for fields who have had */
/* their redisplay flag set. Redisplay all thos that have. */
for(test=cform->field;test!=NULL;test=test->prev) {
if(test->redisp) {
cfield=cform->cfield;
cform->cfield=test;
disp_field(cform,NULL,test==cfield?1:0);
cform->cfield=cfield;
test->redisp=OFF;
}
}
}
/*---------------------------------------------------------------------------*/
/* this function returns the given field's window */
/* column closest to the current window column */
static int closest_column(struct _form_t *cform,struct _field_t *field)
{
register int cwcol,wcol;
int tcol,lcol;
cwcol=cform->cwcol;
wcol=field->wcol;
lcol=wcol+field->lenfld-1;
if( (cwcol>=wcol) && (cwcol<=lcol) )
tcol=cwcol;
else
if(wcol<cwcol)
tcol=lcol;
else
tcol=wcol;
return(tcol);
}
/*---------------------------------------------------------------------------*/
/* this function prepares for conditional update */
static int cond_update(struct _form_t *cform)
{
/* if conditional update, then start cursor end of line */
if(cform->cfield->mode==2) {
if(!strblank(cform->pbuf)) end_line(cform);
return(NO);
}
return(YES);
}
/*---------------------------------------------------------------------------*/
/* this function will right justify, space fill numbers before the decimal */
static void deci_left(struct _form_t *cform,char *start)
{
char *p,*q,*left;
struct _field_t *cfield;
/* abbreviate pointer to current field */
cfield=cform->cfield;
left=cfield->buf+cfield->decpos-2;
/* blank out from starting position to left side of decimal */
for(p=start;p<=left;*p++=' ');
/* search for first space to left of decimal */
for(p=left;*p!=' '&&p>cfield->buf;p--);
if(p>cfield->buf) {
/* while q >= first position in field */
q=p;
while(q>=cfield->buf) {
for(;(*q==' ')&&(q>=cfield->buf);q--);
while((q>=cfield->buf)&&(*q!=' ')) {
*p--=*q;
*q--=' ';
}
}
}
/* change leading zeros to blanks */
q=left;
for(p=cfield->buf;*p==' '&&p<q;p++);
if(p<q) while(*p=='0'&&p<q) *p++=' ';
/* check for all blanks to left of decimal */
if(*left==' ') *left='0';
}
/*---------------------------------------------------------------------------*/
/* this function will right justify, space fill numbers before the decimal
point, and left justify, zero fill numbers after the decimal point */
static void deci_right(struct _form_t *cform,char *start)
{
char *p,*q,*last,*right;
struct _field_t *cfield;
/* abbreviate pointer to current field */
cfield=cform->cfield;
/* calculate last position and position to right of decimal */
last=cfield->buf+cfield->lenbuf-1;
right=cfield->buf+cfield->decpos-1;
/* blank out from start position to end of field */
for(p=start;p<=last;*p++=' ');
/* first do left side of decimal */
deci_left(cform,start);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -