home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / dirs / 'liner_394.lzh / 'Liner / Source / mouse.c < prev    next >
C/C++ Source or Header  |  1990-10-28  |  19KB  |  730 lines

  1. #include "Globals.h"
  2. char InvBuf[]=
  3.    {CSI,'7',0x6d,NULL,CSI,'0',0x6d};
  4. char Inv[]=
  5.    {CSI,'7',0x6d,NULL};
  6. char Norm[]=
  7.    {CSI,'0',0x6d,NULL};
  8.  
  9. struct LineItem *InvItem;
  10.  
  11. void MovedMouse(x,y)   /*The mouse was moved! Record its new position*/
  12. int x,y;
  13. {
  14.    LastX=PtrX;
  15.    LastY=PtrY;
  16.  
  17.    PtrY=(prefs.DS) ? (y/16)+1 : (y/8)+1;
  18.    PtrX=(x/8)+1;
  19. }
  20.  
  21. HandleButton(Seconds,Micros)  /*Handle a button press*/
  22. int Seconds,Micros;
  23. {
  24.    int status;
  25.    static int LastSeconds=1,LastMicros=1,DoubClicked=FALSE;
  26.    static UBYTE ButtonX,ButtonY;
  27.  
  28.    /*If the user double-clicked (the mouse button), start or modify*/
  29.    /*a highlighted block*/
  30.    if(DoubleClick(LastSeconds,LastMicros,Seconds,Micros) &&
  31.          PtrY==ButtonY && !DoubClicked)
  32.    {
  33.       PtrX=ButtonX;
  34.       PtrY=ButtonY;
  35.       DoubClicked=TRUE;
  36.       HandleInvs();
  37.       BLastX=PtrX;
  38.    }
  39.    else  /*Otherwise, just move the cursor accordingly*/
  40.       if(PtrY > 0 && PtrY <= SCRNHEIGHT)
  41.          {
  42.          ButtonX=PtrX;
  43.          ButtonY=PtrY;
  44.          DoubClicked=FALSE;
  45.          if(PtrY != InvY && InvsMode > NOINV) /*End text highlighting*/
  46.             EndLineInvs(); /*if the cursor is moved to a new line*/
  47.  
  48.          if(PtrY-CurY < 0)    /*move the cursor to a new line*/
  49.             status=MoveBack(-(PtrY-CurY));
  50.          else
  51.             status=MoveForward(PtrY-CurY);
  52.          if(status==FALSE)
  53.             return(FALSE);
  54.  
  55.          if(PtrX > MaxX(CurrentItem)) /*Move the cursor to a new*/
  56.             CurX=MaxX(CurrentItem);    /*X position*/
  57.          else
  58.             if(PtrX < MinX(CurrentItem))
  59.                CurX=MinX(CurrentItem);
  60.             else
  61.                CurX=PtrX;
  62.          PlotCursor(CurX,PtrY);
  63.          }
  64.    LastSeconds=Seconds;
  65.    LastMicros=Micros;
  66. }
  67.  
  68. void HandleInvs() /*Handle a modification or creation of a highlighted block*/
  69. {
  70.    if(InvsMode==NOINV)
  71.       if(PtrX >= MinX(CurrentItem) && PtrX <= MaxX(CurrentItem))
  72.          HandleLineInvs();
  73.       else
  74.          HandleBlockInvs();
  75.    else
  76.       if(InvsMode > NOINV)
  77.          HandleLineInvs(); /*Highlighting on one line*/
  78.       else
  79.          HandleBlockInvs();   /*Block highlighting*/
  80. }
  81.  
  82. HandleBlockInvs() /*Handle the inverse of a block of lines*/
  83. {
  84.    int X,Y;
  85.  
  86.    if(InvsMode==NOINV) /*If nothing is highlighted*/
  87.       {
  88.       InvY=EndIY=CurY;
  89.       WriteConsole(Inv,-1);
  90.       PlotCursor(1,CurY);
  91.       PrintItem(CurrentItem);
  92.       WriteConsole(Norm,-1);
  93.       EndIItem=StartIItem=(struct LineItem *)CurrentItem;
  94.       PlotCursor(MinX(CurrentItem),CurY);
  95.       InvsMode=BLOCK_PENDING;
  96.       return(TRUE);
  97.       }
  98.  
  99.    if(InvsMode==BLOCK_PENDING) /*If one line is highlighted*/
  100.       {
  101.       if(StartIItem == CurrentItem) /*Same line?  End highlighting*/
  102.          {
  103.          EndBlockInvs();
  104.          return(TRUE);
  105.          }
  106.       else /*Else, highlight a block (up or down, depending)*/
  107.          if(IsAfter(CurrentItem,StartIItem)) /*down*/
  108.          {
  109.             EndIItem=(struct LineItem *)CurrentItem;
  110.             if((Y=IsOnScreen(StartIItem->NextItem)))
  111.             {
  112.                PlotCursor(1,Y);
  113.                RvsBlock(StartIItem->NextItem,EndIItem);
  114.             }
  115.             else
  116.             {
  117.                PlotCursor(1,1);
  118.                RvsBlock(FirstScrnItem,EndIItem);
  119.             }
  120.             EndIY=CurY=PtrY;
  121.             InvsMode=BLOCK_DOWN;
  122.             PlotCursor(MinX(EndIItem),CurY);
  123.          }
  124.          else /*up*/
  125.             if(IsBefore(CurrentItem,StartIItem))
  126.                {
  127.                EndIItem=(struct LineItem *)CurrentItem;
  128.                EndIY=CurY;
  129.                if( (Y=IsOnScreen(StartIItem->PrevItem)) )
  130.                   RvsBlock(EndIItem,StartIItem->PrevItem);
  131.                else
  132.                   RvsBlock(EndIItem,ScrnBtm);
  133.                PlotCursor(MinX(EndIItem),EndIY);
  134.                InvsMode=BLOCK_UP;
  135.                }
  136.          return(TRUE);
  137.       }
  138.  
  139.    if(InvsMode == BLOCK_DOWN) /*If highlighting is down*/
  140.    {
  141.       if((IsAfter(CurrentItem,EndIItem)) && CurrentItem != EndIItem)
  142.       {  /*Highlight more*/
  143.          if( (Y=IsOnScreen(EndIItem->NextItem)))
  144.          {
  145.             PlotCursor(1,Y);
  146.             RvsBlock(EndIItem->NextItem,CurrentItem);
  147.          }
  148.          else
  149.          {
  150.             PlotCursor(1,1);
  151.             RvsBlock(FirstScrnItem,CurrentItem);
  152.          }
  153.          EndIY=CurY=PtrY;
  154.          EndIItem=(struct LineItem *)CurrentItem;
  155.          PlotCursor(MinX(EndIItem),IsOnScreen(CurrentItem));
  156.       }
  157.       if((IsBefore(CurrentItem,EndIItem)) && CurrentItem != EndIItem)
  158.       {  /*Unhighlight some*/
  159.          if(IsBefore(CurrentItem,StartIItem))
  160.          {
  161.             EndBlockInvs(FALSE);
  162.             return(TRUE);
  163.          }
  164.          EndIY=Y=CurY;
  165.          X=CurX;
  166.          PlotCursor(CurX,CurY+1);
  167.          NormBlock(CurrentItem->NextItem,EndIItem);
  168.          PlotCursor(X,Y);
  169.          EndIItem=(struct LineItem *)CurrentItem;
  170.       }
  171.    }
  172.    else  /*The higlighting goes up*/
  173.    {
  174.       if((IsBefore(CurrentItem,EndIItem)) && CurrentItem != EndIItem)
  175.       {     /*Highlight*/
  176.          EndIY=Y=CurY;
  177.          if( (Y=IsOnScreen(EndIItem->PrevItem)) )
  178.             RvsBlock(CurrentItem,EndIItem->PrevItem);
  179.          else
  180.             RvsBlock(CurrentItem,ScrnBtm);
  181.  
  182.          PlotCursor(MinX(CurrentItem),IsOnScreen(CurrentItem));
  183.          EndIItem=(struct LineItem *)CurrentItem;
  184.       }
  185.             /*Normalize*/
  186.       if((IsAfter(CurrentItem,EndIItem)) && CurrentItem != EndIItem)
  187.       {
  188.          if((CurrentItem==StartIItem)||(IsAfter(CurrentItem,StartIItem)))
  189.          {
  190.             EndBlockInvs();
  191.             return(TRUE);
  192.          }
  193.          Y=CurY;
  194.          PlotCursor(CurX,EndIY);
  195.          NormBlock(EndIItem,CurrentItem->PrevItem);
  196.          EndIItem=(struct LineItem *)CurrentItem;
  197.          PlotCursor(MinX(CurrentItem),IsOnScreen(CurrentItem));
  198.          EndIY=CurY;
  199.       }
  200.    }
  201. }
  202.  
  203. void NormIt(Start,End,Start_y) /*Un-highlight an area on screen*/
  204. struct LineItem *Start,*End;
  205. int Start_y;
  206. {
  207.    struct LineItem *CurItem;
  208.  
  209.    CurItem=(struct LineItem *)Start;
  210.    WriteConsole(Norm,-1);
  211.    
  212.    PlotCursor(1,Start_y);
  213.    CurY--;
  214.    while(CurItem != End->NextItem) /*Go down the screen*/
  215.       {
  216.       PlotCursor(1,CurY+1);
  217.       PrintItem(CurItem);
  218.       CurItem=(struct LineItem *)CurItem->NextItem;
  219.       }
  220. }
  221.  
  222. void NormBlock(Start,End)  /*Unhighlight a block of text, keeping it to*/
  223. struct LineItem *Start,*End;         /*what is on screen currently*/
  224. {
  225.    int beg_y,end_y,old_y,old_x;
  226.    
  227.    old_y=CurY;
  228.    old_x=CurX;
  229.    
  230.    if((beg_y=IsOnScreen(Start))) /*If 'Start' is on the screen*/
  231.       if((end_y=IsOnScreen(End)))   /*If 'End' is on screen*/
  232.          NormIt(Start,End,beg_y);   /*Normalize a block in the normal way*/
  233.       else
  234.          NormIt(Start,ScrnBtm,beg_y);/*Normalize from 'Start' to end of screen*/
  235.    else
  236.       if(IsBefore(Start,FirstScrnItem)) /*If 'Start' is above the screen*/
  237.          if(IsAfter(End,ScrnBtm))      /*and 'End' is below it*/
  238.             NormIt(FirstScrnItem,ScrnBtm,1); /*Unhighlight the whole screen*/
  239.          else
  240.             if((IsOnScreen(End)))  /*If the end is on the screen*/
  241.                NormIt(FirstScrnItem,End,1);  /*Unhighlight from top to End*/
  242.    /*That's it (any other possibilities cause nothing to happen)*/
  243.  
  244.    PlotCursor(old_x,old_y);
  245. }
  246.  
  247.  
  248. void RvsBlock(Start,End)  /*Highlight a block*/
  249. struct LineItem *Start,*End;
  250. {
  251.    struct LineItem *CurItem;
  252.    int y;
  253.  
  254.    CurItem=(struct LineItem *)Start;   /*Start at the start*/
  255.    WriteConsole(Inv,-1);   /*Activate inversed text*/
  256.  
  257.    CurY--;
  258.    while(CurItem != End->NextItem)  /*Go through list*/
  259.    {
  260.       if(y=IsOnScreen(CurItem)) /*Only do lines on screen*/
  261.       {
  262.          PlotCursor(1,y);
  263.          PrintItem(CurItem);
  264.       }
  265.       CurItem=(struct LineItem *)CurItem->NextItem;
  266.    }
  267.    WriteConsole(Norm,-1);
  268. }
  269.  
  270. void EndBlockInvs() /*End the highlight of a block of lines*/
  271. {
  272.    struct WhichOne which;
  273.    
  274.    FindStartEnd(StartIItem,EndIItem,&which);
  275.    NormBlock(which.Start,which.End);
  276.    PlotCursor(MinX(CurrentItem),CurY);
  277.    InvsMode=NOINV;
  278. }
  279.  
  280. HandleLineInvs()  /*Handle the inverse of individual characters*/
  281. {
  282.    int NewEnd;
  283.  
  284.    if(PtrX < MinX(CurrentItem))
  285.       PtrX=MinX(CurrentItem);
  286.    else
  287.       if(PtrX > MaxX(CurrentItem))
  288.          PtrX=MaxX(CurrentItem);
  289.  
  290.    if(InvsMode==NOINV)  /*If nothing is highlighted, start highlighting*/
  291.       {
  292.       InvBuf[3]=CurrentItem->Text[PosInText(CurrentItem->Level)];
  293.       WriteConsole(InvBuf,7);
  294.       StartChar=EndChar=PosInText(CurrentItem->Level);
  295.       PlotCursor(CurX,CurY);
  296.       InvsMode=LINE_PENDING;
  297.       InvY=CurY;
  298.       InvItem=(struct LineItem *)CurrentItem;
  299.       return(TRUE);
  300.       }
  301.  
  302.    if(InvsMode==LINE_PENDING) /*If one character only*/
  303.       {
  304.       if(PtrX == BLastX)   /*Same character?  Cancel highlighting*/
  305.          {
  306.          EndLineInvs();
  307.          return(TRUE);
  308.          }
  309.  
  310.       if(PtrX > BLastX) /*After the character*/
  311.       {
  312.          EndChar=PosInText(InvItem->Level);
  313.          PlotCursor(BLastX,CurY);
  314.          RvsText(StartChar,EndChar);
  315.          CurX=CurX+EndChar-StartChar;
  316.          InvsMode=LINE_FWD;
  317.          PlotCursor(CurX,CurY);
  318.          return(TRUE);
  319.       }
  320.  
  321.       if(PtrX < BLastX) /*Before the character*/
  322.       {
  323.          EndChar=PosInText(InvItem->Level);
  324.          RvsText(EndChar,StartChar-1);
  325.          PlotCursor(PtrX,CurY);
  326.          InvsMode=LINE_BACK;
  327.       }
  328.       return(TRUE);
  329.       }
  330.    else
  331.       if(InvsMode==LINE_FWD)  /*Left to right highlighting*/
  332.          {
  333.          if(PtrX > BLastX) /*Forward (highlight more)*/
  334.             {
  335.             NewEnd=PtrX-MinX(InvItem);
  336.             PlotCursor(EndChar+MinX(InvItem),CurY);
  337.             RvsText(EndChar,NewEnd);
  338.             CurX=NewEnd+MinX(InvItem);
  339.             PlotCursor(CurX,CurY);
  340.             EndChar=NewEnd;
  341.             }
  342.  
  343.          if(PtrX < BLastX) /*Backward (un-highlight)*/
  344.             if(PtrX-MinX(InvItem)<=StartChar)
  345.                EndLineInvs();
  346.             else
  347.                {
  348.                NewEnd=PtrX-MinX(InvItem);
  349.                NormText(NewEnd+1,EndChar);
  350.                PlotCursor(CurX,CurY);
  351.                EndChar=NewEnd;
  352.                }
  353.          }
  354.       else  /*Right to left highlighting*/
  355.          {
  356.          if(PtrX < BLastX) /*Backward (highlight more)*/
  357.             {
  358.             NewEnd=PtrX-MinX(InvItem);
  359.             RvsText(NewEnd+1,EndChar);
  360.             PlotCursor(CurX,CurY);
  361.             EndChar=NewEnd;
  362.             }
  363.  
  364.          if(PtrX > BLastX) /*Forward (un-highlight some)*/
  365.             if(PtrX-MinX(InvItem)>=StartChar)
  366.                EndLineInvs();
  367.             else
  368.                {
  369.                NewEnd=PtrX-MinX(InvItem)-1;
  370.                PlotCursor(EndChar+MinX(InvItem),CurY);
  371.                NormText(EndChar,NewEnd);
  372.                CurX=NewEnd+MinX(InvItem);
  373.                EndChar=NewEnd;
  374.                PlotCursor(CurX+1,CurY);
  375.                }
  376.          }
  377. }
  378.  
  379. void RvsText(Start,End)   /*Highlight a block of text*/
  380. int Start,End;
  381. {
  382.    char Buffer[80];
  383.    int c,l;
  384.  
  385.    strcpy(Buffer,Inv);
  386.    l=strlen(Buffer);
  387.  
  388.    for(c=l; c-l < End-Start+1 ; c++)
  389.       {
  390.       Buffer[c]=InvItem->Text[c+Start-l];
  391.       }
  392.    Buffer[c]=0;
  393.  
  394.    strcat(Buffer,Norm);
  395.  
  396.    WriteConsole(Inv,-1);
  397.    WriteConsole(Buffer,c);
  398.    WriteConsole(Norm,-1);
  399. }
  400.  
  401.  
  402. MoveBack(Number)  /*Move back in the item list a specified number of times*/
  403. int Number;
  404. {
  405.    int c;
  406.  
  407.    for(c=0;c<Number;c++)
  408.       {
  409.       if(CurrentItem->PrevItem==NULL)
  410.          return(FALSE);
  411.       else
  412.          CurrentItem=(struct LineItem *)CurrentItem->PrevItem;
  413.       }
  414.    return(TRUE);
  415. }
  416.  
  417. MoveForward(Number)  /*Move forward in the item list a specifiecd*/
  418. int Number;       /*number of times*/
  419. {
  420.    int c;
  421.    struct LineItem *OrigItem;
  422.  
  423.    OrigItem=(struct LineItem *)CurrentItem;
  424.    for(c=0;c<Number;c++)
  425.       {
  426.       if(CurrentItem->NextItem==NULL)
  427.          {
  428.          CurrentItem=(struct LineItem *)OrigItem;
  429.          return(FALSE);
  430.          }
  431.       else
  432.          CurrentItem=(struct LineItem *)CurrentItem->NextItem;
  433.       }
  434.    return(TRUE);
  435. }
  436.  
  437. void EndLineInvs()  /*End text inverse*/
  438. {
  439.    if(StartChar < EndChar)
  440.       NormText(StartChar,EndChar);
  441.    else
  442.       NormText(EndChar,StartChar);
  443.    InvsMode=NOINV;
  444. }
  445.  
  446. void NormText(Start,End)     /*Un-reverse text*/
  447. int Start,End;
  448. {
  449.    int TempX,c;
  450.    char Buffer[80];
  451.  
  452.    for(c=Start;c<=End;c++)
  453.       Buffer[c-Start]=InvItem->Text[c];
  454.  
  455.    Buffer[c-Start]=0;
  456.  
  457.    TempX=CurX;
  458.    PlotCursor(MinX(InvItem)+Start,InvY);
  459.    WriteConsole(Buffer,-1);
  460.    PlotCursor(TempX,InvY);
  461. }
  462.  
  463. HandleDelBlock()  /*Delete a block of lines*/
  464. {
  465.    struct WhichOne which;
  466.    struct LineItem *temp;
  467.    BOOL stat;
  468.  
  469.          /*If you're deleting everything, just call New*/
  470.    if((StartIItem->PrevItem==NULL && EndIItem->NextItem==NULL) ||
  471.          (StartIItem->NextItem==NULL && EndIItem->PrevItem==NULL))
  472.       {
  473.       NewAll();
  474.       return(TRUE);
  475.       }
  476.  
  477.       /*Otherwise, find the true start and end and delete the block*/
  478.    FindStartEnd(StartIItem,EndIItem,&which);
  479.    
  480.    if(which.Start->NextItem != NULL && which.Start->NextItem->cont &&
  481.          !which.Start->cont && which.Start==which.End) /*TRUE==parent*/
  482.       return(FALSE);
  483.       
  484.    InvsMode=NOINV;
  485.    
  486.       /*Find the end (last child)*/
  487.    if(which.End->NextItem->cont && (which.Start!=which.End))
  488.    {
  489.       temp=(struct LineItem *)which.End->PrevItem;
  490.       stat=FALSE;
  491.       
  492.       while(temp!=which.Start)
  493.       {
  494.          if(!temp->cont)
  495.             stat=TRUE;
  496.          temp=(struct LineItem *)temp->PrevItem;
  497.       }
  498.       if(stat)
  499.          which.End=(struct LineItem *)FindNextNonCont(which.End);
  500.    }
  501.    
  502.    DelBlock(which.Start,which.End,IsOnScreen(which.Start),
  503.          IsOnScreen(which.End));
  504.    return(TRUE);
  505. }
  506.  
  507. /*When dealing with highlighted blocks, it is not guaranteed that*/
  508. /*StartIItem comes before EndIItem in the linked list.  This function*/
  509. /*sorts out which is which and puts each pointer in an appropriate*/
  510. /*space in a WhichOne structure (created especially for this function)*/
  511. /*A kludge, I know.  But 'Liner's grown up around this technique.  It*/
  512. /*would take more work than it is worth to change it*/
  513.  
  514. void FindStartEnd(Start,End,which)
  515. struct LineItem *Start,*End;
  516. struct WhichOne *which;
  517. {  
  518.    if(IsBefore(Start,End))
  519.    {
  520.       which->Start=(struct LineItem *)Start;
  521.       which->End=(struct LineItem *)End;
  522.    }
  523.    else
  524.    {
  525.       which->Start=(struct LineItem *)End;
  526.       which->End=(struct LineItem *)Start;
  527.    }
  528. }
  529.  
  530. void DelBlock(Start,End,StartY,EndY)  /*Delete a block of lines*/
  531. struct LineItem *Start,*End;
  532. int StartY,EndY;
  533. {
  534.    int TOS;
  535.    
  536.    if(!Start->cont)
  537.    {
  538.       Start=(struct LineItem *)FindPrevNonCont(Start);
  539.       End=(struct LineItem *)FindNextNonCont(End);
  540.    }
  541.    
  542.    StartY=IsOnScreen(Start);
  543.    EndY=IsOnScreen(End);
  544.    
  545.    if(!StartY)        /*If the start of the inversed block isn't on*/
  546.    {                       /*the screen, put it on the screen and then delete*/
  547.       FirstScrnItem=CurrentItem=(struct LineItem *)Start;
  548.       PrintItemList(Start,(StartY=1));
  549.    }
  550.  
  551.    if(!EndY)      /*Handle when the end isn't on screen*/
  552.       EndY=SCRNHEIGHT;
  553.  
  554.    if(Start==FirstScrnItem)
  555.       TOS=TRUE;
  556.    else
  557.       TOS=FALSE;
  558.    
  559.    if(Start->PrevItem == NULL) /*If there is nothing before 'Start'*/
  560.       {  /*Make 'End' the start of everything*/
  561.       CurrentItem=FirstItem=FirstScrnItem=
  562.             (struct LineItem *)End->NextItem;
  563.       CurrentItem->PrevItem=NULL;
  564.       RemItem(CurrentItem);
  565.       AddItem(CurrentItem);
  566.       TOS=FALSE;
  567.       }
  568.    else
  569.       if(End->NextItem==NULL) /*If 'End' is the end of everything, make*/
  570.          {     /*'Start'->PrevItem the start of everything*/
  571.          CurrentItem=LastItem=
  572.                (struct LineItem *)Start->PrevItem;
  573.          LastItem->NextItem=NULL;
  574.          if(Start==FirstScrnItem)
  575.             {
  576.             FirstScrnItem=ScrnBtm=(struct LineItem *)CurrentItem;
  577.             StartY=1;
  578.             }
  579.          else
  580.             StartY--;
  581.          TOS=FALSE;
  582.          }
  583.       else
  584.          {
  585.          CurrentItem=Start->PrevItem->NextItem=(struct LineItem *)
  586.                End->NextItem;
  587.          End->NextItem->PrevItem=
  588.                (struct LineItem *)Start->PrevItem;
  589.          }
  590.          
  591.    if(TOS)  /*If the Start was at the top of the screen...*/
  592.       CurrentItem=FirstScrnItem=(struct LineItem *)End->NextItem;
  593.  
  594.    /*Free the deleted block's memory*/
  595.    FreeListMem(Start,End);
  596.    /*Update some ItemNumbers*/
  597.    RemItem(CurrentItem);
  598.    AddItem(CurrentItem);
  599.    
  600.    BackSearchRefresh(CurrentItem);
  601.    PrintItemList(CurrentItem,StartY);
  602.    PlotCursor(MinX(CurrentItem),StartY);
  603. }
  604.  
  605. void FreeListMem(Start,End)  /*Free several Items at once*/
  606. struct LineItem *Start,*End;
  607. {
  608.    struct LineItem *Item,*Next;
  609.    Next=(struct LineItem *)Start;
  610.    do
  611.       {
  612.       Item=(struct LineItem *)Next;
  613.       Next=(struct LineItem *)Item->NextItem;
  614.       RemItem(Item);
  615.      
  616.       if(Item->PrevItem !=NULL)
  617.          Item->PrevItem->NextItem=(struct LineItem *)Item->NextItem;
  618.       if(Item->NextItem != NULL)
  619.          Item->NextItem->PrevItem=(struct LineItem *)Item->PrevItem;
  620.          
  621.       FreeMem(Item,sizeof(struct LineItem));
  622.       }
  623.    while(Item != End && Next != NULL);
  624. }
  625.  
  626. void DelTextBlock() /*Delete the highlighted text*/
  627. {
  628.    int c,Start,End,len;
  629.    char Buffer[2];
  630.  
  631.    if(StartChar < EndChar) /*Find the start of the highlighted block*/
  632.       {
  633.       Start=StartChar;
  634.       End=EndChar;
  635.       }
  636.    else
  637.       {
  638.       Start=EndChar;
  639.       End=StartChar;
  640.       }
  641.    len=strlen(InvItem->Text);
  642.  
  643.    for(c=0;c <= len-End; c++)
  644.       InvItem->Text[c+Start]=InvItem->Text[c+End+1];
  645.  
  646.    PlotCursor(1,InvY);
  647.    Buffer[0]=CSI;
  648.    Buffer[1]=0x4b;
  649.    WriteConsole(Buffer,2);
  650.    PrintItem(InvItem);
  651.    PlotCursor(MinX(InvItem)+Start,InvY);
  652.    InvsMode=NOINV;
  653. }
  654.  
  655. CancelLineInvs()  /*Cancel an inversed text section*/
  656. {
  657.    if(NOINV == InvsMode)
  658.       return(FALSE);
  659.    else
  660.       if(InvsMode > NOINV)
  661.          EndLineInvs();
  662. }
  663.  
  664. CancelInvs()  /*Cancel inversed text or lines*/
  665. {
  666.    if(NOINV == InvsMode)
  667.       return(FALSE);
  668.    else
  669.       if(InvsMode > NOINV)
  670.          EndLineInvs();
  671.       else
  672.          EndBlockInvs();
  673.  
  674.    return(TRUE);
  675. }
  676.  
  677. DelInvs()   /*Delete the highlighted block or text*/
  678. {
  679.    if(InvsMode==NULL)
  680.       return(FALSE);
  681.  
  682.    if(InvsMode > NOINV)
  683.       DelTextBlock();
  684.    else
  685.       HandleDelBlock();
  686.  
  687.    return(TRUE);
  688. }
  689.  
  690. void TitleError(string) /*Display 'string' in the title bar*/
  691. char *string;
  692. {
  693.    DisplayBeep(Screen);
  694.    ErrorInTitle = TRUE;
  695.    SetWindowTitles(Window,-1,string);
  696. }
  697.  
  698. void TitleErrorCancel() /*Set the title bar text to normal (with the */
  699. {                          /*current filename in the title bar*/
  700.    static char Title[85];
  701.  
  702.    strcpy(Title,ScreenTitle);
  703.    if(FileName[0])
  704.       strncat(Title,FileName,65);
  705.    else
  706.       strcat(Title,"Untitled");
  707.    if(Modified==TRUE)   /*If the outline has been modified*/
  708.       Title[0]='*';        /*Put a '*' before "'Liner"*/
  709.    ErrorInTitle = FALSE;
  710.    SetWindowTitles(Window,-1,Title);
  711. }
  712.  
  713. void BackSearchRefresh(Base)    /*Do a refresh of ItemNumbers by searching*/
  714. struct LineItem *Base;    /*back through the item list*/
  715. {
  716.    struct LineItem *Work,Dummy;
  717.  
  718.    Dummy.PrevItem=(struct LineItem *)Base->PrevItem;
  719.    Dummy.NextItem=(struct LineItem *)Base->NextItem;
  720.  
  721.    for(Dummy.Level=Base->Level;Dummy.Level > 0;Dummy.Level--)
  722.       if((Work=(struct LineItem *)FindPrev(&Dummy))!=NULL)
  723.          {
  724.          RemItem(Work);
  725.          AddItem(Work);
  726.          }
  727. }
  728.  
  729. /*End of mouse.c*/
  730.