home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CSAPE32.ARJ / SOURCE / CSSRC / FNTED.C < prev    next >
C/C++ Source or Header  |  1990-10-19  |  9KB  |  408 lines

  1. /*
  2.     fnted.c
  3.  
  4.     % ted_funcs        virtual field funcs for text editing, limited size
  5.  
  6.     C-scape 3.2
  7.     Copyright (c) 1988, 1989 by Oakland Group, Inc.
  8.     ALL RIGHTS RESERVED.
  9.  
  10.     Revision History:
  11.     -----------------
  12.      8/22/88 jdc    Created
  13.      9/10/88 jmd    Preened
  14.      9/12/88 jdc    Preened even more
  15.      9/17/88 jmd     added std_ funcs
  16.      9/22/88 jmd     added ted_fenter
  17.     10/09/88 jmd     added SED_ABORT support
  18.     10/14/88 jdc    added var_size element to field_funcs_struct
  19.     11/05/88 jmd    removed menu_Close
  20.  
  21.      2/07/89 jmd    added char * cast
  22.      4/19/89 jdc    fixed checking for sed_GetTB() and sed_SetTB()
  23.      6/07/89 jmd    added test for mouse code (later removed)
  24.      3/28/90 jmd    ansi-fied
  25.      4/25/90 jmd    the cut buffer is now stored in the field 2nd data pointer
  26.      6/13/90 jmd    ted_sexit now resets the field data pointer (not the sed 's)
  27.      6/14/90 jdc    now Sets, not Gets
  28.      6/26/90 jdc    fixed cutbuf check for cut & copy
  29.      9/13/90 jmd    made #defines for all text strings
  30.     10/19/90 mla    added mouse support to pop_Search
  31. */
  32.  
  33. #include <stdio.h>
  34. #include <string.h>
  35. #include <ctype.h>
  36.  
  37. #include "cscape.h"
  38. #include "scancode.h"
  39.  
  40. #include "teddecl.h"
  41.  
  42. OGLOBAL field_funcs_struct ted_funcs = {
  43.     ted_fenter,
  44.     std_fexit,
  45.     ted_fkey,
  46.     ted_senter,
  47.     ted_sexit,
  48.     VAR_TED
  49. };
  50.  
  51. OSTATIC int pop_Search(boolean mode, char *srch, char *repl);
  52.  
  53. /* strings used by ted_funcs */
  54.  
  55. #define MSG_SEARCH            "Search"
  56. #define MSG_REPLACE            "Replace"
  57. #define MSG_SEARCHING        "Searching..."
  58. #define MSG_REPLACING        "Replacing..."
  59. #define MSG_NOTFOUND        "Pattern not found."
  60. #define    MSG_REPLACEYNG        "Replace? Yes, No, Global : "
  61. #define MSG_ENDOFTEXT        "Searching for end of text."
  62.  
  63. /* -------------------------------------------------------------------------- */
  64.  
  65. void ted_fenter(sed_type sed)
  66. {
  67.     std_fenter(sed);
  68.  
  69.     ted_StartWorking(sed);
  70.  
  71.     /* the cut buffer gets created when needed */
  72. }
  73.  
  74. static char search[51];
  75. static char replace[51];
  76.  
  77. void ted_fkey(sed_type sed)
  78. /*
  79. */
  80. {
  81.     int scancode, key, rlen, row, col;
  82.     menu_type cutbuf;
  83.  
  84.     scancode = kb_Read();
  85.  
  86.     if (sed_DoSpecial(sed, scancode))
  87.         return;
  88.     if (special_key(sed, scancode))
  89.         return;
  90.  
  91.     switch (scancode) {
  92.     case ESC:
  93.         /* leave editor */
  94.         sed_ToggleExit(sed);
  95.         sed_SetBaton(sed, 0);
  96.         return;
  97.  
  98.     case ALT_M:
  99.         /* toggle row-wise mark mode */
  100.         if (ted_GetMark(sed) == TED_NOMARK) {
  101.             ted_SetMark(sed, TED_MARK);
  102.         }
  103.         else {
  104.             ted_SetMark(sed, TED_NOMARK);
  105.         }
  106.         break;
  107.  
  108.     case ALT_C:
  109.         /* toggle column-wise mark mode */
  110.         if (ted_GetMark(sed) == TED_NOMARK) {
  111.             ted_SetMark(sed, TED_COLMARK);
  112.         }
  113.         else {
  114.             ted_SetMark(sed, TED_NOMARK);
  115.         }
  116.         break;
  117.  
  118.     case GREYMINUS:
  119.         /* cut marked region */
  120.         /* fall through to copy case */
  121.     case GREYPLUS:
  122.         /* copy marked region */
  123.         /* create a cut buffer, attach it to the field second data pointer */
  124.         if ((cutbuf = (menu_type)sed_GetFieldData(sed, sed_GetFieldNo(sed), 1)) == NULL) {
  125.             cutbuf = menu_Open();
  126.             sed_SetFieldData(sed, sed_GetFieldNo(sed), 1, (VOID *)cutbuf);
  127.         }
  128.  
  129.         if (cutbuf != NULL) {
  130.             if (scancode == GREYMINUS) {
  131.                 ted_BlockCut(sed, cutbuf);
  132.             }
  133.             else {
  134.                 ted_BlockCopy(sed, cutbuf);
  135.             }
  136.         }
  137.         ted_SetMark(sed, TED_NOMARK);
  138.         break;
  139.  
  140.     case INS:
  141.         /* paste the cut buffer */
  142.         if ((cutbuf = (menu_type)sed_GetFieldData(sed, sed_GetFieldNo(sed), 1)) != NULL 
  143.             && !ted_BlockPaste(sed, cutbuf)) {
  144.  
  145.             /* probably hit ted_MaxSize, signal user */
  146.             tone();
  147.         }
  148.         break;
  149.  
  150.     case DEL:
  151.         if (ted_GetMark(sed) != TED_NOMARK) {
  152.         /* delete the marked region (if there is one) */
  153.             ted_BlockDelete(sed);
  154.             ted_SetMark(sed, TED_NOMARK);
  155.         }
  156.         else {
  157.         /* Otherwise, delete a character */
  158.             ted_DeleteChar(sed);
  159.         }
  160.         break;
  161.  
  162.     case ALT_S:
  163.         /* Search for a string */
  164.         if (pop_Search(FALSE, search, replace)) {
  165.             sed_BorderPrompt(sed, MSG_SEARCHING);
  166.  
  167.             if (ted_Search(sed, search, TED_FORWARD | TED_AFTER))    {
  168.                 sed_BorderPrompt(sed, NULL);
  169.             }
  170.             else {
  171.                 sed_BorderPrompt(sed, MSG_NOTFOUND);
  172.             }
  173.         }
  174.         break;
  175.  
  176.     case ALT_R:
  177.         /* Search and replace string */
  178.         /* Step 1 */
  179.         if (pop_Search(TRUE, search, replace)) {
  180.             sed_BorderPrompt(sed, MSG_SEARCHING);
  181.  
  182.             /* Step 2 */
  183.             ted_GetPosition(sed, &row, &col);
  184.  
  185.             key = (int)'y';
  186.  
  187.             /* get the length of the replace string only once */
  188.             rlen = strlen(replace);
  189.  
  190.             /* Step 3 */
  191.             if (ted_Search(sed, search, TED_FORWARD) == FALSE) {
  192.                 sed_BorderPrompt(sed, MSG_NOTFOUND);
  193.                 break;
  194.             }
  195.             /* Step 4 */
  196.             while (ted_Search(sed, search, TED_FORWARD)) {
  197.  
  198.                 /* Step 5 */
  199.                 ted_SetMark(sed, TED_MARK);
  200.  
  201.                 /* Step 6 */
  202.                 ted_Search(sed, search, TED_FORWARD | TED_AFTER);
  203.  
  204.                 /* make sure cursor isn't past the end of the pattern */
  205.                 ted_GotoCursor(sed, ted_GetCursor(sed) - 1L);
  206.  
  207.                 /* Step 7 */
  208.                 if ((char)key != 'G' && (char)key != 'g') {
  209.                     sed_BorderPrompt(sed, MSG_REPLACEYNG);
  210.  
  211.                     if ((key = kb_Read()) == ESC) {
  212.                         /* Stop searching */
  213.                         ted_SetMark(sed, TED_NOMARK);
  214.                         break;
  215.                     }
  216.                     key = ascii(key);
  217.  
  218.                     if (key == 'G' || key == 'g') {
  219.                         /* Turn off refresh while globally replacing */
  220.                         ted_SetRefresh(sed, TED_NOREFRESH);
  221.                         sed_BorderPrompt(sed, MSG_REPLACING);
  222.                     }
  223.                 }                    
  224.  
  225.                 if (key == 'N' || key == 'n') {
  226.                     /* Skip this one, move past current pattern */
  227.                     ted_SetMark(sed, TED_NOMARK);
  228.                     ted_GotoCursor(sed, ted_GetCursor(sed) + 1L);
  229.                 }
  230.                 else {
  231.                     /* Step 8 */
  232.                     ted_BlockDelete(sed);
  233.                     ted_AddString(sed, replace, rlen);
  234.                 }
  235.             }
  236.  
  237.             /* Step 10 */
  238.             sed_BorderPrompt(sed, NULL);
  239.             ted_SetRefresh(sed, TED_REFRESH);
  240.             if (key != ESC) {
  241.                 ted_GotoPosition(sed, row, col);
  242.             }
  243.             sed_RepaintText(sed);
  244.         }
  245.         break;
  246.  
  247.     case UP:
  248.         ted_UpChar(sed);
  249.         break;
  250.     case DOWN:
  251.         ted_DownChar(sed);
  252.         break;
  253.     case LEFT:
  254.         ted_LeftChar(sed, TED_TABJUMP);
  255.         break;
  256.     case RIGHT:
  257.         ted_RightChar(sed, TED_TABJUMP);
  258.         break;
  259.     case HOME:
  260.         ted_GoHome(sed);
  261.         break;
  262.     case END:
  263.         ted_GoEnd(sed);
  264.         break;
  265.     case PGUP:
  266.         ted_PageUp(sed);
  267.         break;
  268.     case PGDN:
  269.         ted_PageDown(sed);
  270.         break;
  271.     case CTRL_HOME:
  272.     case CTRL_PGUP:
  273.         ted_GoTop(sed);
  274.         break;
  275.     case CTRL_END:
  276.     case CTRL_PGDN:
  277.         sed_BorderPrompt(sed, MSG_ENDOFTEXT);
  278.         ted_GoBottom(sed);
  279.         sed_BorderPrompt(sed, NULL);
  280.         break;
  281.  
  282.     case ENTER:
  283.         if (ted_GetInsert(sed) == TED_INSERT) {
  284.             if (!ted_AddRow(sed)) {
  285.                 /* probably hit ted_MaxSize, signal user */
  286.                 tone();
  287.             }
  288.         }
  289.         else {
  290.             ted_DownChar(sed);
  291.             ted_GoHome(sed);
  292.         }
  293.         break;
  294.  
  295.     case BACKSPACE:
  296.         if (ted_LeftChar(sed, TED_TABJUMP)) {
  297.             ted_DeleteChar(sed);
  298.         }
  299.         break;
  300.  
  301.     case TAB:
  302.         if (!ted_AddChar(sed, '\t')) {
  303.  
  304.             /* probably hit ted_MaxSize, signal user */
  305.             tone();
  306.         }
  307.         break;
  308.  
  309.     default:
  310.         key = ascii(scancode);
  311.         if (isprint(key) || ((unsigned char) (key)) > 127) {
  312.             if (!ted_AddChar(sed, (unsigned char) key)) {
  313.  
  314.                 /* probably hit ted_MaxSize, signal user */
  315.                 tone();
  316.             }
  317.         }
  318.         break;
  319.     }
  320.  
  321.     /* reset baton */
  322.     sed_SetBaton(sed, -1);
  323. }
  324.  
  325. void ted_senter(sed_type sed, int fieldno)
  326. /*
  327.     Copy the string into the ted.
  328. */
  329. {
  330.     unsigned int len;
  331.     char *text;
  332.  
  333.     /* if limiting is set and the var is not NULL then sed_SetTB() */
  334.     if (ted_GetMaxSize(sed) > 0L && (text = (char *) sed_GetVar(sed, fieldno)) != NULL) {
  335.         len = strlen(text);
  336.         sed_ClearTB(sed);
  337.         sed_SetTB(sed, text, len);
  338.         sed_RewindTB(sed);
  339.     }
  340.     ted_SetInsert(sed, TED_INSERT);
  341. }
  342.  
  343. void ted_sexit(sed_type sed, int fieldno)
  344. /*
  345.     Copy the ted into the string.
  346. */
  347. {
  348.     int len, row, col;
  349.     char *text;
  350.     menu_type cutbuf;
  351.  
  352.     /* if limiting is set and the var is not NULL then sed_GetTB() */
  353.     if (sed_GetBaton(sed) != SED_ABORT && ted_GetMaxSize(sed) > 0L 
  354.         && (text = (char *) sed_GetVar(sed, fieldno)) != NULL) {
  355.  
  356.         ted_GetPosition(sed, &row, &col);
  357.  
  358.         /* go to top of textbuf, don't show it on screen */
  359.         sed_RewindTB(sed);
  360.         len = sed_GetTB(sed, text, (unsigned int)ted_GetMaxSize(sed), TED_SOFT);
  361.  
  362.         /* always a '\n' at the end, replace it with a '\0' */
  363.         text[len - 1] = '\0';
  364.  
  365.         /* restore cursor */
  366.         ted_GotoPosition(sed, row, col);
  367.     }
  368.  
  369.     if ((cutbuf = (menu_type) sed_GetFieldData(sed, fieldno, 1)) != NULL)    {
  370.         /* destroy the cut buffer (menu) */
  371.         menu_Destroy(cutbuf);
  372.         sed_SetFieldData(sed, fieldno, 1, NULL);
  373.     }
  374. }
  375.  
  376. static int pop_Search(boolean mode, char *srch, char *repl)
  377. /*
  378.     Get a search string, put it into srch.
  379.     if mode is TRUE
  380.         also get a replace string, put it into repl.
  381.     Return 0 if ESC is pressed.
  382. */
  383. {
  384.     menu_type menu;
  385.     sed_type sed;
  386.     int ret;
  387.  
  388.     menu = menu_Open();
  389.  
  390.     menu_Printf(menu, "%s  : @fw20[@[50,#]]", MSG_SEARCH, srch, &string_funcs);
  391.     if (mode == TRUE) {
  392.         menu_Printf(menu, "\n%s : @fw20[@[50,#]]", MSG_REPLACE, repl, &string_funcs);
  393.     }
  394.  
  395.     sed = sed_Open(menu);
  396.  
  397.     sed_SetBorder(sed, bd_1);
  398.     sed_SetPosition(sed, 10, 20);
  399.     sed_SetMouse(sed, sedmou_GreedyTrack);
  400.  
  401.     sed_Repaint(sed);
  402.     ret = sed_Go(sed);
  403.  
  404.     sed_Close(sed);
  405.  
  406.     return(ret);
  407. }
  408.