
//////////////////////////////////////////////////
//  MySQL Data Access Components
//  Copyright © 1998-2025 Devart. All right reserved.
//  Connect Form
//////////////////////////////////////////////////

{$IFNDEF CLR}

unit MyConnectForm;
{$ENDIF}

interface

{$IFNDEF UNIX}
{$IFNDEF POSIX}
  {$DEFINE MSWINDOWS}
{$ENDIF}
{$ENDIF}

uses
{$IFDEF MSWINDOWS}
  Windows, Messages,
{$ENDIF}
  SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
{$IFDEF FPC}
  LResources,
{$ENDIF}
  CRTypes, DBAccess, MyCall, MyAccess;

type
  TMyConnectForm = class(TForm)
    Panel: TPanel;
    pUserName: TPanel;
    lbUsername: TLabel;
    edUsername: TEdit;
    pPassword: TPanel;
    pServer: TPanel;
    pPort: TPanel;
    pDatabase: TPanel;
    edPassword: TEdit;
    lbPassword: TLabel;
    lbServer: TLabel;
    edServer: TComboBox;
    lbPort: TLabel;
    edPort: TEdit;
    lbDatabase: TLabel;
    edDatabase: TComboBox;
    pButtons: TPanel;
    btCancel: TButton;
    btConnect: TButton;
    procedure btConnectClick(Sender: TObject);
    procedure edServerDropDown(Sender: TObject);
    procedure edDatabaseDropDown(Sender: TObject);
    procedure edExit(Sender: TObject);

  private
    FConnectDialog: TCustomConnectDialog;
    FRetries: integer;
    FRetry: boolean;

    FListGot: boolean;

    procedure SetConnectDialog(Value: TCustomConnectDialog);

  protected
    procedure DoInit; virtual;
    procedure DoConnect; virtual;

  public

  published
    property ConnectDialog: TCustomConnectDialog read FConnectDialog write SetConnectDialog;
  end;

implementation

{$IFNDEF FPC}
{$IFDEF IDE}
{$R *.dfm}
{$ELSE}
{$R MyConnectForm.dfm}
{$ENDIF}
{$ELSE}
{$R *.lfm}
{$ENDIF}

uses
  CRFunctions, DAConsts, DacVcl, MyDacVcl;

procedure TMyConnectForm.DoInit;
var
  CurTop, i: integer;
  ConnectDialogOptions: TConnectDialogOptionArray;
  CurPanel: TPanel;
  CurControl: TWinControl;
  NeedSetActiveControl, IsEmbedded: Boolean;
begin
  FRetry := False;
  FRetries := FConnectDialog.Retries;
  Caption := FConnectDialog.Caption;
  FListGot := False;

  IsEmbedded := (FConnectDialog.Connection.ClassName = 'TMyEmbConnection') or
    (
     (FConnectDialog.Connection is TMyConnection) and
      TMyConnection(FConnectDialog.Connection).Options.Embedded
    );

  FConnectDialog.GetOptions(ConnectDialogOptions);
  CurTop := 0;
  NeedSetActiveControl := True;
  for i := Low(ConnectDialogOptions) to High(ConnectDialogOptions) do begin
    case ConnectDialogOptions[i].Kind of
      okServer: begin
        pServer.Visible := ConnectDialogOptions[i].Visible and not IsEmbedded;
        CurPanel := pServer;
        CurControl := edServer;
        lbServer.Caption := ConnectDialogOptions[i].Caption;
      end;
      okUserName: begin
        pUserName.Visible := ConnectDialogOptions[i].Visible;
        CurPanel := pUserName;
        CurControl := edUsername;
        lbUsername.Caption := ConnectDialogOptions[i].Caption;
      end;
      okPassword: begin
        pPassword.Visible := ConnectDialogOptions[i].Visible;
        CurPanel := pPassword;
        CurControl := edPassword;
        lbPassword.Caption := ConnectDialogOptions[i].Caption;
      end;
      okDatabase: begin
        pDatabase.Visible := ConnectDialogOptions[i].Visible;
        CurPanel := pDatabase;
        CurControl := edDatabase;
        lbDatabase.Caption := ConnectDialogOptions[i].Caption;
      end;
      okPort: begin
        pPort.Visible := ConnectDialogOptions[i].Visible and not IsEmbedded;
        CurPanel := pPort;
        CurControl := edPort;
        lbPort.Caption := ConnectDialogOptions[i].Caption;
      end;
    else
      raise Exception.Create(Format(SInternalErrorInvalidValue,
        ['TMyConnectForm.DoInit', 'ConnectDialogOptions[i].Kind',
        IntToStr(Integer(ConnectDialogOptions[i].Kind))]));
    end;
    CurPanel.TabOrder := i;
    if CurPanel.Visible then begin
      if i = 0 then
        CurPanel.Top := CurTop + 2
      else
        CurPanel.Top := CurTop;
      CurTop := CurTop + CurPanel.Height;
    end;
    if NeedSetActiveControl and CurPanel.Visible then begin
      ActiveControl := CurControl;
      NeedSetActiveControl := False;
    end;
  end;
  Panel.Height := CurTop + 2;
  pButtons.Top := Panel.Height + 8;
  ClientHeight := pButtons.Top + pButtons.Height + 2;

  btConnect.Caption := FConnectDialog.ConnectButton;
  btCancel.Caption := FConnectDialog.CancelButton;

  edUsername.Text := FConnectDialog.Connection.Username;
  edPassword.Text := FConnectDialog.Connection.Password;
  edServer.Text := FConnectDialog.Connection.Server;

  if FConnectDialog.Connection is TCustomMyConnection then
    edDatabase.Text := TCustomMyConnection(FConnectDialog.Connection).Database;
  if FConnectDialog.Connection is TMyConnection then begin
    edPort.Text := IntToStr(TMyConnection(FConnectDialog.Connection).Port);
  end;

  if (edUsername.Text <> '') and (edPassword.Text = '') and pPassword.Visible then
    ActiveControl := edPassword;
end;

procedure TMyConnectForm.DoConnect;
begin
  try
    edExit(nil);
    FConnectDialog.Connection.PerformConnect(FRetry);
    ModalResult := mrOk;
  except
    on E: EDAError do begin
      Dec(FRetries);
      FRetry := True;
      if FRetries = 0 then
        ModalResult:= mrCancel;

      case E.ErrorCode of
        ER_ACCESS_DENIED_ERROR: ActiveControl := edUsername;
        CR_UNKNOWN_HOST: ActiveControl := edServer;
      end;
      raise;
    end
    else
      raise;
  end;
end;

procedure TMyConnectForm.SetConnectDialog(Value: TCustomConnectDialog);
begin
  FConnectDialog := Value;
  DoInit;
end;

procedure TMyConnectForm.btConnectClick(Sender: TObject);
begin
  DoConnect;
end;

procedure TMyConnectForm.edServerDropDown(Sender: TObject);
var
  OldCursor: TCursor;
  List: TStringList;
begin
  if FListGot then
    Exit;

  FListGot := True;
  OldCursor := GetScreenCursor;
  SetScreenCursor(crSQLWait);
  List := TStringList.Create;
  try
    FConnectDialog.GetServerList(List);
    AssignStrings(List, edServer.Items);
  finally
    List.Free;
    SetScreenCursor(OldCursor);
  end;
end;

procedure TMyConnectForm.edDatabaseDropDown(Sender: TObject);
var
  OldCursor: TCursor;
  OldLoginPrompt: boolean;
  List: TStringList;
begin
  if not (FConnectDialog.Connection is TCustomMyConnection) then
    Exit;

  edDatabase.Items.Clear;
  OldLoginPrompt := FConnectDialog.Connection.LoginPrompt;
  OldCursor := GetScreenCursor;
  SetScreenCursor(crSQLWait);
  List := TStringList.Create;
  try
    FConnectDialog.Connection.LoginPrompt := False;
    GetDatabasesList(TCustomMyConnection(FConnectDialog.Connection), List);
    AssignStrings(List, edDatabase.Items);
  finally
    List.Free;
    FConnectDialog.Connection.LoginPrompt := OldLoginPrompt;
    SetScreenCursor(OldCursor);
  end;
end;

procedure TMyConnectForm.edExit(Sender: TObject);
begin
  try
    if pPassword.Visible then
      FConnectDialog.Connection.Password := edPassword.Text;

    if pServer.Visible then
      FConnectDialog.Connection.Server := edServer.Text;

    if pUsername.Visible then
      FConnectDialog.Connection.UserName := edUsername.Text;

    if FConnectDialog.Connection is TCustomMyConnection then begin
      if pDatabase.Visible then
        TCustomMyConnection(FConnectDialog.Connection).Database := edDatabase.Text;
    end;

    if FConnectDialog.Connection is TMyConnection then begin
      if pPort.Visible then
        TMyConnection(FConnectDialog.Connection).Port := StrToInt(edPort.Text);
    end;
  except
    ActiveControl := Sender as TWinControl;
    raise;
  end;
end;

initialization
  if GetClass('TMyConnectForm') = nil then
    Classes.RegisterClass(TMyConnectForm);

end.
