⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 teestore.pas

📁 TeeChart7Source 控件
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{*********************************************}
{  TeeChart Storage functions                 }
{  Copyright (c) 1997-2004 by David Berneda   }
{  All rights reserved                        }
{*********************************************}
unit TeeStore;
{$I TeeDefs.inc}

interface

Uses {$IFNDEF LINUX}
     Windows,
     {$ENDIF}
     Classes,
     TeeProcs, TeEngine, Chart;

{ Read a Chart from a file (example: Chart1,'c:\demo.tee' ) }
Procedure LoadChartFromFile(Var AChart:TCustomChart; Const AFileName:String);

{ Write a Chart to a file (example: Chart1,'c:\demo.tee' ) }
Procedure SaveChartToFile(AChart:TCustomChart; Const AFileName:String;
                          IncludeData:Boolean=True;
                          TextFormat:Boolean=False);

{ The same using TStream components (good for BLOB fields, etc)  }
Procedure LoadChartFromStream(Var AChart:TCustomChart; AStream:TStream);

Procedure SaveChartToStream(AChart:TCustomChart; AStream:TStream;
                            IncludeData:Boolean=True;
                            TextFormat:Boolean=False);

{ (Advanced) Read charts and check for errors  }
{ return True if ok, False to stop loading }
type TProcTeeCheckError=function(const Message: string): Boolean of object;

Procedure LoadChartFromStreamCheck( Var AChart:TCustomChart;
                                    AStream:TStream;
                                    ACheckError:TProcTeeCheckError=nil;

                                    // For compatibility with version 5 saved
                                    // charts.
                                    // Pass FALSE to skip past-reading
                                    TryReadData:Boolean=True  // 6.01
                               );

Procedure LoadChartFromFileCheck( Var AChart:TCustomChart;
                                  Const AName:String;
                                  ACheckError:TProcTeeCheckError
                                  );

// Convert a binary *.tee file to text format
Procedure ConvertTeeFileToText(Const InputFile,OutputFile:String);

// Convert a text *.tee file to binary format
Procedure ConvertTeeFileToBinary(Const InputFile,OutputFile:String);

type
  TSeriesData=class(TTeeExportData)
  private
    FIncludeColors : Boolean;
    FIncludeIndex  : Boolean;
    FIncludeHeader : Boolean;
    FIncludeLabels : Boolean;
    FChart         : TCustomChart;
    FSeries        : TChartSeries;

    IFormat        : TeeFormatFlag;
    Procedure Prepare;
  protected
    Procedure GuessSeriesFormat; virtual;
    Function MaxSeriesCount:Integer;
    Function PointToString(Index:Integer):String; virtual;
  public
    Constructor Create(AChart:TCustomChart; ASeries:TChartSeries=nil); virtual;

    Function AsString:String; override;

    property Chart:TCustomChart read FChart write FChart;
    property IncludeColors:Boolean read FIncludeColors write FIncludeColors default False;
    property IncludeHeader:Boolean read FIncludeHeader write FIncludeHeader default False;
    property IncludeIndex:Boolean read FIncludeIndex write FIncludeIndex default False;
    property IncludeLabels:Boolean read FIncludeLabels write FIncludeLabels default True;
    property Series:TChartSeries read FSeries write FSeries;
  end;

  TSeriesDataText=class(TSeriesData)
  private
    FTextDelimiter : {$IFDEF CLX}WideChar{$ELSE}Char{$ENDIF};
    FTextQuotes    : String;
    FValueFormat   : String;
  protected
    procedure GuessSeriesFormat; override;  // 7.0
    Function PointToString(Index:Integer):String; override;
  public
    Constructor Create(AChart:TCustomChart;
                       ASeries:TChartSeries=nil); override;
    Function AsString:String; override;

    property TextDelimiter:{$IFDEF CLX}WideChar{$ELSE}Char{$ENDIF}
           read FTextDelimiter write FTextDelimiter default TeeTabDelimiter;
    property TextQuotes:String read FTextQuotes write FTextQuotes;  // 7.0
    property ValueFormat:String read FValueFormat write FValueFormat; // 7.0 #1249
  end;

  TSeriesDataXML=class(TSeriesData)
  private
    FEncoding : String;
    function DefaultEncoding:String;
    function IsEncodingStored:Boolean;
  public
    Constructor Create(AChart:TCustomChart; ASeries:TChartSeries=nil); override;
    Function AsString:String; override;
  published
    property Encoding:String read FEncoding write FEncoding stored IsEncodingStored;  // 7.0
    property IncludeHeader default True;
  end;

  TSeriesDataHTML=class(TSeriesData)
  protected
    Function PointToString(Index:Integer):String; override;
  public
    Function AsString:String; override;
  end;

  TSeriesDataXLS=class(TSeriesData)
  public
    Procedure SaveToStream(AStream:TStream); override;
  end;

Const TeeTextLineSeparator= #13#10;

// Makes sure AFileName contains the ".tee" extension
Function TeeCheckExtension(Const AFileName:String):String;

implementation

Uses {$IFDEF CLX}
     QGraphics, QClipbrd,
     {$ELSE}
     Graphics, Clipbrd,
     {$ENDIF}
     SysUtils,
     TeCanvas, TeeConst;

Const MagicTeeFile  =$3060;
      {$IFDEF D7}
      VersionTeeFile=$0157; { Delphi 7 }
      {$ELSE}
      {$IFDEF CLX}
      VersionTeeFile=$0145; { Delphi 6 CLX / Kylix }
      {$ELSE}
      {$IFDEF D6}
      VersionTeeFile=$0150; { Delphi 6 }
      {$ELSE}
      {$IFDEF C5}
      VersionTeeFile=$0140; { C++ Builder 5 }
      {$ELSE}
      {$IFDEF D5}
      VersionTeeFile=$0130; { Delphi 5 }
      {$ELSE}
      {$IFDEF C4}
      VersionTeeFile=$0125; { C++ Builder 4 }
      {$ELSE}
      {$IFDEF D4}
      VersionTeeFile=$0120; { Delphi 4 }
      {$ELSE}
      {$IFDEF C3}
      VersionTeeFile=$0110; { C++ Builder 3 }
      {$ELSE}
      VersionTeeFile=$0100; { Delphi 3 }
      {$ENDIF}
      {$ENDIF}
      {$ENDIF}
      {$ENDIF}
      {$ENDIF}
      {$ENDIF}
      {$ENDIF}
      {$ENDIF}


type
  TTeeFileHeader=Packed Record
    Magic   : Word; { secure checking }
    Version : Word; { Chart file version }
  end;

  TSeriesAccess=class(TChartSeries);

// compatibility with previous versions saved *.tee files
Procedure ReadChartData(AStream:TStream; AChart:TCustomChart);
Var t : Integer;
begin { read each Series data }
  for t:=0 to AChart.SeriesCount-1 do TSeriesAccess(AChart[t]).ReadData(AStream);
end;

{ Special reader to skip Delphi 3 or 4 new properties when
  reading Charts in Delphi 1.0 or 2.0 }
type 
  TChartReader=class(TReader)
  protected
    procedure FindMethodEvent(Reader: TReader; const MethodName: string;
                              var Address: {$IFDEF CLR}TMethodCode{$ELSE}Pointer{$ENDIF};
                              var Error: Boolean);
    function Error(const Message: string): Boolean; override;
  public
    CheckError:TProcTeeCheckError;
  end;

function TChartReader.Error(const Message: string): Boolean;
begin
  if Assigned(CheckError) then result:=CheckError(Message)
                          else result:=True;
end;

procedure TChartReader.FindMethodEvent(Reader: TReader; const MethodName: string;
                                       var Address: {$IFDEF CLR}TMethodCode{$ELSE}Pointer{$ENDIF}; 
                                       var Error: Boolean);
begin
  Error:=False;
end;

Procedure ReadHeader(Stream:TStream; var Header: TTeeFileHeader);
begin
  {$IFDEF CLR}
  Stream.Read(Header.Magic,SizeOf(Header.Magic));
  Stream.Read(Header.Version,SizeOf(Header.Version));
  {$ELSE}
  Stream.Read(Header,SizeOf(Header));
  {$ENDIF}
end;

function TeeFileIsValid(Stream:TStream):Boolean;
var Pos    : Integer;
    Header : TTeeFileHeader;
begin
  Pos := Stream.Position;
  ReadHeader(Stream,Header);
  { check is a valid Tee file }
  result:=Header.Magic=MagicTeeFile;
  if not result then
     result:={$IFDEF CLR}AnsiChar{$ELSE}Char{$ENDIF}(Header.Magic) in ['o','O'];
  Stream.Position := Pos;
end;

function TeeFileIsBinary(Stream:TStream):Boolean;
var Pos : Integer;
    Header  : TTeeFileHeader;
begin
  Pos := Stream.Position;
  ReadHeader(Stream,Header);
  { check is a valid Tee file }
  result:=Header.Magic=MagicTeeFile;
  Stream.Position := Pos;
end;

Procedure TeeWriteHeader(AStream:TStream);
var Header  : TTeeFileHeader;
begin
  { write file header, with "magic" number and version }
  Header.Magic:=MagicTeeFile;
  Header.Version:=VersionTeeFile;
  {$IFDEF CLR}
  AStream.Write(Header.Magic,SizeOf(Header.Magic));
  AStream.Write(Header.Version,SizeOf(Header.Version));
  {$ELSE}
  AStream.Write(Header,SizeOf(Header));
  {$ENDIF}
end;

Procedure ConvertTeeToBinary(SInput,SOutput:TStream);
begin
  if TeeFileIsValid(SInput) then
  begin
    if not TeeFileIsBinary(SInput) then
    begin
      TeeWriteHeader(SOutput);
      ObjectTextToBinary(SInput,SOutput);
    end
    else
       SOutput.CopyFrom(SInput,SInput.Size);
  end
  else Raise ChartException.Create(TeeMsg_WrongTeeFileFormat); { 5.01 }
end;

Procedure ConvertTeeToText(SInput,SOutput:TStream);
var Header  : TTeeFileHeader;
begin
  if TeeFileIsValid(SInput) then
  begin
    if TeeFileIsBinary(SInput) then
    begin
      ReadHeader(SInput,Header);
      ObjectBinaryToText(SInput,SOutput);
    end
    else SOutput.CopyFrom(SInput,SInput.Size);
  end
  else Raise ChartException.Create(TeeMsg_WrongTeeFileFormat); { 5.01 }
end;

{ Reads Series and Points from a Stream into a Chart }
Procedure LoadChartFromStreamCheck( Var AChart:TCustomChart;
                                    AStream:TStream;
                                    ACheckError:TProcTeeCheckError=nil;
                                    TryReadData:Boolean=True);
var Reader  : TChartReader;
    tmp     : TCustomChart;
    tmpName : TComponentName;
    DestStream : TStream;
    Header  : TTeeFileHeader;
begin

  { 5.01 commented: This allows saving more things to the AStream
                    before calling here.
  AStream.Position:=0; <--- commented out
  }

  if AStream.Size=0 then
     raise ChartException.Create(TeeMsg_EmptyTeeFile);

  if TeeFileIsValid(AStream) then
  begin
    { disable auto-repaint }
    AChart.AutoRepaint:=False;

    { remove all child Series and Tools }
    AChart.FreeAllSeries;
    AChart.Tools.Clear;

    DestStream:=AStream;

    if not TeeFileIsBinary(AStream) then
    begin
      AStream:=TMemoryStream.Create;
      ConvertTeeToBinary(DestStream,AStream);
      AStream.Position:=0;
    end;

    ReadHeader(AStream,Header);

    { read the Chart, Series and Tools properties }
    Reader:=TChartReader.Create(AStream, 4096);
    try
      Reader.OnFindMethod:=Reader.FindMethodEvent;

      Reader.CheckError:=ACheckError;
      tmp:=AChart;
      try
        tmpName:=tmp.Name; { 5.01 preserve the Chart Name }
        Reader.ReadRootComponent(AChart);
      finally
        AChart:=tmp;
      end;

      if tmpName<>'' then
         AChart.Name:=tmpName; { 5.01 set back the same Chart Name }
    finally
      Reader.Free;
    end;

    if Assigned(AChart) then
    begin
      // compatibility with previous versions saved *.tee files
      // read the Series points
      if TryReadData and (AStream.Size>AStream.Position) then
         ReadChartData(AStream,AChart);

      (*
      { change each Series ownership }
      { 5.01 Doing this breaks TeeFunction objects as DataSource !! }
      if AChart.Owner<>nil then
      for t:=0 to AChart.SeriesCount-1 do
      begin
        AChart[t].Owner.RemoveComponent(AChart[t]);
        AChart.Owner.InsertComponent(AChart[t]);
      end;
      *)

      { restore AutoRepaint }
      AChart.AutoRepaint:=True;
      AChart.Invalidate;
    end
    else raise ChartException.Create(TeeMsg_InvalidTeeFile);

    if DestStream<>AStream then AStream.Free;
  end
  else { is the Stream.Position maybe not zero ? }
    raise ChartException.Create(TeeMsg_WrongTeeFileFormat);
end;

Procedure LoadChartFromStream(Var AChart:TCustomChart; AStream:TStream);
begin
  LoadChartFromStreamCheck(AChart,AStream);
end;

Function TeeCheckExtension(Const AFileName:String):String;
begin  // Append ".tee" to filename if the extension is missing
  if ExtractFileExt(AFileName)='' then
     result:=AFileName+'.'+TeeMsg_TeeExtension
  else
     result:=AFileName;
end;

Procedure LoadChartFromFileCheck( Var AChart:TCustomChart;
                                  Const AName:String;
                                  ACheckError:TProcTeeCheckError );
Var tmp : TFileStream;
begin
  tmp:=TFileStream.Create(TeeCheckExtension(AName),fmOpenRead or fmShareDenyWrite);
  try
    LoadChartFromStreamCheck(AChart,tmp,ACheckError);
  finally
    tmp.Free;
  end;
end;

Procedure LoadChartFromFile(Var AChart:TCustomChart; Const AFileName:String);
begin
  LoadChartFromFileCheck(AChart,AFileName,nil);
end;

Procedure ConvertTeeFile(Const InputFile,OutputFile:String; ToText:Boolean);
var SInput  : TFileStream;
    SOutput : TFileStream;
begin
  SInput:=TFileStream.Create(InputFile,fmOpenRead);
  try
    SOutput:=TFileStream.Create(OutputFile,fmCreate);
    try
      if ToText then ConvertTeeToText(SInput,SOutput)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -