home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / the25.zip / thesrc251.zip / box.c < prev    next >
C/C++ Source or Header  |  1997-09-10  |  17KB  |  454 lines

  1. /***********************************************************************/
  2. /* BOX.C -                                                             */
  3. /* This file contains all functions relating to box operations.        */
  4. /***********************************************************************/
  5. /*
  6.  * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
  7.  * Copyright (C) 1991-1997 Mark Hessling
  8.  *
  9.  * This program is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU General Public License as
  11.  * published by the Free Software Foundation; either version 2 of
  12.  * the License, or any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17.  * General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to:
  21.  *
  22.  *    The Free Software Foundation, Inc.
  23.  *    675 Mass Ave,
  24.  *    Cambridge, MA 02139 USA.
  25.  *
  26.  *
  27.  * If you make modifications to this software that you feel increases
  28.  * it usefulness for the rest of the community, please email the
  29.  * changes, enhancements, bug fixes as well as any and all ideas to me.
  30.  * This software is going to be maintained and enhanced as deemed
  31.  * necessary by the community.
  32.  *
  33.  * Mark Hessling                 Email:             M.Hessling@qut.edu.au
  34.  * PO Box 203                    Phone:                    +617 3802 0800
  35.  * Bellara                       http://www.gu.edu.au/gext/the/markh.html
  36.  * QLD 4507                      **** Maintainer PDCurses & REXX/SQL ****
  37.  * Australia                     ************* Author of THE ************
  38.  */
  39.  
  40. /*
  41. $Id: box.c 2.1 1995/06/24 16:28:35 MH Rel MH $
  42. */
  43.  
  44. #include <the.h>
  45. #include <proto.h>
  46.  
  47. #ifdef HAVE_PROTO
  48. static short box_copy_to_temp(BOXP *);
  49. static short box_copy_from_temp(BOXP *,bool);
  50. #else
  51. static short box_copy_to_temp();
  52. static short box_copy_from_temp();
  53. #endif
  54.  
  55. /*#define DEBUG 1*/
  56. /***********************************************************************/
  57. #ifdef HAVE_PROTO
  58. void box_operations(short action,CHARTYPE reset,bool overlay,CHARTYPE fillchar)
  59. #else
  60. void box_operations(action,reset,overlay,fillchar)
  61. short action;
  62. CHARTYPE reset;
  63. bool overlay;
  64. CHARTYPE fillchar;
  65. #endif
  66. /***********************************************************************/
  67. {
  68. /*-------------------------- external data ----------------------------*/
  69.  extern VIEW_DETAILS *vd_mark;
  70. /*--------------------------- local data ------------------------------*/
  71.  BOXP boxp;
  72.  short rc=RC_OK;
  73.  unsigned short y=0,x=0;
  74.  LENGTHTYPE offset=0;
  75.  short save_mark_type=MARK_VIEW->mark_type;
  76. /*--------------------------- processing ------------------------------*/
  77. #ifdef TRACE
  78.  trace_function("box.c:     box_operations");
  79. #endif
  80. /*---------------------------------------------------------------------*/
  81. /* This procedure is for copying, deleting, filling, moving and        */
  82. /* overlaying box blocks. Box blocks consist of BOX, WORD and COLUMN   */
  83. /* blocks.                                                             */
  84. /*---------------------------------------------------------------------*/
  85.  post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
  86. /*---------------------------------------------------------------------*/
  87. /* If the command was issued on the command line then the destination  */
  88. /* line is the current line and the destination column is 0;           */
  89. /*---------------------------------------------------------------------*/
  90.  if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
  91.    {
  92.     if (CURRENT_VIEW->current_line == 0L)
  93.        boxp.dst_start_line = 1L;
  94.     else
  95.        boxp.dst_start_line = CURRENT_VIEW->current_line;
  96.     boxp.dst_start_col = 0;
  97.    }
  98.  else
  99.    {
  100.     if (CURRENT_VIEW->focus_line == 0L)
  101.        boxp.dst_start_line = 1L;
  102.     else
  103.        boxp.dst_start_line = CURRENT_VIEW->focus_line;
  104.     getyx(CURRENT_WINDOW,y,x);
  105.     boxp.dst_start_col = x + CURRENT_VIEW->verify_col-1;
  106.    }
  107. /*---------------------------------------------------------------------*/
  108. /* Set up the source and destination views...                          */
  109. /*---------------------------------------------------------------------*/
  110.  boxp.src_view = MARK_VIEW;
  111.  boxp.dst_view = CURRENT_VIEW;
  112.  
  113.  boxp.src_start_line = MARK_VIEW->mark_start_line;
  114.  boxp.src_start_col = MARK_VIEW->mark_start_col-1;
  115.  
  116.  boxp.num_cols =  MARK_VIEW->mark_end_col - MARK_VIEW->mark_start_col + 1;
  117. /*---------------------------------------------------------------------*/
  118. /* If the block type is COLUMN, the number of lines to operate on is   */
  119. /* the number of lines in the source file and the destination start    */
  120. /* line is line 1. Reset these values set above.                       */
  121. /*---------------------------------------------------------------------*/
  122.  if (MARK_VIEW->mark_type == M_COLUMN)
  123.    {
  124.     boxp.num_lines = MARK_VIEW->file_for_view->number_lines - boxp.src_start_line +1L;
  125.     boxp.dst_start_line = 1L;
  126.    }
  127.  else
  128.     boxp.num_lines = MARK_VIEW->mark_end_line - boxp.src_start_line +1L;
  129. /*---------------------------------------------------------------------*/
  130. /* Find the current LINE pointer for both the source and destination   */
  131. /* lines.                                                              */
  132. /*---------------------------------------------------------------------*/
  133.  boxp.curr_src = lll_find(MARK_FILE->first_line,MARK_FILE->last_line,boxp.src_start_line,MARK_FILE->number_lines);
  134.  if (action != BOX_D)
  135.     boxp.curr_dst = lll_find(CURRENT_FILE->first_line,CURRENT_FILE->last_line,boxp.dst_start_line,CURRENT_FILE->number_lines);
  136. /*---------------------------------------------------------------------*/
  137. /* Call the appropriate box function...                                */
  138. /*---------------------------------------------------------------------*/
  139.  boxp.action = action;
  140.  switch(action)
  141.    {
  142.     case BOX_D:
  143.         rc = box_delete(&boxp);
  144.         break;
  145.     case BOX_M:
  146.         rc = box_move(&boxp,overlay);
  147.         break;
  148.     case BOX_C:
  149.         rc = box_move(&boxp,overlay);
  150.         break;
  151.     case BOX_F:
  152.         rc = box_fill(&boxp,fillchar);
  153.         break;
  154.    }
  155. /*---------------------------------------------------------------------*/
  156. /* Increment the alteration counts...                                  */
  157. /*---------------------------------------------------------------------*/
  158.  increment_alt(CURRENT_FILE);
  159. /*---------------------------------------------------------------------*/
  160. /* Set the parameters in the MARK_VIEW to OFF;                         */
  161. /*---------------------------------------------------------------------*/
  162.  MARK_VIEW->marked_line = MARK_VIEW->marked_col = FALSE;
  163.  MARK_VIEW = (VIEW_DETAILS *)NULL;
  164. /*---------------------------------------------------------------------*/
  165. /* If we are not resetting the block, set up block markers...          */
  166. /*---------------------------------------------------------------------*/
  167.  if (reset != SOURCE_BLOCK_RESET)
  168.    {
  169.     if (boxp.src_start_col < boxp.dst_start_col
  170.     && action == BOX_M)
  171.        offset = boxp.num_cols;
  172.     MARK_VIEW = CURRENT_VIEW;
  173.     MARK_VIEW->mark_start_line = boxp.dst_start_line;
  174.     MARK_VIEW->mark_end_line = boxp.dst_start_line+boxp.num_lines-1L;
  175.     MARK_VIEW->mark_start_col = boxp.dst_start_col+1-offset;
  176.     MARK_VIEW->mark_end_col = boxp.dst_start_col+boxp.num_cols-offset;
  177.     MARK_VIEW->mark_type = save_mark_type;
  178.     MARK_VIEW->marked_line = MARK_VIEW->marked_col = TRUE;
  179.     wmove(CURRENT_WINDOW,y,x-offset);
  180.    }
  181.  pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  182.  build_screen(current_screen); 
  183.  display_screen(current_screen); /* should only call this is the marked block is in view */
  184. #ifdef TRACE
  185.  trace_return();
  186. #endif
  187.  return;
  188. }
  189. /***********************************************************************/
  190. #ifdef HAVE_PROTO
  191. short box_delete(BOXP *prm)
  192. #else
  193. short box_delete(prm)
  194. BOXP *prm;
  195. #endif
  196. /***********************************************************************/
  197. {
  198. /*-------------------------- external data ----------------------------*/
  199.  extern VIEW_DETAILS *vd_mark;
  200. /*--------------------------- local data ------------------------------*/
  201.  LINETYPE i=0L;
  202.  LENGTHTYPE j=0;
  203.  LENGTHTYPE num_to_move=0,length_diff=0;
  204. /*--------------------------- processing ------------------------------*/
  205. #ifdef TRACE
  206.  trace_function("box.c:     box_delete");
  207. #endif
  208.  for (i=0L;i<prm->num_lines;i++)
  209.     {
  210.      if (processable_line(prm->dst_view,prm->src_start_line+i,prm->curr_src) == LINE_LINE)
  211.        {
  212.         if ((LINETYPE)prm->curr_src->length >= (LINETYPE)MARK_VIEW->mark_start_col)
  213.           {
  214.            num_to_move = (LENGTHTYPE)max((LINETYPE)prm->curr_src->length -
  215.                                          (LINETYPE)MARK_VIEW->mark_end_col,0L);
  216.            length_diff = (LENGTHTYPE)min((LINETYPE)MARK_VIEW->mark_end_col-(LINETYPE)MARK_VIEW->mark_start_col+1L,
  217.                                          (LINETYPE)prm->curr_src->length-(LINETYPE)MARK_VIEW->mark_start_col+1L);
  218.           }
  219.         else
  220.            num_to_move = length_diff = 0;
  221.         if (length_diff != 0)
  222.           {
  223.            add_to_recovery_list(prm->curr_src->line,prm->curr_src->length);
  224.            prm->curr_src->length = (LENGTHTYPE)((LINETYPE)prm->curr_src->length-(LINETYPE)length_diff);
  225.            for (j=0;j<num_to_move;j++)
  226.               *(prm->curr_src->line+(LENGTHTYPE)((LINETYPE)j+(LINETYPE)MARK_VIEW->mark_start_col-1L)) = *(prm->curr_src->line+prm->src_start_col+j+prm->num_cols);
  227.            *(prm->curr_src->line+prm->curr_src->length) = '\0';/* null terminate */
  228.           }
  229.        }
  230.      prm->curr_src = prm->curr_src->next;  /* this should NEVER go past the end */
  231.     }
  232. #ifdef TRACE
  233.  trace_return();
  234. #endif
  235.  return(RC_OK);
  236. }
  237. /***********************************************************************/
  238. #ifdef HAVE_PROTO
  239. short box_move(BOXP *prm,bool overlay)
  240. #else
  241. short box_move(prm,overlay)
  242. BOXP *prm;
  243. bool overlay;
  244. #endif
  245. /***********************************************************************/
  246. {
  247. /*-------------------------- external data ----------------------------*/
  248. /*--------------------------- local data ------------------------------*/
  249.  LINE *first_save=NULL,*save_src=NULL,*temp_src=NULL;
  250.  LINETYPE save_src_start_line=0L;
  251.  LENGTHTYPE save_src_start_col=0;
  252. /*--------------------------- processing ------------------------------*/
  253. #ifdef TRACE
  254.  trace_function("box.c:     box_move");
  255. #endif
  256.  save_src_start_col = prm->src_start_col;
  257.  save_src_start_line = prm->src_start_line;
  258.  save_src = prm->curr_src;
  259.  box_copy_to_temp(prm);                  /* copy box from file to temp */
  260.  if (prm->dst_start_col <= prm->src_start_col+prm->num_cols
  261.  &&  prm->action == BOX_M)
  262.    {
  263.     temp_src = prm->curr_src; /* save the LINE pointer to temp src lines */
  264.     prm->curr_src = save_src; /* point to file src lines */
  265.     box_delete(prm);
  266.     prm->curr_src = temp_src; /* point to temp src lines */
  267.    }
  268.  prm->src_start_line = 0L;
  269.  prm->src_start_col = 0;
  270.  box_copy_from_temp(prm,overlay);        /* copy box from temp to file */
  271.  first_save = lll_free(first_save);
  272.  prm->src_start_line = save_src_start_line;
  273.  prm->src_start_col = save_src_start_col;
  274.  prm->curr_src = save_src;
  275.  if (prm->dst_start_col > prm->src_start_col+prm->num_cols
  276.  &&  prm->action == BOX_M)
  277.     box_delete(prm);
  278.  
  279. #ifdef TRACE
  280.  trace_return();
  281. #endif
  282.  return(RC_OK);
  283. }
  284. /***********************************************************************/
  285. #ifdef HAVE_PROTO
  286. static short box_copy_to_temp(BOXP *prm)
  287. #else
  288. static short box_copy_to_temp(prm)
  289. BOXP *prm;
  290. #endif
  291. /***********************************************************************/
  292. {
  293. /*-------------------------- external data ----------------------------*/
  294.  extern CHARTYPE *rec;
  295.  extern unsigned short rec_len;
  296. /*--------------------------- local data ------------------------------*/
  297.  LINE *first_save=NULL,*save_src=NULL,*tmp=NULL;
  298.  LINETYPE i=0L;
  299.  short rc=RC_OK;
  300. /*--------------------------- processing ------------------------------*/
  301. #ifdef TRACE
  302.  trace_function("box.c:     box_copy_to_temp");
  303. #endif
  304.  tmp = prm->curr_src;
  305.  for (i=0L;i<prm->num_lines;i++)
  306.     {
  307.      if (processable_line(prm->src_view,prm->src_start_line+i,tmp) == LINE_LINE)
  308.        {
  309.         memset(rec,' ',max_line_length);       /* copy line into rec[] */
  310.         memcpy(rec,tmp->line,tmp->length);
  311.         rec_len = tmp->length;
  312.         if ((save_src = add_line(first_save,save_src,
  313.              rec+prm->src_start_col,prm->num_cols,0,TRUE)) == (LINE *)NULL)
  314.           {
  315. #ifdef TRACE
  316.            trace_return();
  317. #endif
  318.            return(RC_OUT_OF_MEMORY);
  319.           }
  320.         if (first_save == (LINE *)NULL)
  321.            first_save = save_src;
  322.        }
  323.      tmp = tmp->next;
  324.     }
  325.  prm->curr_src = first_save;
  326. #ifdef TRACE
  327.  trace_return();
  328. #endif
  329.  return(rc);
  330. }
  331. /***********************************************************************/
  332. #ifdef HAVE_PROTO
  333. static short box_copy_from_temp(BOXP *prm,bool overlay)
  334. #else
  335. static short box_copy_from_temp(prm,overlay)
  336. BOXP *prm;
  337. bool overlay;
  338. #endif
  339. /***********************************************************************/
  340. {
  341. /*-------------------------- external data ----------------------------*/
  342.  extern CHARTYPE *rec;
  343.  extern unsigned short rec_len;
  344. /*--------------------------- local data ------------------------------*/
  345.  LINETYPE dst_lineno=0L;
  346.  LENGTHTYPE j=0;
  347.  CHARTYPE chr=0;
  348.  short rc=RC_OK,line_type=0;
  349. /*--------------------------- processing ------------------------------*/
  350. #ifdef TRACE
  351.  trace_function("box.c:     box_copy_from_temp");
  352. #endif
  353.  dst_lineno = prm->dst_start_line;
  354.  while(prm->curr_src)
  355.    {
  356.     while(1)
  357.       {
  358.        line_type = processable_line(prm->dst_view,dst_lineno,prm->curr_dst);
  359.        if (line_type == LINE_LINE)
  360.           break;
  361. /*       if (line_type == LINE_TOF_EOF) MH12 */
  362.        if (line_type == LINE_TOF
  363.        ||  line_type == LINE_EOF)
  364.          {
  365.           if ((prm->curr_dst = add_line(CURRENT_FILE->first_line,prm->curr_dst->prev,
  366.                                  (CHARTYPE *)"",0,0,TRUE)) == (LINE *)NULL)
  367.             {
  368. #ifdef TRACE
  369.              trace_return();
  370. #endif
  371.              return(RC_OUT_OF_MEMORY);
  372.             }
  373.           CURRENT_FILE->number_lines++;
  374.           break;
  375.          }
  376.        dst_lineno++;
  377.        prm->curr_dst = prm->curr_dst->next;
  378.       }
  379.  
  380.     pre_process_line(prm->dst_view,dst_lineno,(LINE *)NULL);/* copy dest line into rec */
  381.     for (j=0;j<prm->num_cols;j++)
  382.       {
  383.        if (prm->src_start_col+j+1 > prm->curr_src->length)
  384.           chr = (CHARTYPE)' ';
  385.        else
  386.           chr = (CHARTYPE)*(prm->curr_src->line+prm->src_start_col+j);
  387.        if (overlay)
  388.           rec[prm->dst_start_col+j] = chr;
  389.        else
  390.           meminschr(rec,chr,prm->dst_start_col+j,max_line_length,rec_len++);
  391.       }
  392.     rc = memrevne(rec,' ',max_line_length);
  393.     if (rc == (-1))
  394.        rec_len = 0;
  395.     else
  396.        rec_len = rc+1;
  397.     post_process_line(prm->dst_view,dst_lineno,(LINE *)NULL,FALSE);
  398.     prm->curr_src = prm->curr_src->next;   /* this should NEVER go past the end */
  399.     prm->curr_dst = prm->curr_dst->next;   /* this should NEVER go past the end */
  400.     dst_lineno++;
  401.    }
  402.  prm->num_lines = dst_lineno - prm->dst_start_line;
  403. #ifdef TRACE
  404.  trace_return();
  405. #endif
  406.  return(RC_OK);
  407. }
  408. /***********************************************************************/
  409. #ifdef HAVE_PROTO
  410. short box_fill(BOXP *prm,CHARTYPE fillchar)
  411. #else
  412. short box_fill(prm,fillchar)
  413. BOXP *prm;
  414. CHARTYPE fillchar;
  415. #endif
  416. /***********************************************************************/
  417. {
  418. /*-------------------------- external data ----------------------------*/
  419.  extern CHARTYPE *rec;
  420.  extern unsigned short rec_len;
  421. /*--------------------------- local data ------------------------------*/
  422.  LINETYPE i=0L;
  423.  LENGTHTYPE j=0;
  424.  short rc=RC_OK;
  425. /*--------------------------- processing ------------------------------*/
  426. #ifdef TRACE
  427.  trace_function("box.c:     box_fill");
  428. #endif
  429.  for (i=0L;i<prm->num_lines;i++)
  430.     {
  431.      if (processable_line(CURRENT_VIEW,prm->src_start_line+i,prm->curr_src) == LINE_LINE)
  432.        {
  433.         pre_process_line(CURRENT_VIEW,prm->src_start_line+i,(LINE *)NULL);/* copy source line into rec */
  434.         for (j=0;j<prm->num_cols;j++)
  435.             rec[prm->src_start_col+j] = fillchar;
  436.         rc = memrevne(rec,' ',max_line_length);
  437.         if (rc == (-1))
  438.            rec_len = 0;
  439.         else
  440.            rec_len = rc+1;
  441.         post_process_line(CURRENT_VIEW,prm->src_start_line+i,(LINE *)NULL,FALSE);
  442.        }
  443.      prm->curr_src = prm->curr_src->next;   /* this should NEVER go past the end */
  444.     }
  445.  
  446.  prm->dst_start_col = prm->src_start_col;
  447.  prm->dst_start_line = prm->src_start_line;
  448.  
  449. #ifdef TRACE
  450.  trace_return();
  451. #endif
  452.  return(RC_OK);
  453. }
  454.