home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / thesrc15.zip / box.c < prev    next >
C/C++ Source or Header  |  1993-11-17  |  13KB  |  387 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-1993 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@gu.edu.au
  34.  * 36 David Road                     Phone: +61 7 849 7731
  35.  * Holland Park                      Fax:   +61 7 875 5314
  36.  * QLD 4121
  37.  * Australia
  38.  */
  39.  
  40. /*
  41. $Header: C:\THE\RCS\box.c 1.4 1993/09/01 16:25:30 MH Interim MH $
  42. */
  43.  
  44. #include <stdio.h>
  45.  
  46. #include "the.h"
  47. #include "proto.h"
  48.  
  49. /*#define DEBUG 1*/
  50. /*-------------------------- external data ----------------------------*/
  51. extern VIEW_DETAILS *vd_current,*vd_mark;
  52. extern char *rec;
  53. extern unsigned short rec_len;
  54. /***********************************************************************/
  55. #ifdef PROTO
  56. void box_operations(int action,char reset,bool overlay,char fillchar)
  57. #else
  58. void box_operations(action,reset,overlay,fillchar)
  59. int action;
  60. char reset;
  61. bool overlay;
  62. char fillchar;
  63. #endif
  64. /***********************************************************************/
  65. {
  66. /*--------------------------- local data ------------------------------*/
  67.  BOXP boxp;
  68.  int rc;
  69.  unsigned short y,x;
  70.  int offset=0;
  71. /*--------------------------- processing ------------------------------*/
  72. #ifdef TRACE
  73.  trace_function("commutil.c:box_operations");
  74. #endif
  75.  
  76.  post_process_line(CURRENT_VIEW->focus_line);
  77.  
  78. /*---------------------------------------------------------------------*/
  79. /* If the command was issued on the command line then the destination  */
  80. /* line is the current line and the destination column is 0;           */
  81. /*---------------------------------------------------------------------*/
  82.  if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
  83.    {
  84.     boxp.dst_start_line = CURRENT_VIEW->current_line;
  85.     boxp.dst_start_col = 0;
  86.    }
  87.  else
  88.    {
  89.     if (CURRENT_VIEW->focus_line == 0L)
  90.        boxp.dst_start_line = 1L;
  91.     else
  92.        boxp.dst_start_line = CURRENT_VIEW->focus_line;
  93.     getyx(CURRENT_WINDOW,y,x);
  94.     boxp.dst_start_col = x + CURRENT_VIEW->verify_col-1;
  95.    }
  96.  
  97.  boxp.src_start_line = MARK_VIEW->mark_start_line;
  98.  boxp.src_start_col = MARK_VIEW->mark_start_col-1;
  99.  
  100.  boxp.num_cols =  MARK_VIEW->mark_end_col - MARK_VIEW->mark_start_col + 1;
  101.  
  102.  boxp.num_lines = MARK_VIEW->mark_end_line - boxp.src_start_line +1L;
  103. /*---------------------------------------------------------------------*/
  104. /* Find the current LINE pointer for both the source and destination   */
  105. /* lines.                                                              */
  106. /*---------------------------------------------------------------------*/
  107. #ifdef USE_VOID
  108.  boxp.curr_src = (LINE *)ll_find((void *)MARK_FILE->first_line,boxp.src_start_line);
  109. #else
  110.  boxp.curr_src = lll_find(MARK_FILE->first_line,boxp.src_start_line);
  111. #endif
  112.  if (action != BOX_D)
  113. #ifdef USE_VOID
  114.     boxp.curr_dst = (LINE *)ll_find((void *)CURRENT_FILE->first_line,boxp.dst_start_line);
  115. #else
  116.     boxp.curr_dst = lll_find(CURRENT_FILE->first_line,boxp.dst_start_line);
  117. #endif
  118. /*---------------------------------------------------------------------*/
  119. /* Call the appropriate box function...                                */
  120. /*---------------------------------------------------------------------*/
  121.  boxp.action = action;
  122.  switch(action)
  123.    {
  124.     case BOX_D:
  125.         rc = box_delete(&boxp);
  126.         break;
  127.     case BOX_M:
  128.         rc = box_move(&boxp,overlay);
  129.         break;
  130.     case BOX_C:
  131. /*      rc = box_copy(&boxp,overlay);*/
  132.         rc = box_move(&boxp,overlay);
  133.         break;
  134.     case BOX_F:
  135.         rc = box_fill(&boxp,fillchar);
  136.         break;
  137.    }
  138.  
  139.  if ((rc = increment_alt(CURRENT_FILE)) != RC_OK)
  140.    {
  141. #ifdef TRACE
  142.     trace_return();
  143. #endif
  144.     return;  /* should return a value */
  145.    }
  146.  
  147. /*---------------------------------------------------------------------*/
  148. /* Set the parameters in the MARK_VIEW to OFF;                         */
  149. /*---------------------------------------------------------------------*/
  150.  MARK_VIEW->mark_start_line = MARK_VIEW->mark_end_line = (-1L);
  151.  MARK_VIEW->mark_start_col = MARK_VIEW->mark_end_col = (-1L);
  152.  MARK_VIEW = (VIEW_DETAILS *)NULL;
  153.  
  154. /*---------------------------------------------------------------------*/
  155. /* If we are not resetting the block, set up block markers...          */
  156. /*---------------------------------------------------------------------*/
  157.  if (reset != SOURCE_BLOCK_RESET)
  158.    {
  159.     if (boxp.src_start_col < boxp.dst_start_col
  160.     && action == BOX_M)
  161.        offset = boxp.num_cols;
  162.     MARK_VIEW = CURRENT_VIEW;
  163.     MARK_VIEW->mark_start_line = boxp.dst_start_line;
  164.     MARK_VIEW->mark_end_line = boxp.dst_start_line+boxp.num_lines-1L;
  165.     MARK_VIEW->mark_start_col = boxp.dst_start_col+1-offset;
  166.     MARK_VIEW->mark_end_col = boxp.dst_start_col+boxp.num_cols-offset;
  167.     MARK_VIEW->mark_type = M_BOX;
  168.     wmove(CURRENT_WINDOW,y,x-offset);
  169.    }
  170.  
  171.  pre_process_line(CURRENT_VIEW->focus_line);
  172.  
  173.  show_page(); /* should only call this is the marked block is in view */
  174.  
  175. #ifdef TRACE
  176.  trace_return();
  177. #endif
  178.  return;
  179. }
  180. /***********************************************************************/
  181. #ifdef PROTO
  182. int box_delete(BOXP *prm)
  183. #else
  184. int box_delete(prm)
  185. BOXP *prm;
  186. #endif
  187. /***********************************************************************/
  188. {
  189. /*--------------------------- local data ------------------------------*/
  190.  register int i,j;
  191.  int num_to_move;
  192. /*--------------------------- processing ------------------------------*/
  193. #ifdef TRACE
  194.  trace_function("commutil.c:box_delete");
  195. #endif
  196.  for (i=0;i<prm->num_lines;i++)
  197.     {
  198.      num_to_move = prm->curr_src->length - MARK_VIEW->mark_end_col;
  199.      if (num_to_move <= 0)
  200.          num_to_move = 0;
  201.      add_to_recovery_list(prm->curr_src->line,prm->curr_src->length);
  202.      prm->curr_src->length = min(prm->curr_src->length,prm->src_start_col+num_to_move);
  203.      for (j=0;j < num_to_move;j++)
  204.          *(prm->curr_src->line+j+prm->src_start_col) = *(prm->curr_src->line+prm->src_start_col+j+prm->num_cols);
  205.      *(prm->curr_src->line+prm->curr_src->length) = '\0';/* null terminate */
  206.      prm->curr_src = prm->curr_src->next;  /* this should NEVER go past the end */
  207.     }
  208. #ifdef TRACE
  209.  trace_return();
  210. #endif
  211.  return(RC_OK);
  212. }
  213. /***********************************************************************/
  214. #ifdef PROTO
  215. int box_move(BOXP *prm,bool overlay)
  216. #else
  217. int box_move(prm,overlay)
  218. BOXP *prm;
  219. bool overlay;
  220. #endif
  221. /***********************************************************************/
  222. {
  223. /*--------------------------- local data ------------------------------*/
  224.  register int i,j;
  225.  int num_to_move;
  226.  LINE *first_save=NULL,*save_src=NULL,*tmp=NULL;
  227.  bool copy_first=FALSE;
  228.  int save_src_start_line,save_src_start_col;
  229. /*--------------------------- processing ------------------------------*/
  230. #ifdef TRACE
  231.  trace_function("commutil.c:box_move");
  232. #endif
  233.  if (prm->dst_start_col > prm->src_start_col+prm->num_cols)
  234.     copy_first = TRUE;
  235.  save_src_start_col = prm->src_start_col;
  236.  save_src_start_line = prm->src_start_line;
  237.  if (copy_first)
  238.    {
  239.     save_src = prm->curr_src;
  240.     box_copy(prm,overlay);
  241.     prm->src_start_line = save_src_start_line;
  242.     prm->src_start_col = save_src_start_col;
  243.     prm->curr_src = save_src;
  244.     if (prm->action == BOX_M)
  245.        box_delete(prm);
  246.    }
  247.  else
  248.    {
  249. /*---------------------------------------------------------------------*/
  250. /* Save the data that is to be deleted. It is saved in a format that   */
  251. /* can be used in copy_box() as the src line pointer.                  */
  252. /*---------------------------------------------------------------------*/
  253.     tmp = prm->curr_src;
  254.     for (i=0;i<prm->num_lines;i++)
  255.        {
  256.         memset(rec,' ',max_line_length);       /* copy line into rec[] */
  257.         memcpy(rec,tmp->line,tmp->length);
  258.         rec_len = tmp->length;
  259.         if ((save_src = add_line(first_save,save_src,
  260.             rec+prm->src_start_col,prm->num_cols)) == (LINE *)NULL)
  261.           {
  262. #ifdef TRACE
  263.            trace_return();
  264. #endif
  265.            return(RC_OUT_OF_MEMORY);
  266.           }
  267.         if (first_save == (LINE *)NULL)
  268.            first_save = save_src;
  269.         tmp = tmp->next;
  270.        }
  271.     if (prm->action == BOX_M)
  272.        box_delete(prm);
  273.     prm->src_start_line = 0L;
  274.     prm->src_start_col = 0;
  275.     prm->curr_src = first_save;
  276.     box_copy(prm,overlay);
  277. #ifdef USE_VOID
  278.     ll_free((void *)first_save);
  279. #else
  280.     first_save = lll_free(first_save);
  281. #endif
  282.     prm->src_start_line = save_src_start_line;
  283.     prm->src_start_col = save_src_start_col;
  284.    }
  285. #ifdef TRACE
  286.  trace_return();
  287. #endif
  288.  return(RC_OK);
  289. }
  290. /***********************************************************************/
  291. #ifdef PROTO
  292. int box_copy(BOXP *prm,bool overlay)
  293. #else
  294. int box_copy(prm,overlay)
  295. BOXP *prm;
  296. bool overlay;
  297. #endif
  298. /***********************************************************************/
  299. {
  300. /*--------------------------- local data ------------------------------*/
  301.  register int i,j;
  302.  char chr;
  303.  int rc;
  304. /*--------------------------- processing ------------------------------*/
  305. #ifdef TRACE
  306.  trace_function("commutil.c:box_copy");
  307. #endif
  308.  for (i=0;i<prm->num_lines;i++)
  309.     {
  310.      if (prm->curr_dst->next == (LINE *)NULL)  /* on *** Bottom of File *** */
  311.        {
  312.         if ((prm->curr_dst = add_line(CURRENT_FILE->first_line,prm->curr_dst->prev,
  313.                                  (char *)"",0)) == (LINE *)NULL)
  314.           {
  315. #ifdef TRACE
  316.            trace_return();
  317. #endif
  318.            return(RC_OUT_OF_MEMORY);
  319.           }
  320.         CURRENT_FILE->number_lines++;
  321.        }
  322.      pre_process_line(prm->dst_start_line+i);/* copy dest line into rec */
  323.      for (j=0;j<prm->num_cols;j++)
  324.         {
  325.          if (prm->src_start_col+j+1 > prm->curr_src->length)
  326.             chr = ' ';
  327.          else
  328.             chr = *(prm->curr_src->line+prm->src_start_col+j);
  329.          if (overlay)
  330.             rec[prm->dst_start_col+j] = chr;
  331.          else
  332.             meminschr(rec,chr,prm->dst_start_col+j,max_line_length,rec_len++);
  333.         }
  334.      rc = memrevne(rec,' ',max_line_length);
  335.      if (rc == (-1))
  336.         rec_len = 0;
  337.      else
  338.         rec_len = rc+1;
  339.      post_process_line(prm->dst_start_line+i);
  340.      prm->curr_src = prm->curr_src->next;   /* this should NEVER go past the end */
  341.      prm->curr_dst = prm->curr_dst->next;   /* this should NEVER go past the end */
  342.     }
  343. #ifdef TRACE
  344.  trace_return();
  345. #endif
  346.  return(RC_OK);
  347. }
  348. /***********************************************************************/
  349. #ifdef PROTO
  350. int box_fill(BOXP *prm,char fillchar)
  351. #else
  352. int box_fill(prm,fillchar)
  353. BOXP *prm;
  354. char fillchar;
  355. #endif
  356. /***********************************************************************/
  357. {
  358. /*--------------------------- local data ------------------------------*/
  359.  register int i,j;
  360.  int rc;
  361. /*--------------------------- processing ------------------------------*/
  362. #ifdef TRACE
  363.  trace_function("commutil.c:box_fill");
  364. #endif
  365.  for (i=0;i<prm->num_lines;i++)
  366.     {
  367.      pre_process_line(prm->src_start_line+i);/* copy source line into rec */
  368.      for (j=0;j<prm->num_cols;j++)
  369.          rec[prm->src_start_col+j] = fillchar;
  370.      rc = memrevne(rec,' ',max_line_length);
  371.      if (rc == (-1))
  372.         rec_len = 0;
  373.      else
  374.         rec_len = rc+1;
  375.      post_process_line(prm->src_start_line+i);
  376.      prm->curr_src = prm->curr_src->next;   /* this should NEVER go past the end */
  377.     }
  378.  
  379.  prm->dst_start_col = prm->src_start_col;
  380.  prm->dst_start_line = prm->src_start_line;
  381.  
  382. #ifdef TRACE
  383.  trace_return();
  384. #endif
  385.  return(RC_OK);
  386. }
  387.