home *** CD-ROM | disk | FTP | other *** search
- #include <alloc.h>
- #include <dos.h>
- #include <mem.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <conio.h>
- #include "iolib.h"
-
- /*=========================================================================*/
- /* ioed.c -- library of i/o functions for use from Turbo C */
- /* part II : the editor-in-a-box */
- /* by John Queern, Belleville, IL (public domain) */
- /*=========================================================================*/
- /* NOTE: you must also link in iolib.obj if using ioed */
-
- /* function prototypes */
- void do_help (void); /* box editor help */
- void redraw (char *edscreen,int sx, /* draw/redraw editor data */
- int sy, int wid, int lines); /* */
- int edit (char *edscreen,int sx, /* editor-in-a-box */
- int sy, int *px, int *py, int wid,
- int lines);
-
- typedef struct BOX_CHARSET {
- char bul; /* box upper left */
- char bh; /* box horiz */
- char bhc; /* box upper horizontal with cross */
- char bhlc; /* box lower horizontal with cross */
- char bur; /* box upper right */
- char bv; /* box vertical */
- char blvc; /* box left vertical with cross */
- char brvc; /* box right vertical with cross */
- char bll; /* box lower left */
- char bc; /* box cross */
- char blr; /* box lower right */
- } BOXCHARS;
-
-
- BOXCHARS *get_boxchar(void); /* (fncn for internal use) */
- BOXCHARS single = { '┌','─','┬','┴','┐','│','├','┤','└','┼','┘'};
- BOXCHARS duble = { '╔','═','╦','╩','╗','║','╠','╣','╚','╬','╝'};
- BOXCHARS sindub = { '╒','═','╤','╧','╕','│','╞','╡','╘','╪','╛'};
- BOXCHARS dubsin = { '╓','─','╥','╨','╖','║','╟','╢','╙','╫','╜'};
- BOXCHARS ascii = { '+','-','+','+','+','|','+','+','+','+','+'};
- BOXCHARS half1 = { '░','░','░','░','░','░','░','░','░','░','░'};
- BOXCHARS half2 = { '▒','▒','▒','▒','▒','▒','▒','▒','▒','▒','▒'};
- BOXCHARS half3 = { '▓','▓','▓','▓','▓','▓','▓','▓','▓','▓','▓'};
- BOXCHARS solid = { '█','█','█','█','█','█','█','█','█','█','█'};
-
- BOXCHARS *box = &single; /* box char pointer, default style */
-
- /*========================================================================*/
-
- void do_help (void)
- /* help screen for the editor */
- {
- char ch;
-
- savescreen(1);
- bclear(0);
- bwrite(0,5,2, "╔═════════════════════════════════════════════════════════════════════╗");
- bwrite(0,5,3, "║ EDIT HELP SCREEN ║");
- bwrite(0,5,4, "║ F1 - show this help screen ║");
- bwrite(0,5,5, "║ Home - goto line 1, column 1 ║");
- bwrite(0,5,6, "║ ^e PgUp, ^r - goto top ║");
- bwrite(0,5,7, "║ PgDn, ^c - goto bottom ║");
- bwrite(0,5,8, "║ ^ End, ^w - save changes, exit ║");
- bwrite(0,5,9, "║ | Ins, ^v - toggle insert mode ║");
- bwrite(0,5,10,"║ | Del, ^g - delete one character ║");
- bwrite(0,5,11,"║ ^s <----o----> ^d Tab, ^i - goto next tab position ║");
- bwrite(0,5,12,"║ | ^y - delete line ║");
- bwrite(0,5,13,"║ | ^z - blank everything ║");
- bwrite(0,5,14,"║ v ^t - delete word right ║");
- bwrite(0,5,15,"║ ^a/^f - advance word left/right ║");
- bwrite(0,5,16,"║ ^x ^qs/^qd - goto beginning/end of line ║");
- bwrite(0,5,17,"║ ^n - insert line ║");
- bwrite(0,5,18,"║ Cursor Movement ^b/^u, F7/F8 - generate/erase a box ║");
- bwrite(0,5,19,"║ (or use cursor keys) F6 - change box character set ║");
- bwrite(0,5,20,"║ F9/F10 - horiz/vert line draw/erase ║");
- bwrite(0,5,21,"║ Note: ^ = hold Ctrl ║");
- bwrite(0,5,22,"╚═════════════════════════════════════════════════════════════════════╝");
- bwrite(0,5,24,"Press any key to continue editing...");
- restorescreen(0);
- getch();
- restorescreen(1);
-
- }
-
- /*========================================================================*/
-
- BOXCHARS *get_boxchar(void)
- /* display box character set options, & return pointer to selected set */
- {
- int i,j;
- char ch;
- BOXCHARS *b;
-
- savescreen(1);
- savescreen(0);
- bwrite(0,5,2, "╔══════════════════════════════════╗");
- bwrite(0,5,3, "║ Box Character Selection: ║");
- bwrite(0,5,4, "║ ║");
- bwrite(0,5,5, "║ ┌───┐ ║");
- bwrite(0,5,6, "║ a. single │╔═══╗ ║");
- bwrite(0,5,7, "║ b. double └║╒═══╕ ║");
- bwrite(0,5,8, "║ c. sing/doub ╚│╓───╖ ║");
- bwrite(0,5,9, "║ d. doub/sing ╘║+---+ ║");
- bwrite(0,5,10,"║ e. ascii ╙|░░░░░ ║");
- bwrite(0,5,11,"║ f. half1 +░▒▒▒▒▒ ║");
- bwrite(0,5,12,"║ g. half2 ▒▓▓▓▓▓ ║");
- bwrite(0,5,13,"║ h. half3 ▓█████ ║");
- bwrite(0,5,14,"║ i. solie █████ ║");
- bwrite(0,5,15,"║ ║");
- bwrite(0,5,16,"║ Selection (a-i)? ║");
- bwrite(0,5,17,"║ ║");
- bwrite(0,5,18,"╚══════════════════════════════════╝");
- restorescreen(0);
- gotoxy(26,16);
- fflush(stdin);
- ch=getche();
- ch=tolower(ch);
- switch (ch) {
- case 'a': b=&single; break;
- case 'b': b=&duble; break;
- case 'c': b=&sindub; break;
- case 'd': b=&dubsin; break;
- case 'e': b=&ascii; break;
- case 'f': b=&half1; break;
- case 'g': b=&half2; break;
- case 'h': b=&half3; break;
- case 'i': b=&solid;
- }
-
- restorescreen(1);
- return(b);
- }
-
- /*========================================================================*/
-
- void redraw (char *edscreen,int sx, int sy, int wid, int lines)
- /* redraw internal part of screen */
- /* NOTE: this routine uses screen buffer 1 */
- {
-
- int i;
-
- savescreen(1);
- for (i=0; i<lines; i++) pad(edscreen + i*wid+i,wid); /* pad lines */
- for (i=0; i<lines; i++) bwrite(1,sx,i+sy,(edscreen + i*wid + i));
- restorescreen(1);
- }
-
- /*========================================================================*/
-
- int edit (char *edscreen,int sx, int sy, int *px, int *py, int wid, int lines)
- /* editor in a box */
- /* Initiate multiline editor using buffer edscreen, in a box at sx,sy;
- edscreen is a buffer which must contain at least (lines*wid+lines) bytes;
- The editor will assume it is set up as an array of <lines> strings,
- each <wid> long; return special keys which aren't handled internally;
- */
- {
- char ch;
- int a,b;
- int i,j,n,retcd,_retcd;
- int x,y,xx;
- char *blank;
-
- int inbox,inclear,savetrim;
- char *lptr, *cptr, *lcptr, *tcptr, *bcptr;
-
- blank=(char *)calloc(1,wid+1);
- blank[0]=0;
- pad(blank,wid);
- _retcd=0;
- inbox=inclear=insert=FALSE;
- savetrim=trimblanks;
- trimblanks=FALSE;
-
- redraw(edscreen,sx,sy,wid,lines);
- x=*px;
- y=*py; /* x and y are relative--(0,0) is upper l.h. corner of box */
- colx=coly=24;
- do {
- gotoxy(5,24);
- cprintf("Row: %3d Column: %3d ",y+1,x+1);
- gotoxy(45,24);
- if (inbox) cprintf("<in box>");
- else if (inclear) cprintf("<in clr>");
- else cprintf(" ");
-
- lptr=edscreen+y*wid+y; /* pointer to current line (line y) */
- retcd=getstring(sx,sy+y,&x,lptr,wid);
- cptr=lptr+x; /* pointer to char at cursor pos */
-
- switch (retcd) {
- case 0 :
- case 1 :
- x=0;
- case 6 :
- if (y<lines-1) y++;
- else {
- _retcd = retcd;
- retcd = 8;
- }
- break;
- case 3 :
- if (y>0) y--;
- else {
- _retcd = retcd;
- retcd = 8;
- }
- break;
- case 11 : /* F1 */
- do_help();
- break;
- case 16 : /* F6 */
- box = get_boxchar();
- break;
- case 24 : /* Home */
- y = 0;
- x = 0;
- break;
- case 9 : /* PgUp */
- y = 0;
- break;
- case 10: /* PgDn */
- y = lines-1;
- break;
-
- case 17: /* F7 or */
- case 25: /* ctrl-b (box) */
- if (! inbox) {
- /* save cursor position */
- a=x; /* offset */
- b=y;
- inbox = TRUE;
- }
- /* already in box-- draw it */
- else {
- /* draw horizontal pieces */
- bcptr=edscreen+y*wid+y+min(a,x);
- tcptr=edscreen+b*wid+b+min(a,x);
- for (i=min(a,x)+1;i<max(a,x);i++) {
- *(++bcptr)=box->bh;
- *(++tcptr)=box->bh;
- }
- /* draw vertical pieces */
- bcptr=edscreen+min(y,b)*wid+min(y,b)+a;
- tcptr=edscreen+min(y,b)*wid+min(y,b)+x;
- for (i=min(b,y); i<=max(b,y)-1; i++) {
- *bcptr=box->bv;
- *tcptr=box->bv;
- bcptr += wid + 1;
- tcptr += wid + 1;
- }
- /* add corners */
- *(edscreen+min(b,y)*wid+min(b,y)+min(a,x))=box->bul;
- *(edscreen+max(b,y)*wid+max(b,y)+min(a,x))=box->bll;
- *(edscreen+min(b,y)*wid+min(b,y)+max(a,x))=box->bur;
- *(edscreen+max(b,y)*wid+max(b,y)+max(a,x))=box->blr;
- inbox = FALSE;
- x=a;
- y=b;
- redraw(edscreen,sx,sy,wid,lines);
- }
- break;
-
- case 18: /* F8 or */
- case 26: /* ctrl-u (box clear) */
- if (! inclear) {
- /* save cursor position */
- a=x; /* offset */
- b=y;
- inclear = TRUE;
- }
- /* already in clear-- clear it */
- else {
- /* clear horizontal pieces */
- bcptr=edscreen+y*wid+y+min(a,x);
- tcptr=edscreen+b*wid+b+min(a,x);
- for (i=min(a,x)+1;i<max(a,x);i++) {
- *(++bcptr)=' ';
- *(++tcptr)=' ';
- }
- /* clear vertical pieces */
- bcptr=edscreen+min(y,b)*wid+min(y,b)+a;
- tcptr=edscreen+min(y,b)*wid+min(y,b)+x;
- for (i=min(b,y); i<=max(b,y)-1; i++) {
- *bcptr=' ';
- *tcptr=' ';
- bcptr += wid + 1;
- tcptr += wid + 1;
- }
- /* clear corners */
- *(edscreen+min(b,y)*wid+min(b,y)+min(a,x))=' ';
- *(edscreen+max(b,y)*wid+max(b,y)+min(a,x))=' ';
- *(edscreen+min(b,y)*wid+min(b,y)+max(a,x))=' ';
- *(edscreen+max(b,y)*wid+max(b,y)+max(a,x))=' ';
- inclear = FALSE;
- x=a;
- y=b;
- redraw(edscreen,sx,sy,wid,lines);
- }
- break;
-
- case 19: /* F9 - draw horizontal line */
- lcptr = cptr - 1; /* char to left of current pos */
- tcptr = edscreen+(y-1)*wid+(y-1)+x; /* char above current */
- bcptr = edscreen+(y+1)*wid+(y+1)+x; /* char below current */
-
- /* fix up left hand connection if necessary */
- if (*cptr==box->bh || *cptr==box->bc) { /* erasing a line? */
- if (*lcptr==box->bul) *lcptr=box->bv;
- else if (*lcptr==box->blvc) *lcptr=box->bv;
- else if (*lcptr==box->blvc) *lcptr=box->bv;
- else if (*lcptr==box->bhc) *lcptr=box->bur;
- else if (*lcptr==box->bhlc) *lcptr=box->blr;
- else if (*lcptr==box->bc) *lcptr=box->brvc;
- }
- else { /* adding a line? */
- if (*lcptr==box->bv) {
- if ((*(tcptr-1)==box->bv || *(tcptr-1)==box->bc
- || *(tcptr-1)==box->blvc)
- && (*(bcptr-1)==box->bv || *(bcptr-1)==box->bc
- || *(bcptr-1)==box->blvc))
- *lcptr=box->blvc;
- else if (*(tcptr-1)==box->bv || *(tcptr-1)==box->bc)
- *lcptr=box->bll;
- else if (*(bcptr-1)==box->bv || *(bcptr-1)==box->bc)
- *lcptr=box->bul;
- }
- else if (*lcptr==box->bur) *lcptr=box->bhc;
- else if (*lcptr==box->blr) *lcptr=box->bhlc;
- else if (*lcptr==box->brvc) *lcptr=box->bc;
- }
- for (i=x; i<wid; i++) {
- if (*cptr==box->bv) *cptr=box->bc;
- else if (*cptr==box->bh) *cptr=' ';
- else if (*cptr==box->brvc) *cptr=box->bv;
- else if (*cptr==box->blvc) *cptr=box->bv;
- else if (*cptr==box->bc) *cptr=box->bv;
- else if (*cptr==box->bhlc) *cptr=box->bv;
- else if (*cptr==box->bhc) *cptr=box->bv;
- else *cptr=box->bh;
- cptr++;
- }
- redraw(edscreen,sx,sy,wid,lines);
- break;
-
- case 20: /* F10 - draw vertical line */
- lcptr = cptr - 1; /* char to left of current pos */
- tcptr = edscreen+(y-1)*wid+(y-1)+x; /* char above current */
- bcptr = edscreen+(y+1)*wid+(y+1)+x; /* char below current */
-
- /* fix up upper connection if necessary */
- if (*cptr==box->bv || *cptr==box->bc) { /* erasing a line? */
- if (*tcptr==box->bur || *tcptr==box->bul
- || *tcptr==box->bhc) *tcptr=box->bh;
- else if (*tcptr==box->blvc) *tcptr=box->bll;
- else if (*tcptr==box->brvc) *tcptr=box->blr;
- else if (*tcptr==box->bc) *tcptr=box->bhlc;
- }
- else { /* adding a line? */
- if (*tcptr==box->bh) {
- if ((*(tcptr-1)==box->bh || *(tcptr-1)==box->bc
- || *(tcptr-1)==box->bhc) &&
- (*(tcptr+1)==box->bh || *(tcptr-1)==box->bc
- || *(tcptr+1)==box->bhc))
- *tcptr=box->bhc;
- else if (*(tcptr-1)==box->bh || *(tcptr-1)==box->bc)
- *tcptr=box->bur;
- else if (*(tcptr+1)==box->bv || *(tcptr+1)==box->bc)
- *tcptr=box->bul;
- }
- else if (*tcptr==box->bll) *tcptr=box->blvc;
- else if (*tcptr==box->blr) *tcptr=box->brvc;
- else if (*tcptr==box->bhc) *tcptr=box->bc;
- }
- for (i=y; i<lines; i++) {
- if (*cptr==box->bh) *cptr=box->bc;
- else if (*cptr==box->bv) *cptr=' ';
- else if (*cptr==box->bc) *cptr=box->bh;
- else if (*cptr==box->blvc) *cptr=box->bh;
- else if (*cptr==box->brvc) *cptr=box->bh;
- else if (*cptr==box->bhlc) *cptr=box->bh;
- else if (*cptr==box->bhc) *cptr=box->bh;
- else *cptr=box->bv;
- cptr += (wid + 1);
- }
- redraw(edscreen,sx,sy,wid,lines);
- break;
-
- case 21: /* ctrl-y */
- for (i=y; i<lines-1; i++)
- strcpy(edscreen+i*wid+i,edscreen+(i+1)*wid+i+1);
- strcpy(edscreen+(lines-1)*wid+lines-1,blank);
- redraw(edscreen,sx,sy,wid,lines);
- break;
- case 22: /* ctrl-z */
- gotoxy(10,24);
- clreol();
- cprintf("Zap entire screen -- you sure (Y/N)?");
- ch=getch();
- ch=toupper(ch);
- if (ch == 'Y') {
- for (i=0; i<lines; i++) {
- strcpy(edscreen+i*wid+i,blank);
- }
- y=1;
- x=0;
- redraw(edscreen,sx,sy,wid,lines);
- }
- else {
- gotoxy(10,24);
- clreol();
- }
- break;
- case 23: /* ctrl-n */
- for (i=lines-1; i>y; i--) strcpy(edscreen+i*wid+i,
- edscreen+(i-1)*wid+i-1);
- *(edscreen+y*wid+y+x)=0; /* cut orig line short */
- if (y<lines-1) {
- strdel(edscreen+(y+1)*wid+y+1,0,x);
- pad(edscreen+y*wid+y,wid);
- y++;
- x=0;
- }
- redraw(edscreen,sx,sy,wid,lines);
- break;
- default: /* any other special keys */
- _retcd=retcd;
- retcd=8;
- break;
- } /* switch retcd */
- }
- while ((retcd != 7) && (retcd != 8));
-
- gotoxy(1,24);
- clreol();
- colx=0;
- coly=0;
-
- trimblanks=savetrim;
- if (trimblanks==TRUE)
- for (i=0; i<lines; i++) trim(edscreen+i*wid+i); /* trim blanks */
-
- *px = x; /* return position in box when leaving */
- *py = y;
- return(_retcd);
-
- } /* edit */
-