home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / turbo4 / mclib.pas < prev    next >
Pascal/Delphi Source File  |  1987-12-08  |  12KB  |  433 lines

  1.  
  2. {           Copyright (c) 1985, 87 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. { gibt den Inhalt einer Zelle aus }
  12.  
  13. function SetOFlags(Col, Row : Word; Display : Boolean) : Word;
  14. { setzt das Flag "Overwrite" ab (col+1, row) und liefert die Nummer der
  15.   Spalte rechts neben der zuletzt gesetzten Spalte zurück }
  16. procedure ClearOFlags(Col, Row : Word; Display : Boolean);
  17. { löscht das Flag "Overwrite" ab (col, row) }
  18.  
  19. procedure UpdateOFlags(Col, Row : Word; Display : Boolean);
  20. { sucht ab col rückwärts nach der letzten TEXT-Zelle und bringt alle
  21.   Flags auf den neuesten Stand }
  22.  
  23. procedure DeleteCell(Col, Row : Word; Display : Boolean);
  24. { löscht eine Zelle }
  25.  
  26. procedure SetLeftCol;   { setzt den Wert von LeftCol abhängig von RightCol }
  27. procedure SetRightCol;  { setzt den Wert von RightCol abhängig von LeftCol }
  28. procedure SetTopRow;    { setzt TopRow abhängig von BottomRow }
  29. procedure SetBottomRow; { setzt BottomRow abhängig von TopRow }
  30. procedure SetLastCol;   { sucht die rechteste belegte Spalte }
  31. procedure SetLastRow;   { sucht die unterste belegte Zeile }
  32.  
  33. procedure ClearLastCol;  { löscht Daten in der rechtesten Spalte }
  34.  
  35. procedure DisplayCol(Col : Word; Updating : Boolean);
  36. { stellt eine Spalte auf dem Bildschirm dar }
  37. procedure DisplayRow(Row : Word; Updating : Boolean);
  38. { stellt eine Zeile auf dem Bildschirm dar }
  39. procedure DisplayScreen(Updating : Boolean);
  40. { stellt den aktuellen Ausschnitt des Rechenblattes auf dem Bildschirm dar }
  41.  
  42. procedure RedrawScreen;  { akualisiert den gesamten Bildschirm }
  43.  
  44. procedure FixFormula(Col, Row, Action, Place : Word);
  45. { paßt eine Formel nach Löschen/Einfügen von Zeilen/Spalten an }
  46.  
  47. procedure ChangeAutoCalc(NewMode : Boolean);
  48. { schaltet zwischen "Manuell" und "AutoCalc" um }
  49.  
  50. procedure ChangeFormDisplay(NewMode : Boolean);
  51. { schaltet zwischen "Ergebnisse" und "Formel-Darstellung" um }
  52.  
  53. procedure Recalc;
  54. { rechnet alle Zellen des Rechenblattes neu durch }
  55.  
  56. procedure Act(S : String);  { interpretiert Eingaben }
  57.  
  58. {***************************************************************}
  59. {***************************************************************}
  60. implementation
  61.  
  62. procedure DisplayCell;
  63. var
  64.   Color : Word;
  65.   S : IString;
  66. begin
  67.   if Updating and
  68.       ((Cell[Col, Row] = Nil) or (Cell[Col, Row]^.Attrib <> FORMULA)) then
  69.     Exit;
  70.   S := CellString(Col, Row, Color, DOFORMAT);
  71.   if Highlighting then
  72.   begin
  73.     if Color = ERRORCOLOR then Color := HIGHLIGHTERRORCOLOR
  74.      else Color := HIGHLIGHTCOLOR;
  75.   end;
  76.   SetColor(Color);
  77.   WriteXY(S, ColStart[Succ(Col - LeftCol)], Row - TopRow + 3);
  78. end;
  79.  
  80. function SetOFlags;
  81. var
  82.   Len : Integer;
  83. begin
  84.   Len := Length(Cell[Col, Row]^.T) - ColWidth[Col];
  85.   Inc(Col);
  86.   while (Col <= MAXCOLS) and (Len > 0) and (Cell[Col, Row] = nil) do
  87.   begin
  88.     Format[Col, Row] := Format[Col, Row] or OVERWRITE;
  89.     Dec(Len, ColWidth[Col]);
  90.     if Display and (Col >= LeftCol) and (Col <= RightCol) then
  91.       DisplayCell(Col, Row, NOHIGHLIGHT, NOUPDATE);
  92.     Inc(Col);
  93.   end;
  94.   SetOFlags := Col;
  95. end;
  96.  
  97. procedure ClearOFlags;
  98. begin
  99.   while (Col <= MAXCOLS) and (Format[Col, Row] >= OVERWRITE) and
  100.         (Cell[Col, Row] = nil) do
  101.   begin
  102.     Format[Col, Row] := Format[Col, Row] and (not OVERWRITE);
  103.     if Display and (Col >= LeftCol) and (Col <= RightCol) then
  104.       DisplayCell(Col, Row, NOHIGHLIGHT, NOUPDATE);
  105.     Inc(Col);
  106.   end;
  107. end;
  108.  
  109. procedure UpdateOFlags;
  110. var
  111.   Dummy : Word;
  112. begin
  113.   while (Cell[Col, Row] = nil) and (Col > 1) do
  114.     Dec(Col);
  115.   if (Cell[Col, Row]^.Attrib = TXT) and (Col >= 1) then
  116.     Dummy := SetOFlags(Col, Row, Display);
  117. end;
  118.  
  119. procedure DeleteCell;
  120. var
  121.   CPtr : CellPtr;
  122.   Size : Word;
  123. begin
  124.   CPtr := Cell[Col, Row];
  125.   if CPtr = nil then Exit;
  126.   case CPtr^.Attrib of
  127.     TXT : begin
  128.       Size := Length(CPtr^.T) + 3;
  129.       ClearOFlags(Succ(Col), Row, Display);
  130.     end;
  131.     VALUE : Size := SizeOf(Real) + 2;
  132.     FORMULA : Size := SizeOf(Real) + Length(CPtr^.Formula) + 3;
  133.   end; { case }
  134.   Format[Col, Row] := Format[Col, Row] and (not OVERWRITE);
  135.   FreeMem(CPtr, Size);
  136.   Cell[Col, Row] := nil;
  137.   if Col = LastCol then SetLastCol;
  138.   if Row = LastRow then SetLastRow;
  139.   UpdateOFlags(Col, Row, Display);
  140.   Changed := True;
  141. end;
  142.  
  143. procedure SetLeftCol;
  144. var
  145.   Col : Word;
  146.   Total : Integer;
  147. begin
  148.   Total := 81;
  149.   Col := 0;
  150.   while (Total > LEFTMARGIN) and (RightCol - Col > 0) do
  151.   begin
  152.     Dec(Total, ColWidth[RightCol - Col]);
  153.     if Total > LEFTMARGIN then ColStart[SCREENCOLS - Col] := Total;
  154.     Inc(Col);
  155.   end;
  156.   if Total > LEFTMARGIN then Inc(Col);
  157.   Move(ColStart[SCREENCOLS - Col + 2], ColStart, Pred(Col));
  158.   LeftCol := RightCol - Col + 2;
  159.   Total := Pred(ColStart[1] - LEFTMARGIN);
  160.   if Total <> 0 then
  161.     for Col := LeftCol to RightCol do
  162.       Dec(ColStart[Succ(Col - LeftCol)], Total);
  163.   PrintCol;
  164. end;
  165.  
  166. procedure SetRightCol;
  167. var
  168.   Total, Col : Word;
  169. begin
  170.   Total := Succ(LEFTMARGIN);
  171.   Col := 1;
  172.   repeat
  173.     ColStart[Col] := Total;
  174.     Inc(Total, ColWidth[Pred(LeftCol + Col)]);
  175.     Inc(Col);
  176.   until (Total > 81) or (Pred(LeftCol + Col) > MAXCOLS);
  177.   if Total > 81 then Dec(Col);
  178.   RightCol := LeftCol + Col - 2;
  179.   PrintCol;
  180. end;
  181.  
  182. procedure SetTopRow;
  183. begin
  184.   if BottomRow < ScreenRows then BottomRow := ScreenRows;
  185.   TopRow := Succ(BottomRow - ScreenRows);
  186.   PrintRow;
  187. end;
  188.  
  189. procedure SetBottomRow;
  190. begin
  191.   if TopRow + ScreenRows > Succ(MAXROWS) then
  192.     TopRow := Succ(MAXROWS - ScreenRows);
  193.   BottomRow := Pred(TopRow + ScreenRows);
  194.   PrintRow;
  195. end;
  196.  
  197. procedure SetLastCol;
  198. var
  199.   Row, Col : Word;
  200. begin
  201.   for Col := LastCol downto 1 do
  202.     for Row := 1 to LastRow do
  203.       if Cell[Col, Row] <> nil then
  204.       begin
  205.         LastCol := Col;
  206.         Exit;
  207.       end;
  208.   LastCol := 1;
  209. end;
  210.  
  211. procedure SetLastRow;
  212. var
  213.   Row, Col : Word;
  214. begin
  215.   for Row := LastRow downto 1 do
  216.     for Col := 1 to LastCol do
  217.       if Cell[Col, Row] <> nil then
  218.       begin
  219.         LastRow := Row;
  220.         Exit;
  221.       end;
  222.   LastRow := 1;
  223. end;
  224.  
  225. procedure ClearLastCol;
  226. var
  227.   Col : Word;
  228. begin
  229.   Col := ColStart[Succ(RightCol - LeftCol)] + ColWidth[RightCol];
  230.   if (Col < 80) then Scroll(UP, 0, Col, 3, 80, ScreenRows + 2, White);
  231. end;
  232.  
  233. procedure DisplayCol;
  234. var
  235.   Row : Word;
  236. begin
  237.   for Row := TopRow to BottomRow do
  238.     DisplayCell(Col, Row, NOHIGHLIGHT, Updating);
  239. end;
  240.  
  241. procedure DisplayRow;
  242. var
  243.   Col : Word;
  244. begin
  245.   for Col := LeftCol to RightCol do
  246.     DisplayCell(Col, Row, NOHIGHLIGHT, Updating);
  247. end;
  248.  
  249. procedure DisplayScreen;
  250. var
  251.   Row : Word;
  252. begin
  253.   for Row := TopRow to BottomRow do
  254.     DisplayRow(Row, Updating);
  255.   ClearLastCol;
  256. end;
  257.  
  258. procedure RedrawScreen;
  259. begin
  260.   CurRow := 1; CurCol := 1; LeftCol := 1; TopRow := 1;
  261.   SetRightCol; SetBottomRow;
  262.   GotoXY(1, 1);
  263.   SetColor(MSGMEMORYCOLOR);
  264.   Write(MSGMEMORY);
  265.   GotoXY(29, 1);
  266.   SetColor(PROMPTCOLOR);
  267.   Write(MSGCOMMAND);
  268.   ChangeAutocalc(Autocalc);
  269.   ChangeFormDisplay(FormDisplay);
  270.   PrintFreeMem;
  271.   DisplayScreen(NOUPDATE);
  272. end;
  273.  
  274. procedure FixFormula;
  275. var
  276.   FormLen, ColStart, RowStart, CurPos, FCol, FRow : Word;
  277.   CPtr : CellPtr;
  278.   Value : Real;
  279.   S : String[5];
  280.   NewFormula : IString;
  281.   Good : Boolean;
  282. begin
  283.   CPtr := Cell[Col, Row];
  284.   CurPos := 1;
  285.   NewFormula := CPtr^.Formula;
  286.   while CurPos < Length(NewFormula) do
  287.   begin
  288.     if FormulaStart(NewFormula, CurPos, FCol, FRow, FormLen) then
  289.     begin
  290.       if FCol > 26 then
  291.       begin
  292.         RowStart := CurPos + 2;
  293.         ColStart := RowStart - 2;
  294.       end
  295.       else begin
  296.         RowStart := Succ(CurPos);
  297.         ColStart := Pred(RowStart);
  298.       end;
  299.       case Action of
  300.        COLADD:  if FCol >= Place then
  301.                 begin
  302.                   if FCol = 26 then
  303.                     if Length(NewFormula) = MAXINPUT then
  304.                     begin
  305.                       DeleteCell(Col, Row, NOUPDATE);
  306.                       Good := AllocText(Col, Row, NewFormula);
  307.                       Exit;
  308.                     end;
  309.                   S := ColString(FCol);
  310.                   Delete(NewFormula, ColStart, Length(S));
  311.                   S := ColString(Succ(FCol));
  312.                   Insert(S, NewFormula, ColStart);
  313.                 end;
  314.       ROWADD : if FRow >= Place then
  315.                begin
  316.                  if RowWidth(Succ(FRow)) <> RowWidth(FRow) then
  317.                     if Length(NewFormula) = MAXINPUT then
  318.                     begin
  319.                       DeleteCell(Col, Row, NOUPDATE);
  320.                       Good := AllocText(Col, Row, NewFormula);
  321.                       Exit;
  322.                     end;
  323.                  S := WordToString(FRow, 1);
  324.                  Delete(NewFormula, RowStart, Length(S));
  325.                  S := WordToString(Succ(FRow), 1);
  326.                  Insert(S, NewFormula, RowStart);
  327.                end;
  328.       COLDEL : if FCol > Place then
  329.                begin
  330.                  S := ColString(FCol);
  331.                  Delete(NewFormula, ColStart, Length(S));
  332.                  S := ColString(Pred(FCol));
  333.                  Insert(S, NewFormula, ColStart);
  334.                end;
  335.      ROWDEL : if FRow > Place then
  336.               begin
  337.                 S := WordToString(FRow, 1);
  338.                 Delete(NewFormula, RowStart, Length(S));
  339.                 S := WordToString(Pred(FRow), 1);
  340.                 Insert(S, NewFormula, RowStart);
  341.               end;
  342.       end; { case }
  343.       Inc(CurPos, FormLen);
  344.     end
  345.     else Inc(CurPos);
  346.   end;
  347.   if Length(NewFormula) <> Length(CPtr^.Formula) then
  348.   begin
  349.     Value := CPtr^.FValue;
  350.     DeleteCell(Col, Row, NOUPDATE);
  351.     Good := AllocFormula(Col, Row, NewFormula, Value);
  352.   end
  353.   else CPtr^.Formula := NewFormula;
  354. end;
  355.  
  356. procedure ChangeAutoCalc;
  357. var
  358.   S : String[15];
  359. begin
  360.   if (not AutoCalc) and NewMode then Recalc;
  361.   AutoCalc := NewMode;
  362.   if AutoCalc then S := MSGAUTOCALC
  363.   else S := '';
  364.   SetColor(MSGAUTOCALCCOLOR);
  365.   GotoXY(73, 1);
  366.   Write(S:Length(MSGAUTOCALC));
  367. end;
  368.  
  369. procedure ChangeFormDisplay;
  370. var S: String[15];
  371. begin
  372.   FormDisplay := NewMode;
  373.   if FormDisplay then S := MSGFORMDISPLAY
  374.   else S := '';
  375.   SetColor(MSGFORMDISPLAYCOLOR);
  376.   GotoXY(65, 1);
  377.   Write(S:Length(MSGFORMDISPLAY));
  378. end;
  379.  
  380. procedure Recalc;
  381. var
  382.   Col, Row, Attrib : Word;
  383. begin
  384.   for Col := 1 to LastCol do
  385.     for Row := 1 to LastRow do
  386.       if ((Cell[Col, Row] <> nil) and (Cell[Col, Row]^.Attrib = FORMULA)) then
  387.       begin
  388.         Cell[Col, Row]^.FValue := Parse(Cell[Col, Row]^.Formula, Attrib);
  389.         Cell[Col, Row]^.Error := Attrib >= 4;
  390.       end;
  391.   DisplayScreen(UPDATE);
  392. end;
  393.  
  394. procedure Act;
  395. var
  396.   Attrib, Dummy : Word;
  397.   Allocated : Boolean;
  398.   V : Real;
  399. begin
  400.   DeleteCell(CurCol, CurRow, UPDATE);
  401.   V := Parse(S, Attrib);
  402.   case (Attrib and 3) of
  403.     TXT : begin
  404.       Allocated := AllocText(CurCol, CurRow, S);
  405.       if Allocated then
  406.         DisplayCell(CurCol, CurRow, NOHIGHLIGHT, NOUPDATE);
  407.     end;
  408.     VALUE : Allocated := AllocValue(CurCol, CurRow, V);
  409.     FORMULA : Allocated := AllocFormula(CurCol, CurRow, UpperCase(S), V);
  410.   end; { case }
  411.   if Allocated then
  412.   begin
  413.     if Attrib >= 4 then
  414.     begin
  415.       Cell[CurCol, CurRow]^.Error := True;
  416.       Dec(Attrib, 4);
  417.     end
  418.      else Cell[CurCol, CurRow]^.Error := False;
  419.     Format[CurCol, CurRow] := Format[CurCol, CurRow] and (not OVERWRITE);
  420.     ClearOFlags(Succ(CurCol), CurRow, UPDATE);
  421.     if Attrib = TXT then Dummy := SetOFlags(CurCol, CurRow, UPDATE);
  422.     if CurCol > LastCol then LastCol := CurCol;
  423.     if CurRow > LastRow then LastRow := CurRow;
  424.     if AutoCalc then Recalc;
  425.   end
  426.   else
  427.     ErrorMsg(MSGLOMEM);
  428.   PrintFreeMem;
  429. end;
  430.  
  431. begin  { keine Initialisierungen }
  432. end.
  433.