home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / FORMGE.ZIP / IOED.C < prev    next >
C/C++ Source or Header  |  1989-04-18  |  18KB  |  454 lines

  1. #include <alloc.h>
  2. #include <dos.h>
  3. #include <mem.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <conio.h>
  8. #include "iolib.h"
  9.  
  10. /*=========================================================================*/
  11. /*  ioed.c    -- library of i/o functions for use from Turbo C             */
  12. /*               part II : the editor-in-a-box                             */
  13. /*               by John Queern, Belleville, IL (public domain)            */
  14. /*=========================================================================*/
  15. /* NOTE: you must also link in iolib.obj if using ioed                     */
  16.  
  17. /* function prototypes */
  18. void do_help (void);                        /* box editor help         */
  19. void redraw (char *edscreen,int sx,         /* draw/redraw editor data */
  20.    int sy, int wid, int lines);             /*                         */
  21. int  edit (char *edscreen,int sx,           /* editor-in-a-box         */
  22.    int sy, int *px, int *py, int wid,
  23.    int lines);
  24.  
  25. typedef struct BOX_CHARSET {
  26.     char    bul;    /* box upper left */
  27.     char    bh;     /* box horiz */
  28.     char    bhc;    /* box upper horizontal with cross */
  29.     char    bhlc;   /* box lower horizontal with cross */
  30.     char    bur;    /* box upper right */
  31.     char    bv;     /* box vertical */
  32.     char    blvc;   /* box left vertical with cross */
  33.     char    brvc;   /* box right vertical with cross */
  34.     char    bll;    /* box lower left */
  35.     char    bc;     /* box cross */
  36.     char    blr;    /* box lower right */
  37.     } BOXCHARS;
  38.  
  39.  
  40. BOXCHARS *get_boxchar(void);        /* (fncn for internal use) */
  41. BOXCHARS single = { '┌','─','┬','┴','┐','│','├','┤','└','┼','┘'};
  42. BOXCHARS duble =  { '╔','═','╦','╩','╗','║','╠','╣','╚','╬','╝'};
  43. BOXCHARS sindub = { '╒','═','╤','╧','╕','│','╞','╡','╘','╪','╛'};
  44. BOXCHARS dubsin = { '╓','─','╥','╨','╖','║','╟','╢','╙','╫','╜'};
  45. BOXCHARS ascii =  { '+','-','+','+','+','|','+','+','+','+','+'};
  46. BOXCHARS half1 =  { '░','░','░','░','░','░','░','░','░','░','░'};
  47. BOXCHARS half2 =  { '▒','▒','▒','▒','▒','▒','▒','▒','▒','▒','▒'};
  48. BOXCHARS half3 =  { '▓','▓','▓','▓','▓','▓','▓','▓','▓','▓','▓'};
  49. BOXCHARS solid =  { '█','█','█','█','█','█','█','█','█','█','█'};
  50.  
  51. BOXCHARS  *box = &single;       /* box char pointer, default style */
  52.  
  53. /*========================================================================*/
  54.  
  55. void do_help (void)
  56. /* help screen for the editor */
  57. {
  58.     char   ch;
  59.  
  60.     savescreen(1);
  61.     bclear(0);
  62.     bwrite(0,5,2, "╔═════════════════════════════════════════════════════════════════════╗");
  63.     bwrite(0,5,3, "║     EDIT HELP SCREEN                                                ║");
  64.     bwrite(0,5,4, "║                             F1 - show this help screen              ║");
  65.     bwrite(0,5,5, "║                             Home - goto line 1, column 1            ║");
  66.     bwrite(0,5,6, "║           ^e                PgUp, ^r - goto top                     ║");
  67.     bwrite(0,5,7, "║                             PgDn, ^c - goto bottom                  ║");
  68.     bwrite(0,5,8, "║            ^                End, ^w  - save changes, exit           ║");
  69.     bwrite(0,5,9, "║            |                Ins, ^v  - toggle insert mode           ║");
  70.     bwrite(0,5,10,"║            |                Del, ^g  - delete one character         ║");
  71.     bwrite(0,5,11,"║    ^s <----o----> ^d        Tab, ^i  - goto next tab position       ║");
  72.     bwrite(0,5,12,"║            |                ^y  -  delete line                      ║");
  73.     bwrite(0,5,13,"║            |                ^z  -  blank everything                 ║");
  74.     bwrite(0,5,14,"║            v                ^t  -  delete word right                ║");
  75.     bwrite(0,5,15,"║                             ^a/^f  -  advance word left/right       ║");
  76.     bwrite(0,5,16,"║           ^x                ^qs/^qd - goto beginning/end of line    ║");
  77.     bwrite(0,5,17,"║                             ^n  -  insert line                      ║");
  78.     bwrite(0,5,18,"║     Cursor Movement         ^b/^u, F7/F8 - generate/erase a box     ║");
  79.     bwrite(0,5,19,"║    (or use cursor keys)     F6 - change box character set           ║");
  80.     bwrite(0,5,20,"║                             F9/F10 - horiz/vert line draw/erase     ║");
  81.     bwrite(0,5,21,"║    Note: ^ = hold Ctrl                                              ║");
  82.     bwrite(0,5,22,"╚═════════════════════════════════════════════════════════════════════╝");
  83.     bwrite(0,5,24,"Press any key to continue editing...");
  84.     restorescreen(0);
  85.     getch();
  86.     restorescreen(1);
  87.  
  88. }
  89.  
  90. /*========================================================================*/
  91.  
  92. BOXCHARS *get_boxchar(void)
  93. /* display box character set options, & return pointer to selected set */
  94. {
  95.     int     i,j;
  96.     char    ch;
  97.     BOXCHARS *b;
  98.  
  99.     savescreen(1);
  100.     savescreen(0);
  101.     bwrite(0,5,2, "╔══════════════════════════════════╗");
  102.     bwrite(0,5,3, "║  Box Character Selection:        ║");
  103.     bwrite(0,5,4, "║                                  ║");
  104.     bwrite(0,5,5, "║               ┌───┐              ║");
  105.     bwrite(0,5,6, "║  a. single    │╔═══╗             ║");
  106.     bwrite(0,5,7, "║  b. double    └║╒═══╕            ║");
  107.     bwrite(0,5,8, "║  c. sing/doub  ╚│╓───╖           ║");
  108.     bwrite(0,5,9, "║  d. doub/sing   ╘║+---+          ║");
  109.     bwrite(0,5,10,"║  e. ascii        ╙|░░░░░         ║");
  110.     bwrite(0,5,11,"║  f. half1         +░▒▒▒▒▒        ║");
  111.     bwrite(0,5,12,"║  g. half2           ▒▓▓▓▓▓       ║");
  112.     bwrite(0,5,13,"║  h. half3            ▓█████      ║");
  113.     bwrite(0,5,14,"║  i. solie             █████      ║");
  114.     bwrite(0,5,15,"║                                  ║");
  115.     bwrite(0,5,16,"║  Selection (a-i)?                ║");
  116.     bwrite(0,5,17,"║                                  ║");
  117.     bwrite(0,5,18,"╚══════════════════════════════════╝");
  118.     restorescreen(0);
  119.     gotoxy(26,16);
  120.     fflush(stdin);
  121.     ch=getche();
  122.     ch=tolower(ch);
  123.     switch (ch) {
  124.         case 'a': b=&single; break;
  125.         case 'b': b=&duble;  break;
  126.         case 'c': b=&sindub; break;
  127.         case 'd': b=&dubsin; break;
  128.         case 'e': b=&ascii;  break;
  129.         case 'f': b=&half1;  break;
  130.         case 'g': b=&half2;  break;
  131.         case 'h': b=&half3;  break;
  132.         case 'i': b=&solid;
  133.     }
  134.  
  135.     restorescreen(1);
  136.     return(b);
  137. }
  138.  
  139. /*========================================================================*/
  140.  
  141. void redraw (char *edscreen,int sx, int sy, int wid, int lines)
  142. /* redraw internal part of screen */
  143. /* NOTE: this routine uses screen buffer 1 */
  144. {
  145.  
  146.     int     i;
  147.  
  148.     savescreen(1);
  149.     for (i=0; i<lines; i++) pad(edscreen + i*wid+i,wid); /* pad lines */
  150.     for (i=0; i<lines; i++) bwrite(1,sx,i+sy,(edscreen + i*wid + i));
  151.     restorescreen(1);
  152. }
  153.  
  154. /*========================================================================*/
  155.  
  156. int  edit (char *edscreen,int sx, int sy, int *px, int *py, int wid, int lines)
  157. /* editor in a box */
  158. /* Initiate multiline editor using buffer edscreen, in a box at sx,sy;
  159.    edscreen is a buffer which must contain at least (lines*wid+lines) bytes;
  160.    The editor will assume it is set up as an array of <lines> strings,
  161.    each <wid> long;  return special keys which aren't handled internally;
  162. */
  163. {
  164.     char        ch;
  165.     int         a,b;
  166.     int         i,j,n,retcd,_retcd;
  167.     int         x,y,xx;
  168.     char        *blank;
  169.     
  170.     int         inbox,inclear,savetrim;
  171.     char        *lptr, *cptr, *lcptr, *tcptr, *bcptr;
  172.  
  173.     blank=(char *)calloc(1,wid+1);
  174.     blank[0]=0;
  175.     pad(blank,wid);
  176.     _retcd=0;
  177.     inbox=inclear=insert=FALSE;
  178.     savetrim=trimblanks;
  179.     trimblanks=FALSE;
  180.     
  181.     redraw(edscreen,sx,sy,wid,lines);
  182.     x=*px;
  183.     y=*py; /* x and y are relative--(0,0) is upper l.h. corner of box */
  184.     colx=coly=24;
  185.     do  {
  186.         gotoxy(5,24);
  187.         cprintf("Row: %3d   Column: %3d    ",y+1,x+1);
  188.         gotoxy(45,24);
  189.         if (inbox) cprintf("<in box>");
  190.         else if (inclear) cprintf("<in clr>");
  191.         else cprintf("        ");
  192.  
  193.         lptr=edscreen+y*wid+y;  /* pointer to current line (line y) */
  194.         retcd=getstring(sx,sy+y,&x,lptr,wid);
  195.         cptr=lptr+x;          /* pointer to char at cursor pos */
  196.  
  197.         switch (retcd) {
  198.           case 0 :
  199.           case 1 :
  200.             x=0;
  201.           case 6 :
  202.             if (y<lines-1) y++;
  203.             else {
  204.                 _retcd = retcd;
  205.                 retcd = 8;
  206.             }
  207.             break;
  208.           case 3 :
  209.             if (y>0) y--;
  210.             else {
  211.                 _retcd = retcd;
  212.                 retcd = 8;
  213.             }
  214.             break;
  215.           case 11 :         /* F1 */
  216.             do_help();
  217.             break;
  218.           case 16 :         /* F6 */
  219.             box = get_boxchar();
  220.             break;
  221.           case 24 :         /* Home */
  222.             y = 0;
  223.             x = 0;
  224.             break;
  225.           case 9 :          /* PgUp */
  226.             y = 0;
  227.             break;
  228.           case 10:          /* PgDn */
  229.             y = lines-1;
  230.             break;
  231.  
  232.           case 17:          /* F7 or  */
  233.           case 25:          /* ctrl-b (box) */
  234.             if (! inbox) {
  235.                 /* save cursor position */
  236.                 a=x; /* offset */
  237.                 b=y;
  238.                 inbox = TRUE;
  239.             }
  240.             /* already in box-- draw it */
  241.             else {
  242.                 /* draw horizontal pieces */
  243.                 bcptr=edscreen+y*wid+y+min(a,x);
  244.                 tcptr=edscreen+b*wid+b+min(a,x);
  245.                 for (i=min(a,x)+1;i<max(a,x);i++) {
  246.                     *(++bcptr)=box->bh;
  247.                     *(++tcptr)=box->bh;
  248.                 }
  249.                 /* draw vertical pieces */
  250.                 bcptr=edscreen+min(y,b)*wid+min(y,b)+a;
  251.                 tcptr=edscreen+min(y,b)*wid+min(y,b)+x;
  252.                 for (i=min(b,y); i<=max(b,y)-1; i++) {
  253.                     *bcptr=box->bv;
  254.                     *tcptr=box->bv;
  255.                     bcptr += wid + 1;
  256.                     tcptr += wid + 1;
  257.                 }
  258.                 /* add corners */
  259.                 *(edscreen+min(b,y)*wid+min(b,y)+min(a,x))=box->bul;
  260.                 *(edscreen+max(b,y)*wid+max(b,y)+min(a,x))=box->bll;
  261.                 *(edscreen+min(b,y)*wid+min(b,y)+max(a,x))=box->bur;
  262.                 *(edscreen+max(b,y)*wid+max(b,y)+max(a,x))=box->blr;
  263.                 inbox = FALSE;
  264.                 x=a;
  265.                 y=b;
  266.                 redraw(edscreen,sx,sy,wid,lines);
  267.             }
  268.             break;
  269.  
  270.           case 18:          /* F8 or  */
  271.           case 26:          /* ctrl-u (box clear) */
  272.             if (! inclear) {
  273.                 /* save cursor position */
  274.                 a=x; /* offset */
  275.                 b=y;
  276.                 inclear = TRUE;
  277.             }
  278.             /* already in clear-- clear it */
  279.             else {
  280.                 /* clear horizontal pieces */
  281.                 bcptr=edscreen+y*wid+y+min(a,x);
  282.                 tcptr=edscreen+b*wid+b+min(a,x);
  283.                 for (i=min(a,x)+1;i<max(a,x);i++) {
  284.                     *(++bcptr)=' ';
  285.                     *(++tcptr)=' ';
  286.                 }
  287.                 /* clear vertical pieces */
  288.                 bcptr=edscreen+min(y,b)*wid+min(y,b)+a;
  289.                 tcptr=edscreen+min(y,b)*wid+min(y,b)+x;
  290.                 for (i=min(b,y); i<=max(b,y)-1; i++) {
  291.                     *bcptr=' ';
  292.                     *tcptr=' ';
  293.                     bcptr += wid + 1;
  294.                     tcptr += wid + 1;
  295.                 }
  296.                 /* clear corners */
  297.                 *(edscreen+min(b,y)*wid+min(b,y)+min(a,x))=' ';
  298.                 *(edscreen+max(b,y)*wid+max(b,y)+min(a,x))=' ';
  299.                 *(edscreen+min(b,y)*wid+min(b,y)+max(a,x))=' ';
  300.                 *(edscreen+max(b,y)*wid+max(b,y)+max(a,x))=' ';
  301.                 inclear = FALSE;
  302.                 x=a;
  303.                 y=b;
  304.                 redraw(edscreen,sx,sy,wid,lines);
  305.             }
  306.             break;
  307.  
  308.           case 19:          /* F9 - draw horizontal line */
  309.             lcptr = cptr - 1;  /* char to left of current pos */
  310.             tcptr = edscreen+(y-1)*wid+(y-1)+x;  /* char above current */
  311.             bcptr = edscreen+(y+1)*wid+(y+1)+x;  /* char below current */
  312.  
  313.             /* fix up left hand connection if necessary */
  314.             if (*cptr==box->bh || *cptr==box->bc) {  /* erasing a line? */
  315.                 if (*lcptr==box->bul) *lcptr=box->bv;
  316.                 else if (*lcptr==box->blvc) *lcptr=box->bv;
  317.                 else if (*lcptr==box->blvc) *lcptr=box->bv;
  318.                 else if (*lcptr==box->bhc) *lcptr=box->bur;
  319.                 else if (*lcptr==box->bhlc) *lcptr=box->blr;
  320.                 else if (*lcptr==box->bc) *lcptr=box->brvc;
  321.             }
  322.             else {                                  /* adding a line? */
  323.                 if (*lcptr==box->bv) {
  324.                     if ((*(tcptr-1)==box->bv || *(tcptr-1)==box->bc
  325.                         || *(tcptr-1)==box->blvc)
  326.                         && (*(bcptr-1)==box->bv || *(bcptr-1)==box->bc
  327.                         || *(bcptr-1)==box->blvc))
  328.                         *lcptr=box->blvc;
  329.                     else if (*(tcptr-1)==box->bv || *(tcptr-1)==box->bc)
  330.                         *lcptr=box->bll;
  331.                     else if (*(bcptr-1)==box->bv || *(bcptr-1)==box->bc)
  332.                         *lcptr=box->bul;
  333.                 }
  334.                 else if (*lcptr==box->bur) *lcptr=box->bhc;
  335.                 else if (*lcptr==box->blr) *lcptr=box->bhlc;
  336.                 else if (*lcptr==box->brvc) *lcptr=box->bc;
  337.             }
  338.             for (i=x; i<wid; i++) {
  339.                 if (*cptr==box->bv) *cptr=box->bc;
  340.                 else if (*cptr==box->bh) *cptr=' ';
  341.                 else if (*cptr==box->brvc) *cptr=box->bv;
  342.                 else if (*cptr==box->blvc) *cptr=box->bv;
  343.                 else if (*cptr==box->bc) *cptr=box->bv;
  344.                 else if (*cptr==box->bhlc) *cptr=box->bv;
  345.                 else if (*cptr==box->bhc) *cptr=box->bv;
  346.                 else *cptr=box->bh;
  347.                 cptr++;
  348.             }
  349.             redraw(edscreen,sx,sy,wid,lines);
  350.             break;
  351.  
  352.           case 20:          /* F10 - draw vertical line */
  353.             lcptr = cptr - 1;  /* char to left of current pos */
  354.             tcptr = edscreen+(y-1)*wid+(y-1)+x;  /* char above current */
  355.             bcptr = edscreen+(y+1)*wid+(y+1)+x;  /* char below current */
  356.  
  357.             /* fix up upper connection if necessary */
  358.             if (*cptr==box->bv || *cptr==box->bc) {  /* erasing a line? */
  359.                 if (*tcptr==box->bur || *tcptr==box->bul
  360.                     || *tcptr==box->bhc) *tcptr=box->bh;
  361.                 else if (*tcptr==box->blvc) *tcptr=box->bll;
  362.                 else if (*tcptr==box->brvc) *tcptr=box->blr;
  363.                 else if (*tcptr==box->bc) *tcptr=box->bhlc;
  364.             }
  365.             else {                                  /* adding a line? */
  366.                 if (*tcptr==box->bh) {
  367.                     if ((*(tcptr-1)==box->bh || *(tcptr-1)==box->bc
  368.                         || *(tcptr-1)==box->bhc) &&
  369.                         (*(tcptr+1)==box->bh || *(tcptr-1)==box->bc
  370.                         || *(tcptr+1)==box->bhc))
  371.                         *tcptr=box->bhc;
  372.                     else if (*(tcptr-1)==box->bh || *(tcptr-1)==box->bc)
  373.                         *tcptr=box->bur;
  374.                     else if (*(tcptr+1)==box->bv || *(tcptr+1)==box->bc)
  375.                         *tcptr=box->bul;
  376.                 }
  377.                 else if (*tcptr==box->bll) *tcptr=box->blvc;
  378.                 else if (*tcptr==box->blr) *tcptr=box->brvc;
  379.                 else if (*tcptr==box->bhc) *tcptr=box->bc;
  380.             }
  381.             for (i=y; i<lines; i++) {
  382.                 if (*cptr==box->bh) *cptr=box->bc;
  383.                 else if (*cptr==box->bv) *cptr=' ';
  384.                 else if (*cptr==box->bc) *cptr=box->bh;
  385.                 else if (*cptr==box->blvc) *cptr=box->bh;
  386.                 else if (*cptr==box->brvc) *cptr=box->bh;
  387.                 else if (*cptr==box->bhlc) *cptr=box->bh;
  388.                 else if (*cptr==box->bhc) *cptr=box->bh;
  389.                 else *cptr=box->bv;
  390.                 cptr += (wid + 1);
  391.             }
  392.             redraw(edscreen,sx,sy,wid,lines);
  393.             break;
  394.  
  395.           case 21:          /* ctrl-y */
  396.             for (i=y; i<lines-1; i++)
  397.                 strcpy(edscreen+i*wid+i,edscreen+(i+1)*wid+i+1);
  398.             strcpy(edscreen+(lines-1)*wid+lines-1,blank);
  399.             redraw(edscreen,sx,sy,wid,lines);
  400.             break;
  401.           case 22:          /* ctrl-z */
  402.             gotoxy(10,24);
  403.             clreol();
  404.             cprintf("Zap entire screen -- you sure (Y/N)?");
  405.             ch=getch();
  406.             ch=toupper(ch);
  407.             if (ch == 'Y') {
  408.                 for (i=0; i<lines; i++) {
  409.                     strcpy(edscreen+i*wid+i,blank);
  410.                 }
  411.                 y=1;
  412.                 x=0;
  413.                 redraw(edscreen,sx,sy,wid,lines);
  414.             }
  415.             else {
  416.              gotoxy(10,24);
  417.                 clreol();
  418.             }
  419.             break;
  420.           case 23:      /* ctrl-n */
  421.             for (i=lines-1; i>y; i--) strcpy(edscreen+i*wid+i,
  422.               edscreen+(i-1)*wid+i-1);
  423.             *(edscreen+y*wid+y+x)=0; /* cut orig line short */
  424.             if (y<lines-1) {
  425.               strdel(edscreen+(y+1)*wid+y+1,0,x);
  426.               pad(edscreen+y*wid+y,wid);
  427.               y++;
  428.               x=0;
  429.             }
  430.             redraw(edscreen,sx,sy,wid,lines);
  431.             break;
  432.           default:     /* any other special keys */
  433.             _retcd=retcd;
  434.             retcd=8;
  435.             break;
  436.         } /* switch retcd */
  437.     }
  438.     while ((retcd != 7) && (retcd != 8));
  439.  
  440.     gotoxy(1,24);
  441.     clreol();
  442.     colx=0;
  443.     coly=0;
  444.  
  445.     trimblanks=savetrim;
  446.     if (trimblanks==TRUE)
  447.       for (i=0; i<lines; i++) trim(edscreen+i*wid+i); /* trim blanks */
  448.     
  449.     *px = x; /* return position in box when leaving */
  450.     *py = y;
  451.     return(_retcd);
  452.  
  453. } /* edit */
  454.