Jump to content

About SubComponents


RafaelW

Recommended Posts

Hello, i trying to implement a new component Edit with aside button..

 

And internally already implemented OnClick.

 

But this OnClick method is never called.

 

here is the code :

 

for compile the PLUniPesquisa can be removed...

 

 

 

unit PLUniEdit;

interface

uses
  SysUtils, Classes, Controls, StdCtrls, Messages, PLUniSeekButton, Db, Datasnap.DBClient,
  Windows, Forms, Graphics, PLUniUtils, Math, StrUtils, Variants,
  PesquisaConfig, Vcl.ExtCtrls, PLUniPesquisa, System.TypInfo, uniEdit;

type
  TPLUniEditKeyValueChange = procedure(Sender: TObject; Value: Variant) of object;
  TPLUniEdit = class(TUniEdit)
  private
    fKeyValue: string;
    FBtn: TPLUniSeekButton;
    FOnExit: TNotifyEvent;
    FOnKeyValueChange: TPLUniEditKeyValueChange;
    FVisibleButton: Boolean;
    fPesquisa: TPesquisaConfig;
    fRequired: boolean;
    fOnClickButton: TNotifyEvent;
    FControlsOtherFields: TStrings;
    fOtherFieldsRecursive: Boolean;

    function getCtl3D: boolean;
    function getLeft: integer;
    function getTop: integer;
    function getWidth: integer;

    procedure setKeyValue(const Value: string);
    procedure AutoFit;
    procedure SetupInternalButton;
    procedure setCtl3D(const Value: boolean);
    procedure setLeft(const Value: integer);
    procedure setTop(const Value: integer);
    procedure setWidth(const Value: integer);
    procedure SetOnKeyValueChange(const Value: TPLUniEditKeyValueChange);
    procedure SetVisibleButton(const Value: Boolean);
    procedure setPesquisa(Sender: TObject);
    procedure SetControlsOtherFields(const Value: TStrings);

    procedure ValidatePesquisa;
  protected
    procedure Loaded; override;
    procedure OnPLExit( sender: TObject ); virtual;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure SetParent(AParent: TWinControl); override;

    procedure SetName(const Value: TComponentName); override;

    procedure OnClickBtn(Sender: TObject);

    procedure PopulateDataFromPesquisa(ReturnDataset: TClientDataset; Clear: Boolean);
    procedure PopulateOtherControls(control: TPLUniEdit; ReturnDataset: TClientDataset; Clear: Boolean);
  public
    property KeyValue: string read fKeyValue write setKeyValue;

    procedure SetBounds(ALeft: Integer; ATop: Integer; AWidth: Integer; AHeight: Integer); override;


    constructor Create(AOwner: TComponent); override;

    destructor Destroy; override;

    procedure GetUniqueValue;

  published
    property OnExit : TNotifyEvent read FOnExit write FOnExit;
    property OnClickButton: TNotifyEvent read fOnClickButton write fOnClickButton;
    property OnKeyValueChange: TPLUniEditKeyValueChange read FOnKeyValueChange write SetOnKeyValueChange;

    property Required : boolean read fRequired write fRequired default false;
    property Pesquisa: TPesquisaConfig read fPesquisa write fPesquisa;
    property Button : TPLUniSeekButton read FBtn;
    property Top : integer read getTop write setTop;
    property Left : integer read getLeft write setLeft;
    property Ctl3D : boolean read getCtl3D write setCtl3D;
    property Width : integer read getWidth write setWidth;

    property VisibleButton : Boolean read FVisibleButton write SetVisibleButton default False;

    property ControlsOtherFields: TStrings read FControlsOtherFields write SetControlsOtherFields;
    property OtherFieldsRecursive: Boolean read fOtherFieldsRecursive write fOtherFieldsRecursive default True;
  end;

implementation

procedure TPLUniEdit.AutoFit;
begin
  if assigned(FBtn) then
  begin
    FBtn.Top := Top;
    FBtn.Left := Left+Width+1;

    if FBtn.Visible then
    begin
      FBtn.Width := Height;
      FBtn.Height := Height;
    end;

    if assigned(FBtn.JSControl) then
      FBtn.JSControl.SetPosition(FBtn.Left, FBtn.Top);
  end;
end;

constructor TPLUniEdit.Create(AOwner: TComponent);
begin
  inherited Create( AOwner );

  inherited OnExit := OnPLExit;

  fPesquisa := TPesquisaConfig.Create;
  fPesquisa.NotifyPesquisa := setPesquisa;

  self.Ctl3D := False;
  SetupInternalButton;

  TEdit(self).Modified := False;
  fVisibleButton := False;
  fRequired := False;

  FControlsOtherFields := TStringList.Create;
  fOtherFieldsRecursive := True;
end;

destructor TPLUniEdit.Destroy;
begin
  if Assigned(fPesquisa) then
    FreeAndNil(fPesquisa);

  if Assigned(FControlsOtherFields) then
    FControlsOtherFields.Free;

  inherited;
end;

function TPLUniEdit.getCtl3D: boolean;
begin
  result := inherited Ctl3D;
end;

function TPLUniEdit.getLeft: integer;
begin
  Result := inherited Left;
end;

function TPLUniEdit.getTop: integer;
begin
  Result := inherited Top;
end;

procedure TPLUniEdit.GetUniqueValue;
begin
  if (not FVisibleButton) and Assigned(fPesquisa.Pesquisa) then
  begin
    ValidatePesquisa;

    fPesquisa.Pesquisa.BackupConfiguration;
    try
      fPesquisa.Pesquisa.AOWner := self.Owner;
      fPesquisa.Pesquisa.SQL.Text := fPesquisa.SQL.Text;
      fPesquisa.Pesquisa.TagToUpdate := self.Tag;
      fPesquisa.Pesquisa.ExecSQLOnStart := True;

      fPesquisa.Pesquisa.KeyField := getPesquisaFieldId(nil, fPesquisa.FieldId, self);
      fPesquisa.Pesquisa.Column := IfThen(fPesquisa.FieldSearch.IsEmpty, fPesquisa.FieldDisplay, fPesquisa.FieldSearch);

      if not self.KeyValue.IsEmpty then
      begin
        fPesquisa.Pesquisa.Column := fPesquisa.Pesquisa.KeyField;
        fPesquisa.Pesquisa.Value  := self.KeyValue;
      end
      else
      if not trim(self.Text).IsEmpty then
      begin
        fPesquisa.Pesquisa.Column := IfThen(fPesquisa.FieldSearch.IsEmpty, fPesquisa.FieldDisplay, fPesquisa.FieldSearch);
        fPesquisa.Pesquisa.Value  := self.KeyValue;
      end;

      fPesquisa.Pesquisa.MethodAtualizaComp := PopulateDataFromPesquisa;
      fPesquisa.Pesquisa.Execute(True);
    finally
      fPesquisa.Pesquisa.RestoreConfiguration;
    end;
  end;
end;

function TPLUniEdit.getWidth: integer;
begin
  Result := inherited Width;
end;


procedure TPLUniEdit.Loaded;
begin
  inherited;
  FBtn.Visible := Visible and (assigned(fPesquisa.Pesquisa) or FVisibleButton);

  if FBtn.Visible then
  begin
    self.Button.OnClick := self.OnClickBtn;
  end;
end;

procedure TPLUniEdit.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);

  if (AComponent = FBtn) and (Operation = opRemove) then
    FBtn := nil;

end;

procedure TPLUniEdit.OnClickBtn(Sender: TObject);
begin
  if self.ReadOnly then
    Exit;

  if (not FVisibleButton) and assigned(fPesquisa.Pesquisa) then
  begin

      ValidatePesquisa;

      fPesquisa.Pesquisa.BackupConfiguration;
      try
        if self.CanFocus then
          self.SetFocus;

        fPesquisa.Pesquisa.SQL.Text := fPesquisa.SQL.Text;
        fPesquisa.Pesquisa.KeyField := fPesquisa.FieldId;
        fPesquisa.Pesquisa.Column   :=
          IfThen(fPesquisa.FieldSearch.IsEmpty, fPesquisa.FieldDisplay, fPesquisa.FieldSearch);

        fPesquisa.Pesquisa.TitlePesquisa :=
          ifthen(self.FieldLabel.IsEmpty, self.EmptyText, self.FieldLabel);
        fPesquisa.Pesquisa.Value         := self.Text;
        fPesquisa.Pesquisa.AOWner        := self.Owner;
        fPesquisa.Pesquisa.ForcePesquisa := True;
        fPesquisa.Pesquisa.TagToUpdate   := self.Tag;

        fPesquisa.Pesquisa.MethodAtualizaComp := PopulateDataFromPesquisa;
        fPesquisa.Pesquisa.Execute;
      finally
        fPesquisa.Pesquisa.RestoreConfiguration;
      end;

  end
  else
  begin
    if Assigned(fOnClickButton) then
      fOnClickButton(Self);
  end;
end;

procedure TPLUniEdit.onPLExit(sender: TObject);
begin
  if Assigned(FOnExit) then
    FOnExit(Sender);

  if fRequired and trim(self.Text).IsEmpty then
    raise Exception.Create(
      ifthen(self.FieldLabel.IsEmpty, self.EmptyText, self.FieldLabel)+' é um campo obrigatório.');

  if (not FVisibleButton) and Assigned(fPesquisa.Pesquisa) then
  begin
    ValidatePesquisa;

    if TEdit(self).Modified then
    begin
      fPesquisa.Pesquisa.BackupConfiguration;
      try
        fPesquisa.Pesquisa.SQL.Text := fPesquisa.SQL.Text;

        fPesquisa.Pesquisa.Value    := self.Text;
        fPesquisa.Pesquisa.AOWner   := self.Owner;
        fPesquisa.Pesquisa.KeyField := getPesquisaFieldId(nil, fPesquisa.FieldId, self);
        fPesquisa.Pesquisa.Column   := IfThen(fPesquisa.FieldSearch.IsEmpty, fPesquisa.FieldDisplay, fPesquisa.FieldSearch);

        fPesquisa.Pesquisa.TagToUpdate := self.Tag;

        fPesquisa.Pesquisa.MethodAtualizaComp := PopulateDataFromPesquisa;

        if not trim(self.Text).IsEmpty then
          fPesquisa.Pesquisa.Execute
        else
        begin
          self.Clear;
          fPesquisa.Pesquisa.LimpaTela;
          PopulateOtherControls(Self, fPesquisa.Pesquisa.ResultDataSet, True);
        end;
      finally
        fPesquisa.Pesquisa.RestoreConfiguration;
      end;
    end;
  end;
end;

procedure TPLUniEdit.PopulateDataFromPesquisa(ReturnDataset: TClientDataset; Clear: Boolean);
var IdFieldName: string;
begin
  // Key Value

  IdFieldName := getPesquisaFieldId(ReturnDataset, fPesquisa.FieldId, self);

  if (not VarIsNull(ReturnDataset.FieldByName(IdFieldName).Value)) and (not Clear) then
    self.KeyValue := ReturnDataset.FieldByName(IdFieldName).Value
  else
    self.KeyValue := '';

  // Display Value

  if not Assigned(ReturnDataset.FindField(self.Pesquisa.FieldDisplay)) then
    raise Exception.Create('O campo da propriedade '+
                            self.Name+'.Pesquisa.FieldDisplay='+self.Pesquisa.FieldDisplay.ToUpper+' não existe no SQL ou na tabela/view em '+
                            self.Name+'.Pesquisa.SQL');

  if (not VarIsNull(ReturnDataset.FieldByName(self.Pesquisa.FieldDisplay).Value)) and (not Clear) and (not KeyValue.IsEmpty) then
    self.Text := ReturnDataset.FieldByName(self.Pesquisa.FieldDisplay).Value
  else
    self.Text := '';

  // Campos configurados para receberem valor além de CHAVE e DISPLAY
  PopulateOtherControls(Self, ReturnDataset, Clear);
end;

procedure TPLUniEdit.PopulateOtherControls(control: TPLUniEdit; ReturnDataset: TClientDataset; Clear: Boolean);
var i: Integer;
    otherControl: TComponent;
begin
  if (control.Pesquisa.OtherFields.Count > 0) then
  begin
    for i := 0 to control.Pesquisa.OtherFields.Count-1 do
    begin
      if (control.Owner <> nil) then
      begin
        otherControl := control.Owner.FindComponent(control.ControlsOtherFields[i]);

        if Assigned(otherControl) and (otherControl is TPLUniEdit) then
        begin
          if Assigned( ReturnDataset.FindField( control.Pesquisa.OtherFields[i] ) ) and (not clear) then
          begin
            if not TPLUniEdit(otherControl).Pesquisa.FieldId.IsEmpty then
              TPLUniEdit(otherControl).KeyValue := VarToStrDef(ReturnDataset.FieldByName(TPLUniEdit(otherControl).Pesquisa.FieldId).Value,'');

            TPLUniEdit(otherControl).Text := VarToStrDef(ReturnDataset.FieldByName(control.Pesquisa.OtherFields[i]).Value,'');

            if control.OtherFieldsRecursive then
               PopulateOtherControls(otherControl as TPLUniEdit, ReturnDataset, Clear);
          end
          else
            TPLUniEdit(otherControl).Clear;
        end;

        if Assigned(otherControl) and (otherControl is TLabel) then
          if not clear then
            TLabel(otherControl).Caption := VarToStrDef(ReturnDataset.FieldByName(control.Pesquisa.OtherFields[i]).Value,'')
          else
            TLabel(otherControl).Caption := EmptyStr;

        if Assigned(otherControl) and (otherControl is TStaticText) then
          if not clear then
            TStaticText(otherControl).Caption := VarToStrDef(ReturnDataset.FieldByName(control.Pesquisa.OtherFields[i]).Value,'')
          else
            TStaticText(otherControl).Caption := EmptyStr;

      end;
    end;
  end;
end;

procedure TPLUniEdit.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
  inherited SetBounds(ALeft, ATop, AWidth, AHeight);

  AutoFit;
end;

procedure TPLUniEdit.SetControlsOtherFields(const Value: TStrings);
var i: Integer;
begin
  FControlsOtherFields.Assign( Value );

  for i := (FControlsOtherFields.Count-1) downto 0 do
  begin
    if Trim(FControlsOtherFields[i]).IsEmpty then
      FControlsOtherFields.Delete(i);
  end;
end;

procedure TPLUniEdit.setCtl3D(const Value: boolean);
begin
  inherited Ctl3D := Value;
  AutoFit;
end;

procedure TPLUniEdit.setKeyValue(const Value: string);
begin
  fKeyValue := Value;

  if Assigned(FOnKeyValueChange) then
  begin
    if (not fKeyValue.IsEmpty) then
      FOnKeyValueChange(Self,fKeyValue)
    else
      FOnKeyValueChange(Self,Null);
  end;
end;

procedure TPLUniEdit.setLeft(const Value: integer);
begin
  inherited Left := Value;
  AutoFit;
end;

procedure TPLUniEdit.SetOnKeyValueChange(const Value: TPLUniEditKeyValueChange);
begin
  FOnKeyValueChange := Value;
end;

procedure TPLUniEdit.SetParent(AParent: TWinControl);
begin
  inherited SetParent(AParent);

  if assigned(FBtn) then
    FBtn.Parent := AParent;
    
end;

procedure TPLUniEdit.setPesquisa(sender: TObject);
begin
  if Assigned(fPesquisa.Pesquisa) then
    self.VisibleButton := False;

  FBtn.Visible := self.Visible and assigned(fPesquisa.Pesquisa);

  SetupInternalButton;
  self.AutoFit;
end;

procedure TPLUniEdit.setTop(const Value: integer);
begin
  inherited Top := Value;
  AutoFit;
end;

procedure TPLUniEdit.SetupInternalButton;
begin
  if not Assigned(FBtn)then
    FBtn := TPlUniSeekButton.Create(Self);

  FBtn.FreeNotification( Self );
  FBtn.Cursor   := crArrow;
  FBtn.AutoSize := True;
  FBtn.Visible  := Visible and (assigned(fPesquisa.Pesquisa) or FVisibleButton);

  if Assigned(fPesquisa.Pesquisa) then
  begin
    FBtn.OnClick := OnClickBtn;
  end;

//    FBtn.ClientEvents.ExtEvents.Values['click'] :=
//    'function click(sender, e, eOpts) '+
//    '{                                           '+
//    '  ajaxRequest(sender, ''customEvent'',      '+
//    '               {                            '+
//    '                  name: sender.text,        '+
//    '                  width: sender.getWidth()  '+
//    '               }                            '+
//    '             );                             '+
//    '}';
 // end;

  RecreateWnd;
end;

procedure TPLUniEdit.setWidth(const Value: integer);
begin
  inherited Width := Value;
  AutoFit;
end;

procedure TPLUniEdit.ValidatePesquisa;
begin
  if fPesquisa.Pesquisa.Working then
    abort;

  if fPesquisa.SQL.Count = 0 then
    raise Exception.Create(self.Name+'.Pesquisa.SQL precisa ter um SQL');

  if fPesquisa.FieldId.IsEmpty then
    raise Exception.Create(self.Name+'.Pesquisa.FieldId precisa de um campo configurado');

  if fPesquisa.FieldDisplay.IsEmpty then
    raise Exception.Create(self.Name+'.Pesquisa.FieldDisplay precisa de um campo configurado');
end;

procedure TPLUniEdit.SetName(const Value: TComponentName);
begin

  inherited SetName(Value);

  if csDesigning in ComponentState then
    Text := '';
end;


procedure TPLUniEdit.SetVisibleButton(const Value: Boolean);
begin
  FVisibleButton := Value;

  if Assigned(fPesquisa.Pesquisa) and FVisibleButton then
    fPesquisa.Pesquisa := nil;

  FBtn.Visible := (self.Visible and FVisibleButton);

  AutoFit;
end;

end.

 

 

 

And code of the internal button is here:

unit PLUniSeekButton;

interface

uses
  SysUtils, Classes, Controls, Buttons, Messages, Windows, Forms, Graphics,
  uniSpeedButton;

type
  TPLUniSeekButton = class(TUniSpeedButton)
  public
    procedure Loaded; override;
    constructor Create( AOWner : TComponent ); override;
  published
    property AutoSize;
  end;

implementation


constructor TPLUniSeekButton.Create(AOWner: TComponent);
begin
  inherited Create(AOWner);
  Name := AOWner.Name+'SubButton';
  SetSubComponent(True);
  Hint := 'Pesquisar <F2>';
  Height := 0;
  Width := 0;
  caption := '...';
end;

procedure TPLUniSeekButton.Loaded;
begin
  inherited;
  Name := Self.Owner.Name+'SubButton';

  if (self.Hint = '') then
    self.Hint := 'Pesquisar <F2>';

  caption := '...';
end;

end.

Thanks for any help!

Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • Create New...