return; /* incorrect */ if( x < 0 || x > width ) return; /* incorrect */ AID_LFT = MIN(LDX, maxlen); AID_RGT = MAX(0, MIN(maxlen, width-1 - LDX)); if( aid < *cur && x <= AID_LFT && oldshift > 0 ) goto Scroll; else if( aid > *cur && x >= AID_RGT && oldshift + width < maxlen ) goto Scroll; if( oldshift <= aid && aid < oldshift + width ) /* - */ goto Position; Scroll: if( aid >= *cur ) newshift = aid - AID_RGT; else newshift = aid - AID_LFT; if( newshift + width > maxlen || (len == maxlen && aid == len)) newshift = maxlen - width; if( newshift < 0 ) newshift = 0; if( newshift != oldshift ){ *shift = newshift; (*draw)(ptr); drawn = YES; } Position: if((x = aid - newshift) >= width && len != maxlen ) beep(); /* ERROR */ (*go)(ptr, x, !drawn ); *cur = aid; } /* at- */ void LePointAt( LineEdit *le, int at ){ /* at == len */ if( at < 0 || at > le->len ) return; if( le->pos == at ) return; /* */ LeCursorHide( le ); LeRoll( le, at, & le->pos, & le->shift, le->width, le->len, le->maxlen, LePoint, LeDraw, LINE_DX); le->pos = at; LeCursorShow( le ); } /* scroll bar */ void LePoint( LineEdit *le, int x, int eraseOld ){ if(le->scrollBar) (*le->scrollBar)(le, BAR_HOR, x + le->shift, le->maxlen+1 ); GetBack( le->savep, le->win); } /* scroll bar */ /* , len */ void LeReport( LineEdit *le ){ if(le->scrollBar) le->scrollBar (le, BAR_VER, le->len, le->maxlen+1 ); GetBack( le->savep, le->win); } /* */ void LeDraw( LineEdit *le ){ LeDrawLine( le, 0); } /* */ void LeDelCh( LineEdit *le ){ if( le->len <= 0 || le->pos < 0 || le->pos >= le->len ) return; LeCursorHide( le ); (void) cdelete( le->line, le->pos ); le->len --; LeDrawLine( le, le->pos - le->shift ); LeReport( le ); } /* */ void LeInsCh( LineEdit *le, int c ){ if( le->len < 0 || le->pos < 0 || le->pos > le->len ) return; LeCursorHide( le ); insert( le->line, le->pos, c ); le->len++; LeDrawLine( le, le->pos - le->shift ); LeReport( le ); } /* */ void LeRepCh( LineEdit *le, int c ){ if( le->len <= 0 || le->pos < 0 || le->pos >= le->len ) return; LeCursorHide( le ); le->line[ le->pos ] = c; LePutChar( le, le->pos - le-> shift ); } /* */ int LeInsStr( LineEdit *le, char *s){ int len = le->len, slen = strlen(s); register i; if( len + slen > le->maxlen ) slen = le->maxlen - len; if( ! slen ) return 0; for( i=0; i < slen ; i ++ ) insert( le->line, le->pos+i, s[i] ); le->len += slen; LeCursorHide( le ); LeDrawLine( le, le->pos - le->shift ); LePointAt( le, le->pos + slen ); LeReport( le ); return slen ; } /* */ int LeWerase( LineEdit *le, char *to ){ register i; register char *s = le->line; char c; if( to ) *to = '\0'; i = le->pos; if( s[i] == ' ' || s[i] == '\0' ){ /* */ for( --i; i >= 0 ; i-- ) if( s[i] != ' ' ) break; if( i < 0 || le->len == 0 ){ beep(); return NO; } } /* */ for( ; i >= 0 && s[i] != ' ' ; i-- ); i++; /* i < 0 || s[i] == ' ' */ LeCursorHide( le ); LePointAt( le, i ); while( s[i] != ' ' && s[i] != '\0' ){ c = cdelete( s, i ); if( to ) *to++ = c; le->len --; } /* */ while( s[i] == ' ' ){ c = cdelete( s, i ); le->len --; } if( to ) *to = '\0'; LeDrawLine( le, i - le->shift ); LeReport( le ); return YES; } /* le->line . le->maxlen . . le->win , . le->width . le->top - le->left win. le->insert = YES . le->nc = YES . le->histIn NULL. le->histOut NULL. le->showMe NULL. le->hideMe NULL. le->hitkeys NULL. le->handler NULL. le->scrollBar scroll bar- NULL. le->posMe . le->bg_attrib . le->fr_attrib . le->wl_attrib . le->sel_attrib . */ int LeEdit( LineEdit *le ){ int c; int nchar = 0; /* */ Info *inf; /* */ if( le->showMe ) if( (*le->showMe) (le) <= 0 ) return (-1); if( !le->win ) return (le->key = -1); Again: le -> pos = 0; le -> len = strlen( le->line ); le -> shift = 0; le -> cursorOn = NO; le->key = (-1); LeDraw( le ); if(le->posMe) (*le->posMe)(le); LePointAt(le, le->pos ); LePoint( le, le->pos - le->shift, NO ); LeReport( le ); for (;;) { LeCursorShow( le ); c = WinGetch(le->win); /* */ nchar++; /* */ INP: if( le->hitkeys && le->handler ){ HandlerReply reply; if( is_in(c, le->hitkeys)){ /* ? */ c = (*le->handler)(le, c, &reply); /* scroll bars */ LePoint( le, le->pos - le->shift, NO ); LeReport( le ); switch( reply ){ case HANDLER_CONTINUE: continue; case HANDLER_NEWCHAR: goto INP; case HANDLER_OUT: goto out; case HANDLER_AGAIN: /* reset */ LeCursorHide(le); goto Again; case HANDLER_SWITCH: default: break; /* goto switch(c) */ } } } sw: switch (c) { case KEY_RIGHT: /* */ if (le->pos != le->len && le->len > 0) LePointAt( le, le->pos + 1); break; case KEY_LEFT: /* */ if (le->pos > 0) LePointAt(le, le->pos - 1); break; case '\t': /* */ if (le->pos + 8 > le->len) LePointAt(le, le->len); else LePointAt(le, le->pos + 8); break; case KEY_BACKTAB: /* */ case ctrl('X'): if( le->pos - 8 < 0 ) LePointAt(le, 0); else LePointAt(le, le->pos - 8 ); break; case KEY_HOME: /* */ LePointAt(le, 0); break; case KEY_END: /* KEY_LL */ if( le->len > 0 ) LePointAt(le, le->len); break; case 0177: /* */ case KEY_BACKSPACE: case '\b': if (le->pos == 0) break; LePointAt(le, le->pos - 1); /* */ /* DC ... */ case KEY_F (6): /* */ case KEY_DC: if (! le->len || le->pos == le->len) break; LeDelCh(le); break; case KEY_UP: /* */ case KEY_DOWN: case KEY_NPAGE: case KEY_PPAGE: case KEY_F(4): if( ! le->histIn ) break; /* */ inf = HistSelect( le->histIn, wbegx(le->win) + le->pos - le->shift + 2, le->top + 1); if( inf == (Info *) NULL ) break; LeCursorHide( le ); strncpy( le->line, inf->s, le->maxlen ); goto Again; out: case '\r': case '\n': case ESC: /* - */ LeCursorHide( le ); if( c != ESC && le->histOut && *le->line ) /* */ HistAdd( le->histOut, le->line, 0); if( le->hideMe ) /* */ (*le->hideMe)(le); return (le->key = c); case KEY_F (8): /* */ case ctrl('U'): le->line[0] = '\0'; le->len = le->pos = le->shift = 0; LeCursorHide( le ); LeReport( le ); goto REWRITE; case KEY_F(0): /* F10: */ if( le->pos == le->len ) break; le->line[ le->pos ] = '\0'; le->len = strlen( le->line ); LeCursorHide( le ); LeDrawLine( le, le->pos - le->shift ); LeReport( le ); break; case ctrl('W'): /* */ LeWerase( le, NULL ); break; case ctrl('A'): /* */ LeCursorHide(le); /* RedrawScreen(); */ REWRITE: LeDraw(le); break; case KEY_F(7): /* / */ le->insert = ! le->insert; LeCursorHide( le ); break; #ifndef M_UNIX case ctrl('V'): /* */ nchar--; c = WinGetch(le->win); nchar++; if( c >= 0400 ) goto sw; goto Input; #endif case 0: break; default: /* */ if (c >= 0400 || ! isprint(c)) break; Input: if( le->nc && nchar == 1 && le->insert && /*le->pos == 0 &&*/ le->len != 0 ){ /* , /* /* */ le->shift = 0; le->len = le->pos = 1; le->line[0] = c; le->line[1] = '\0'; LeCursorHide( le ); LeReport( le ); goto REWRITE; } if (!le->insert) { /* REPLACE - */ if (le->pos == le->len) goto AddChar; /* INSERT */ LeRepCh( le, c ); LePointAt( le, le->pos + 1 ); } else { /* INSERT - */ AddChar: if( le->len >= le->maxlen ){ beep(); /* */ break; } LeInsCh( le, c ); LePointAt( le, le->pos + 1 ); } /* endif */ } /* endswitch */ } /* endfor */ } /* endfunc */ /* 22 */ /* ______________________________________________________________ */ /* - */ /* _______________________ table.h _________________________ */ typedef struct _Table { /* */ int nitems; /* */ Info *items; /* */ char *fmt; /* */ int key; /* , */ int current; /* */ int shift; /* */ WINDOW *win; /* */ int left, top, height, width; /* */ int space; /* */ int elen; /* . */ int tcols; /* */ int cols; /* */ int cutpos; /* */ int scrollok; /* ? */ int exposed; /* ? */ int elems; /* - */ int maxelems; /* - */ int maxshift; /* */ int bg_attrib, sel_attrib; /* */ Point savep; /* / */ int (*showMe)(struct _Table *tbl); void (*hideMe)(struct _Table *tbl); void (*scrollBar)(struct _Table *tbl, int whichbar, int n, int among); /* */ int *hitkeys; int (*handler)(struct _Table *tbl, int c, HandlerReply *reply); } Table; #define T_BOLD M_BOLD #define T_NOSEL I_NOSEL #define T_HATCH M_HATCH #define T_LABEL M_LABEL #define T_SET(m, i, flg) (((m)->items)[i]).fl |= (flg) #define T_CLR(m, i, flg) (((m)->items)[i]).fl &= ~(flg) #define T_TST(m, i, flg) ((((m)->items)[i]).fl & (flg)) #define T_ITEM(m, i) ((((m)->items)[i]).s) /* 'd' * : */ #define T_ITEMF(m, i, cut) \ ((m)->fmt && *(m)->fmt != 'd' ? \ TblConvert(T_ITEM((m), i), (m)->fmt, (cut)) : T_ITEM((m), i)) #define T_VISIBLE(tbl, new) ((tbl)->exposed == YES && \ (new) >= (tbl)->shift && (new) < (tbl)->shift + (tbl)->elems) #define TLABSIZE 2 /* */ #define T_REFUSED(t) ((t)->key < 0 || (t)->key == ESC ) int TblCount( Table *tbl ); void TblInit( Table *tbl, int forcedOneColumn ); void TblChkCur ( Table *tbl ); int TblChkShift( Table *tbl ); void TblChk ( Table *tbl ); char *TblConvert( char *s, char *fmt, int cutpos ); void TblPointAt ( Table *tbl, int snew ); void TblPoint ( Table *tbl, int snew, int eraseOld ); void TblDraw ( Table *tbl ); void TblDrawItem( Table *tbl, int at, int reverse, int selection); void TblBox ( Table *tbl, int at, int reverse, int hatched, int width, int axl, int axi, int ay); int TblClear( Table *tbl ); int TblPlaceByName( Table *tbl, char *p ); void TblReport( Table *tbl ); void TblTag ( Table *tbl, int at, int flag); void TblUntag( Table *tbl, int at, int flag); void TblRetag( Table *tbl, int at, int flag); void TblTagAll( Table *tbl, char *pattern, int flag ); void TblUntagAll( Table *tbl, char *pattern, int flag ); int TblUsualSelect( Table *tbl ); /* _______________________ table.c _________________________ */ #include "w.h" #include "glob.h" #include "menu.h" #include "table.h" extern char STRING_BUFFER[MAXLEN]; /* imported from menu.c */ /* , sizeof(STRING_BUFFER) */ /* fmt . * . */ char *TblConvert( char *s, char *fmt, int cutpos ){ if( fmt && *fmt == 'd'){ register i, j, len; char *p = strrchr(s, '.'); if((len = strlen(s)) < DIR_SIZE && *s != '.' && p ){ int sufxlen = strlen(p); for(i=0; i < len - sufxlen ; ++i) STRING_BUFFER[i] = s[i]; for(; i < DIR_SIZE - sufxlen; ++i) STRING_BUFFER[i] = ' '; for(j=0; i < DIR_SIZE; j++, ++i) STRING_BUFFER[i] = p[j]; STRING_BUFFER[i] = '\0'; } else strcpy(STRING_BUFFER, s); if(cutpos > 0 && cutpos < sizeof(STRING_BUFFER)) STRING_BUFFER[cutpos] = '\0'; } else { /* , */ if( cutpos <= 0 ) cutpos = 32000; /* */ strncpy(STRING_BUFFER, s, MIN(sizeof(STRING_BUFFER) - 1, cutpos)); } return STRING_BUFFER; } /* s cutpos */ char *TblCut( char *s, int cutpos ){ if( cutpos <= 0 ) return s; strncpy(STRING_BUFFER, s, MIN(sizeof(STRING_BUFFER) - 1, cutpos)); return STRING_BUFFER; } /* */ int TblCount( Table *tbl ){ register i, L, LL; char *s; L = i = 0; if( tbl->items) while((s = T_ITEM(tbl, i)) != NULL ){ if( tbl->fmt ) s = TblConvert(s, tbl->fmt, 0); LL = strlen(s); if( LL > L ) L = LL; i++; } tbl->nitems = i; return L; } /* . : t->items , . t->exposed = NO ? t->fmt , . t->win . t->showMe . t->hideMe . t->hitkeys []. -1. t->handler NULL. t->width . t->height . t->left . t->top . t->scrollBar scroll-bar- NULL. t->bg_attrib (== ). t->sel_attrib . forcedOneColumn == YES 1 . */ void TblInit( Table *tbl, int forcedOneColumn ){ int mlen = TblCount( tbl ); /* */ /* */ if( mlen > tbl->width || forcedOneColumn ) mlen = tbl->width; /* */ /* = + + */ tbl->elen = mlen + TLABSIZE + 1; /* #####_| */ /* 1 */ /* */ tbl->tcols = (tbl->nitems + tbl->height - 1) / tbl->height; /* , (+1 ) */ tbl->cols = tbl->width / (tbl->elen + 1); if( tbl->cols == 0 ){ /* */ tbl->cols = 1; /* */ tbl->elen = tbl->width - 2; mlen = tbl->elen - (TLABSIZE + 1); tbl->cutpos = mlen; /* */ } else tbl->cutpos = 0; /* */ tbl->cols = MIN(tbl->cols, tbl->tcols); /* */ tbl->space = (tbl->width - tbl->cols * tbl->elen)/(tbl->cols+1); if( tbl->space < 0 ){ beep(); tbl->space = 0; } /* */ tbl->maxelems = tbl-> cols * tbl->height; tbl->maxshift = (tbl->tcols * tbl->height) - tbl->maxelems; if( tbl->maxshift < 0 ) tbl->maxshift = 0; /* */ tbl->scrollok = (tbl->nitems > tbl->maxelems); tbl->elems = tbl->shift = tbl->current = 0; /* */ tbl->exposed = NO; /* */ tbl->key = (-1); } /* */ void TblChkCur( Table *tbl ){ if( tbl->current >= tbl->nitems ) tbl->current = tbl->nitems - 1; if( tbl->current < 0 ) tbl->current = 0; } /* ( ) */ int TblChkShift( Table *tbl ){ register int oldshift = tbl->shift; /* */ if( tbl->cols == 1 && /* 1 */ tbl->tcols > 1 && /* */ tbl->nitems - tbl->shift < tbl->height / 2 + 1 ) tbl->shift = tbl->nitems - (tbl->height/2 + 1); if( tbl->shift > tbl->maxshift ) tbl->shift = tbl->maxshift; if( tbl->shift < 0 ) tbl->shift = 0; return tbl->shift != oldshift; /* ? */ } /* */ void TblChk( Table *tbl ){ again: TblChkCur( tbl ); TblChkShift( tbl ); if( tbl -> maxelems ){ if( tbl -> current >= tbl->shift + tbl->maxelems ){ tbl->shift = tbl->current - (tbl->maxelems - 1); goto again; } if( tbl->current < tbl->shift ){ tbl->shift = tbl->current; goto again; } } } /* snew- , */ void TblPointAt( Table *tbl, int snew ){ int curCol; /* ( current) */ int newCol; /* ( snew) */ int colw; /* ( snew) */ int gap; /* */ int newshift = tbl->shift; /* */ int drawn = NO; /* ? */ /* */ if( snew < 0 ) snew = 0; if( snew >= tbl->nitems ) snew = tbl->nitems - 1; if( tbl->current == snew && tbl->exposed == YES) return; /* */ #define WANTINC 1 #define WANTDEC (tbl->cols-1-WANTINC) gap = (tbl->height - (tbl->shift % tbl->height)) % tbl->height; /* gap - , --0-- --3-- --1-- --4-- --2-- --5-- ____ |------ gap=2___/ g0 --1-- g3 | --4-- g6 .... \____ g1 --2-- g4 | --5-- g7 --0-- g2 --3-- g5 | --6-- g8 |------ shift=4 */ /* : TblRoll() _________________*/ /* ? */ /* elems TblDraw() */ if( T_VISIBLE(tbl, snew)) goto ThisWindow; /* smooth scrolling ( ) */ if( snew == tbl->shift + tbl->elems && /* */ tbl->current == tbl->shift + tbl->elems - 1 /* */ ){ newshift++; gap--; if ( gap < 0 ) gap = tbl->height - 1 ; goto do_this; } if( snew == tbl->shift - 1 && /* */ tbl->current == tbl->shift /* */ ){ newshift --; gap = (gap + 1) % tbl->height; goto do_this; } /* jump scrolling ( ) */ curCol = (tbl->current+gap) / tbl->height; newCol = (snew +gap) / tbl->height; if( tbl->cols > 1 ){ if( newCol > curCol ) colw = WANTINC; else colw = WANTDEC; } else colw = 0; newshift = (newCol - colw) * tbl->height - gap ; do_this: if( tbl->shift != newshift || tbl->exposed == NO){ tbl->shift = newshift; TblChkShift( tbl ); /* >= 0 && <= max */ TblDraw( tbl ); /* */ drawn = YES; /* */ } ThisWindow: /* */ TblPoint( tbl, snew, !drawn ); /* tbl->current = snew; TblPoint() */ } /* */ void TblPoint ( Table *tbl, int snew, int eraseOld ){ if( ! T_VISIBLE(tbl, snew)){ beep(); /* ERROR !!! */ return; } if( eraseOld && tbl->current != snew ) TblDrawItem( tbl, tbl->current, NO, YES ); TblDrawItem( tbl, snew, YES, YES ); tbl->current = snew; TblReport( tbl ); } /* scroll bar . , * , * T_ITEM(tbl, tbl->current) . */ void TblReport( Table *tbl ){ if ( tbl->scrollBar ) (*tbl->scrollBar)( tbl, BAR_VER|BAR_HOR, tbl->current, tbl->nitems); GetBack( tbl->savep, tbl->win ); /* ! */ } /* */ void TblDraw( Table *tbl ){ register next; /* ( * */ tbl->elems = MIN(tbl->nitems - tbl->shift, tbl->maxelems ); for( next = 0; next < tbl->maxelems; next++ ) TblDrawItem(tbl, next + tbl->shift, NO, tbl->scrollok ? YES : NO); tbl->exposed = YES; /* */ } /* */ void TblDrawItem( Table *tbl, int at, int reverse, int selection){ register WINDOW *w = tbl->win; int pos; char *s; int hatch, bold, label, under; int ax, axl, ay, column; if( at >= 0 && at < tbl->nitems ){ s = T_ITEM( tbl, at ); if( tbl->fmt ) s = TblConvert(s, tbl->fmt, tbl->cutpos); else if( tbl->cutpos > 0 ) s = TblCut(s, tbl->cutpos); /* */ hatch = T_TST( tbl, at, T_HATCH ); bold = T_TST( tbl, at, T_BOLD ); label = T_TST( tbl, at, T_LABEL ); under = T_TST( tbl, at, I_EXE ); } else { s = "~"; label = hatch = bold = under = NO; } at -= tbl->shift; /* . */ ay = tbl->top + at % tbl->height; column = at / tbl->height; /* */ axl = tbl->left + tbl->space + column * (tbl->space + tbl->elen); /* - */ ax = axl + TLABSIZE; if(selection) TblBox( tbl, at, reverse, reverse && hatch, strlen(s), axl, ax, ay ); wattrset (w, reverse ? tbl->sel_attrib : tbl->bg_attrib); if( hatch ) wattron(w, A_ITALICS); if( bold ) wattron(w, A_BOLD); if( under ) wattron(w, A_UNDERLINE); mvwaddstr(w, ay, ax, s); wattrset(w, tbl->bg_attrib | (bold ? A_BOLD:0)); if( label ) mvwaddch(w, ay, axl, LABEL); if( under ){ wattron(w, A_BOLD); mvwaddch(w, ay, axl+1, BOX_HATCHED);} wattrset(w, tbl->bg_attrib); if( column != tbl->cols-1 ) /* */ mvwaddch(w, ay, axl+tbl->elen-1 + (tbl->space+1)/2, VER_LINE); wmove(w, ay, ax-1); /* */ SetPoint(tbl->savep, ay, ax-1); /* */ } /* */ void TblBox(Table *tbl, int at, int reverse, int hatched, int width, int axl, int axi, int ay){ register WINDOW *w = tbl->win; int len = tbl->elen; wattrset (w, tbl->bg_attrib); wboxerase(w, axl, ay, axl+len-1, ay); wattrset (w, reverse ? tbl->sel_attrib : tbl->bg_attrib); /* axl+len+1, * */ wboxerase(w, axi, ay, axl+width-1, ay); wattrset (w, tbl->bg_attrib); } /* tbl->win, * . * , * TblInit() - * (*showMe)(); */ int TblClear( Table *tbl ){ tbl->exposed = NO; tbl->elems = 0; /* exposed:= NO */ wboxerase( tbl->win, tbl->left, tbl->top, tbl->left + tbl->width - 1, tbl->top + tbl->height - 1); return 1; } /* */ void TblTag( Table *tbl, int at, int flag){ if( T_TST(tbl, at, flag)) return; T_SET(tbl, at, flag); if( T_VISIBLE(tbl, at)) TblDrawItem(tbl, at, tbl->current == at ? YES:NO, YES ); } /* */ void TblUntag( Table *tbl, int at, int flag){ if( ! T_TST(tbl, at, flag)) return; T_CLR(tbl, at, flag); if( T_VISIBLE(tbl, at)) TblDrawItem(tbl, at, tbl->current == at ? YES:NO, YES ); } /* */ void TblRetag( Table *tbl, int at, int flag){ if( T_TST(tbl, at, flag)) T_CLR(tbl, at, flag); else T_SET(tbl, at, flag); if( T_VISIBLE(tbl, at)) TblDrawItem(tbl, at, tbl->current == at ? YES:NO, YES ); } /* match() */ void TblMatchErr(){} /* , */ void TblTagAll( Table *tbl, char *pattern, int flag ){ register i; for(i=0; i < tbl->nitems; i++) if( !T_TST(tbl, i, I_DIR) && match( T_ITEMF(tbl, i, 0), pattern)) TblTag( tbl, i, flag ); } /* */ void TblUntagAll( Table *tbl, char *pattern, int flag ){ register i; for(i=0; i < tbl->nitems; i++) if( match( T_ITEMF(tbl, i, 0), pattern)) TblUntag( tbl, i, flag ); } /* */ int TblPlaceByName( Table *tbl, char *p ){ register i; char *s; for( i=0; i < tbl->nitems; i++ ){ s = T_ITEMF(tbl, i, 0); if( match( s, p )){ if( tbl->exposed == NO ){ /* shift, * */ tbl->shift = tbl->nitems+1; tbl->elems = 0; } TblPointAt( tbl, i ); return i; } } return (-1); } /* */ static int TblTrack( Table *tbl, int c){ char *s; register i; int from; /* */ int found = 0; /* */ int plength = 0; int more = 0; char pattern[20]; if( c >= 0400 || iscntrl(c)){ beep(); return 0; } AddCh: from = 0; pattern[plength] = c; pattern[plength+1] = '*'; pattern[plength+2] = '\0'; plength++; More: for(i = from; i < tbl->nitems; i++){ s = T_ITEMF(tbl, i, 0); if( match(s, pattern)){ ++found; from = i+1; TblPointAt( tbl, i ); c = WinGetch( tbl->win ); switch(c){ case '\t': /* find next matching */ more++; goto More; case KEY_BACKSPACE: case '\177': case '\b': if( plength > 1 ){ plength--; pattern[plength] = '*'; pattern[plength+1] = '\0'; from = 0; more++; goto More; } else goto out; default: if( c >= 0400 || iscntrl(c)) return c; if( plength >= sizeof pattern - 2 ) goto out; goto AddCh; } } } /* */ if(more && found){ /* , - */ beep(); more = found = from = 0; goto More; } out: beep(); return 0; } /* */ int TblUsualSelect( Table *tbl ){ int c, want; tbl->key = (-1); if( tbl->items == NULL || tbl->nitems <= 0 ) return TOTAL_NOSEL; TblChk( tbl ); if( tbl->showMe ) if((*tbl->showMe)(tbl) <= 0 ) return (-1); if( !tbl->win ) return TOTAL_NOSEL; if( tbl->exposed == NO ){ TblDraw ( tbl ); } /* */ TblPoint( tbl, tbl->current, NO); TblReport( tbl ); for( ;; ){ c = WinGetch(tbl->win); INP: if( tbl->hitkeys && tbl->handler ){ HandlerReply reply; if( is_in(c, tbl->hitkeys)){ c = (*tbl->handler)(tbl, c, &reply); TblReport( tbl ); /* restore scroll bar */ switch( reply ){ case HANDLER_CONTINUE: continue; case HANDLER_NEWCHAR: goto INP; case HANDLER_OUT: goto out; case HANDLER_SWITCH: default: break; /* goto switch(c) */ } } } sw: switch( c ){ case KEY_LEFT: want = tbl->current - tbl->height; goto mv; case KEY_RIGHT: want = tbl->current + tbl->height; goto mv; case KEY_UP: want = tbl->current - 1; goto mv; case KEY_DOWN: next: want = tbl->current + 1; goto mv; case KEY_HOME: want = 0; goto mv; case KEY_END: want = tbl->nitems - 1; goto mv; case KEY_NPAGE: want = tbl->current + tbl->elems; goto mv; case KEY_PPAGE: want = tbl->current - tbl->elems; goto mv; case KEY_IC: if( T_TST(tbl, tbl->current, T_LABEL )) T_CLR(tbl, tbl->current, T_LABEL ); else T_SET(tbl, tbl->current, T_LABEL); if( tbl->current == tbl->nitems - 1 /* LAST */){ TblPoint(tbl, tbl->current, NO ); break; } TblPointAt(tbl, tbl->current ); /* if not goto next; * but break; * then use * TblPoint(tbl, tbl->current, NO); * here */ goto next; case KEY_DC: if( T_TST(tbl, tbl->current, T_HATCH )) T_CLR(tbl, tbl->current, T_HATCH ); else T_SET(tbl, tbl->current, T_HATCH); if( tbl->current == tbl->nitems - 1 /* LAST */){ TblPoint(tbl, tbl->current, NO ); break; } TblPointAt(tbl, tbl->current ); goto next; case ESC: case '\r': case '\n': goto out; case 0: break; default: c = TblTrack(tbl, c); if( c ) goto INP; break; } continue; mv: TblPointAt( tbl, want ); } out: wnoutrefresh( tbl->win ); if( tbl->hideMe ) (*tbl->hideMe)(tbl); return ((tbl->key = c) == ESC ? -1 : tbl->current ); } # 23 - simple visual shell. # UNIX commander ######################################################################### # Makefile uxcom - - # . # -I # include-, #include "ߔ". # : # 17, 18, 19, 21, 23 . # # + Left Right _Commands Tools Sorttype + # | /usr/a+---------------------008/013-+ | # +-----------------| |---+--+ # | .. +--------------------------+--+ | | # | .BAD | Current directory | | | | # | .contents.m| Root directory | | |##| # | DUMP | Menus | | | | # | Makefile +--------------------------+ | | | # | PLAN | Help | | | | # | _points | Unimplemented | | | | # | table | Change sorttype |##| | | # | #unbold | _Look directory history | | | | # | #uxcom +--------------------------+ | | | # | x.++ | Quit | | | | # | 00 +--------------------------+ | | | # | 11 | Redraw screen | | | | # | LOOP_p +--------------------------+--+ | | # | LOOP_q .c | etc | | # | LOOP_strt .c | install | | # +-------------------------+-------------------------+ | # | points 165 -r--r-- | .cshrc 2509 -rw-r--r-- | | # +-------------------------+-------------------------+ | # | | | # +---------------------------------------------------+--+ # SHELL=/bin/sh SRCS = glob.c w.c menu.c pull.c match.c pwd.c hist.c line.c table.c \ main.c treemk.c OBJS = glob.o w.o menu.o pull.o match.o pwd.o hist.o line.o table.o \ main.o treemk.o # INCLUDE = /usr/include # LIB = -lncurses INCLUDE = -I../../src/curses LIB = ../../src/curses/libncurses.a DEFINES = -DUSG -DTERMIOS CC = cc -O # C-compiler + #CC = gcc -O # GNU C-compiler uxcom: $(OBJS) $(CC) $(OBJS) -o $@ $(LIB) sync; ls -l $@; size $@ glob.o: glob.c glob.h # " 18" $(CC) -c glob.c w.o: w.c w.h # " 17" $(CC) -c $(INCLUDE) $(DEFINES) w.c menu.o: menu.c glob.h w.h menu.h # " 19" $(CC) -c $(INCLUDE) $(DEFINES) menu.c pull.o: pull.c glob.h w.h menu.h pull.h # " 20" $(CC) -c $(INCLUDE) $(DEFINES) pull.c match.o: match.c $(CC) -c -DMATCHONLY \ -DMATCH_ERR="TblMatchErr()" match.c pwd.o: pwd.c $(CC) -c -DU42 -DCWDONLY pwd.c treemk.o: treemk.c $(CC) -c $(DEFINES) \ -DERR_CANT_READ=tree_err_cant_read \ -DERR_NAME_TOO_LONG=tree_name_too_long \ -DTREEONLY -DU42 treemk.c hist.o: hist.c hist.h glob.h menu.h w.h # " 21" $(CC) -c $(INCLUDE) $(DEFINES) hist.c line.o: line.c w.h glob.h menu.h hist.h line.h # " 21" $(CC) -c $(INCLUDE) $(DEFINES) line.c table.o: table.c w.h glob.h menu.h table.h # " 22" $(CC) -c $(INCLUDE) $(DEFINES) table.c main.o: main.c glob.h w.h menu.h hist.h line.h pull.h table.h $(CC) -c $(INCLUDE) $(DEFINES) main.c w.h: wcur.h touch w.h /* _______________________ main.c __________________________ */ /* , /etc/termcap * * A_STANDOUT A_REVERSE ! */ #include "w.h" #include "glob.h" #include "menu.h" #include "hist.h" #include "line.h" #include "table.h" #include "pull.h" #include <signal.h> #include <ustat.h> #include <locale.h> void t_enter(), t_leave(); LineEdit edit; /* */ Hist hcwd, hedit, hpat; /* : */ /* , , */ Menu mwrk, msort; /* static */ PullMenu pull; typedef enum { SEL_WRK=0, SEL_PANE1, SEL_PANE2, SEL_PULL, SEL_HELP } Sel; Sel current_menu; /* */ Sel previous_menu; /* */ #define SEL_PANE (current_menu == SEL_PANE1 || current_menu == SEL_PANE2) typedef struct { Table t; /* */ DirContents d; /* */ } FileWidget; FileWidget tpane1, tpane2; /* */ FileWidget *A_pane = &tpane1; /* */ FileWidget *B_pane = &tpane2; /* */ #define A_tbl (&A_pane->t) #define A_dir (&A_pane->d) #define B_tbl (&B_pane->t) #define B_dir (&B_pane->d) #define TblFW(tbl) ((tbl) == A_tbl ? A_pane : B_pane) void ExchangePanes(){ /* */ FileWidget *tmp = A_pane; A_pane = B_pane; B_pane = tmp; current_menu = (current_menu == SEL_PANE1 ? SEL_PANE2 : SEL_PANE1); } #define Other_pane(p) ((p) == A_pane ? B_pane : A_pane) #define Other_tbl(t) ((t) == A_tbl ? B_tbl : A_tbl ) WINDOW *panewin; /* , = stdscr */ typedef enum { NORUN=0, RUNCMD=1, CHDIR=2, TAG=3, FIND=4 } RunType; #define REPEAT_KEY 666 /* " " */ #define LEAVE_KEY 777 /* " " */ #define NOSELECTED (-1) /* */ #define CENTER (COLS/2-2) /* */ int done; /* ? */ char CWD[MAXLEN]; /* */ char SELECTION[MAXLEN]; /* */ /*-----------------------------------------------------------------*/ /* */ /*-----------------------------------------------------------------*/ #include <stdarg.h> void Message(char *s, ... ){ char msg[80]; va_list args; int field_width; va_start(args, s); vsprintf(msg, s, args); va_end(args); wattrset (panewin, A_tbl->sel_attrib); field_width = A_tbl->width + B_tbl->width - 3; mvwprintw (panewin, LINES-2, tpane1.t.left+1, " %*.*s ", -field_width, field_width, msg); wattrset (panewin, A_tbl->bg_attrib); wnoutrefresh(panewin); } /*-----------------------------------------------------------------* * . * *-----------------------------------------------------------------*/ Info sort_info[] = { { " ", 0}, { " ", 0}, { " ", 0}, { " ", 0}, { " ", M_HATCH}, { NULL, 0} }; /* */ void sort_show(Menu *m){ MnuPointAt(&msort, (int) sorttype); } /* */ static void SelectSortType(int sel){ if( sel == NOSELECTED ) sel = MnuUsualSelect(&msort, NO); MnuHide(&msort); current_menu = previous_menu; if(M_REFUSED(&msort)) return; sorttype = (Sort) sel; A_dir->lastRead = B_dir->lastRead = 0L; /* */ /* */ } /*-----------------------------------------------------------------* * . * *-----------------------------------------------------------------*/ #define NON_VALID(d) ((d)->readErrors || (d)->valid == NO) /* */ void InitTblFromDir(FileWidget *wd, int chdired, char *savename){ char *msg, *name; Table *tbl = &(wd->t); DirContents *d = &wd->d; int saveind = tbl->current, saveshift = tbl->shift; char *svname = NULL; if(tbl->nitems > 0 ) svname = strdup(T_ITEMF(tbl, saveind, 0)); /* */ if( NON_VALID(d)) wattrset(tbl->win, A_REVERSE); TblClear(tbl); if(d->valid == NO){ msg = " "; name = d->name; goto Report; } else if(d->readErrors){ /* d->files->s == NULL */ msg = " "; name = d->name; Report: mvwaddstr(tbl->win, tbl->top + tbl->height/2, tbl->left + (tbl->width - strlen(name))/2, name); mvwaddstr(tbl->win, tbl->top + tbl->height/2+1, tbl->left + (tbl->width - strlen(msg))/2, msg); } wattrset(tbl->win, tbl->bg_attrib); tbl->items = d->files; TblInit(tbl, NO); /* */ if( chdired ) TblPlaceByName(tbl, savename); else { if( svname == NULL || TblPlaceByName(tbl, svname) < 0 ){ tbl->shift = saveshift; tbl->current = saveind; TblChk(tbl); } } if(svname) free(svname); } /* */ int mychdir(char *newdir){ int code = chdir(newdir); if( code < 0 ) return code; getwd(CWD); in_the_root = (strcmp(CWD, "/") == 0); HistAdd(&hcwd, CWD, 0); /* */ t_enter(&tpane1.t); /* */ return code; } /* */ int cd(char *newdir, FileWidget *wd, char *oldname){ char oldbase[MAXLEN], *s, *strrchr(char *,char); /* oldbase oldname ( CWD) */ if(s = strrchr(oldname, '/')) s++; else s = oldname; strcpy(oldbase, s); if( mychdir(newdir) < 0){ /* */ Message(" %s", *newdir ? newdir : "???"); beep(); return (-1); } if( ReadDir(CWD, &wd->d)){ /* */ InitTblFromDir (wd, YES, oldbase); return 1; } return 0; } /* */ void checkBothPanes(){ /* NON_VALID , Init...