{********************************************}
{     TeeChart Pro Charting Library          }
{ Copyright (c) 1995-2020 by Steema Software }
{         All Rights Reserved                }
{********************************************}
unit TeeSourceEdit;
{$I TeeDefs.inc}

interface

uses {$IFNDEF LINUX}
     Windows, Messages,
     {$ENDIF}
     SysUtils, Classes,

     {$IFDEF D17}
     System.UITypes,
     {$ENDIF}
     
     Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,

     {$IFDEF LCL}
     Buttons,
     {$ENDIF}
     TeEngine, TeeProcs, TeCanvas, Chart;

type
  { special case for TFormDesigner in TeeCharteg unit }
  TAddComponentDataSource=Procedure( const AComponent:TComponent;
                                     const AItems:TStrings;
                                     AddCurrent:Boolean) of object;

  TOnGetDesignerNamesEvent=Procedure( const AProc:TAddComponentDataSource;
                                      const ASeries:TChartSeries;
                                      const AItems:TStrings;
                                      AddCurrent:Boolean);

  TBaseSourceEditor = class(TForm)
    LLabel: TLabel;
    CBSources: TComboFlat;
    Pan: TPanel;
    PanelApply: TPanel;
    BApply: TButton;
    procedure CBSourcesChange(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  protected
    Chart     : TCustomChart;
    TheSeries : TChartSeries;
    SkipValidation : Boolean;

    IDataSource : TTeeSeriesSource;

    Procedure AddComponentDataSource(const AComponent:TComponent;
                                     const AItems:TStrings;
                                     AddCurrent:Boolean);

    procedure CheckDataSource(SourceClass:TTeeSeriesSourceClass);
    procedure CheckReplaceSource(NewSource:TTeeSeriesSource);
    Function IsValid(AComponent:TComponent):Boolean; virtual;
  public
    { Public declarations }
    procedure Translate; dynamic;
  end;

implementation

{$IFNDEF LCL}
{$R *.DFM}
{$ELSE}
{$R *.lfm}
{$ENDIF}

uses
  TeeConst;

Procedure TBaseSourceEditor.AddComponentDataSource(const AComponent:TComponent;
                                                   const AItems:TStrings;
                                                   AddCurrent:Boolean);
var tmp         : String;
    tmpFormName : TComponentName;
begin
  if AItems.IndexOfObject(AComponent)=-1 then
  if AddCurrent or (TheSeries.DataSources.IndexOf(AComponent)=-1) then
  if IsValid(AComponent) then
     if SkipValidation or
        TheSeries.ParentChart.IsValidDataSource(TheSeries,AComponent) then
     begin
       if AComponent is TChartSeries then
          tmp:=SeriesTitleOrName(TChartSeries(AComponent))
       else
          tmp:=AComponent.Name;

       if (TheSeries.Owner<>AComponent.Owner) and
          Assigned(AComponent.Owner) then
       begin
         tmpFormName:=AComponent.Owner.Name;

         if tmpFormName<>'' then
            tmp:=tmpFormName+'.'+tmp;
       end;

       AItems.AddObject(tmp,AComponent);
     end;
end;

procedure TBaseSourceEditor.CBSourcesChange(Sender: TObject);
begin
  BApply.Enabled:=True;
end;

procedure TBaseSourceEditor.FormShow(Sender: TObject);
var tmp : TObject;
begin
  // Trick. Use the "Tag" property to receive either a Series or a Chart

  tmp:=TObject(Tag);
  if tmp is TChartSeries then
     TheSeries:=TChartSeries(tmp)
  else
  if tmp is TCustomChart then
     Chart:=TCustomChart(tmp)
  else
  if tmp is TTeeSeriesSource then
  begin
    IDataSource:=TTeeSeriesSource(tmp);
    TheSeries:=IDataSource.Series;
  end;

  BApply.Enabled:=False;
  TeeTranslateControl(Self);
end;

type
  TButtonAccess=class(TButton);

procedure TBaseSourceEditor.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
begin
  inherited;

  if BApply.Enabled then
  Case MessageDlg(TeeMsg_SureToApply,mtConfirmation,[mbYes,mbNo,mbCancel],0) of
    mrYes: begin
             TButtonAccess(BApply).Click;
             CanClose:=not BApply.Enabled;
           end;
     mrNo: begin
            BApply.Enabled:=False;
            CanClose:=True;
           end;
 mrCancel: CanClose:=False;
  end;
end;

function TBaseSourceEditor.IsValid(AComponent: TComponent): Boolean;
begin
  result:=False;
end;

procedure TBaseSourceEditor.CheckReplaceSource(
  NewSource: TTeeSeriesSource);
var tmpSource : TTeeSeriesSource;
begin
  // Pending Chart.DataSource:
  if Assigned(Chart) and (not Assigned(TheSeries)) then
     TheSeries:=Chart.AddSeries(TeeSeriesTypes[0].SeriesClass);

  if Assigned(TheSeries) and (TheSeries.DataSource<>NewSource) then
  begin
    { if the datasource is an internal "Series Source",
      remove and free it ! }
    if Assigned(TheSeries.DataSource) and
       (TheSeries.DataSource is TTeeSeriesSource) and
       (TheSeries.DataSource.Owner=TheSeries) then
    begin
      tmpSource:=TTeeSeriesSource(TheSeries.DataSource);
      tmpSource.Series:=nil;
      tmpSource.Free;
    end;

    TheSeries.DataSource:=nil;

    if not Assigned(NewSource.Series) then
       NewSource.Series:=TheSeries;

    TheSeries.DataSource:=NewSource;
  end;
end;

procedure TBaseSourceEditor.FormCreate(Sender: TObject);
begin
  SkipValidation:=False;
  Align:=alClient;
end;

procedure TBaseSourceEditor.Translate;
begin
  TeeTranslateControl(Self);
end;

procedure TBaseSourceEditor.CheckDataSource(SourceClass: TTeeSeriesSourceClass);
begin
  if (not Assigned(IDataSource)) and Assigned(TheSeries) then
  begin
    if Assigned(TheSeries.DataSource) and
       (TheSeries.DataSource is SourceClass) then
          IDataSource:=TTeeSeriesSource(TheSeries.DataSource);
  end;

  if not Assigned(IDataSource) then
  begin
    if Assigned(TheSeries) then
       IDataSource:=SourceClass.Create(TheSeries.Owner)
    else
       IDataSource:=SourceClass.Create(Self);

    IDataSource.Name:=TeeGetUniqueName(IDataSource.Owner,
         Copy(SourceClass.ClassName,2,Length(SourceClass.ClassName)));
  end;
end;

procedure TBaseSourceEditor.FormDestroy(Sender: TObject);
begin
  if Assigned(IDataSource) and
     (not Assigned(IDataSource.Series)) then
       if IDataSource.Owner=Self then
          IDataSource.Free;
end;

end.
