📄 tmsuescherrecords.pas
字号:
unit tmsUEscherRecords;
{$INCLUDE ..\FLXCOMPILER.INC}
interface
uses tmsXlsMessages, tmsUFlxMessages, tmsUXlsBaseRecords, Classes, SysUtils, Contnrs, tmsUXlsBaseClientData,
tmsUBreakList, tmsUXlsBaseList, tmsUOle2Impl;
type
TEscherRecordHeader= packed record
Pre, Id: word;
Size: Longint;
end;
TEscherRecord = class;
TEscherClientDataRecord = class;
TEscherClientAnchorRecord = class;
TEscherBStoreRecord = class;
TEscherDgRecord = class;
TEscherSolverContainerRecord = class;
TEscherDggRecord = class;
TEscherContainerRecord=class;
TEscherSpgrContainerRecord=class;
TEscherSPRecord=class;
TEscherOPTRecord= class;
TEscherRecordCache = class (TBaseList)
{$INCLUDE TEscherRecordCacheHdr.inc}
constructor Create;
procedure ArrangeInsertRowsAndCols(const aRowPos, aRowCount, aColPos, aColCount: integer; const SheetInfo: TSheetInfo; const Forced: boolean; const dSheet: TObject);
end;
TEscherObjCache = class (TEscherRecordCache)
{$INCLUDE TEscherObjCacheHdr.inc}
procedure ArrangeCopySheet(const SheetInfo: TSheetInfo);
end;
TEscherAnchorCache = class (TEscherRecordCache)
{$INCLUDE TEscherAnchorCacheHdr.inc}
end;
TEscherShapeCache = class (TEscherRecordCache)
{$INCLUDE TEscherShapeCacheHdr.inc}
end;
TEscherOPTCache = class (TEscherRecordCache)
{$INCLUDE TEscherOPTCacheHdr.inc}
end;
TEscherDwgCache = record
Destroying: boolean;
MaxObjId: word;
Dg: TEscherDgRecord;
Solver: TEscherSolverContainerRecord;
Patriarch: TEscherSpgrContainerRecord;
Anchor: TEscherAnchorCache;
Shape: TEscherShapeCache;
Obj: TEscherObjCache;
Blip: TEscherOPTCache;
end;
PEscherDwgCache=^TEscherDwgCache;
TEscherDwgGroupCache = record
BStore: TEscherBStoreRecord;
Dgg: TEscherDggRecord;
end;
PEscherDwgGroupCache=^TEscherDwgGroupCache;
//--------------------------------Base records---------------------------//
ClassOfTEscherRecord= class of TEscherRecord;
TEscherRecord= class
private
FParent: TEscherContainerRecord;
procedure IncNextPos(var NextPos: integer; const Size: integer; var RealSize: integer; const BreakList: TBreakList);
procedure CheckSplit(const DataStream: TOle2File; const BreakList: TBreakList);
procedure WriteNewRecord(const DataStream: TOle2File; const BreakList: TBreakList);
protected
DwgCache: PEscherDwgCache;
DwgGroupCache: PEscherDwgGroupCache;
public
Pre, Id: word;
TotalDataSize, LoadedDataSize: integer;
CopiedTo: TEscherRecord;
protected
function DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer; const dSheet: TObject): TEscherRecord; virtual;
function Instance: word;
function Version: word;
public
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord); virtual;
procedure AfterCreate; virtual;
procedure Load(var aRecord: TBaseRecord; var aPos: integer); virtual ; abstract;
procedure SaveToStream(const DataStream: TOle2File; const BreakList: TBreakList); virtual;
function CopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer; const dSheet: TObject): TEscherRecord; //this should be non-virtual
function TotalSizeNoSplit: int64;virtual;
function Loaded: boolean;virtual;
function IsContainer(const aPre: word): boolean;
function WaitingClientData(out ClientType: ClassOfTBaseClientData) : boolean; virtual;
procedure AssignClientData(const aClientData: TBaseClientData);virtual;
procedure SplitRecords(var NextPos, RealSize, NextDwg: integer;const BreakList: TBreakList);virtual;
procedure ArrangeInsertRowsAndCols(const aRowPos, aRowCount, aColPos, aColCount: integer; const SheetInfo: TSheetInfo; const Forced: boolean; const dSheet: TObject);virtual;
procedure ClearCopiedTo; virtual;
function FindRoot: TEscherRecord;
function FindRec(const RecClass: ClassOfTEscherRecord): TEscherRecord; virtual;
function Patriarch: TEscherSpgrContainerRecord;
function CopyDwg(const RowOfs, ColOfs: integer; const dSheet: TObject): TEscherRecord;
function CompareRec(const aRecord: TEscherRecord): integer; virtual;//this is used for searching
end;
TEscherRecordList= class (TBaseList)
private
{$INCLUDE TEscherRecordListHdr.inc}
public
procedure SaveToStream(const DataStream: TOle2File; const BreakList: TBreakList);
procedure CopyFrom(const aEscherRecordList: TEscherRecordList; const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer; const dSheet: TObject);
function TotalSizeNoSplit: int64;
end;
TEscherDataRecord= class(TEscherRecord)
protected
Data: PArrayOfByte;
function DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer; const dSheet: TObject): TEscherRecord; override;
public
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);override;
destructor Destroy; override;
procedure Load(var aRecord: TBaseRecord; var aPos: integer);override;
procedure SaveToStream(const DataStream: TOle2File; const BreakList: TBreakList); override;
function TotalSizeNoSplit: int64;override;
procedure SplitRecords(var NextPos, RealSize, NextDwg: integer; const BreakList: TBreakList);override;
function CompareRec(const aRecord: TEscherRecord): integer;override; //this is used for searching
procedure ClearData;
end;
TEscherContainerRecord=class(TEscherRecord)
protected
FContainedRecords: TEscherRecordList;
function DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer; const dSheet: TObject): TEscherRecord; override;
public
property ContainedRecords: TEscherRecordList read FContainedRecords;
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);override;
destructor Destroy; override;
procedure Load(var aRecord: TBaseRecord; var aPos: integer);override;
procedure SaveToStream(const DataStream: TOle2File; const BreakList: TBreakList); override;
function TotalSizeNoSplit: int64;override;
function WaitingClientData(out ClientType: ClassOfTBaseClientData): boolean;override;
procedure AssignClientData(const aClientData: TBaseClientData);override;
function LastRecord: TEscherRecord;
procedure SplitRecords(var NextPos, RealSize: integer; var NextDwg: integer; const BreakList: TBreakList);override;
procedure ArrangeInsertRowsAndCols(const aRowPos, aRowCount, aColPos, aColCount: integer; const SheetInfo: TSheetInfo; const Forced: boolean; const dSheet: TObject);override;
procedure ClearCopiedTo; override;
function FindRec(const RecClass: ClassOfTEscherRecord): TEscherRecord; override;
end;
TEscherSpContainerRecord=class(TEscherContainerRecord)
public
SP: TEscherSPRecord;
Opt: TEscherOPTRecord;
ClientAnchor: TEscherClientAnchorRecord;
function Row: integer;
function Col: integer;
end;
TEscherSpgrContainerRecord=class(TEscherContainerRecord)
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);override;
destructor Destroy; override;
end;
TEscherClientDataRecord= class(TEscherDataRecord)
public
ClientData: TBaseClientData;
protected
function DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer; const dSheet: TObject): TEscherRecord; override;
public
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);override;
constructor CreateFromData(const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache:PEscherDwgCache; const aParent: TEscherContainerRecord);
destructor Destroy; override;
procedure SaveToStream(const DataStream: TOle2File; const BreakList: TBreakList); override;
function TotalSizeNoSplit: int64;override;
function Loaded: boolean;override;
function WaitingClientData(out ClientType: ClassOfTBaseClientData): boolean;override;
procedure SplitRecords(var NextPos, RealSize: integer; var NextDwg: integer; const BreakList: TBreakList);override;
procedure AssignClientData(const aClientData: TBaseClientData);override;
procedure ArrangeCopyRowsAndCols(const RowOfs, ColOfs: integer);
procedure ArrangeInsertRowsAndCols(const aRowPos, aRowCount, aColPos, aColCount: integer; const SheetInfo: TSheetInfo; const Forced: boolean; const dSheet: TObject);override;
function ObjId: word;
end;
//------------------------------------Other records---------------------------//
TEscherSplitMenuRecord= class (TEscherDataRecord)
constructor CreateFromData(const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
end;
TAbsoluteAnchorRect = record
x1, x2, y1, y2: integer;
end;
TEscherClientAnchorRecord= class (TEscherDataRecord)
private
Anchor: PClientAnchor;
SaveRect: TAbsoluteAnchorRect;
public
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord); override;
constructor CreateFromData(const aAnchor: TClientAnchor;const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord; const sSheet: TObject);
destructor Destroy; override;
procedure ArrangeInsertRowsAndCols(const aRowPos, aRowCount, aColPos, aColCount: integer; const SheetInfo: TSheetInfo; const Forced: boolean; const dSheet: TObject);override;
function AllowCopy(const FirstRow, LastRow, FirstCol, LastCol: integer): boolean;
function AllowDelete(const FirstRow, LastRow, FirstCol, LastCol: integer): boolean;
function DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer; const dSheet: TObject): TEscherRecord; override;
function Row: integer;
function Col: integer;
function GetAnchor: TClientAnchor;
procedure SetAnchor(const aAnchor: TClientAnchor; const sSheet: TObject);
procedure RestoreObjectCoords(const dSheet: TObject);
procedure SaveObjectCoords(const sSheet: TObject);
end;
TEscherBStoreRecord= class (TEscherContainerRecord)
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord); override;
destructor Destroy; override;
procedure AddRef(const BlipPos: integer);
procedure Release(const BlipPos: integer);
procedure SaveToStream(const DataStream: TOle2File; const BreakList: TBreakList); override;
end;
TEscherBSERecord= class (TEscherDataRecord)
BStorePos: integer;
procedure AddRef;
procedure Release;
function References: LongWord;
function CompareRec(const aRecord: TEscherRecord): integer;override; //search by signature
procedure CopyFromData(const BSEHeader: Pointer; const BlipHeader: TEscherRecordHeader; const BlipData: TMemoryStream);
procedure SaveGraphicToStream(const aData:TStream; out aDataType: TXlsImgTypes);
end;
TDg= packed record
ShapeCount: LongWord;
MaxSpId: LongWord;
end;
PDg = ^TDg;
TEscherDgRecord= class(TEscherDataRecord)
private
Dg: PDg;
public
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord); override;
constructor CreateFromData(const csp, cspidCur: LongWord; const FirstShapeId: int64; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
destructor Destroy; override;
function DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer; const dSheet: TObject): TEscherRecord; override;
function IncMaxShapeId: LongWord;
procedure DecShapeCount;
end;
TDgg= packed record
MaxShapeId: LongWord;
FIDclCount: LongWord;
ShapesSaved: LongWord;
DwgSaved: LongWord;
end;
PDgg= ^TDgg;
TEscherDggRecord= class(TEscherDataRecord)
private
procedure GetNewCluster(var DgId: integer; const GetNewId: Boolean; const ShapeCount: int64; out FirstShapeId: int64);
public
FDgg: PDgg;
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord); override;
constructor CreateFromData(const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
destructor Destroy; override;
function AddImage(const DgId: integer; const LastImageId: Int64): Int64;
procedure AddNewCluster(DgId: integer; const ShapeCount: Int64; out FirstShapeId: Int64);
procedure DestroyClusters(const DgId: integer);
procedure GetNewDgIdAndCluster(out DgId: integer; out FirstShapeId: Int64);
function IsEmpty: Boolean;
procedure RemoveImage(const DgId: integer);
end;
PLongWord= ^LongWord;
TEscherSPRecord= class(TEscherDataRecord)
public
ShapeId: PLongWord;
protected
function DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer; const dSheet: TObject): TEscherRecord; override;
public
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord); override;
constructor CreateFromData(const Pre, aShapeId: LongWord; const Flags: LongWord; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
destructor Destroy; override;
end;
TEscherSolverContainerRecord = class (TEscherContainerRecord)
public
MaxRuleId: LongWord;
public
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord); override;
destructor Destroy; override;
function IncMaxRuleId: LongWord;
procedure CheckMax(const aRuleId: LongWord);
procedure DeleteRef(const Shape: TEscherSPRecord);
procedure FixPointers;
procedure ArrangeCopyRowsAndCols(const dSheet: TObject);
end;
TEscherOPTRecord= class (TEscherDataRecord)
private
BlipPtr: array of TEscherBSERecord;
BlipPos: array of LongWord;
FShapeName: UTF16String;
function GetShapeName: UTF16String;
function AddImg(const Data: ByteArray; const DataType: TXlsImgTypes): integer;
protected
function DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer; const dSheet: TObject): TEscherRecord;override;
public
constructor Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord); override;
constructor CreateFromDataImg(const aPict: ByteArray; const aPicType: TXlsImgTypes; const PicName: UTF16String; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
constructor CreateFromDataNote( const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord; const Dummy: integer=1);
constructor CreateFromDataAutoFilter( const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord; const Dummy1: integer = 1; Dummy2: integer=1);
constructor GroupCreateFromData(const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
destructor Destroy; override;
procedure AfterCreate;override;
property ShapeName: UTF16String read GetShapeName;
procedure SaveToStream(const DataStream: TOle2File; const BreakList: TBreakList); override;
function Row: integer;
function Col: integer;
function GetAnchor: TClientAnchor;
procedure SetAnchor(const aAnchor: TClientAnchor; const sSheet: TObject);
procedure ChangeRef(const aBSE: TEscherBSERecord);
procedure ReplaceImg(const Data: ByteArray; const DataType: TXlsImgTypes);
procedure GetImageFromStream(const Data: TStream; out DataType: TXlsImgTypes);
end;
implementation
uses tmsUXlsClientData,tmsUEscherOtherRecords,tmsUEscherGraphToBSE, tmsUXlsSheet;
{ TEscherRecordCache }
{$INCLUDE TEscherRecordCacheImp.inc}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -