1926 lines
61 KiB
Plaintext
1926 lines
61 KiB
Plaintext
|
|
|||
|
{ Copyright (c) 1989 by Borland International, Inc. }
|
|||
|
|
|||
|
unit TCCell;
|
|||
|
{ Turbo Pascal 5.5 object-oriented example cell routines.
|
|||
|
This unit is used by TCALC.PAS.
|
|||
|
See TCALC.DOC for an more information about this example.
|
|||
|
}
|
|||
|
|
|||
|
{$N+,S-}
|
|||
|
|
|||
|
interface
|
|||
|
|
|||
|
uses Objects, TCUtil, TCLStr, TCScreen, TCHash;
|
|||
|
|
|||
|
const
|
|||
|
DollarString = ' $ ';
|
|||
|
RepeatFirstChar = '\';
|
|||
|
TextFirstChar = ' ';
|
|||
|
EmptyCellName = 'Empty';
|
|||
|
ValueCellName = 'Value';
|
|||
|
TextCellName = 'Text';
|
|||
|
FormulaCellName = 'Formula';
|
|||
|
RepeatCellName = 'Repeat';
|
|||
|
DecPlacesPart = $0F;
|
|||
|
JustShift = 4;
|
|||
|
JustPart = $03;
|
|||
|
DollarPart = $40;
|
|||
|
CommasPart = $80;
|
|||
|
NoMemory = 203;
|
|||
|
|
|||
|
type
|
|||
|
SSStream = object(DosStream)
|
|||
|
procedure RegisterTypes; virtual;
|
|||
|
end;
|
|||
|
CellTypes = (ClEmpty, ClValue, ClText, ClFormula, ClRepeat);
|
|||
|
CellPos = record
|
|||
|
Col : Word;
|
|||
|
Row : Word;
|
|||
|
end;
|
|||
|
FormatType = Byte;
|
|||
|
Justification = (JLeft, JCenter, JRight);
|
|||
|
DollarStr = String[Length(DollarString)];
|
|||
|
Block = object
|
|||
|
Start, Stop : CellPos;
|
|||
|
constructor Init(InitStart : CellPos);
|
|||
|
function ExtendTo(NewLoc : CellPos) : Boolean;
|
|||
|
function CellInBlock(CheckCell : CellPos) : Boolean;
|
|||
|
end;
|
|||
|
CellHashTablePtr = ^CellHashTable;
|
|||
|
CellPtr = ^Cell;
|
|||
|
CellHashTable = object(HashTable) { Keeps pointers to all cells }
|
|||
|
CurrCell : CellPtr; { Information about the cell that is being }
|
|||
|
CurrLoc : CellPos; { added, deleted, or searched for }
|
|||
|
constructor Init(InitBuckets : BucketRange);
|
|||
|
destructor Done;
|
|||
|
function Add(ACell : CellPtr) : Boolean;
|
|||
|
procedure Delete(DelLoc : CellPos; var DeletedCell : CellPtr);
|
|||
|
{ Removes a cell from the hash table }
|
|||
|
function Search(SPos : CellPos) : CellPtr;
|
|||
|
{ Searches for a cell in the hash table }
|
|||
|
function HashValue : Word; virtual;
|
|||
|
{ Computes the hash value of the cell }
|
|||
|
function Found(Item : HashItemPtr) : Boolean; virtual;
|
|||
|
{ Returns True if the hash item being searched for is found }
|
|||
|
procedure CreateItem(var Item : HashItemPtr); virtual;
|
|||
|
{ Fills in the information for a new hash item }
|
|||
|
function ItemSize : HashItemSizeRange; virtual;
|
|||
|
procedure Load(var S : SSStream; Total : Longint);
|
|||
|
procedure Store(var S : SSStream);
|
|||
|
function FirstItem : CellPtr;
|
|||
|
function NextItem : CellPtr;
|
|||
|
end;
|
|||
|
FormatHashTable = object(HashTable)
|
|||
|
CurrStart, CurrStop : CellPos;
|
|||
|
CurrFormat : FormatType;
|
|||
|
constructor Init;
|
|||
|
destructor Done;
|
|||
|
function Overwrite(NewStart, NewStop : CellPos) : Boolean;
|
|||
|
function Add(NewStart, NewStop : CellPos;
|
|||
|
NewFormat : FormatType) : Boolean;
|
|||
|
function Delete(DStart, DStop : CellPos) : Boolean;
|
|||
|
function Search(SPos : CellPos; var F : FormatType) : Boolean;
|
|||
|
function HashValue : Word; virtual;
|
|||
|
function Found(Item : HashItemPtr) : Boolean; virtual;
|
|||
|
procedure CreateItem(var Item : HashItemPtr); virtual;
|
|||
|
function ItemSize : HashItemSizeRange; virtual;
|
|||
|
procedure Load(var S : SSStream; Total : Longint);
|
|||
|
procedure Store(var S : SSStream);
|
|||
|
end;
|
|||
|
WidthHashTable = object(HashTable)
|
|||
|
CurrCol : Word;
|
|||
|
CurrWidth : Byte;
|
|||
|
DefaultColWidth : Byte;
|
|||
|
constructor Init(InitBuckets : BucketRange; InitDefaultColWidth : Byte);
|
|||
|
destructor Done;
|
|||
|
function Add(SCol : Word; NewWidth : Byte) : Boolean;
|
|||
|
procedure Delete(Col : Word);
|
|||
|
function Search(Col : Word) : Byte;
|
|||
|
function HashValue : Word; virtual;
|
|||
|
function Found(Item : HashItemPtr) : Boolean; virtual;
|
|||
|
procedure CreateItem(var Item : HashItemPtr); virtual;
|
|||
|
function ItemSize : HashItemSizeRange; virtual;
|
|||
|
function GetDefaultColWidth : Byte;
|
|||
|
procedure Load(var S : SSStream; Total : Longint);
|
|||
|
procedure Store(var S : SSStream);
|
|||
|
end;
|
|||
|
OverwriteHashTable = object(HashTable)
|
|||
|
CurrCell : CellPtr;
|
|||
|
CurrPos : CellPos;
|
|||
|
EndCol : Word;
|
|||
|
constructor Init(InitBuckets : BucketRange);
|
|||
|
destructor Done;
|
|||
|
function Add(SCell : CellPtr; Overwritten : Word) : Boolean;
|
|||
|
procedure Delete(SPos : CellPos);
|
|||
|
function Change(SCell : CellPtr; Overwritten : Word) : Boolean;
|
|||
|
function Search(SPos : CellPos) : CellPtr;
|
|||
|
function HashValue : Word; virtual;
|
|||
|
function Found(Item : HashItemPtr) : Boolean; virtual;
|
|||
|
procedure CreateItem(var Item : HashItemPtr); virtual;
|
|||
|
function ItemSize : HashItemSizeRange; virtual;
|
|||
|
end;
|
|||
|
GetColWidthFunc = function(var WHash : WidthHashTable;
|
|||
|
C : Word) : Byte;
|
|||
|
Cell = object(Base)
|
|||
|
Loc : CellPos;
|
|||
|
constructor Init(InitLoc : CellPos);
|
|||
|
destructor Done; virtual;
|
|||
|
function CellType : CellTypes; virtual;
|
|||
|
function LegalValue : Boolean; virtual;
|
|||
|
function Name : String; virtual;
|
|||
|
function Format(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : FormatType; virtual;
|
|||
|
function Width(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : Word; virtual;
|
|||
|
function Overwritten(var CHash : CellHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable; var LastPos : CellPos;
|
|||
|
MaxCols : Word; GetColWidth : GetColWidthFunc;
|
|||
|
FormulasDisplayed : Boolean) : Word; virtual;
|
|||
|
function ShouldUpdate : Boolean; virtual;
|
|||
|
function HasError : Boolean; virtual;
|
|||
|
function CurrValue : Extended; virtual;
|
|||
|
function OverwriteStart(var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc; EndCol : Word;
|
|||
|
DisplayFormulas : Boolean) : Word; virtual;
|
|||
|
procedure EditString(MaxDecPlaces : Byte; var L : LStringPtr); virtual;
|
|||
|
function DisplayString(FormulasDisplayed : Boolean;
|
|||
|
MaxDecPlaces : Byte) : String; virtual;
|
|||
|
function FormattedString(var OHash : OverwriteHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
CPos : CellPos; FormulasDisplayed : Boolean;
|
|||
|
Start : Word; ColWidth : Byte;
|
|||
|
var DString : DollarStr;
|
|||
|
var Color : Byte) : String; virtual;
|
|||
|
function CopyString(ColLit, RowLit : Boolean; Diff : Longint;
|
|||
|
var L : LStringPtr) : LStringPtr; virtual;
|
|||
|
end;
|
|||
|
EmptyCellPtr = ^EmptyCell;
|
|||
|
EmptyCell = object(Cell)
|
|||
|
constructor Init;
|
|||
|
function CellType : CellTypes; virtual;
|
|||
|
function LegalValue : Boolean; virtual;
|
|||
|
function Name : String; virtual;
|
|||
|
function Format(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : FormatType; virtual;
|
|||
|
function Width(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : Word; virtual;
|
|||
|
function Overwritten(var CHash : CellHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable; var LastPos : CellPos;
|
|||
|
MaxCols : Word; GetColWidth : GetColWidthFunc;
|
|||
|
FormulasDisplayed : Boolean) : Word; virtual;
|
|||
|
function ShouldUpdate : Boolean; virtual;
|
|||
|
function HasError : Boolean; virtual;
|
|||
|
function CurrValue : Extended; virtual;
|
|||
|
function OverwriteStart(var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc; EndCol : Word;
|
|||
|
DisplayFormulas : Boolean) : Word; virtual;
|
|||
|
procedure EditString(MaxDecPlaces : Byte; var L : LStringPtr); virtual;
|
|||
|
function DisplayString(FormulasDisplayed : Boolean;
|
|||
|
MaxDecPlaces : Byte) : String; virtual;
|
|||
|
function FormattedString(var OHash : OverwriteHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
CPos : CellPos; FormulasDisplayed : Boolean;
|
|||
|
Start : Word; ColWidth : Byte;
|
|||
|
var DString : DollarStr;
|
|||
|
var Color : Byte) : String; virtual;
|
|||
|
function CopyString(ColLit, RowLit : Boolean; Diff : Longint;
|
|||
|
var L : LStringPtr) : LStringPtr; virtual;
|
|||
|
end;
|
|||
|
ValueCellPtr = ^ValueCell;
|
|||
|
ValueCell = object(Cell)
|
|||
|
Error : Boolean;
|
|||
|
Value : Extended; { A cell with a numeric value }
|
|||
|
constructor Init(InitLoc : CellPos; InitError : Boolean;
|
|||
|
InitValue : Extended);
|
|||
|
function CellType : CellTypes; virtual;
|
|||
|
function LegalValue : Boolean; virtual;
|
|||
|
function Name : String; virtual;
|
|||
|
function Format(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : FormatType; virtual;
|
|||
|
function Width(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : Word; virtual;
|
|||
|
function Overwritten(var CHash : CellHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable; var LastPos : CellPos;
|
|||
|
MaxCols : Word; GetColWidth : GetColWidthFunc;
|
|||
|
FormulasDisplayed : Boolean) : Word; virtual;
|
|||
|
function ShouldUpdate : Boolean; virtual;
|
|||
|
function HasError : Boolean; virtual;
|
|||
|
function CurrValue : Extended; virtual;
|
|||
|
function OverwriteStart(var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc; EndCol : Word;
|
|||
|
DisplayFormulas : Boolean) : Word; virtual;
|
|||
|
procedure EditString(MaxDecPlaces : Byte; var L : LStringPtr); virtual;
|
|||
|
function DisplayString(FormulasDisplayed : Boolean;
|
|||
|
MaxDecPlaces : Byte) : String; virtual;
|
|||
|
function FormattedString(var OHash : OverwriteHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
CPos : CellPos; FormulasDisplayed : Boolean;
|
|||
|
Start : Word; ColWidth : Byte;
|
|||
|
var DString : DollarStr;
|
|||
|
var Color : Byte) : String; virtual;
|
|||
|
function CopyString(ColLit, RowLit : Boolean; Diff : Longint;
|
|||
|
var L : LStringPtr) : LStringPtr; virtual;
|
|||
|
constructor Load(var S : SSStream);
|
|||
|
procedure Store(var S : SSStream);
|
|||
|
end;
|
|||
|
TextCellPtr = ^TextCell;
|
|||
|
TextCell = object(Cell)
|
|||
|
Txt : LStringPtr; { A cell with text }
|
|||
|
constructor Init(InitLoc : CellPos; InitTxt : LStringPtr);
|
|||
|
destructor Done; virtual;
|
|||
|
function CellType : CellTypes; virtual;
|
|||
|
function LegalValue : Boolean; virtual;
|
|||
|
function Name : String; virtual;
|
|||
|
function Format(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : FormatType; virtual;
|
|||
|
function Width(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : Word; virtual;
|
|||
|
function Overwritten(var CHash : CellHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable; var LastPos : CellPos;
|
|||
|
MaxCols : Word; GetColWidth : GetColWidthFunc;
|
|||
|
FormulasDisplayed : Boolean) : Word; virtual;
|
|||
|
function ShouldUpdate : Boolean; virtual;
|
|||
|
function HasError : Boolean; virtual;
|
|||
|
function CurrValue : Extended; virtual;
|
|||
|
function OverwriteStart(var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc; EndCol : Word;
|
|||
|
DisplayFormulas : Boolean) : Word; virtual;
|
|||
|
procedure EditString(MaxDecPlaces : Byte; var L : LStringPtr); virtual;
|
|||
|
function DisplayString(FormulasDisplayed : Boolean;
|
|||
|
MaxDecPlaces : Byte) : String; virtual;
|
|||
|
function FormattedString(var OHash : OverwriteHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
CPos : CellPos; FormulasDisplayed : Boolean;
|
|||
|
Start : Word; ColWidth : Byte;
|
|||
|
var DString : DollarStr;
|
|||
|
var Color : Byte) : String; virtual;
|
|||
|
function CopyString(ColLit, RowLit : Boolean; Diff : Longint;
|
|||
|
var L : LStringPtr) : LStringPtr; virtual;
|
|||
|
constructor Load(var S : SSStream);
|
|||
|
procedure Store(var S : SSStream);
|
|||
|
end;
|
|||
|
FormulaCellPtr = ^FormulaCell;
|
|||
|
FormulaCell = object(Cell)
|
|||
|
Error : Boolean;
|
|||
|
Value : Extended;
|
|||
|
Formula : LStringPtr; { A cell with a formula }
|
|||
|
constructor Init(InitLoc : CellPos; InitError : Boolean;
|
|||
|
InitValue : Extended; InitFormula : LStringPtr);
|
|||
|
destructor Done; virtual;
|
|||
|
function CellType : CellTypes; virtual;
|
|||
|
function LegalValue : Boolean; virtual;
|
|||
|
function Name : String; virtual;
|
|||
|
function Format(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : FormatType; virtual;
|
|||
|
function Width(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : Word; virtual;
|
|||
|
function Overwritten(var CHash : CellHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable; var LastPos : CellPos;
|
|||
|
MaxCols : Word; GetColWidth : GetColWidthFunc;
|
|||
|
FormulasDisplayed : Boolean) : Word; virtual;
|
|||
|
function ShouldUpdate : Boolean; virtual;
|
|||
|
function HasError : Boolean; virtual;
|
|||
|
function CurrValue : Extended; virtual;
|
|||
|
function OverwriteStart(var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc; EndCol : Word;
|
|||
|
DisplayFormulas : Boolean) : Word; virtual;
|
|||
|
procedure EditString(MaxDecPlaces : Byte; var L : LStringPtr); virtual;
|
|||
|
function DisplayString(FormulasDisplayed : Boolean;
|
|||
|
MaxDecPlaces : Byte) : String; virtual;
|
|||
|
function FormattedString(var OHash : OverwriteHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
CPos : CellPos; FormulasDisplayed : Boolean;
|
|||
|
Start : Word; ColWidth : Byte;
|
|||
|
var DString : DollarStr;
|
|||
|
var Color : Byte) : String; virtual;
|
|||
|
function CopyString(ColLit, RowLit : Boolean; Diff : Longint;
|
|||
|
var L : LStringPtr) : LStringPtr; virtual;
|
|||
|
constructor Load(var S : SSStream);
|
|||
|
procedure Store(var S : SSStream);
|
|||
|
function GetFormula : LStringPtr;
|
|||
|
end;
|
|||
|
RepeatCellPtr = ^RepeatCell;
|
|||
|
RepeatCell = object(Cell)
|
|||
|
RepeatChar : Char; { A cell with text that will repeat - used for
|
|||
|
underlining, etc. }
|
|||
|
constructor Init(InitLoc : CellPos; InitChar : Char);
|
|||
|
function CellType : CellTypes; virtual;
|
|||
|
function LegalValue : Boolean; virtual;
|
|||
|
function Name : String; virtual;
|
|||
|
function Format(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : FormatType; virtual;
|
|||
|
function Width(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : Word; virtual;
|
|||
|
function Overwritten(var CHash : CellHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable; var LastPos : CellPos;
|
|||
|
MaxCols : Word; GetColWidth : GetColWidthFunc;
|
|||
|
FormulasDisplayed : Boolean) : Word; virtual;
|
|||
|
function ShouldUpdate : Boolean; virtual;
|
|||
|
function HasError : Boolean; virtual;
|
|||
|
function CurrValue : Extended; virtual;
|
|||
|
function OverwriteStart(var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc; EndCol : Word;
|
|||
|
DisplayFormulas : Boolean) : Word; virtual;
|
|||
|
procedure EditString(MaxDecPlaces : Byte; var L : LStringPtr); virtual;
|
|||
|
function DisplayString(FormulasDisplayed : Boolean;
|
|||
|
MaxDecPlaces : Byte) : String; virtual;
|
|||
|
function FormattedString(var OHash : OverwriteHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
CPos : CellPos; FormulasDisplayed : Boolean;
|
|||
|
Start : Word; ColWidth : Byte;
|
|||
|
var DString : DollarStr;
|
|||
|
var Color : Byte) : String; virtual;
|
|||
|
function CopyString(ColLit, RowLit : Boolean; Diff : Longint;
|
|||
|
var L : LStringPtr) : LStringPtr; virtual;
|
|||
|
constructor Load(var S : SSStream);
|
|||
|
procedure Store(var S : SSStream);
|
|||
|
end;
|
|||
|
|
|||
|
var
|
|||
|
Empty : CellPtr; { This is a special cell. It is used as the return
|
|||
|
value if a cell cannot be found so that the EmptyCell
|
|||
|
methods can be executed instead of having special
|
|||
|
routines that act differently depending on whether a
|
|||
|
cell is found ot not. }
|
|||
|
|
|||
|
implementation
|
|||
|
|
|||
|
var
|
|||
|
SavedExitProc : Pointer;
|
|||
|
|
|||
|
procedure SSStream.RegisterTypes;
|
|||
|
{ Registers the different cell types so that they will be written out
|
|||
|
correctly to disk }
|
|||
|
begin
|
|||
|
DosStream.RegisterTypes;
|
|||
|
Register(TypeOf(ValueCell), @ValueCell.Store, @ValueCell.Load);
|
|||
|
Register(TypeOf(TextCell), @TextCell.Store, @TextCell.Load);
|
|||
|
Register(TypeOf(FormulaCell), @FormulaCell.Store, @FormulaCell.Load);
|
|||
|
Register(TypeOf(RepeatCell), @RepeatCell.Store, @RepeatCell.Load);
|
|||
|
end; { SSStream.RegisterTypes }
|
|||
|
|
|||
|
constructor Block.Init(InitStart : CellPos);
|
|||
|
{ Initializes a block of cells, setting the end to be the same as the start }
|
|||
|
begin
|
|||
|
Start := InitStart;
|
|||
|
Stop := Start;
|
|||
|
end; { Block.Init }
|
|||
|
|
|||
|
function Block.ExtendTo(NewLoc : CellPos) : Boolean;
|
|||
|
{ Extends a block to a new position, as long as the new position is to the
|
|||
|
right and down from the old position }
|
|||
|
begin
|
|||
|
if (NewLoc.Col >= Start.Col) and (NewLoc.Row >= Start.Row) then
|
|||
|
begin
|
|||
|
Stop := NewLoc;
|
|||
|
ExtendTo := True;
|
|||
|
end
|
|||
|
else
|
|||
|
ExtendTo := False;
|
|||
|
end; { Block.ExtendTo }
|
|||
|
|
|||
|
function Block.CellInBlock(CheckCell : CellPos) : Boolean;
|
|||
|
{ Checks to see if a cell is inside a particular block }
|
|||
|
begin
|
|||
|
CellInBlock := (CheckCell.Col >= Start.Col) and
|
|||
|
(CheckCell.Col <= Stop.Col) and
|
|||
|
(CheckCell.Row >= Start.Row) and
|
|||
|
(CheckCell.Row <= Stop.Row);
|
|||
|
end; { Block.CellInBlock }
|
|||
|
|
|||
|
constructor CellHashTable.Init(InitBuckets : BucketRange);
|
|||
|
{ Initializes a cell hash table, which stores pointers to the cells in a
|
|||
|
spreadsheet }
|
|||
|
begin
|
|||
|
if not HashTable.Init(InitBuckets) then
|
|||
|
Fail;
|
|||
|
end; { CellHashTable.Init }
|
|||
|
|
|||
|
destructor CellHashTable.Done;
|
|||
|
{ Removes a cell hash table from memory }
|
|||
|
var
|
|||
|
CP : CellPtr;
|
|||
|
begin
|
|||
|
CP := FirstItem;
|
|||
|
while CP <> nil do
|
|||
|
begin
|
|||
|
Dispose(CP, Done);
|
|||
|
CP := NextItem;
|
|||
|
end;
|
|||
|
HashTable.Done;
|
|||
|
end; { CellHashTable.Done }
|
|||
|
|
|||
|
function CellHashTable.Add(ACell : CellPtr) : Boolean;
|
|||
|
{ Adds a cell to a cell hash table }
|
|||
|
begin
|
|||
|
CurrCell := ACell;
|
|||
|
CurrLoc := CurrCell^.Loc;
|
|||
|
Add := HashTable.Add;
|
|||
|
end; { CellHashTable.Add }
|
|||
|
|
|||
|
procedure CellHashTable.Delete(DelLoc : CellPos; var DeletedCell : CellPtr);
|
|||
|
{ Deletes a cell from a cell hash table }
|
|||
|
begin
|
|||
|
CurrLoc := DelLoc;
|
|||
|
HashTable.Delete(@DeletedCell);
|
|||
|
end; { CellHashTable.Delete }
|
|||
|
|
|||
|
function CellHashTable.Search(SPos : CellPos) : CellPtr;
|
|||
|
{ Searches for a cell in a cell hash table, returning the cell if found, or
|
|||
|
returning the Empty cell if not found }
|
|||
|
var
|
|||
|
I : HashItemPtr;
|
|||
|
C : CellPtr;
|
|||
|
begin
|
|||
|
CurrLoc := SPos;
|
|||
|
I := HashTable.Search;
|
|||
|
if I = nil then
|
|||
|
Search := Empty
|
|||
|
else begin
|
|||
|
Move(I^.Data, C, SizeOf(C));
|
|||
|
Search := C;
|
|||
|
end;
|
|||
|
end; { CellHashTable.Search }
|
|||
|
|
|||
|
function CellHashTable.HashValue : Word;
|
|||
|
{ Calculates the hash value of a cell }
|
|||
|
begin
|
|||
|
HashValue := CurrLoc.Col + CurrLoc.Row;
|
|||
|
end; { CellHashTable.HashValue }
|
|||
|
|
|||
|
function CellHashTable.Found(Item : HashItemPtr) : Boolean;
|
|||
|
{ Checks to see if a hash item is the one searched for by comparing the
|
|||
|
location information in both }
|
|||
|
var
|
|||
|
C : CellPtr;
|
|||
|
begin
|
|||
|
Move(Item^.Data, C, SizeOf(C));
|
|||
|
Found := Compare(C^.Loc, CurrLoc, SizeOf(CurrLoc));
|
|||
|
end; { CellHashTable.Found }
|
|||
|
|
|||
|
procedure CellHashTable.CreateItem(var Item : HashItemPtr);
|
|||
|
{ Writes the cell poionter information out to the hash item }
|
|||
|
begin
|
|||
|
Move(CurrCell, Item^.Data, SizeOf(CurrCell));
|
|||
|
end; { CellHashTable.CreateItem }
|
|||
|
|
|||
|
function CellHashTable.ItemSize : HashItemSizeRange;
|
|||
|
{ The hash item size is current - just cell pointers are stored }
|
|||
|
begin
|
|||
|
ItemSize := SizeOf(CurrCell);
|
|||
|
end; { CellHashTable.ItemSize }
|
|||
|
|
|||
|
procedure CellHashTable.Load(var S : SSStream; Total : Longint);
|
|||
|
{ Loads a cell hash table from disk }
|
|||
|
var
|
|||
|
Counter : Longint;
|
|||
|
begin
|
|||
|
for Counter := 1 to Total do
|
|||
|
begin
|
|||
|
if not Add(CellPtr(S.Get)) then
|
|||
|
begin
|
|||
|
S.Error(NoMemory);
|
|||
|
Exit;
|
|||
|
end;
|
|||
|
end;
|
|||
|
end; { CellHashTable.Load }
|
|||
|
|
|||
|
procedure CellHashTable.Store(var S : SSStream);
|
|||
|
{ Writes a cell hash table to disk }
|
|||
|
var
|
|||
|
CP : CellPtr;
|
|||
|
begin
|
|||
|
CP := FirstItem;
|
|||
|
while CP <> nil do
|
|||
|
begin
|
|||
|
S.Put(CP);
|
|||
|
CP := NextItem;
|
|||
|
end;
|
|||
|
end; { CellHashTable.Store }
|
|||
|
|
|||
|
function HashItemPtrToCellPtr(H : HashItemPtr) : CellPtr;
|
|||
|
{ Converts a hash item pointer to a cell pointer }
|
|||
|
var
|
|||
|
CP : CellPtr;
|
|||
|
begin
|
|||
|
if H = nil then
|
|||
|
HashItemPtrToCellPtr := nil
|
|||
|
else begin
|
|||
|
Move(H^.Data, CP, SizeOf(CP));
|
|||
|
HashItemPtrToCellPtr := CP;
|
|||
|
end;
|
|||
|
end; { HashItemPtrToCellPtr }
|
|||
|
|
|||
|
function CellHashTable.FirstItem : CellPtr;
|
|||
|
{ Returns the first hash item in a cell hash table }
|
|||
|
begin
|
|||
|
FirstItem := HashItemPtrToCellPtr(HashTable.FirstItem);
|
|||
|
end; { CellHashTable.FirstItem }
|
|||
|
|
|||
|
function CellHashTable.NextItem : CellPtr;
|
|||
|
{ Returns the second and subsequent hash items in a cell hash table }
|
|||
|
begin
|
|||
|
NextItem := HashItemPtrToCellPtr(HashTable.NextItem);
|
|||
|
end; { CellHashTable.NextItem }
|
|||
|
|
|||
|
constructor WidthHashTable.Init(InitBuckets : BucketRange;
|
|||
|
InitDefaultColWidth : Byte);
|
|||
|
{ Initializes the width hash table, which stores column widths that are
|
|||
|
different than the default. It stores the column and the width in the
|
|||
|
hash table }
|
|||
|
begin
|
|||
|
if not HashTable.Init(InitBuckets) then
|
|||
|
Fail;
|
|||
|
DefaultColWidth := InitDefaultColWidth;
|
|||
|
end; { WidthHashTable.Init }
|
|||
|
|
|||
|
destructor WidthHashTable.Done;
|
|||
|
begin
|
|||
|
HashTable.Done;
|
|||
|
end; { WidthHashTable.Done }
|
|||
|
|
|||
|
function WidthHashTable.Add(SCol : Word; NewWidth : Byte) : Boolean;
|
|||
|
begin
|
|||
|
CurrCol := SCol;
|
|||
|
CurrWidth := NewWidth;
|
|||
|
Add := HashTable.Add;
|
|||
|
end; { WidthHashTable }
|
|||
|
|
|||
|
procedure WidthHashTable.Delete(Col : Word);
|
|||
|
begin
|
|||
|
CurrCol := Col;
|
|||
|
HashTable.Delete(nil);
|
|||
|
end; { WidthHashTable.Delete }
|
|||
|
|
|||
|
function WidthHashTable.Search(Col : Word) : Byte;
|
|||
|
var
|
|||
|
I : HashItemPtr;
|
|||
|
W : Byte;
|
|||
|
begin
|
|||
|
CurrCol := Col;
|
|||
|
I := HashTable.Search;
|
|||
|
if I = nil then
|
|||
|
Search := 0
|
|||
|
else begin
|
|||
|
Move(I^.Data[SizeOf(CurrCol)], W, SizeOf(W));
|
|||
|
Search := W;
|
|||
|
end;
|
|||
|
end; { WidthHashTable.Search }
|
|||
|
|
|||
|
function WidthHashTable.HashValue : Word;
|
|||
|
begin
|
|||
|
HashValue := CurrCol;
|
|||
|
end; { WidthHashTable.HashValue }
|
|||
|
|
|||
|
function WidthHashTable.Found(Item : HashItemPtr) : Boolean;
|
|||
|
var
|
|||
|
C : Word;
|
|||
|
begin
|
|||
|
Move(Item^.Data, C, SizeOf(C));
|
|||
|
Found := CurrCol = C;
|
|||
|
end; { WidthHashTable.Found }
|
|||
|
|
|||
|
procedure WidthHashTable.CreateItem(var Item : HashItemPtr);
|
|||
|
begin
|
|||
|
Move(CurrCol, Item^.Data, SizeOf(CurrCol));
|
|||
|
Move(CurrWidth, Item^.Data[SizeOf(CurrCol)], SizeOf(CurrWidth));
|
|||
|
end; { WidthHashTable.CreateItem }
|
|||
|
|
|||
|
function WidthHashTable.ItemSize : HashItemSizeRange;
|
|||
|
begin
|
|||
|
ItemSize := SizeOf(CurrCol) + SizeOf(CurrWidth);
|
|||
|
end; { WidthHashTable.ItemSize }
|
|||
|
|
|||
|
function WidthHashTable.GetDefaultColWidth : Byte;
|
|||
|
begin
|
|||
|
GetDefaultColWidth := DefaultColWidth;
|
|||
|
end; { WidthHashTable.GetDefaultColWidth }
|
|||
|
|
|||
|
procedure WidthHashTable.Load(var S : SSStream; Total : Longint);
|
|||
|
var
|
|||
|
Counter : Longint;
|
|||
|
Col : Word;
|
|||
|
Width : Byte;
|
|||
|
begin
|
|||
|
for Counter := 1 to Total do
|
|||
|
begin
|
|||
|
S.Read(Col, SizeOf(Col));
|
|||
|
S.Read(Width, SizeOf(Width));
|
|||
|
if not Add(Col, Width) then
|
|||
|
begin
|
|||
|
S.Error(NoMemory);
|
|||
|
Exit;
|
|||
|
end;
|
|||
|
end;
|
|||
|
end; { WidthHashTable.Load }
|
|||
|
|
|||
|
procedure WidthHashTable.Store(var S : SSStream);
|
|||
|
var
|
|||
|
H : HashItemPtr;
|
|||
|
Col : Word;
|
|||
|
Width : Byte;
|
|||
|
begin
|
|||
|
H := FirstItem;
|
|||
|
while H <> nil do
|
|||
|
begin
|
|||
|
Move(H^.Data, Col, SizeOf(Col));
|
|||
|
S.Write(Col, SizeOf(Col));
|
|||
|
Move(H^.Data[SizeOf(Col)], Width, SizeOf(Width));
|
|||
|
S.Write(Width, SizeOf(Width));
|
|||
|
H := NextItem;
|
|||
|
end;
|
|||
|
end; { WidthHashTable.Store }
|
|||
|
|
|||
|
constructor FormatHashTable.Init;
|
|||
|
{ Initializes a format hash table, which is used to store formatted areas
|
|||
|
that differ from the default. The area and the format are stored in the
|
|||
|
hash table }
|
|||
|
begin
|
|||
|
if not HashTable.Init(1) then { Use a single bucket so that a search
|
|||
|
Fail; will be possible }
|
|||
|
end; { FormatHashTable.Init }
|
|||
|
|
|||
|
destructor FormatHashTable.Done;
|
|||
|
begin
|
|||
|
HashTable.Done;
|
|||
|
end; { FormatHashTable.Done }
|
|||
|
|
|||
|
function FormatHashTable.Overwrite(NewStart, NewStop : CellPos) : Boolean;
|
|||
|
{ Checks to see if a new format area has overwritten an old one, requiring
|
|||
|
the old area to be overwritten or broken into parts }
|
|||
|
var
|
|||
|
H : HashItemPtr;
|
|||
|
AStart, AStop, BStart, BStop : CellPos;
|
|||
|
OldF, F : FormatType;
|
|||
|
P : CellPos;
|
|||
|
Added : Boolean;
|
|||
|
begin
|
|||
|
Overwrite := False;
|
|||
|
H := HashData^[1];
|
|||
|
while H <> nil do
|
|||
|
begin
|
|||
|
Move(H^.Data, BStart, SizeOf(CellPos));
|
|||
|
Move(H^.Data[SizeOf(CellPos)], BStop, SizeOf(CellPos));
|
|||
|
if ((((NewStart.Col >= BStart.Col) and (NewStart.Col <= BStop.Col)) or
|
|||
|
((NewStop.Col >= BStart.Col) and (NewStop.Col <= BStop.Col))) and
|
|||
|
(((NewStart.Row >= BStart.Row) and (NewStart.Row <= BStop.Row)) or
|
|||
|
((NewStop.Row >= BStart.Row) and (NewStop.Row <= BStop.Row)))) or
|
|||
|
((((BStart.Col >= NewStart.Col) and (BStart.Col <= NewStop.Col)) or
|
|||
|
((BStop.Col >= NewStart.Col) and (BStop.Col <= NewStop.Col))) and
|
|||
|
(((BStart.Row >= NewStart.Row) and (BStart.Row <= NewStop.Row)) or
|
|||
|
((BStop.Row >= NewStart.Row) and (BStop.Row <= NewStop.Row)))) then
|
|||
|
begin
|
|||
|
Move(H^.Data[SizeOf(CellPos) shl 1], F, SizeOf(F));
|
|||
|
CurrStart := BStart;
|
|||
|
CurrStop := BStop;
|
|||
|
HashTable.Delete(nil);
|
|||
|
if BStart.Row < NewStart.Row then
|
|||
|
begin
|
|||
|
AStart := BStart;
|
|||
|
AStop.Col := BStop.Col;
|
|||
|
AStop.Row := Pred(NewStart.Row);
|
|||
|
if not Add(AStart, AStop, F) then
|
|||
|
Exit;
|
|||
|
end;
|
|||
|
if BStop.Row > NewStop.Row then
|
|||
|
begin
|
|||
|
AStart.Col := BStart.Col;
|
|||
|
AStart.Row := Succ(NewStop.Row);
|
|||
|
AStop.Col := BStop.Col;
|
|||
|
AStop.Row := BStop.Row;
|
|||
|
if not Add(AStart, AStop, F) then
|
|||
|
Exit;
|
|||
|
end;
|
|||
|
if BStart.Col < NewStart.Col then
|
|||
|
begin
|
|||
|
AStart.Col := BStart.Col;
|
|||
|
AStart.Row := Max(BStart.Row, NewStart.Row);
|
|||
|
AStop.Col := Pred(NewStart.Col);
|
|||
|
AStop.Row := Min(BStop.Row, NewStop.Row);
|
|||
|
if not Add(AStart, AStop, F) then
|
|||
|
Exit;
|
|||
|
end;
|
|||
|
if BStop.Col > NewStop.Col then
|
|||
|
begin
|
|||
|
AStart.Col := Succ(NewStop.Col);
|
|||
|
AStart.Row := Max(BStart.Row, NewStart.Row);
|
|||
|
AStop.Col := BStop.Col;
|
|||
|
AStop.Row := Min(BStop.Row, NewStop.Row);
|
|||
|
if not Add(AStart, AStop, F) then
|
|||
|
Exit;
|
|||
|
end;
|
|||
|
end;
|
|||
|
H := H^.Next;
|
|||
|
end;
|
|||
|
Overwrite := True;
|
|||
|
end; { FormatHashTable.Overwrite }
|
|||
|
|
|||
|
function FormatHashTable.Add(NewStart, NewStop : CellPos;
|
|||
|
NewFormat : FormatType) : Boolean;
|
|||
|
begin
|
|||
|
if not Overwrite(NewStart, NewStop) then
|
|||
|
begin
|
|||
|
Add := False;
|
|||
|
Exit;
|
|||
|
end;
|
|||
|
CurrStart := NewStart;
|
|||
|
CurrStop := NewStop;
|
|||
|
CurrFormat := NewFormat;
|
|||
|
Add := HashTable.Add;
|
|||
|
end; { FormatHashTable.Add }
|
|||
|
|
|||
|
function FormatHashTable.Delete(DStart, DStop : CellPos) : Boolean;
|
|||
|
begin
|
|||
|
Delete := Overwrite(DStart, DStop);
|
|||
|
end; { FormatHashTable.Delete }
|
|||
|
|
|||
|
function FormatHashTable.Search(SPos : CellPos; var F : FormatType) :
|
|||
|
Boolean;
|
|||
|
var
|
|||
|
H : HashItemPtr;
|
|||
|
begin
|
|||
|
CurrStart := SPos;
|
|||
|
H := HashTable.Search;
|
|||
|
if H = nil then
|
|||
|
Search := False
|
|||
|
else begin
|
|||
|
Move(H^.Data[SizeOf(CellPos) shl 1], F, SizeOf(F));
|
|||
|
Search := True;
|
|||
|
end;
|
|||
|
end; { FormatHashTable.Search }
|
|||
|
|
|||
|
function FormatHashTable.HashValue : Word;
|
|||
|
{ Since the hash table has only one bucket, the hash value is always 1 }
|
|||
|
begin
|
|||
|
HashValue := 1;
|
|||
|
end; { FormatHashTable.HashValue }
|
|||
|
|
|||
|
function FormatHashTable.Found(Item : HashItemPtr) : Boolean;
|
|||
|
var
|
|||
|
P : CellPos;
|
|||
|
B : Block;
|
|||
|
Start, Stop : CellPos;
|
|||
|
Good : Boolean;
|
|||
|
begin
|
|||
|
Move(Item^.Data, Start, SizeOf(CellPos));
|
|||
|
Move(Item^.Data[SizeOf(CellPos)], Stop, SizeOf(CellPos));
|
|||
|
B.Init(Start);
|
|||
|
B.Stop := Stop;
|
|||
|
Found := B.CellInBlock(CurrStart);
|
|||
|
end; { FormatHashTable.Found }
|
|||
|
|
|||
|
procedure FormatHashTable.CreateItem(var Item : HashItemPtr);
|
|||
|
begin
|
|||
|
with Item^ do
|
|||
|
begin
|
|||
|
Move(CurrStart, Data, SizeOf(CellPos));
|
|||
|
Move(CurrStop, Data[SizeOf(CellPos)], SizeOf(CellPos));
|
|||
|
Move(CurrFormat, Data[SizeOf(CellPos) shl 1], SizeOf(CurrFormat));
|
|||
|
end; { with }
|
|||
|
end; { FormatHashTable.CreateItem }
|
|||
|
|
|||
|
function FormatHashTable.ItemSize : HashItemSizeRange;
|
|||
|
begin
|
|||
|
ItemSize := (SizeOf(CellPos) shl 1) + SizeOf(FormatType);
|
|||
|
end; { FormatHashTable.ItemSize }
|
|||
|
|
|||
|
procedure FormatHashTable.Load(var S : SSStream; Total : Longint);
|
|||
|
var
|
|||
|
Counter : Longint;
|
|||
|
C1, C2 : CellPos;
|
|||
|
Format : FormatType;
|
|||
|
begin
|
|||
|
for Counter := 1 to Total do
|
|||
|
begin
|
|||
|
S.Read(C1, SizeOf(C1));
|
|||
|
S.Read(C2, SizeOf(C2));
|
|||
|
S.Read(Format, SizeOf(Format));
|
|||
|
if not Add(C1, C2, Format) then
|
|||
|
begin
|
|||
|
S.Error(NoMemory);
|
|||
|
Exit;
|
|||
|
end;
|
|||
|
end;
|
|||
|
end; { FormatHashTable.Load }
|
|||
|
|
|||
|
procedure FormatHashTable.Store(var S : SSStream);
|
|||
|
var
|
|||
|
H : HashItemPtr;
|
|||
|
C : CellPos;
|
|||
|
Format : Byte;
|
|||
|
begin
|
|||
|
H := FirstItem;
|
|||
|
while H <> nil do
|
|||
|
begin
|
|||
|
Move(H^.Data, C, SizeOf(C));
|
|||
|
S.Write(C, SizeOf(C));
|
|||
|
Move(H^.Data[SizeOf(CellPos)], C, SizeOf(C));
|
|||
|
S.Write(C, SizeOf(C));
|
|||
|
Move(H^.Data[SizeOf(CellPos) shl 1], Format, SizeOf(Format));
|
|||
|
S.Write(Format, SizeOf(Format));
|
|||
|
H := NextItem;
|
|||
|
end;
|
|||
|
end; { FormatHashTable.Store }
|
|||
|
|
|||
|
constructor OverwriteHashTable.Init(InitBuckets : BucketRange);
|
|||
|
{ Initializes an overwrite hash table, which keeps track of which cells are
|
|||
|
overwritten by other cells }
|
|||
|
begin
|
|||
|
if not HashTable.Init(InitBuckets) then
|
|||
|
Fail;
|
|||
|
end; { OverwriteHashTable.Init }
|
|||
|
|
|||
|
destructor OverwriteHashTable.Done;
|
|||
|
begin
|
|||
|
HashTable.Done;
|
|||
|
end; { OverwriteHashTable.Done }
|
|||
|
|
|||
|
function OverwriteHashTable.Add(SCell : CellPtr;
|
|||
|
Overwritten : Word) : Boolean;
|
|||
|
var
|
|||
|
CP : CellPtr;
|
|||
|
begin
|
|||
|
if Overwritten = 0 then
|
|||
|
begin
|
|||
|
Add := True;
|
|||
|
Exit;
|
|||
|
end;
|
|||
|
CP := Search(SCell^.Loc);
|
|||
|
if CP <> Empty then
|
|||
|
begin
|
|||
|
if not Change(CP, Pred(SCell^.Loc.Col)) then
|
|||
|
begin
|
|||
|
Add := False;
|
|||
|
Exit;
|
|||
|
end;
|
|||
|
end;
|
|||
|
CurrCell := SCell;
|
|||
|
CurrPos := SCell^.Loc;
|
|||
|
EndCol := CurrPos.Col + Overwritten;
|
|||
|
Add := HashTable.Add;
|
|||
|
end; { OverwriteHashTable.Add }
|
|||
|
|
|||
|
procedure OverwriteHashTable.Delete(SPos : CellPos);
|
|||
|
begin
|
|||
|
CurrPos := SPos;
|
|||
|
HashTable.Delete(nil);
|
|||
|
end; { OverwriteHashTable.Delete }
|
|||
|
|
|||
|
function OverwriteHashTable.Change(SCell : CellPtr;
|
|||
|
Overwritten : Word) : Boolean;
|
|||
|
begin
|
|||
|
if Overwritten = 0 then
|
|||
|
begin
|
|||
|
Delete(SCell^.Loc);
|
|||
|
Change := True;
|
|||
|
end
|
|||
|
else begin
|
|||
|
CurrCell := SCell;
|
|||
|
CurrPos := CurrCell^.Loc;
|
|||
|
EndCol := SCell^.Loc.Col + Overwritten;
|
|||
|
Change := HashTable.Change;
|
|||
|
end;
|
|||
|
end; { OverwriteHashTable.Change }
|
|||
|
|
|||
|
function OverwriteHashTable.Search(SPos : CellPos) : CellPtr;
|
|||
|
var
|
|||
|
I : HashItemPtr;
|
|||
|
C : CellPtr;
|
|||
|
begin
|
|||
|
CurrPos := SPos;
|
|||
|
I := HashTable.Search;
|
|||
|
if I = nil then
|
|||
|
Search := Empty
|
|||
|
else begin
|
|||
|
Move(I^.Data, C, SizeOf(C));
|
|||
|
Search := C;
|
|||
|
end;
|
|||
|
end; { OverwriteHashTable.Search }
|
|||
|
|
|||
|
function OverwriteHashTable.HashValue : Word;
|
|||
|
begin
|
|||
|
HashValue := CurrPos.Row;
|
|||
|
end; { OverwriteHashTable.HashValue }
|
|||
|
|
|||
|
function OverwriteHashTable.Found(Item : HashItemPtr) : Boolean;
|
|||
|
var
|
|||
|
C : CellPtr;
|
|||
|
E : Word;
|
|||
|
begin
|
|||
|
Move(Item^.Data, C, SizeOf(C));
|
|||
|
Move(Item^.Data[SizeOf(C)], E, SizeOf(E));
|
|||
|
with CurrPos do
|
|||
|
Found := (Row = C^.Loc.Row) and (Col >= C^.Loc.Col) and
|
|||
|
(Col <= E);
|
|||
|
end; { OverwriteHashTable.Found }
|
|||
|
|
|||
|
procedure OverwriteHashTable.CreateItem(var Item : HashItemPtr);
|
|||
|
begin
|
|||
|
Move(CurrCell, Item^.Data, SizeOf(CurrCell));
|
|||
|
Move(EndCol, Item^.Data[SizeOf(CurrCell)], SizeOf(EndCol));
|
|||
|
end; { OverwriteHashTable.CreateItem }
|
|||
|
|
|||
|
function OverwriteHashTable.ItemSize : HashItemSizeRange;
|
|||
|
begin
|
|||
|
ItemSize := SizeOf(CurrCell) + SizeOf(EndCol);
|
|||
|
end; { OverwriteHashTable.ItemSize }
|
|||
|
|
|||
|
constructor Cell.Init(InitLoc : CellPos);
|
|||
|
{ Initializes a cell's location }
|
|||
|
begin
|
|||
|
Loc := InitLoc;
|
|||
|
end; { Cell.Init }
|
|||
|
|
|||
|
destructor Cell.Done;
|
|||
|
{ Frees memory used by the cell }
|
|||
|
begin
|
|||
|
end; { Cell.Done }
|
|||
|
|
|||
|
function Cell.CellType : CellTypes;
|
|||
|
{ Returns the type of a cell - used in copying cells }
|
|||
|
begin
|
|||
|
Abstract('Cell.CellType');
|
|||
|
end; { Cell.CellType }
|
|||
|
|
|||
|
function Cell.LegalValue : Boolean;
|
|||
|
{ Returns True if the cell has a legal numeric value }
|
|||
|
begin
|
|||
|
Abstract('Cell.LegalValue');
|
|||
|
end; { Cell.LegalValue }
|
|||
|
|
|||
|
function Cell.Name : String;
|
|||
|
{ Returns the name of the cell type }
|
|||
|
begin
|
|||
|
Abstract('Cell.Name');
|
|||
|
end; { Cell.Name }
|
|||
|
|
|||
|
function Cell.Format(var FHash : FormatHashTable; FormulasDisplayed : Boolean) :
|
|||
|
FormatType;
|
|||
|
{ Returns the format of a cell }
|
|||
|
begin
|
|||
|
Abstract('Cell.Format');
|
|||
|
end; { Cell.Format }
|
|||
|
|
|||
|
function Cell.Width(var FHash : FormatHashTable; FormulasDisplayed : Boolean) :
|
|||
|
Word;
|
|||
|
{ Returns the width of a cell (including the cells that it will overwrite) }
|
|||
|
begin
|
|||
|
Abstract('Cell.Width');
|
|||
|
end; { Cell.Width }
|
|||
|
|
|||
|
function Cell.Overwritten(var CHash : CellHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
var LastPos : CellPos;
|
|||
|
MaxCols : Word;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
FormulasDisplayed : Boolean) : Word;
|
|||
|
{ Calculates how many cells a cell will overwrite }
|
|||
|
begin
|
|||
|
Abstract('Cell.Overwritten');
|
|||
|
end; { Cell.Overwritten }
|
|||
|
|
|||
|
function Cell.ShouldUpdate : Boolean;
|
|||
|
{ Returns True if the cell needs to be updated when the spreadsheet changes }
|
|||
|
begin
|
|||
|
Abstract('Cell.ShouldUpdate');
|
|||
|
end; { Cell.ShouldUpdate }
|
|||
|
|
|||
|
function Cell.HasError : Boolean;
|
|||
|
{ Returns True if the cell has a numeric error in it }
|
|||
|
begin
|
|||
|
Abstract('Cell.HasError');
|
|||
|
end; { Cell.HasError }
|
|||
|
|
|||
|
function Cell.CurrValue : Extended;
|
|||
|
{ Returns the current numeric value of a cell }
|
|||
|
begin
|
|||
|
Abstract('Cell.CurrValue');
|
|||
|
end; { Cell.CurrValue }
|
|||
|
|
|||
|
function Cell.OverwriteStart(var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc; EndCol : Word;
|
|||
|
DisplayFormulas : Boolean) : Word;
|
|||
|
{ Determines, for overwritten cells, where in the overwriting data they will
|
|||
|
Start to display a value }
|
|||
|
begin
|
|||
|
Abstract('Cell.OverwriteStart');
|
|||
|
end; { Cell.OverwriteStart }
|
|||
|
|
|||
|
procedure Cell.EditString(MaxDecPlaces : Byte;
|
|||
|
var L : LStringPtr);
|
|||
|
{ Sets up a long string with the cell's value that can be edited }
|
|||
|
begin
|
|||
|
Abstract('Cell.EditString');
|
|||
|
end; { Cell.EditString }
|
|||
|
|
|||
|
function Cell.DisplayString(FormulasDisplayed : Boolean;
|
|||
|
MaxDecPlaces : Byte) : String;
|
|||
|
{ Returns the string that will be displayed just above the input line }
|
|||
|
begin
|
|||
|
Abstract('Cell.DisplayString');
|
|||
|
end; { Cell.DisplayString }
|
|||
|
|
|||
|
function Cell.FormattedString(var OHash : OverwriteHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
CPos : CellPos; FormulasDisplayed : Boolean;
|
|||
|
Start : Word; ColWidth : Byte;
|
|||
|
var DString : DollarStr;
|
|||
|
var Color : Byte) : String;
|
|||
|
{ Returns the string that will be printed in a cell }
|
|||
|
begin
|
|||
|
Abstract('Cell.FormattedString');
|
|||
|
end; { Cell.FormattedString }
|
|||
|
|
|||
|
function Cell.CopyString(ColLit, RowLit : Boolean; Diff : Longint;
|
|||
|
var L : LStringPtr) : LStringPtr;
|
|||
|
{ Copies a cell's string information to another cell's }
|
|||
|
begin
|
|||
|
Abstract('Cell.CopyString');
|
|||
|
end; { Cell.CopyString }
|
|||
|
|
|||
|
constructor EmptyCell.Init;
|
|||
|
var
|
|||
|
NewLoc : CellPos;
|
|||
|
begin
|
|||
|
NewLoc.Col := 0;
|
|||
|
NewLoc.Row := 0;
|
|||
|
Cell.Init(NewLoc);
|
|||
|
end; { EmptyCell.Init }
|
|||
|
|
|||
|
function EmptyCell.CellType : CellTypes;
|
|||
|
begin
|
|||
|
CellType := ClEmpty;
|
|||
|
end; { EmptyCell.CellType }
|
|||
|
|
|||
|
function EmptyCell.LegalValue : Boolean;
|
|||
|
begin
|
|||
|
LegalValue := True;
|
|||
|
end; { EmptyCell.LegalValue }
|
|||
|
|
|||
|
function EmptyCell.Name : String;
|
|||
|
begin
|
|||
|
Name := EmptyCellName;
|
|||
|
end; { EmptyCell.Name }
|
|||
|
|
|||
|
function EmptyCell.Format(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : FormatType;
|
|||
|
begin
|
|||
|
Format := 0;
|
|||
|
end; { EmptyCell.Format }
|
|||
|
|
|||
|
function EmptyCell.Width(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : Word;
|
|||
|
begin
|
|||
|
Width := 0;
|
|||
|
end; { EmptyCell.Width }
|
|||
|
|
|||
|
function EmptyCell.Overwritten(var CHash : CellHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
var LastPos : CellPos;
|
|||
|
MaxCols : Word;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
FormulasDisplayed : Boolean) : Word;
|
|||
|
begin
|
|||
|
Overwritten := 0;
|
|||
|
end; { EmptyCell.Overwritten }
|
|||
|
|
|||
|
function EmptyCell.ShouldUpdate : Boolean;
|
|||
|
begin
|
|||
|
ShouldUpdate := False;
|
|||
|
end; { EmptyCell.ShouldUpdate }
|
|||
|
|
|||
|
function EmptyCell.HasError : Boolean;
|
|||
|
begin
|
|||
|
HasError := False;
|
|||
|
end; { Cell.HasError }
|
|||
|
|
|||
|
function EmptyCell.CurrValue : Extended;
|
|||
|
begin
|
|||
|
CurrValue := 0;
|
|||
|
end; { EmptyCell.CurrValue }
|
|||
|
|
|||
|
function EmptyCell.OverwriteStart(var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
EndCol : Word;
|
|||
|
DisplayFormulas : Boolean) : Word;
|
|||
|
begin
|
|||
|
OverwriteStart := 1;
|
|||
|
end; { EmptyCell.OverwriteStart }
|
|||
|
|
|||
|
procedure EmptyCell.EditString(MaxDecPlaces : Byte;
|
|||
|
var L : LStringPtr);
|
|||
|
var
|
|||
|
Good : Boolean;
|
|||
|
begin
|
|||
|
Good := L^.FromString('');
|
|||
|
end; { EmptyCell.EditString }
|
|||
|
|
|||
|
function EmptyCell.DisplayString(FormulasDisplayed : Boolean;
|
|||
|
MaxDecPlaces : Byte) : String;
|
|||
|
begin
|
|||
|
DisplayString := '';
|
|||
|
end; { EmptyCell.DisplayString }
|
|||
|
|
|||
|
function EmptyCell.FormattedString(var OHash : OverwriteHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
CPos : CellPos;
|
|||
|
FormulasDisplayed : Boolean;
|
|||
|
Start : Word; ColWidth : Byte;
|
|||
|
var DString : DollarStr;
|
|||
|
var Color : Byte) : String;
|
|||
|
var
|
|||
|
CP : CellPtr;
|
|||
|
begin
|
|||
|
CP := OHash.Search(CPos);
|
|||
|
if CP <> Empty then
|
|||
|
FormattedString := CP^.FormattedString(OHash, FHash, WHash, GetColWidth,
|
|||
|
Loc, FormulasDisplayed,
|
|||
|
CP^.OverWriteStart(FHash, WHash,
|
|||
|
GetColWidth, CPos.Col,
|
|||
|
FormulasDisplayed), ColWidth,
|
|||
|
DString, Color)
|
|||
|
else begin
|
|||
|
FormattedString := '';
|
|||
|
DString := '';
|
|||
|
Color := Colors.BlankColor;
|
|||
|
end;
|
|||
|
end; { EmptyCell.FormattedString }
|
|||
|
|
|||
|
function EmptyCell.CopyString(ColLit, RowLit : Boolean; Diff : Longint;
|
|||
|
var L : LStringPtr) : LStringPtr;
|
|||
|
begin
|
|||
|
CopyString := L;
|
|||
|
end; { EmptyCell.CopyString }
|
|||
|
|
|||
|
constructor ValueCell.Init(InitLoc : CellPos; InitError : Boolean;
|
|||
|
InitValue : Extended);
|
|||
|
begin
|
|||
|
Cell.Init(InitLoc);
|
|||
|
Error := InitError;
|
|||
|
Value := InitValue;
|
|||
|
end; { ValueCell.Init }
|
|||
|
|
|||
|
function ValueCell.CellType : CellTypes;
|
|||
|
begin
|
|||
|
CellType := ClValue;
|
|||
|
end; { ValueCell.CellType }
|
|||
|
|
|||
|
function ValueCell.LegalValue : Boolean;
|
|||
|
begin
|
|||
|
LegalValue := True;
|
|||
|
end; { ValueCell.LegalValue }
|
|||
|
|
|||
|
function ValueCell.Name : String;
|
|||
|
begin
|
|||
|
Name := ValueCellName;
|
|||
|
end; { ValueCell.Name }
|
|||
|
|
|||
|
function ValueCell.Format(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : FormatType;
|
|||
|
var
|
|||
|
F : FormatType;
|
|||
|
begin
|
|||
|
if FHash.Search(Loc, F) then
|
|||
|
Format := F
|
|||
|
else
|
|||
|
Format := (Ord(JRight) shl 4) + 4;
|
|||
|
end; { ValueCell.Format }
|
|||
|
|
|||
|
function ValueCell.Width(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : Word;
|
|||
|
var
|
|||
|
S : String;
|
|||
|
F : FormatType;
|
|||
|
P, W : Word;
|
|||
|
begin
|
|||
|
F := Format(FHash, FormulasDisplayed);
|
|||
|
Str(Value:1:(F and DecPlacesPart), S);
|
|||
|
W := Length(S);
|
|||
|
if (F and DollarPart) <> 0 then
|
|||
|
Inc(W, Length(DollarString));
|
|||
|
if (F and CommasPart) <> 0 then
|
|||
|
begin
|
|||
|
P := Pos('.', S);
|
|||
|
if P = 0 then
|
|||
|
P := Length(S);
|
|||
|
Inc(W, (P - 2) div 3);
|
|||
|
end;
|
|||
|
Width := W;
|
|||
|
end; { ValueCell.Width }
|
|||
|
|
|||
|
function ValueCell.Overwritten(var CHash : CellHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
var LastPos : CellPos;
|
|||
|
MaxCols : Word;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
FormulasDisplayed : Boolean) : Word;
|
|||
|
var
|
|||
|
CellWidth : Longint;
|
|||
|
Total : Word;
|
|||
|
P : CellPos;
|
|||
|
begin
|
|||
|
P := Loc;
|
|||
|
CellWidth := Width(FHash, FormulasDisplayed);
|
|||
|
Total := 0;
|
|||
|
repeat
|
|||
|
Inc(Total);
|
|||
|
Dec(CellWidth, GetColWidth(WHash, P.Col));
|
|||
|
Inc(P.Col);
|
|||
|
until (CellWidth <= 0) or (P.Col = MaxCols) or (CHash.Search(P) <> Empty);
|
|||
|
Dec(Total);
|
|||
|
Overwritten := Total;
|
|||
|
end; { ValueCell.Overwritten }
|
|||
|
|
|||
|
function ValueCell.ShouldUpdate : Boolean;
|
|||
|
begin
|
|||
|
ShouldUpdate := False;
|
|||
|
end; { ValueCell.ShouldUpdate }
|
|||
|
|
|||
|
function ValueCell.HasError : Boolean;
|
|||
|
begin
|
|||
|
HasError := Error;
|
|||
|
end; { ValueCell.HasError }
|
|||
|
|
|||
|
function ValueCell.CurrValue : Extended;
|
|||
|
begin
|
|||
|
CurrValue := Value;
|
|||
|
end; { ValueCell.CurrValue }
|
|||
|
|
|||
|
function ValueCell.OverwriteStart(var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
EndCol : Word;
|
|||
|
DisplayFormulas : Boolean) : Word;
|
|||
|
var
|
|||
|
F : FormatType;
|
|||
|
C, Place : Word;
|
|||
|
begin
|
|||
|
F := Format(FHash, DisplayFormulas);
|
|||
|
Place := 1;
|
|||
|
C := Loc.Col;
|
|||
|
repeat
|
|||
|
Inc(Place, GetColWidth(WHash, C));
|
|||
|
Inc(C);
|
|||
|
until C = EndCol;
|
|||
|
if (F and DollarPart) <> 0 then
|
|||
|
Dec(Place, Length(DollarString));
|
|||
|
OverwriteStart := Place;
|
|||
|
end; { ValueCell.OverwriteStart }
|
|||
|
|
|||
|
procedure ValueCell.EditString(MaxDecPlaces : Byte;
|
|||
|
var L : LStringPtr);
|
|||
|
var
|
|||
|
S : String;
|
|||
|
Good : Boolean;
|
|||
|
begin
|
|||
|
Str(Value:1:MaxDecPlaces, S);
|
|||
|
Good := L^.FromString(S);
|
|||
|
end; { ValueCell.EditString }
|
|||
|
|
|||
|
function ValueCell.DisplayString(FormulasDisplayed : Boolean;
|
|||
|
MaxDecPlaces : Byte) : String;
|
|||
|
var
|
|||
|
S : String;
|
|||
|
begin
|
|||
|
Str(Value:1:MaxDecPlaces, S);
|
|||
|
DisplayString := S;
|
|||
|
end; { ValueCell.DisplayString }
|
|||
|
|
|||
|
function ValueCell.FormattedString(var OHash : OverwriteHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
CPos : CellPos;
|
|||
|
FormulasDisplayed : Boolean;
|
|||
|
Start : Word; ColWidth : Byte;
|
|||
|
var DString : DollarStr;
|
|||
|
var Color : Byte) : String;
|
|||
|
var
|
|||
|
Counter : Word;
|
|||
|
S : String;
|
|||
|
F : FormatType;
|
|||
|
begin
|
|||
|
F := Format(FHash, FormulasDisplayed);
|
|||
|
Str(Value:1:F and DecPlacesPart, S);
|
|||
|
if (Start = 1) and ((F and DollarPart) <> 0) then
|
|||
|
DString := ' $ '
|
|||
|
else
|
|||
|
DString := '';
|
|||
|
if (F and CommasPart) <> 0 then
|
|||
|
begin
|
|||
|
Counter := Pos('.', S);
|
|||
|
if Counter = 0 then
|
|||
|
Counter := System.Length(S);
|
|||
|
while Counter > 4 do
|
|||
|
begin
|
|||
|
System.Insert(',', S, Counter - 3);
|
|||
|
Dec(Counter, 3);
|
|||
|
end;
|
|||
|
end;
|
|||
|
Color := Colors.ValueCellColor;
|
|||
|
FormattedString := Copy(S, Start, ColWidth);
|
|||
|
end; { ValueCell.FormattedString }
|
|||
|
|
|||
|
function ValueCell.CopyString(ColLit, RowLit : Boolean; Diff : Longint;
|
|||
|
var L : LStringPtr) : LStringPtr;
|
|||
|
begin
|
|||
|
CopyString := L;
|
|||
|
end; { ValueCell.CopyString }
|
|||
|
|
|||
|
constructor ValueCell.Load(var S : SSStream);
|
|||
|
begin
|
|||
|
S.Read(Loc, SizeOf(Loc));
|
|||
|
S.Read(Error, SizeOf(Error));
|
|||
|
S.Read(Value, SizeOf(Value));
|
|||
|
end; { ValueCell.Load }
|
|||
|
|
|||
|
procedure ValueCell.Store(var S : SSStream);
|
|||
|
begin
|
|||
|
S.Write(Loc, SizeOf(Loc));
|
|||
|
S.Write(Error, SizeOf(Error));
|
|||
|
S.Write(Value, SizeOf(Value));
|
|||
|
end; { ValueCell.Store }
|
|||
|
|
|||
|
constructor TextCell.Init(InitLoc : CellPos; InitTxt : LStringPtr);
|
|||
|
begin
|
|||
|
Cell.Init(InitLoc);
|
|||
|
Txt := New(LStringPtr, Init);
|
|||
|
if Txt = nil then
|
|||
|
Fail;
|
|||
|
if not Txt^.Assign(InitTxt^) then
|
|||
|
begin
|
|||
|
Done;
|
|||
|
Fail;
|
|||
|
end;
|
|||
|
end; { TextCell.Init }
|
|||
|
|
|||
|
destructor TextCell.Done;
|
|||
|
begin
|
|||
|
Dispose(Txt, Done);
|
|||
|
end; { TextCell.Done }
|
|||
|
|
|||
|
function TextCell.CellType : CellTypes;
|
|||
|
begin
|
|||
|
CellType := ClText;
|
|||
|
end; { TextCell.CellType }
|
|||
|
|
|||
|
function TextCell.LegalValue : Boolean;
|
|||
|
begin
|
|||
|
LegalValue := False;
|
|||
|
end; { TextCell.LegalValue }
|
|||
|
|
|||
|
function TextCell.Name : String;
|
|||
|
begin
|
|||
|
Name := TextCellName;
|
|||
|
end; { TextCell.Name }
|
|||
|
|
|||
|
function TextCell.Format(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : FormatType;
|
|||
|
var
|
|||
|
F : FormatType;
|
|||
|
begin
|
|||
|
if FHash.Search(Loc, F) then
|
|||
|
Format := F
|
|||
|
else
|
|||
|
Format := 0;
|
|||
|
end; { TextCell.Format }
|
|||
|
|
|||
|
function TextCell.Width(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : Word;
|
|||
|
begin
|
|||
|
Width := Txt^.Length;
|
|||
|
end; { TextCell.Width }
|
|||
|
|
|||
|
function TextCell.Overwritten(var CHash : CellHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
var LastPos : CellPos;
|
|||
|
MaxCols : Word;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
FormulasDisplayed : Boolean) : Word;
|
|||
|
var
|
|||
|
CellWidth : Longint;
|
|||
|
Total : Word;
|
|||
|
P : CellPos;
|
|||
|
begin
|
|||
|
P := Loc;
|
|||
|
CellWidth := Width(FHash, FormulasDisplayed);
|
|||
|
Total := 0;
|
|||
|
repeat
|
|||
|
Inc(Total);
|
|||
|
Dec(CellWidth, GetColWidth(WHash, P.Col));
|
|||
|
Inc(P.Col);
|
|||
|
until (CellWidth <= 0) or (P.Col = MaxCols) or (CHash.Search(P) <> Empty);
|
|||
|
Dec(Total);
|
|||
|
Overwritten := Total;
|
|||
|
end; { TextCell.Overwritten }
|
|||
|
|
|||
|
function TextCell.ShouldUpdate : Boolean;
|
|||
|
begin
|
|||
|
ShouldUpdate := False;
|
|||
|
end; { TextCell.ShouldUpdate }
|
|||
|
|
|||
|
function TextCell.HasError : Boolean;
|
|||
|
begin
|
|||
|
HasError := False;
|
|||
|
end; { TextCell.HasError }
|
|||
|
|
|||
|
function TextCell.CurrValue : Extended;
|
|||
|
begin
|
|||
|
CurrValue := 0;
|
|||
|
end; { TextCell.CurrValue }
|
|||
|
|
|||
|
function TextCell.OverwriteStart(var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
EndCol : Word;
|
|||
|
DisplayFormulas : Boolean) : Word;
|
|||
|
var
|
|||
|
F : FormatType;
|
|||
|
C, Place : Word;
|
|||
|
begin
|
|||
|
F := Format(FHash, DisplayFormulas);
|
|||
|
Place := 1;
|
|||
|
C := Loc.Col;
|
|||
|
repeat
|
|||
|
Inc(Place, GetColWidth(WHash, C));
|
|||
|
Inc(C);
|
|||
|
until C = EndCol;
|
|||
|
OverwriteStart := Place;
|
|||
|
end; { TextCell.OverwriteStart }
|
|||
|
|
|||
|
procedure TextCell.EditString(MaxDecPlaces : Byte;
|
|||
|
var L : LStringPtr);
|
|||
|
var
|
|||
|
Good : Boolean;
|
|||
|
begin
|
|||
|
Good := L^.Assign(Txt^);
|
|||
|
end; { TextCell.EditString }
|
|||
|
|
|||
|
function TextCell.DisplayString(FormulasDisplayed : Boolean;
|
|||
|
MaxDecPlaces : Byte) : String;
|
|||
|
begin
|
|||
|
DisplayString := Txt^.Copy(2, Scr.CurrCols);
|
|||
|
end; { TextCell.DisplayString }
|
|||
|
|
|||
|
function TextCell.FormattedString(var OHash : OverwriteHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
CPos : CellPos;
|
|||
|
FormulasDisplayed : Boolean;
|
|||
|
Start : Word; ColWidth : Byte;
|
|||
|
var DString : DollarStr;
|
|||
|
var Color : Byte) : String;
|
|||
|
begin
|
|||
|
DString := '';
|
|||
|
Color := Colors.TextCellColor;
|
|||
|
FormattedString := Txt^.Copy(Succ(Start), ColWidth);
|
|||
|
end; { TextCell.FormattedString }
|
|||
|
|
|||
|
function TextCell.CopyString(ColLit, RowLit : Boolean; Diff : Longint;
|
|||
|
var L : LStringPtr) : LStringPtr;
|
|||
|
var
|
|||
|
Good : Boolean;
|
|||
|
begin
|
|||
|
Good := L^.Assign(Txt^);
|
|||
|
CopyString := L;
|
|||
|
end; { TextCell.CopyString }
|
|||
|
|
|||
|
constructor TextCell.Load(var S : SSStream);
|
|||
|
begin
|
|||
|
S.Read(Loc, SizeOf(Loc));
|
|||
|
Txt := New(LStringPtr, Init);
|
|||
|
if Txt = nil then
|
|||
|
begin
|
|||
|
S.Error(NoMemory);
|
|||
|
Exit;
|
|||
|
end;
|
|||
|
if not Txt^.FromStream(S) then
|
|||
|
begin
|
|||
|
Dispose(Txt, Done);
|
|||
|
S.Error(NoMemory);
|
|||
|
end;
|
|||
|
end; { TextCell.Load }
|
|||
|
|
|||
|
procedure TextCell.Store(var S : SSStream);
|
|||
|
begin
|
|||
|
S.Write(Loc, SizeOf(Loc));
|
|||
|
Txt^.ToStream(S);
|
|||
|
end; { TextCell.Store }
|
|||
|
|
|||
|
constructor FormulaCell.Init(InitLoc : CellPos; InitError : Boolean;
|
|||
|
InitValue : Extended; InitFormula : LStringPtr);
|
|||
|
begin
|
|||
|
Cell.Init(InitLoc);
|
|||
|
Formula := New(LStringPtr, Init);
|
|||
|
if Formula = nil then
|
|||
|
Fail;
|
|||
|
if not Formula^.Assign(InitFormula^) then
|
|||
|
begin
|
|||
|
Done;
|
|||
|
Fail;
|
|||
|
end;
|
|||
|
Error := InitError;
|
|||
|
Value := InitValue;
|
|||
|
end; { FormulaCell.Init }
|
|||
|
|
|||
|
destructor FormulaCell.Done;
|
|||
|
begin
|
|||
|
Dispose(Formula, Done);
|
|||
|
end; { FormulaCell.Done }
|
|||
|
|
|||
|
function FormulaCell.CellType : CellTypes;
|
|||
|
begin
|
|||
|
CellType := ClFormula;
|
|||
|
end; { FormulaCell.CellType }
|
|||
|
|
|||
|
function FormulaCell.LegalValue : Boolean;
|
|||
|
begin
|
|||
|
LegalValue := True;
|
|||
|
end; { FormulaCell.LegalValue }
|
|||
|
|
|||
|
function FormulaCell.Name : String;
|
|||
|
begin
|
|||
|
Name := FormulaCellName;
|
|||
|
end; { FormulaCell.Name }
|
|||
|
|
|||
|
function FormulaCell.Format(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : FormatType;
|
|||
|
var
|
|||
|
F : FormatType;
|
|||
|
begin
|
|||
|
if FHash.Search(Loc, F) then
|
|||
|
Format := F
|
|||
|
else if FormulasDisplayed then
|
|||
|
Format := 0
|
|||
|
else
|
|||
|
Format := (Ord(JRight) shl 4) + 4;
|
|||
|
end; { FormulaCell.Format }
|
|||
|
|
|||
|
function FormulaCell.Width(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : Word;
|
|||
|
var
|
|||
|
S : String;
|
|||
|
F : Byte;
|
|||
|
P, W : Word;
|
|||
|
begin
|
|||
|
if FormulasDisplayed then
|
|||
|
Width := Formula^.Length
|
|||
|
else begin
|
|||
|
F := Format(FHash, FormulasDisplayed);
|
|||
|
Str(Value:1:(F and DecPlacesPart), S);
|
|||
|
W := Length(S);
|
|||
|
if (F and DollarPart) <> 0 then
|
|||
|
Inc(W, Length(DollarString));
|
|||
|
if (F and CommasPart) <> 0 then
|
|||
|
begin
|
|||
|
P := Pos('.', S);
|
|||
|
if P = 0 then
|
|||
|
P := Length(S);
|
|||
|
Inc(W, (P - 2) div 3);
|
|||
|
end;
|
|||
|
Width := W;
|
|||
|
end;
|
|||
|
end; { FormulaCell.Width }
|
|||
|
|
|||
|
function FormulaCell.Overwritten(var CHash : CellHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
var LastPos : CellPos;
|
|||
|
MaxCols : Word;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
FormulasDisplayed : Boolean) : Word;
|
|||
|
var
|
|||
|
CellWidth : Longint;
|
|||
|
Total : Word;
|
|||
|
P : CellPos;
|
|||
|
begin
|
|||
|
P := Loc;
|
|||
|
CellWidth := Width(FHash, FormulasDisplayed);
|
|||
|
Total := 0;
|
|||
|
repeat
|
|||
|
Inc(Total);
|
|||
|
Dec(CellWidth, GetColWidth(WHash, P.Col));
|
|||
|
Inc(P.Col);
|
|||
|
until (CellWidth <= 0) or (P.Col = MaxCols) or (CHash.Search(P) <> Empty);
|
|||
|
Dec(Total);
|
|||
|
Overwritten := Total;
|
|||
|
end; { FormulaCell.Overwritten }
|
|||
|
|
|||
|
function FormulaCell.ShouldUpdate : Boolean;
|
|||
|
begin
|
|||
|
ShouldUpdate := True;
|
|||
|
end; { FormulaCell.ShouldUpdate }
|
|||
|
|
|||
|
function FormulaCell.HasError : Boolean;
|
|||
|
begin
|
|||
|
HasError := Error;
|
|||
|
end; { FormulaCell.HasError }
|
|||
|
|
|||
|
function FormulaCell.CurrValue : Extended;
|
|||
|
begin
|
|||
|
CurrValue := Value;
|
|||
|
end; { FormulaCell.CurrValue }
|
|||
|
|
|||
|
function FormulaCell.OverwriteStart(var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
EndCol : Word;
|
|||
|
DisplayFormulas : Boolean) : Word;
|
|||
|
var
|
|||
|
F : FormatType;
|
|||
|
C, Place : Word;
|
|||
|
begin
|
|||
|
F := Format(FHash, DisplayFormulas);
|
|||
|
Place := 1;
|
|||
|
C := Loc.Col;
|
|||
|
repeat
|
|||
|
Inc(Place, GetColWidth(WHash, C));
|
|||
|
Inc(C);
|
|||
|
until C = EndCol;
|
|||
|
if (not DisplayFormulas) and ((F and DollarPart) <> 0) then
|
|||
|
Dec(Place, Length(DollarString));
|
|||
|
OverwriteStart := Place;
|
|||
|
end; { FormulaCell.OverwriteStart }
|
|||
|
|
|||
|
procedure FormulaCell.EditString(MaxDecPlaces : Byte;
|
|||
|
var L : LStringPtr);
|
|||
|
var
|
|||
|
Good : Boolean;
|
|||
|
begin
|
|||
|
Good := L^.Assign(Formula^);
|
|||
|
end; { FormulaCell.EditString }
|
|||
|
|
|||
|
function FormulaCell.DisplayString(FormulasDisplayed : Boolean;
|
|||
|
MaxDecPlaces : Byte) : String;
|
|||
|
var
|
|||
|
S : String;
|
|||
|
begin
|
|||
|
if not FormulasDisplayed then
|
|||
|
DisplayString := Formula^.ToString
|
|||
|
else begin
|
|||
|
Str(Value:1:MaxDecPlaces, S);
|
|||
|
DisplayString := S;
|
|||
|
end;
|
|||
|
end; { FormulaCell.DisplayString }
|
|||
|
|
|||
|
function FormulaCell.FormattedString(var OHash : OverwriteHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
CPos : CellPos;
|
|||
|
FormulasDisplayed : Boolean;
|
|||
|
Start : Word; ColWidth : Byte;
|
|||
|
var DString : DollarStr;
|
|||
|
var Color : Byte) : String;
|
|||
|
var
|
|||
|
S : String;
|
|||
|
Counter : Word;
|
|||
|
F : FormatType;
|
|||
|
begin
|
|||
|
if FormulasDisplayed then
|
|||
|
begin
|
|||
|
DString := '';
|
|||
|
Color := Colors.FormulaCellColor;
|
|||
|
FormattedString := Formula^.Copy(1, ColWidth);
|
|||
|
end
|
|||
|
else begin
|
|||
|
F := Format(FHash, FormulasDisplayed);
|
|||
|
Str(Value:1:F and DecPlacesPart, S);
|
|||
|
if (Start = 1) and ((F and DollarPart) <> 0) then
|
|||
|
DString := ' $ '
|
|||
|
else
|
|||
|
DString := '';
|
|||
|
if (F and CommasPart) <> 0 then
|
|||
|
begin
|
|||
|
Counter := Pos('.', S);
|
|||
|
if Counter = 0 then
|
|||
|
Counter := Length(S);
|
|||
|
while Counter > 4 do
|
|||
|
begin
|
|||
|
Insert(',', S, Counter - 3);
|
|||
|
Dec(Counter, 3);
|
|||
|
end;
|
|||
|
end;
|
|||
|
Color := Colors.ValueCellColor;
|
|||
|
FormattedString := Copy(S, Start, ColWidth);
|
|||
|
end;
|
|||
|
end; { FormulaCell.FormattedString }
|
|||
|
|
|||
|
function FormulaCell.CopyString(ColLit, RowLit : Boolean; Diff : Longint;
|
|||
|
var L : LStringPtr) : LStringPtr;
|
|||
|
var
|
|||
|
Good : Boolean;
|
|||
|
begin
|
|||
|
Good := L^.Assign(Formula^);
|
|||
|
CopyString := L;
|
|||
|
end; { FormulaCell.CopyString }
|
|||
|
|
|||
|
constructor FormulaCell.Load(var S : SSStream);
|
|||
|
begin
|
|||
|
S.Read(Loc, SizeOf(Loc));
|
|||
|
Formula := New(LStringPtr, Init);
|
|||
|
if Formula = nil then
|
|||
|
begin
|
|||
|
S.Error(NoMemory);
|
|||
|
Exit;
|
|||
|
end;
|
|||
|
if not Formula^.FromStream(S) then
|
|||
|
begin
|
|||
|
Dispose(Formula, Done);
|
|||
|
S.Error(NoMemory);
|
|||
|
end;
|
|||
|
end; { FormulaCell.Load }
|
|||
|
|
|||
|
procedure FormulaCell.Store(var S : SSStream);
|
|||
|
begin
|
|||
|
S.Write(Loc, SizeOf(Loc));
|
|||
|
Formula^.ToStream(S);
|
|||
|
end; { FormulaCell.Store }
|
|||
|
|
|||
|
function FormulaCell.GetFormula : LStringPtr;
|
|||
|
begin
|
|||
|
GetFormula := Formula;
|
|||
|
end; { FormulaCell.GetFormula }
|
|||
|
|
|||
|
constructor RepeatCell.Init(InitLoc : CellPos; InitChar : Char);
|
|||
|
begin
|
|||
|
Cell.Init(InitLoc);
|
|||
|
RepeatChar := InitChar;
|
|||
|
end; { RepeatCell.Init }
|
|||
|
|
|||
|
function RepeatCell.CellType : CellTypes;
|
|||
|
begin
|
|||
|
CellType := ClRepeat;
|
|||
|
end; { RepeatCell.CellType }
|
|||
|
|
|||
|
function RepeatCell.LegalValue : Boolean;
|
|||
|
begin
|
|||
|
LegalValue := False;
|
|||
|
end; { RepeatCell.LegalValue }
|
|||
|
|
|||
|
function RepeatCell.Name : String;
|
|||
|
begin
|
|||
|
Name := RepeatCellName;
|
|||
|
end; { RepeatCell.Name }
|
|||
|
|
|||
|
function RepeatCell.Format(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : FormatType;
|
|||
|
begin
|
|||
|
Format := 0;
|
|||
|
end; { RepeatCell.Format }
|
|||
|
|
|||
|
function RepeatCell.Width(var FHash : FormatHashTable;
|
|||
|
FormulasDisplayed : Boolean) : Word;
|
|||
|
begin
|
|||
|
Width := 2;
|
|||
|
end; { RepeatCell.Width }
|
|||
|
|
|||
|
function RepeatCell.Overwritten(var CHash : CellHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
var LastPos : CellPos;
|
|||
|
MaxCols : Word;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
FormulasDisplayed : Boolean) : Word;
|
|||
|
var
|
|||
|
Total : Word;
|
|||
|
P : CellPos;
|
|||
|
begin
|
|||
|
P := Loc;
|
|||
|
Total := 0;
|
|||
|
repeat
|
|||
|
Inc(Total);
|
|||
|
Inc(P.Col);
|
|||
|
until (P.Col > LastPos.Col) or (CHash.Search(P) <> Empty) or
|
|||
|
(P.Col = 0);
|
|||
|
Dec(Total);
|
|||
|
if (P.Col > LastPos.Col) or (P.Col = 0) then
|
|||
|
Total := MaxCols - Loc.Col;
|
|||
|
Overwritten := Total;
|
|||
|
end; { RepeatCell.Overwritten }
|
|||
|
|
|||
|
function RepeatCell.ShouldUpdate : Boolean;
|
|||
|
begin
|
|||
|
ShouldUpdate := False;
|
|||
|
end; { RepeatCell.ShouldUpdate }
|
|||
|
|
|||
|
function RepeatCell.HasError : Boolean;
|
|||
|
begin
|
|||
|
HasError := False;
|
|||
|
end; { RepeatCell.HasError }
|
|||
|
|
|||
|
function RepeatCell.CurrValue : Extended;
|
|||
|
begin
|
|||
|
CurrValue := 0;
|
|||
|
end; { RepeatCell.CurrValue }
|
|||
|
|
|||
|
function RepeatCell.OverwriteStart(var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
EndCol : Word;
|
|||
|
DisplayFormulas : Boolean) : Word;
|
|||
|
begin
|
|||
|
OverwriteStart := 1;
|
|||
|
end; { RepeatCell.OverwriteStart }
|
|||
|
|
|||
|
procedure RepeatCell.EditString(MaxDecPlaces : Byte;
|
|||
|
var L : LStringPtr);
|
|||
|
var
|
|||
|
Good : Boolean;
|
|||
|
begin
|
|||
|
Good := L^.FromString(RepeatFirstChar + RepeatChar);
|
|||
|
end; { RepeatCell.EditString }
|
|||
|
|
|||
|
function RepeatCell.DisplayString(FormulasDisplayed : Boolean;
|
|||
|
MaxDecPlaces : Byte) : String;
|
|||
|
begin
|
|||
|
DisplayString := FillString(Scr.CurrCols, RepeatChar);
|
|||
|
end; { RepeatCell.DisplayString }
|
|||
|
|
|||
|
function RepeatCell.FormattedString(var OHash : OverwriteHashTable;
|
|||
|
var FHash : FormatHashTable;
|
|||
|
var WHash : WidthHashTable;
|
|||
|
GetColWidth : GetColWidthFunc;
|
|||
|
CPos : CellPos;
|
|||
|
FormulasDisplayed : Boolean;
|
|||
|
Start : Word; ColWidth : Byte;
|
|||
|
var DString : DollarStr;
|
|||
|
var Color : Byte) : String;
|
|||
|
begin
|
|||
|
DString := '';
|
|||
|
Color := Colors.RepeatCellColor;
|
|||
|
FormattedString := PadChar('', RepeatChar, ColWidth);
|
|||
|
end; { RepeatCell.FormattedString }
|
|||
|
|
|||
|
function RepeatCell.CopyString(ColLit, RowLit : Boolean; Diff : Longint;
|
|||
|
var L : LStringPtr) : LStringPtr;
|
|||
|
begin
|
|||
|
EditString(0, L);
|
|||
|
CopyString := L;
|
|||
|
end; { RepeatCell.CopyString }
|
|||
|
|
|||
|
constructor RepeatCell.Load(var S : SSStream);
|
|||
|
begin
|
|||
|
S.Read(Loc, SizeOf(Loc));
|
|||
|
S.Read(RepeatChar, SizeOf(RepeatChar));
|
|||
|
end; { RepeatCell.Load }
|
|||
|
|
|||
|
procedure RepeatCell.Store(var S : SSStream);
|
|||
|
begin
|
|||
|
S.Write(Loc, SizeOf(Loc));
|
|||
|
S.Write(RepeatChar, SizeOf(RepeatChar));
|
|||
|
end; { RepeatCell.Store }
|
|||
|
|
|||
|
{$F+}
|
|||
|
|
|||
|
procedure CellExit;
|
|||
|
{ Removes Empty cell from memory, restores ExitProc }
|
|||
|
begin
|
|||
|
Dispose(Empty, Done);
|
|||
|
ExitProc := SavedExitProc;
|
|||
|
end; { CellExit }
|
|||
|
|
|||
|
{$F-}
|
|||
|
|
|||
|
begin
|
|||
|
SavedExitProc := ExitProc;
|
|||
|
ExitProc := @CellExit;
|
|||
|
Empty := New(EmptyCellPtr, Init);
|
|||
|
end.
|
|||
|
|