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

  1. unit TemplateStore;
  2.  
  3. interface
  4. {$R XLSTemplateStore.res}
  5. uses
  6.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, contnrs,
  7.   axctrls, activex, ComObj, XlsMessages, UXlsOLEDoc;
  8.  
  9. type
  10.   TXlsStorageList=class;
  11.  
  12.   TXlsStorage = class
  13.   private
  14.     FCompress: boolean;
  15.     procedure SetCompress(const Value: boolean);
  16.   public
  17.     Name: string;
  18.     Data: TMemoryStream;
  19.     SubStorages: TXlsStorageList;
  20.  
  21.     property Compress: boolean read FCompress write SetCompress;
  22.  
  23.     constructor Create;
  24.     destructor Destroy;override;
  25.  
  26.     procedure WriteData(Stream: TStream);
  27.     procedure ReadData(Stream: TStream);
  28.  
  29.     procedure SaveToDoc( const DocOUT: IStorage);
  30.   end;
  31.  
  32.   TXlsStorageList=class(TObjectList)
  33.     Compress: boolean;
  34.     procedure WriteData(Stream: TStream);
  35.     procedure ReadData(Stream: TStream);
  36.     procedure LoadFrom(const aFileName: TFileName);
  37.   private
  38.     procedure LoadStorage(const DocIN: IStorage);
  39.     function GetItems(index: integer): TXlsStorage;
  40.     function GetStream(Name: widestring): TStream;
  41.   public
  42.     property Items[index: integer]: TXlsStorage read GetItems; default;
  43.     property Stream[Name: widestring]: TStream read GetStream;
  44.   end;
  45.  
  46.   TXlsTemplate= class (TCollectionItem)
  47.   private
  48.     FStorages: TXlsStorageList;
  49.     FFileName: TFileName;
  50.     FCompress: boolean;
  51.  
  52.     procedure SetFileName(const Value: TFileName);
  53.     procedure SetCompress(const Value: boolean);
  54.  
  55.     property Compress: boolean read FCompress write SetCompress;
  56.   protected
  57.     function GetDisplayName: string; override;
  58.     procedure SetDisplayName(const Value: string); override;
  59.  
  60.     procedure WriteData(Stream: TStream);
  61.     procedure ReadData(Stream: TStream);
  62.     procedure DefineProperties(Filer: TFiler); override;
  63.     function Equal(aTemplate: TXlsTemplate): Boolean;
  64.   public
  65.  
  66.     constructor Create(Collection: TCollection); override;
  67.     destructor Destroy; override;
  68.     property Storages: TXlsStorageList read FStorages;
  69.   published
  70.     property FileName: TFileName read FFileName write SetFileName stored false;
  71.   end;
  72.  
  73.   TXlsTemplateList=class(TOwnedCollection) //Items are TXlsTemplate
  74.   private
  75.     FCompress: boolean;
  76.     procedure SetCompress(const Value: boolean);
  77.     property Compress: boolean read FCompress write SetCompress;
  78.     function GetItems(Index: integer): TXlsTemplate;
  79.   public
  80.     property Items[Index: integer]: TXlsTemplate read GetItems; default;
  81.   end;
  82.  
  83.   TXlsTemplateStore = class(TComponent)
  84.   private
  85.     FCompress: boolean;
  86.     procedure SetCompress(const Value: boolean);
  87.     function GetStorages(Name: String): TXlsStorageList;
  88.     { Private declarations }
  89.   protected
  90.     FTemplates: TXlsTemplateList;
  91.     { Protected declarations }
  92.   public
  93.     { Public declarations }
  94.     constructor Create(AOwner: TComponent); override;
  95.     destructor Destroy;override;
  96.     property Storages[Name: String]: TXlsStorageList read GetStorages;
  97.   published
  98.     { Published declarations }
  99.     property Templates: TXlsTemplateList read FTemplates write FTemplates;
  100.     property Compress: boolean read FCompress write SetCompress;
  101.  
  102.  
  103.     //PENDING:AssignTo
  104.   end;
  105.  
  106. procedure Register;
  107.  
  108. implementation
  109. procedure Register;
  110. begin
  111.   RegisterComponents('FlexCel', [TXlsTemplateStore]);
  112. end;
  113.  
  114. { TXlsStorageList }
  115.  
  116. constructor TXlsStorage.Create;
  117. begin
  118.   inherited Create;
  119.   Data:= TMemoryStream.Create;
  120.   SubStorages:= TXlsStorageList.Create;
  121. end;
  122.  
  123. destructor TXlsStorage.Destroy;
  124. begin
  125.   FreeandNil(Data);
  126.   FreeAndNil(SubStorages);
  127.   inherited;
  128. end;
  129.  
  130. procedure TXlsStorage.ReadData(Stream: TStream);
  131. var
  132.   Ds: integer;
  133. begin
  134.   Stream.ReadBuffer(Ds, SizeOf(Ds));
  135.   SetLength(Name, Ds);
  136.   Stream.ReadBuffer(Name[1], Ds);
  137.   Stream.ReadBuffer(Ds, SizeOf(Ds));
  138.   Data.Size:=Ds;
  139.   Data.Position:=0;
  140.   Stream.Read(Data.Memory^, Ds);
  141.   SubStorages.ReadData(Stream);
  142. end;
  143.  
  144. procedure TXlsStorage.SaveToDoc(const DocOUT: IStorage);
  145. var
  146.   StreamOUT: IStream;
  147.   NewDocOUT: IStorage;
  148.   nw: Longint;
  149.   i:integer;
  150.   WideName: WideString;
  151. begin
  152.   WideName:=Name;
  153.   if Data.Size> 0 then
  154.   begin
  155.     OleCheck(DocOUT.CreateStream(PWideChar(WideName), OptionsWrite, 0, 0, StreamOUT));
  156.     try
  157.       OleCheck(StreamOUT.Write(Data.Memory, Data.Size, @nw));
  158.     finally
  159.       StreamOut:=nil;
  160.     end;
  161.   end else
  162.   if SubStorages.Count>0 then
  163.   begin
  164.     OleCheck(DocOUT.CreateStorage(PWideChar(WideName), OptionsWrite, 0, 0, NewDocOUT));
  165.     try
  166.       for i:=0 to SubStorages.Count-1 do (SubStorages[i] as TXlsStorage).SaveToDoc(NewDocOUT);
  167.     finally
  168.       NewDocOUT:=nil;
  169.     end;
  170.   end;
  171. end;
  172.  
  173. procedure TXlsStorage.SetCompress(const Value: boolean);
  174. begin
  175.   FCompress := Value;
  176.   SubStorages.Compress:=Value;
  177. end;
  178.  
  179. procedure TXlsStorage.WriteData(Stream: TStream);
  180. var
  181.   Ln: integer;
  182. begin
  183.   Ln:=Length(Name);
  184.   Stream.WriteBuffer(Ln, SizeOf(Ln));
  185.   Stream.WriteBuffer(Name[1], Ln);
  186.   Ln:=Data.Size;
  187.   Stream.WriteBuffer(Ln, SizeOf(Ln));
  188.   Data.Position:=0;
  189.   Stream.Write(Data.Memory^, Data.Size);
  190.   SubStorages.WriteData(Stream);
  191. end;
  192.  
  193. { TXlsStorageList }
  194.  
  195. procedure TXlsStorageList.LoadStorage(const DocIN: IStorage);
  196. var
  197.   NewDocIN: IStorage;
  198.   Enum: IEnumStatStg;
  199.   NumFetched: integer;
  200.   StatStg: TStatStg;
  201.   StreamIN: IStream;
  202.   OleStreamIn: TOleStream;
  203.   Malloc: IMalloc;
  204.   Stor: TXlsStorage;
  205.   //PENDING: Compress: TCompressionStream;
  206.  
  207. begin
  208.   OleCheck(CoGetMalloc(1, Malloc));
  209.   if DocIN.EnumElements(0, nil, 0, Enum) <> S_OK then
  210.   begin
  211.     DocIN.Stat(StatStg, 0);
  212.     try
  213.       raise Exception.CreateFmt(ErrCantReadFile, [StatStg.pwcsName]);
  214.     finally
  215.       Malloc.Free(StatStg.pwcsName);
  216.     end; //finally
  217.   end;
  218.  
  219.   while Enum.Next(1, StatStg, @NumFetched) = S_OK do
  220.   begin
  221.   try
  222.     case StatStg.dwType of
  223.       STGTY_STREAM:
  224.         begin
  225.           OleCheck(DocIN.OpenStream(StatStg.pwcsName, nil, OptionsRead, 0, StreamIN));
  226.           try
  227.             OleStreamIn:= TOleStream.Create(StreamIn);
  228.             try
  229.               Stor:=(Items[Add(TXlsStorage.Create)] as TXlsStorage);
  230.               try
  231. //                Compress:= TCompressionStream.Create(clMax, Stor.Data);
  232. //                Compress.CopyFrom(OleStreamIn, OleStreamIn.Size);
  233.                 Stor.Data.CopyFrom(OleStreamIn, OleStreamIn.Size);
  234.               finally
  235. //                FreeAndNil(Compress);
  236.               end; //finally
  237.               Stor.Name:=StatStg.pwcsName;
  238.             finally
  239.               FreeAndNil(OleStreamIn);
  240.             end; //finally
  241.           finally
  242.             StreamIN := nil;
  243.           end; //finally
  244.         end;
  245.  
  246.       STGTY_STORAGE:
  247.         begin
  248.           OleCheck(DocIN.OpenStorage(StatStg.pwcsName, nil, OptionsRead, nil, 0, NewDocIN));
  249.           try
  250.             Stor:=(Items[Add(TXlsStorage.Create)] as TXlsStorage);
  251.             Stor.Name:=StatStg.pwcsName;
  252.             Stor.SubStorages.LoadStorage(NewDocIN);
  253.           finally
  254.             NewDocIN := nil;
  255.           end; //finally
  256.         end;
  257.     end; //case
  258.   finally
  259.      Malloc.Free(StatStg.pwcsName);
  260.   end; //finally
  261.   end; //while
  262.  
  263. end;
  264.  
  265. procedure TXlsStorageList.LoadFrom(const aFileName: TFileName);
  266. var
  267.   WideFileName: WideString;
  268.   DocIN: IStorage;
  269. begin
  270.   Clear;
  271.   //Open template
  272.   WideFileName:=aFileName;
  273.  
  274.   if StgIsStorageFile(PWideChar(WideFileName)) <> S_OK then
  275.       raise Exception.CreateFmt(ErrFileIsNotXLS, [WideFileName]);
  276.  
  277.   OleCheck(StgOpenStorage(PWideChar(WideFileName), nil, OptionsRead, nil, 0, DocIN));
  278.   try
  279.     LoadStorage(DocIN);
  280.   finally
  281.     DocIN:=nil;
  282.   end;
  283. end;
  284.  
  285. procedure TXlsStorageList.ReadData(Stream: TStream);
  286. var
  287.   Cnt, i: integer;
  288. begin
  289.   Stream.Read(Cnt, sizeOf(Cnt));
  290.   Clear;
  291.   for i:=0 to Cnt-1 do
  292.    (Items[Add(TXlsStorage.Create)]as TXlsStorage).ReadData(Stream);
  293. end;
  294.  
  295. procedure TXlsStorageList.WriteData(Stream: TStream);
  296. var
  297.   i:integer;
  298. begin
  299.   Stream.Write(Count, SizeOf(Count));
  300.   for i:=0 to Count-1 do
  301.    (Items[i]as TXlsStorage).WriteData(Stream);
  302. end;
  303.  
  304. function TXlsStorageList.GetItems(index: integer): TXlsStorage;
  305. begin
  306.   Result:=inherited Items[index] as TXlsStorage;
  307. end;
  308.  
  309. function TXlsStorageList.GetStream(Name: widestring): TStream;
  310. var
  311.   i:integer;
  312. begin
  313.   for i:=0 to Count-1 do if Items[i].Name=Name then
  314.   begin
  315.     Result:= Items[i].Data;
  316.     exit;
  317.   end;
  318.   raise Exception.CreateFmt(ErrStreamNotFound,[Name]);
  319. end;
  320.  
  321. { TXlsTemplate }
  322.  
  323. constructor TXlsTemplate.Create(Collection: TCollection);
  324. begin
  325.   inherited;
  326.   FStorages:=TXlsStorageList.Create;
  327. end;
  328.  
  329. procedure TXlsTemplate.DefineProperties(Filer: TFiler);
  330.  
  331.   function DoWrite: Boolean;
  332.   begin
  333.     if Filer.Ancestor <> nil then
  334.       Result := not (Filer.Ancestor is TXlsTemplate) or
  335.         not Equal(TXlsTemplate(Filer.Ancestor))
  336.     else
  337.       Result := FFileName<>'';
  338.   end;
  339.  
  340. begin
  341.   inherited DefineProperties(Filer);
  342.   Filer.DefineBinaryProperty('TemplateData', ReadData, WriteData, DoWrite);
  343. end;
  344.  
  345. destructor TXlsTemplate.Destroy;
  346. begin
  347.   FreeAndNil(FStorages);
  348.   inherited;
  349. end;
  350.  
  351. function TXlsTemplate.Equal(aTemplate: TXlsTemplate): Boolean;
  352. begin
  353.   Result:=FFileName=aTemplate.FFileName;
  354. end;
  355.  
  356. function TXlsTemplate.GetDisplayName: string;
  357. begin
  358.   Result:=FFileName;
  359. end;
  360.  
  361. procedure TXlsTemplate.ReadData(Stream: TStream);
  362. var
  363.   Version: SmallInt;
  364.   Ln: integer;
  365. begin
  366.   Stream.ReadBuffer(Version, SizeOf(Version));
  367.   Stream.ReadBuffer(Ln, SizeOF(Ln));
  368.   SetLength(FFileName, Ln);
  369.   Stream.ReadBuffer(FFileName[1], Ln);
  370.   FStorages.ReadData(Stream);
  371. end;
  372.  
  373. procedure TXlsTemplate.SetCompress(const Value: boolean);
  374. var
  375.   i:integer;
  376. begin
  377.   FCompress := Value;
  378.   for i:=0 to FStorages.Count-1 do FStorages[i].Compress:=Value;
  379. end;
  380.  
  381. procedure TXlsTemplate.SetDisplayName(const Value: string);
  382. begin
  383.   inherited;
  384.   FileName:=Value;
  385. end;
  386.  
  387. procedure TXlsTemplate.SetFileName(const Value: TFileName);
  388. begin
  389.   FStorages.LoadFrom(Value);
  390.   FFileName := ExtractFileName(Value);
  391. end;
  392.  
  393. procedure TXlsTemplate.WriteData(Stream: TStream);
  394. var
  395.   Version: SmallInt;
  396.   Ln: integer;
  397. begin
  398.   Version:=1;
  399.   Stream.WriteBuffer(Version,SizeOf(Version));
  400.   Ln:=Length(FFileName);
  401.   Stream.WriteBuffer(Ln, SizeOf(Ln));
  402.   Stream.WriteBuffer(FFileName[1], Ln);
  403.   FStorages.WriteData(Stream);
  404. end;
  405.  
  406. { TXlsTemplateStore }
  407.  
  408. constructor TXlsTemplateStore.Create(AOwner: TComponent);
  409. begin
  410.   inherited;
  411.   FTemplates:= TXlsTemplateList.Create(Self, TXlsTemplate);
  412. end;
  413.  
  414. destructor TXlsTemplateStore.Destroy;
  415. begin
  416.   FreeAndNil(FTemplates);
  417.   inherited;
  418. end;
  419.  
  420. function TXlsTemplateStore.GetStorages(Name: String): TXlsStorageList;
  421. var
  422.   i: integer;
  423. begin
  424.   Name:= ExtractFileName(Name);
  425.   for i:=0 to Templates.Count -1 do if Templates[i].FileName=Name then
  426.   begin
  427.     Result:=Templates[i].Storages;
  428.     exit;
  429.   end;
  430.   raise Exception.CreateFmt(ErrFileNotFound, [Name]);
  431. end;
  432.  
  433. procedure TXlsTemplateStore.SetCompress(const Value: boolean);
  434. begin
  435.   FCompress := Value;
  436.   Templates.Compress:=Value;
  437. end;
  438.  
  439. { TXlsTemplateList }
  440.  
  441. function TXlsTemplateList.GetItems(Index: integer): TXlsTemplate;
  442. begin
  443.   Result:= inherited Items[Index] as TXlsTemplate;
  444. end;
  445.  
  446. procedure TXlsTemplateList.SetCompress(const Value: boolean);
  447. var
  448.   i:integer;
  449. begin
  450.   FCompress := Value;
  451.   for i:=0 to Count-1 do Items[i].Compress:=true;
  452. end;
  453.  
  454. end.
  455.