home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 October / Chip_2002-10_cd1.bin / zkuste / delphi / kolekce / d56 / FLEXCEL.ZIP / XLSAdapter / UXlsReferences.pas < prev    next >
Pascal/Delphi Source File  |  2002-07-01  |  7KB  |  255 lines

  1. unit UXlsReferences;
  2.  
  3. interface
  4. uses Classes, Sysutils, XlsMessages, UXlsBaseRecords, UXlsBaseRecordLists, UxlsBaseList;
  5. type
  6.  
  7.   TSupBookRecord  = class(TBaseRecord)
  8.     function IsLocal: boolean;
  9.     procedure InsertSheets(const SheetCount: word);
  10.   end;
  11.  
  12.   TExternSheetRecord = class(TBaseRecord)
  13.   end;
  14.  
  15.   TExternRef= class
  16.     SupBookRecord: Word;
  17.     FirstSheet, LastSheet: Word;
  18.     constructor Create(const aSupBookRecord, aFirstSheet, aLastSheet: word);
  19.     procedure SaveToStream(const DataStream: TStream);
  20.   end;
  21.  
  22.   TSupBookRecordList = class(TBaseRecordList)
  23.   {$INCLUDE inc\TSupBookRecordListHdr.inc}
  24.   end;
  25.  
  26.  
  27.  
  28.   TExternRefList= class(TBaseList)
  29.   {$INCLUDE inc\TExternRefListHdr.inc}
  30.     procedure Load(const aRecord: TExternSheetRecord);
  31.     procedure SaveToStream(const DataStream: TStream);
  32.     function TotalSize: int64;
  33.  
  34.     procedure InsertSheets(const BeforeSheet, SheetCount:word; LocalSupBook: integer);
  35.   end;
  36.  
  37.   TReferences = class
  38.   private
  39.     FSupBooks: TSupBookRecordList;
  40.     FExternRefs: TExternRefList;
  41.     LocalSupBook: integer;
  42.   public
  43.     constructor Create;
  44.     destructor Destroy; override;
  45.  
  46.     function TotalSize:int64;
  47.     procedure Clear;
  48.     procedure SaveToStream(const DataStream: TStream);
  49.  
  50.     procedure AddSupBook(const aRecord: TSupBookRecord);
  51.     procedure AddExternRef(const aRecord: TExternSheetRecord);
  52.  
  53.     procedure InsertSheets(const BeforeSheet, SheetCount: integer);
  54.     function GetSheet(const SheetRef: word): integer;
  55.     function SetSheet(const Sheet: word): integer;
  56.   end;
  57.  
  58. implementation
  59.  
  60. { TExternRefList }
  61.  
  62. {$INCLUDE inc\TExternRefListImp.inc}
  63.  
  64. procedure TExternRefList.InsertSheets(const BeforeSheet, SheetCount:word; LocalSupBook: integer);
  65. var
  66.   i:integer;
  67. begin
  68.   for i:=0 to Count-1 do
  69.     if Items[i].SupBookRecord= LocalSupBook then
  70.     begin
  71.       if (Items[i].FirstSheet<>$FFFF) and (Items[i].FirstSheet>=BeforeSheet) then IncMax(Items[i].FirstSheet, SheetCount, MaxSheets);
  72.       if (Items[i].LastSheet<>$FFFF) and (Items[i].LastSheet>=BeforeSheet) then IncMax(Items[i].LastSheet, SheetCount, MaxSheets);
  73.     end;
  74. end;
  75.  
  76. procedure TExternRefList.Load(const aRecord: TExternSheetRecord);
  77. var
  78.   n: word;
  79.   i: integer;
  80.   aPos: integer;
  81.   MyRecord: TBaseRecord;
  82.   Index, Fs, Ls: word;
  83. begin
  84.   n:=GetWord(aRecord.Data, 0);
  85.   aPos:=2; MyRecord:= aRecord;
  86.   for i:=0 to n-1 do
  87.   begin
  88.     ReadMem(MyRecord, aPos, 2, @Index);
  89.     ReadMem(MyRecord, aPos, 2, @Fs);
  90.     ReadMem(MyRecord, aPos, 2, @Ls);
  91.     Add(TExternRef.Create(Index,Fs,Ls));
  92.   end;
  93. end;
  94.  
  95. procedure TExternRefList.SaveToStream(const DataStream: TStream);
  96. var
  97.   RecordHeader: TRecordHeader;
  98.   i, k, Lines, CountRecords:integer;
  99.   MyCount: word;
  100. begin
  101.   MyCount:=Count;
  102.   if Count =0 then
  103.   begin
  104.     RecordHeader.Id:= xlr_EXTERNSHEET;
  105.     RecordHeader.Size:=2;
  106.     DataStream.Write(RecordHeader, SizeOf(RecordHeader));
  107.     DataStream.Write(MyCount, SizeOf(MyCount));
  108.     exit;
  109.   end;
  110.  
  111.   Lines:=(6* Count-1) div MaxExternSheetDataSize;
  112.   for i:= 0 to Lines do
  113.   begin
  114.     if i<Lines then CountRecords:= MaxExternSheetDataSize div 6
  115.       else CountRecords:=((6* Count-1) mod MaxExternSheetDataSize + 1) div 6 ;
  116.     RecordHeader.Size:= CountRecords*6;
  117.  
  118.     if i= 0 then
  119.     begin
  120.       RecordHeader.Id:= xlr_EXTERNSHEET;
  121.       inc(RecordHeader.Size,2);
  122.     end
  123.     else RecordHeader.Id:= xlr_CONTINUE;
  124.  
  125.     DataStream.Write(RecordHeader, SizeOf(RecordHeader));
  126.     if i=0 then DataStream.Write( MyCount, SizeOf (MyCount));
  127.  
  128.     for k:= i*(MaxExternSheetDataSize div 6) to i*(MaxExternSheetDataSize div 6)+CountRecords-1 do
  129.      Items[k].SaveToStream(DataStream);
  130.   end;
  131. end;
  132.  
  133. function TExternRefList.TotalSize: int64;
  134. begin
  135.   //Take in count Continues...
  136.   if Count=0 then Result:=2+SizeOf(TRecordHeader) else
  137.   Result:=2+ (((6* Count-1) div MaxExternSheetDataSize)+1)* SizeOf(TRecordHeader)  //header + continues
  138.           + 6*Count;
  139. end;
  140.  
  141.  
  142. { TSupBookRecordList }
  143.  
  144. {$INCLUDE inc\TSupBookRecordListImp.inc}
  145.  
  146. { TReferences }
  147.  
  148. procedure TReferences.AddExternRef(const aRecord: TExternSheetRecord);
  149. begin
  150.   FExternRefs.Load(aRecord);
  151. end;
  152.  
  153. procedure TReferences.AddSupBook(const aRecord: TSupBookRecord);
  154. begin
  155.   FSupBooks.Add(aRecord);
  156.   if aRecord.IsLocal then LocalSupBook:= FSupBooks.Count-1;
  157. end;
  158.  
  159. procedure TReferences.Clear;
  160. begin
  161.   if FSupbooks<>nil then FSupBooks.Clear;
  162.   if FExternRefs<>nil then FExternRefs.Clear;
  163.   LocalSupBook:=-1;
  164. end;
  165.  
  166. constructor TReferences.Create;
  167. begin
  168.   inherited;
  169.   FSupBooks:=TSupBookRecordList.Create;
  170.   FExternRefs:= TExternRefList.Create;
  171.   LocalSupBook:=-1;
  172. end;
  173.  
  174. destructor TReferences.Destroy;
  175. begin
  176.   FreeAndNil(FSupBooks);
  177.   FreeAndNil(FExternRefs);
  178.   inherited;
  179. end;
  180.  
  181. function TReferences.GetSheet(const SheetRef: word): integer;
  182. begin
  183.   if (FExternRefs[SheetRef].SupBookRecord = LocalSupBook) and
  184.      (FExternRefs[SheetRef].FirstSheet = FExternRefs[SheetRef].LastSheet) then
  185.  
  186.     Result:=FExternRefs[SheetRef].FirstSheet else Result:=-1;
  187. end;
  188.  
  189. procedure TReferences.InsertSheets(const BeforeSheet, SheetCount: integer);
  190. begin
  191.   FExternRefs.InsertSheets(BeforeSheet, SheetCount, LocalSupBook);
  192.   if LocalSupBook>=0 then FSupBooks[LocalSupBook].InsertSheets(SheetCount);
  193. end;
  194.  
  195. procedure TReferences.SaveToStream(const DataStream: TStream);
  196. begin
  197.   FSupBooks.SaveToStream(DataStream);
  198.   FExternRefs.SaveToStream(DataStream);
  199. end;
  200.  
  201. function TReferences.SetSheet(const Sheet: word): integer;
  202. var
  203.   i:integer;
  204. begin
  205.   for i:=0 to FExternRefs.Count-1 do
  206.     if (FExternRefs[i].SupBookRecord = LocalSupBook) and
  207.        (FExternRefs[i].FirstSheet = FExternRefs[i].LastSheet) and
  208.        (FExternRefs[i].FirstSheet = Sheet) then
  209.        begin
  210.          Result:=i;
  211.          exit;
  212.        end;
  213.  
  214.   //Ref doesnt exits...
  215.   FExternRefs.Add(TExternRef.Create(LocalSupBook, Sheet, Sheet));
  216.   Result:=FExternRefs.Count-1;
  217.  
  218. end;
  219.  
  220. function TReferences.TotalSize: int64;
  221. begin
  222.   Result:= FSupBooks.TotalSize+ FExternRefs.TotalSize;
  223. end;
  224.  
  225. { TExternRef }
  226.  
  227. constructor TExternRef.Create(const aSupBookRecord, aFirstSheet, aLastSheet: word);
  228. begin
  229.   SupBookRecord:=aSupBookRecord;
  230.   FirstSheet:=aFirstSheet;
  231.   LastSheet:=aLastSheet;
  232. end;
  233.  
  234. procedure TExternRef.SaveToStream(const DataStream: TStream);
  235. begin
  236.   DataStream.Write(SupBookRecord, SizeOf(SupBookRecord));
  237.   DataStream.Write(FirstSheet, SizeOf(FirstSheet));
  238.   DataStream.Write(LastSheet, SizeOf(LastSheet));
  239. end;
  240.  
  241. { TSupBookRecord }
  242.  
  243. procedure TSupBookRecord.InsertSheets(const SheetCount: word);
  244. begin
  245.   if not IsLocal then raise Exception.Create(ErrExcelInvalid);
  246.   IncWord(Data, 0, SheetCount, MaxSheets);
  247. end;
  248.  
  249. function TSupBookRecord.IsLocal: boolean;
  250. begin
  251.   IsLocal:= (DataSize = 4)and (GetWord (Data, 2)= $0401);
  252. end;
  253.  
  254. end.
  255.