home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / turbo5 / mclib.pas < prev    next >
Pascal/Delphi Source File  |  1988-10-09  |  13KB  |  503 lines

  1.  
  2. { Copyright (c) 1985, 88 by Borland International, Inc. }
  3.  
  4. unit MCLIB;
  5.  
  6. interface
  7.  
  8. uses Crt, Dos, MCVars, MCUtil, MCDisply, MCParser;
  9.  
  10. procedure DisplayCell(Col, Row : Word; Highlighting, Updating : Boolean);
  11. { Displays the contents of a cell }
  12.  
  13. function SetOFlags(Col, Row : Word; Display : Boolean) : Word;
  14. { Sets the overwrite flag on cells starting at (col + 1, row) - returns
  15.    the number of the column after the last column set.
  16. }
  17.  
  18. procedure ClearOFlags(Col, Row : Word; Display : Boolean);
  19. { Clears the overwrite flag on cells starting at (col, row) }
  20.  
  21. procedure UpdateOFlags(Col, Row : Word; Display : Boolean);
  22. { Starting in col, moves back to the last TEXT cell and updates all flags }
  23.  
  24. procedure DeleteCell(Col, Row : Word; Display : Boolean);
  25. { Deletes a cell }
  26.  
  27. procedure SetLeftCol;
  28. { Sets the value of LeftCol based on the value of RightCol }
  29.  
  30. procedure SetRightCol;
  31. { Sets the value of rightcol based on the value of leftcol }
  32.  
  33. procedure SetTopRow;
  34. { Figures out the value of toprow based on the value of bottomrow }
  35.  
  36. procedure SetBottomRow;
  37. { Figures out the value of bottomrow based on the value of toprow }
  38.  
  39. procedure SetLastCol;
  40. { Sets the value of lastcol based on the current value }
  41.  
  42. procedure SetLastRow;
  43. { Sets the value of lastrow based on the current value }
  44.  
  45. procedure ClearLastCol;
  46. { Clears any data left in the last column }
  47.  
  48. procedure DisplayCol(Col : Word; Updating : Boolean);
  49. { Displays a column on the screen }
  50.  
  51. procedure DisplayRow(Row : Word; Updating : Boolean);
  52. { Displays a row on the screen }
  53.  
  54. procedure DisplayScreen(Updating : Boolean);
  55. { Displays the current screen of the spreadsheet }
  56.  
  57. procedure RedrawScreen;
  58. { Displays the entire screen }
  59.  
  60. procedure FixFormula(Col, Row, Action, Place : Word);
  61. { Modifies a formula when its column or row designations need to change }
  62.  
  63. procedure ChangeAutoCalc(NewMode : Boolean);
  64. { Changes and prints the current AutoCalc value on the screen }
  65.  
  66. procedure ChangeFormDisplay(NewMode : Boolean);
  67. { Changes and prints the current formula display value on the screen }
  68.  
  69. procedure Recalc;
  70. { Recalculates all of the numbers in the speadsheet }
  71.  
  72. procedure Act(S : String);
  73. { Acts on a particular input }
  74.  
  75. implementation
  76.  
  77. procedure DisplayCell;
  78. var
  79.   Color : Word;
  80.   S : IString;
  81. begin
  82.   if Updating and
  83.       ((Cell[Col, Row] = Nil) or (Cell[Col, Row]^.Attrib <> FORMULA)) then
  84.     Exit;
  85.   S := CellString(Col, Row, Color, DOFORMAT);
  86.   if Highlighting then
  87.   begin
  88.     if Color = ERRORCOLOR then
  89.       Color := HIGHLIGHTERRORCOLOR
  90.     else
  91.       Color := HIGHLIGHTCOLOR;
  92.   end;
  93.   SetColor(Color);
  94.   WriteXY(S, ColStart[Succ(Col - LeftCol)], Row - TopRow + 3);
  95. end; { DisplayCell }
  96.  
  97. function SetOFlags;
  98. var
  99.   Len : Integer;
  100. begin
  101.   Len := Length(Cell[Col, Row]^.T) - ColWidth[Col];
  102.   Inc(Col);
  103.   while (Col <= MAXCOLS) and (Len > 0) and (Cell[Col, Row] = nil) do
  104.   begin
  105.     Format[Col, Row] := Format[Col, Row] or OVERWRITE;
  106.     Dec(Len, ColWidth[Col]);
  107.     if Display and (Col >= LeftCol) and (Col <= RightCol) then
  108.       DisplayCell(Col, Row, NOHIGHLIGHT, NOUPDATE);
  109.     Inc(Col);
  110.   end;
  111.   SetOFlags := Col;
  112. end; { SetOFlags }
  113.  
  114. procedure ClearOFlags;
  115. begin
  116.   while (Col <= MAXCOLS) and (Format[Col, Row] >= OVERWRITE) and
  117.         (Cell[Col, Row] = nil) do
  118.   begin
  119.     Format[Col, Row] := Format[Col, Row] and (not OVERWRITE);
  120.     if Display and (Col >= LeftCol) and (Col <= RightCol) then
  121.       DisplayCell(Col, Row, NOHIGHLIGHT, NOUPDATE);
  122.     Inc(Col);
  123.   end;
  124. end; { ClearOFlags }
  125.  
  126. procedure UpdateOFlags;
  127. var
  128.   Dummy : Word;
  129. begin
  130.   while (Cell[Col, Row] = nil) and (Col > 1) do
  131.     Dec(Col);
  132.   if (Cell[Col, Row] <> nil) and (Cell[Col, Row]^.Attrib = TXT) and 
  133.      (Col >= 1) then
  134.     Dummy := SetOFlags(Col, Row, Display);
  135. end; { UpdateOFlags }
  136.  
  137. procedure DeleteCell;
  138. var
  139.   CPtr : CellPtr;
  140.   Size : Word;
  141. begin
  142.   CPtr := Cell[Col, Row];
  143.   if CPtr = nil then
  144.     Exit;
  145.   case CPtr^.Attrib of
  146.     TXT : begin
  147.       Size := Length(CPtr^.T) + 3;
  148.       ClearOFlags(Succ(Col), Row, Display);
  149.     end;
  150.     VALUE : Size := SizeOf(Real) + 2;
  151.     FORMULA : Size := SizeOf(Real) + Length(CPtr^.Formula) + 3;
  152.   end; { case }
  153.   Format[Col, Row] := Format[Col, Row] and (not OVERWRITE);
  154.   FreeMem(CPtr, Size);
  155.   Cell[Col, Row] := nil;
  156.   if Col = LastCol then
  157.     SetLastCol;
  158.   if Row = LastRow then
  159.     SetLastRow;
  160.   UpdateOFlags(Col, Row, Display);
  161.   Changed := True;
  162. end; { DeleteCell }
  163.  
  164. procedure SetLeftCol;
  165. var
  166.   Col : Word;
  167.   Total : Integer;
  168. begin
  169.   Total := 81;
  170.   Col := 0;
  171.   while (Total > LEFTMARGIN) and (RightCol - Col > 0) do
  172.   begin
  173.     Dec(Total, ColWidth[RightCol - Col]);
  174.     if Total > LEFTMARGIN then
  175.       ColStart[SCREENCOLS - Col] := Total;
  176.     Inc(Col);
  177.   end;
  178.   if Total > LEFTMARGIN then
  179.     Inc(Col);
  180.   Move(ColStart[SCREENCOLS - Col + 2], ColStart, Pred(Col));
  181.   LeftCol := RightCol - Col + 2;
  182.   Total := Pred(ColStart[1] - LEFTMARGIN);
  183.   if Total <> 0 then
  184.   begin
  185.     for Col := LeftCol to RightCol do
  186.       Dec(ColStart[Succ(Col - LeftCol)], Total);
  187.   end;
  188.   PrintCol;
  189. end; { SetLeftCol }
  190.  
  191. procedure SetRightCol;
  192. var
  193.   Total, Col : Word;
  194. begin
  195.   Total := Succ(LEFTMARGIN);
  196.   Col := 1;
  197.   repeat
  198.   begin
  199.     ColStart[Col] := Total;
  200.     Inc(Total, ColWidth[Pred(LeftCol + Col)]);
  201.     Inc(Col);
  202.   end;
  203.   until (Total > 81) or (Pred(LeftCol + Col) > MAXCOLS);
  204.   if Total > 81 then
  205.     Dec(Col);
  206.   RightCol := LeftCol + Col - 2;
  207.   PrintCol;
  208. end; { SetRightCol }
  209.  
  210. procedure SetTopRow;
  211. begin
  212.   if BottomRow < ScreenRows then
  213.     BottomRow := ScreenRows;
  214.   TopRow := Succ(BottomRow - ScreenRows);
  215.   PrintRow;
  216. end; { SetTopRow }
  217.  
  218. procedure SetBottomRow;
  219. begin
  220.   if TopRow + ScreenRows > Succ(MAXROWS) then
  221.     TopRow := Succ(MAXROWS - ScreenRows);
  222.   BottomRow := Pred(TopRow + ScreenRows);
  223.   PrintRow;
  224. end; { SetBottomRow }
  225.  
  226. procedure SetLastCol;
  227. var
  228.   Row, Col : Word;
  229. begin
  230.   for Col := LastCol downto 1 do
  231.   begin
  232.     for Row := 1 to LastRow do
  233.     begin
  234.       if Cell[Col, Row] <> nil then
  235.       begin
  236.         LastCol := Col;
  237.         Exit;
  238.       end;
  239.     end;
  240.   end;
  241.   LastCol := 1;
  242. end; { SetLastCol }
  243.  
  244. procedure SetLastRow;
  245. var
  246.   Row, Col : Word;
  247. begin
  248.   for Row := LastRow downto 1 do
  249.   begin
  250.     for Col := 1 to LastCol do
  251.     begin
  252.       if Cell[Col, Row] <> nil then
  253.       begin
  254.         LastRow := Row;
  255.         Exit;
  256.       end;
  257.     end;
  258.   end;
  259.   LastRow := 1;
  260. end; { SetLastRow }
  261.  
  262. procedure ClearLastCol;
  263. var
  264.   Col : Word;
  265. begin
  266.   Col := ColStart[Succ(RightCol - LeftCol)] + ColWidth[RightCol];
  267.   if (Col < 80) then
  268.     Scroll(UP, 0, Col, 3, 80, ScreenRows + 2, White);
  269. end; { ClearLastCol }
  270.  
  271. procedure DisplayCol;
  272. var
  273.   Row : Word;
  274. begin
  275.   for Row := TopRow to BottomRow do
  276.     DisplayCell(Col, Row, NOHIGHLIGHT, Updating);
  277. end; { DisplayCol }
  278.  
  279. procedure DisplayRow;
  280. var
  281.   Col : Word;
  282. begin
  283.   for Col := LeftCol to RightCol do
  284.     DisplayCell(Col, Row, NOHIGHLIGHT, Updating);
  285. end; { DisplayRow }
  286.  
  287. procedure DisplayScreen;
  288. var
  289.   Row : Word;
  290. begin
  291.   for Row := TopRow to BottomRow do
  292.     DisplayRow(Row, Updating);
  293.   ClearLastCol;
  294. end; { DisplayScreen }
  295.  
  296. procedure RedrawScreen;
  297. begin
  298.   CurRow := 1;
  299.   CurCol := 1;
  300.   LeftCol := 1;
  301.   TopRow := 1;
  302.   SetRightCol;
  303.   SetBottomRow;
  304.   GotoXY(1, 1);
  305.   SetColor(MSGMEMORYCOLOR);
  306.   Write(MSGMEMORY);
  307.   GotoXY(29, 1);
  308.   SetColor(PROMPTCOLOR);
  309.   Write(MSGCOMMAND);
  310.   ChangeAutocalc(Autocalc);
  311.   ChangeFormDisplay(FormDisplay);
  312.   PrintFreeMem;
  313.   DisplayScreen(NOUPDATE);
  314. end; { RedrawScreen }
  315.  
  316. procedure FixFormula;
  317. var
  318.   FormLen, ColStart, RowStart, CurPos, FCol, FRow : Word;
  319.   CPtr : CellPtr;
  320.   Value : Real;
  321.   S : String[5];
  322.   NewFormula : IString;
  323.   Good : Boolean;
  324. begin
  325.   CPtr := Cell[Col, Row];
  326.   CurPos := 1;
  327.   NewFormula := CPtr^.Formula;
  328.   while CurPos < Length(NewFormula) do
  329.   begin
  330.     if FormulaStart(NewFormula, CurPos, FCol, FRow, FormLen) then
  331.     begin
  332.       if FCol > 26 then
  333.       begin
  334.         RowStart := CurPos + 2;
  335.         ColStart := RowStart - 2;
  336.       end
  337.       else begin
  338.         RowStart := Succ(CurPos);
  339.         ColStart := Pred(RowStart);
  340.       end;
  341.       case Action of
  342.         COLADD : begin
  343.           if FCol >= Place then
  344.           begin
  345.             if FCol = 26 then
  346.             begin
  347.               if Length(NewFormula) = MAXINPUT then
  348.               begin
  349.                 DeleteCell(Col, Row, NOUPDATE);
  350.                 Good := AllocText(Col, Row, NewFormula);
  351.                 Exit;
  352.               end;
  353.             end;
  354.             S := ColString(FCol);
  355.             Delete(NewFormula, ColStart, Length(S));
  356.             S := ColString(Succ(FCol));
  357.             Insert(S, NewFormula, ColStart);
  358.           end;
  359.         end;
  360.         ROWADD : begin
  361.           if FRow >= Place then
  362.           begin
  363.             if RowWidth(Succ(FRow)) <> RowWidth(FRow) then
  364.             begin
  365.               if Length(NewFormula) = MAXINPUT then
  366.               begin
  367.                 DeleteCell(Col, Row, NOUPDATE);
  368.                 Good := AllocText(Col, Row, NewFormula);
  369.                 Exit;
  370.               end;
  371.             end;
  372.             S := WordToString(FRow, 1);
  373.             Delete(NewFormula, RowStart, Length(S));
  374.             S := WordToString(Succ(FRow), 1);
  375.             Insert(S, NewFormula, RowStart);
  376.           end;
  377.         end;
  378.         COLDEL : begin
  379.           if FCol > Place then
  380.           begin
  381.             S := ColString(FCol);
  382.             Delete(NewFormula, ColStart, Length(S));
  383.             S := ColString(Pred(FCol));
  384.             Insert(S, NewFormula, ColStart);
  385.           end;
  386.         end;
  387.         ROWDEL : begin
  388.           if FRow > Place then
  389.           begin
  390.             S := WordToString(FRow, 1);
  391.             Delete(NewFormula, RowStart, Length(S));
  392.             S := WordToString(Pred(FRow), 1);
  393.             Insert(S, NewFormula, RowStart);
  394.           end;
  395.         end;
  396.       end; { case }
  397.       Inc(CurPos, FormLen);
  398.     end
  399.     else
  400.       Inc(CurPos);
  401.   end;
  402.   if Length(NewFormula) <> Length(CPtr^.Formula) then
  403.   begin
  404.     Value := CPtr^.FValue;
  405.     DeleteCell(Col, Row, NOUPDATE);
  406.     Good := AllocFormula(Col, Row, NewFormula, Value);
  407.   end
  408.   else
  409.     CPtr^.Formula := NewFormula;
  410. end; { FixFormula }
  411.  
  412. procedure ChangeAutoCalc;
  413. var
  414.   S : String[15];
  415. begin
  416.   if (not AutoCalc) and NewMode then
  417.     Recalc;
  418.   AutoCalc := NewMode;
  419.   if AutoCalc then
  420.     S := MSGAUTOCALC
  421.   else
  422.     S := '';
  423.   SetColor(MSGAUTOCALCCOLOR);
  424.   GotoXY(73, 1);
  425.   Write(S:Length(MSGAUTOCALC));
  426. end; { ChangeAutoCalc }
  427.  
  428. procedure ChangeFormDisplay;
  429. var
  430.   S : String[15];
  431. begin
  432.   FormDisplay := NewMode;
  433.   if FormDisplay then
  434.     S := MSGFORMDISPLAY
  435.   else
  436.     S := '';
  437.   SetColor(MSGFORMDISPLAYCOLOR);
  438.   GotoXY(65, 1);
  439.   Write(S:Length(MSGFORMDISPLAY));
  440. end; { ChangeFormDisplay }
  441.  
  442. procedure Recalc;
  443. var
  444.   Col, Row, Attrib : Word;
  445. begin
  446.   for Col := 1 to LastCol do
  447.   begin
  448.     for Row := 1 to LastRow do
  449.     begin
  450.       if ((Cell[Col, Row] <> nil) and (Cell[Col, Row]^.Attrib = FORMULA)) then
  451.       begin
  452.         Cell[Col, Row]^.FValue := Parse(Cell[Col, Row]^.Formula, Attrib);
  453.         Cell[Col, Row]^.Error := Attrib >= 4;
  454.       end;
  455.     end;
  456.   end;
  457.   DisplayScreen(UPDATE);
  458. end; { Recalc }
  459.  
  460. procedure Act;
  461. var
  462.   Attrib, Dummy : Word;
  463.   Allocated : Boolean;
  464.   V : Real;
  465. begin
  466.   DeleteCell(CurCol, CurRow, UPDATE);
  467.   V := Parse(S, Attrib);
  468.   case (Attrib and 3) of
  469.     TXT : begin
  470.       Allocated := AllocText(CurCol, CurRow, S);
  471.       if Allocated then
  472.         DisplayCell(CurCol, CurRow, NOHIGHLIGHT, NOUPDATE);
  473.     end;
  474.     VALUE : Allocated := AllocValue(CurCol, CurRow, V);
  475.     FORMULA : Allocated := AllocFormula(CurCol, CurRow, UpperCase(S), V);
  476.   end; { case }
  477.   if Allocated then
  478.   begin
  479.     if Attrib >= 4 then
  480.     begin
  481.       Cell[CurCol, CurRow]^.Error := True;
  482.       Dec(Attrib, 4);
  483.     end
  484.     else
  485.       Cell[CurCol, CurRow]^.Error := False;
  486.     Format[CurCol, CurRow] := Format[CurCol, CurRow] and (not OVERWRITE);
  487.     ClearOFlags(Succ(CurCol), CurRow, UPDATE);
  488.     if Attrib = TXT then
  489.       Dummy := SetOFlags(CurCol, CurRow, UPDATE);
  490.     if CurCol > LastCol then
  491.       LastCol := CurCol;
  492.     if CurRow > LastRow then
  493.       LastRow := CurRow;
  494.     if AutoCalc then
  495.       Recalc;
  496.   end
  497.   else
  498.     ErrorMsg(MSGLOMEM);
  499.   PrintFreeMem;
  500. end; { Act }
  501.  
  502. end.
  503.