home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / new / util / edit / jade / src / housekeeping.c < prev    next >
C/C++ Source or Header  |  1994-10-03  |  14KB  |  528 lines

  1. /* housekeeping.c -- Generally editor fiddly stuff
  2.    Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
  3.  
  4.    This file is part of Jade.
  5.  
  6.    Jade is free software; you can redistribute it and/or modify it
  7.    under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    Jade is distributed in the hope that it will be useful, but
  12.    WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.     See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with Jade; see the file COPYING.  If not, write to
  18.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "jade.h"
  21. #include "jade_protos.h"
  22.  
  23. _PR void adjust_marks_add_x(TX *, long, long, long);
  24. _PR void adjust_marks_sub_x(TX *, long, long, long);
  25. _PR void adjust_marks_add_y(TX *, long, long);
  26. _PR void adjust_marks_sub_y(TX *, long, long);
  27. _PR void adjust_marks_split_y(TX *, long, long);
  28. _PR void adjust_marks_join_y(TX *, long, long);
  29. _PR void resync_xy(VW *);
  30. _PR void set_start_col(VW *, long);
  31. _PR void set_start_line(VW *, long);
  32. _PR void reset_all_views(TX *);
  33.  
  34. /* The next few routines deal with updating the various references to
  35.    coordinates throughout the views after chunks have been deleted and
  36.    inserted.  */
  37.  
  38. void
  39. adjust_marks_add_x(TX *tx, long addx, long xpos, long ypos)
  40. {
  41.     VW *thisvw;
  42.     Mark *thismark;
  43.  
  44. #define UPD(x,y)                \
  45.     do {                    \
  46.     if((y == ypos) && (x >= xpos))        \
  47.         x += addx;                \
  48.     } while(0)
  49.  
  50.     for(thisvw = view_chain; thisvw; thisvw = thisvw->vw_Next)
  51.     {
  52.     if(thisvw->vw_Tx == tx)
  53.     {
  54.         UPD(thisvw->vw_CursorPos.pos_Col, thisvw->vw_CursorPos.pos_Line);
  55.             if(!(thisvw->vw_Flags & VWFF_RECTBLOCKS))
  56.         {
  57.         UPD(thisvw->vw_BlockS.pos_Col, thisvw->vw_BlockS.pos_Line);
  58.         UPD(thisvw->vw_BlockE.pos_Col, thisvw->vw_BlockE.pos_Line);
  59.         }
  60.     }
  61.     }
  62.     for(thismark = tx->tx_MarkChain; thismark; thismark = thismark->mk_Next)
  63.     {
  64.     UPD(VPOS(thismark->mk_Pos).pos_Col, VPOS(thismark->mk_Pos).pos_Line);
  65.     }
  66.     UPD(tx->tx_SavedCPos.pos_Col, tx->tx_SavedCPos.pos_Line);
  67.     UPD(tx->tx_SavedWPos.pos_Col, tx->tx_SavedWPos.pos_Line);
  68.     UPD(tx->tx_SavedBlockPos[0].pos_Col, tx->tx_SavedBlockPos[0].pos_Line);
  69.     UPD(tx->tx_SavedBlockPos[1].pos_Col, tx->tx_SavedBlockPos[1].pos_Line);
  70. #if 1
  71.     if((tx->tx_ModStart.pos_Line == ypos) && (tx->tx_ModStart.pos_Col > xpos))
  72.     tx->tx_ModStart.pos_Col += addx;
  73. #else
  74.     UPD(tx->tx_ModStart.pos_Col, tx->tx_ModStart.pos_Line);
  75. #endif
  76.     UPD(tx->tx_ModEnd.pos_Col, tx->tx_ModEnd.pos_Line);
  77.  
  78. #undef UPD
  79. }
  80.  
  81. void
  82. adjust_marks_sub_x(TX *tx, long subx, long xpos, long ypos)
  83. {
  84.     VW *thisvw;
  85.     Mark *thismark;
  86.  
  87. #define UPD(x,y)                \
  88.     do {                    \
  89.     if((y == ypos) && (x >= xpos))        \
  90.     {                    \
  91.         if((x -= subx) < xpos)        \
  92.         x = xpos;            \
  93.     }                    \
  94.     } while(0)
  95.  
  96.     for(thisvw = view_chain; thisvw; thisvw = thisvw->vw_Next)
  97.     {
  98.     if(thisvw->vw_Tx == tx)
  99.     {
  100.         UPD(thisvw->vw_CursorPos.pos_Col, thisvw->vw_CursorPos.pos_Line);
  101.             if(!(thisvw->vw_Flags & VWFF_RECTBLOCKS))
  102.         {
  103.         UPD(thisvw->vw_BlockS.pos_Col, thisvw->vw_BlockS.pos_Line);
  104.         UPD(thisvw->vw_BlockE.pos_Col, thisvw->vw_BlockE.pos_Line);
  105.         }
  106.     }
  107.     }
  108.     for(thismark = tx->tx_MarkChain; thismark; thismark = thismark->mk_Next)
  109.     {
  110.     UPD(VPOS(thismark->mk_Pos).pos_Col, VPOS(thismark->mk_Pos).pos_Line);
  111.     }
  112.     UPD(tx->tx_SavedCPos.pos_Col, tx->tx_SavedCPos.pos_Line);
  113.     UPD(tx->tx_SavedWPos.pos_Col, tx->tx_SavedWPos.pos_Line);
  114.     UPD(tx->tx_SavedBlockPos[0].pos_Col, tx->tx_SavedBlockPos[0].pos_Line);
  115.     UPD(tx->tx_SavedBlockPos[1].pos_Col, tx->tx_SavedBlockPos[1].pos_Line);
  116.  
  117.     UPD(tx->tx_ModStart.pos_Col, tx->tx_ModStart.pos_Line);
  118. #if 1
  119.     if((tx->tx_ModEnd.pos_Line == ypos) && (tx->tx_ModEnd.pos_Col > xpos))
  120.     {
  121.     if((tx->tx_ModEnd.pos_Col -= subx) < xpos)
  122.         tx->tx_ModEnd.pos_Col = xpos;
  123.     }
  124. #else
  125.     UPD(tx->tx_ModEnd.pos_Col, tx->tx_ModEnd.pos_Line);
  126. #endif
  127.  
  128. #undef UPD
  129. }
  130.  
  131. /*
  132.  * Whole lines only please
  133.  */
  134. void
  135. adjust_marks_add_y(TX *tx, long addy, long ypos)
  136. {
  137.     VW *thisvw;
  138.     Mark *thismark;
  139.  
  140. #define UPD(y)                    \
  141.     do {                    \
  142.     if(y >= ypos)                \
  143.         y += addy;                \
  144.     } while(0)
  145.  
  146.     for(thisvw = view_chain; thisvw; thisvw = thisvw->vw_Next)
  147.     {
  148.     if(thisvw->vw_Tx == tx)
  149.     {
  150.         UPD(thisvw->vw_CursorPos.pos_Line);
  151.         UPD(thisvw->vw_BlockS.pos_Line);
  152.         UPD(thisvw->vw_BlockE.pos_Line);
  153.         if(thisvw != curr_vw)
  154.         UPD(thisvw->vw_StartLine);
  155.     }
  156.     }
  157.     for(thismark = tx->tx_MarkChain; thismark; thismark = thismark->mk_Next)
  158.     {
  159.     UPD(VPOS(thismark->mk_Pos).pos_Line);
  160.     }
  161.     UPD(tx->tx_SavedCPos.pos_Line);
  162.     UPD(tx->tx_SavedWPos.pos_Line);
  163.     UPD(tx->tx_SavedBlockPos[0].pos_Line);
  164.     UPD(tx->tx_SavedBlockPos[1].pos_Line);
  165.  
  166. #if 0
  167. #if 1
  168.     if(tx->tx_ModStart.pos_Line > ypos)
  169.     tx->tx_ModStart.pos_Line += addy;
  170. #else
  171.     UPD(tx->tx_ModStart.pos_Line);
  172. #endif
  173.     UPD(tx->tx_ModEnd.pos_Line);
  174. #endif
  175.  
  176. #undef UPD
  177. }
  178.  
  179. /*
  180.  * Whole lines only please
  181.  */
  182. void
  183. adjust_marks_sub_y(TX *tx, long suby, long ypos)
  184. {
  185.     VW *thisvw;
  186.     Mark *thismark;
  187.  
  188. #define UPD(y)                    \
  189.     do {                    \
  190.     if(y > ypos)                \
  191.     {                    \
  192.         if((y -= suby) < ypos)        \
  193.         y = ypos;            \
  194.     }                    \
  195.     } while(0)
  196.  
  197. #define UPD2(x,y)                \
  198.     if(y >= ypos)                \
  199.     {                        \
  200.     if((y -= suby) < ypos)            \
  201.     {                    \
  202.         y = ypos;                \
  203.         x = 0;                \
  204.     }                    \
  205.     } while(0)
  206.  
  207.     for(thisvw = view_chain; thisvw; thisvw = thisvw->vw_Next)
  208.     {
  209.     if(thisvw->vw_Tx == tx)
  210.     {
  211.         UPD2(thisvw->vw_CursorPos.pos_Col, thisvw->vw_CursorPos.pos_Line);
  212.             if(thisvw->vw_Flags & VWFF_RECTBLOCKS)
  213.         {
  214.         UPD(thisvw->vw_BlockS.pos_Line);
  215.         UPD(thisvw->vw_BlockE.pos_Line);
  216.         }
  217.             else
  218.         {
  219.                 UPD2(thisvw->vw_BlockS.pos_Col, thisvw->vw_BlockS.pos_Line);
  220.                 UPD2(thisvw->vw_BlockE.pos_Col, thisvw->vw_BlockE.pos_Line);
  221.         }
  222.         if(thisvw != curr_vw)
  223.         UPD(thisvw->vw_StartLine);
  224.     }
  225.     }
  226.     for(thismark = tx->tx_MarkChain; thismark; thismark = thismark->mk_Next)
  227.     {
  228.     UPD2(VPOS(thismark->mk_Pos).pos_Col, VPOS(thismark->mk_Pos).pos_Line);
  229.     }
  230.     UPD2(tx->tx_SavedCPos.pos_Col, tx->tx_SavedCPos.pos_Line);
  231.     UPD2(tx->tx_SavedWPos.pos_Col, tx->tx_SavedWPos.pos_Line);
  232.     UPD2(tx->tx_SavedBlockPos[0].pos_Col, tx->tx_SavedBlockPos[0].pos_Line);
  233.     UPD2(tx->tx_SavedBlockPos[1].pos_Col, tx->tx_SavedBlockPos[1].pos_Line);
  234.  
  235.     UPD2(tx->tx_ModStart.pos_Col, tx->tx_ModStart.pos_Line);
  236. #if 1
  237.     if(tx->tx_ModEnd.pos_Line > ypos)
  238.     {
  239.     if((tx->tx_ModEnd.pos_Line -= suby) < ypos)
  240.     {
  241.         tx->tx_ModEnd.pos_Line = ypos;
  242.         tx->tx_ModEnd.pos_Col = 0;
  243.     }
  244.     }
  245. #else
  246.     UPD2(tx->tx_ModEnd.pos_Col, tx->tx_ModEnd.pos_Line);
  247. #endif
  248.  
  249. #undef UPD
  250. #undef UPD2
  251. }
  252.  
  253. /*
  254.  * Use when splitting a line into 2, cursor should be at position of split
  255.  */
  256. void
  257. adjust_marks_split_y(TX *tx, long xpos, long ypos)
  258. {
  259.     VW *thisvw;
  260.     Mark *thismark;
  261.  
  262. #define UPD(y)                    \
  263.     do {                    \
  264.     if(y > ypos)                \
  265.         y++;                \
  266.     } while(0)
  267.  
  268. #define UPD2(x,y)                \
  269.     do {                    \
  270.     if((y == ypos) && (x >= xpos))        \
  271.     {                    \
  272.         x -= xpos;                \
  273.         y++;                \
  274.     }                    \
  275.     else if(y > ypos)            \
  276.         y++;                \
  277.     } while(0)
  278.  
  279.     for(thisvw = view_chain; thisvw; thisvw = thisvw->vw_Next)
  280.     {
  281.     if(thisvw->vw_Tx == tx)
  282.     {
  283.         UPD2(thisvw->vw_CursorPos.pos_Col, thisvw->vw_CursorPos.pos_Line);
  284.             if(thisvw->vw_Flags & VWFF_RECTBLOCKS)
  285.         {
  286.         UPD(thisvw->vw_BlockS.pos_Line);
  287.         UPD(thisvw->vw_BlockE.pos_Line);
  288.         }
  289.             else
  290.         {
  291.                 UPD2(thisvw->vw_BlockS.pos_Col, thisvw->vw_BlockS.pos_Line);
  292.                 UPD2(thisvw->vw_BlockE.pos_Col, thisvw->vw_BlockE.pos_Line);
  293.         }
  294.         if(thisvw != curr_vw)
  295.         UPD(thisvw->vw_StartLine);
  296.     }
  297.     }
  298.     for(thismark = tx->tx_MarkChain; thismark; thismark = thismark->mk_Next)
  299.     {
  300.     UPD2(VPOS(thismark->mk_Pos).pos_Col, VPOS(thismark->mk_Pos).pos_Line);
  301.     }
  302.     UPD2(tx->tx_SavedCPos.pos_Col, tx->tx_SavedCPos.pos_Line);
  303.     UPD2(tx->tx_SavedWPos.pos_Col, tx->tx_SavedWPos.pos_Line);
  304.     UPD2(tx->tx_SavedBlockPos[0].pos_Col, tx->tx_SavedBlockPos[0].pos_Line