type

{ TMyConnectDialog }

{$IFDEF VER16P}
  [ComponentPlatformsAttribute(pidWin32 or pidWin64{$IFDEF VER29P} or pidWin64x{$ENDIF}{$IFNDEF STD} or pidOSX32{$IFDEF VER25P} or pidLinux64{$IFDEF VER26P} or pidOSX64{$ENDIF}{$ENDIF}{$ENDIF})]
{$ENDIF}
  {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF} = class(TCustomConnectDialog)
  private
    FDatabaseOption: TConnectDialogOption;
    FPortOption: TConnectDialogOption;
    FDirectOption: TConnectDialogOption;

    function GetDatabaseLabel: string;
    procedure SetDatabaseLabel(Value: string);
    function GetPortLabel: string;
    procedure SetPortLabel(Value: string);
    function GetShowDatabase: Boolean;
    procedure SetShowDatabase(Value: Boolean);
    function GetShowPort: Boolean;
    procedure SetShowPort(Value: Boolean);

    procedure SetDatabaseOption(Value: TConnectDialogOption);
    procedure SetPortOption(Value: TConnectDialogOption);
    procedure SetDirectOption(Value: TConnectDialogOption);

    function GetConnection: TCustomMyConnection;

  protected
    procedure SetLabelSet(Value: TLabelSet); override;

    function DefDialogClass: TClass; override;
  {$IFDEF MSWINDOWS}
    function GetKeyPath: string; override;
    function GetServerStoreName: string; override;
    procedure SaveInfoToRegistry(Registry: TRegistry); override;
    procedure LoadInfoFromRegistry(Registry: TRegistry); override;
  {$ENDIF}

    procedure ReadDatabaseCaptionProperty(Reader: TReader);
    procedure ReadPortCaptionProperty(Reader: TReader);
    procedure ReadShowDatabaseProperty(Reader: TReader);
    procedure ReadShowPortProperty(Reader: TReader);
    procedure DefineProperties(Filer: TFiler); override;
  public
    constructor Create(Owner: TComponent); override;
    destructor Destroy; override;

    function Execute: boolean; override;

    property Connection: TCustomMyConnection read GetConnection;
    procedure GetServerList(List: TStrings); override;

    procedure GetOptions(var Options: TConnectDialogOptionArray; Ordered: Boolean = True); override;

    property DatabaseLabel: string read GetDatabaseLabel write SetDatabaseLabel;
    property PortLabel: string read GetPortLabel write SetPortLabel;
    property ShowDatabase: boolean read GetShowDatabase write SetShowDatabase default True;
    property ShowPort: boolean read GetShowPort write SetShowPort default True;
  published
    property Retries;
    property SavePassword;
    property DialogClass;

    property Caption;
    property ConnectButton;
    property CancelButton;

    property Server;
    property UserName;
    property Password;
    property Database: TConnectDialogOption read FDatabaseOption write SetDatabaseOption;
    property Port: TConnectDialogOption read FPortOption write SetPortOption;
    property Direct: TConnectDialogOption read FDirectOption write SetDirectOption;

    property LabelSet;
    property StoreLogInfo;
  end;

procedure GetMyServerList(List: TStrings; RaiseErrors: boolean = True);

implementation

uses
  {$IFDEF VER16P}{$IFDEF FMX}FMX.Types,{$ELSE}Controls,{$ENDIF}{$ENDIF}
  DAConsts;

function DefConnectDialogClass: TClass;
begin
  Result := {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF};
end;

const
  KeyPath = '\SOFTWARE\Devart\MyDAC\';

procedure GetMyServerList(List: TStrings; RaiseErrors: boolean = True);
const
  sCannotFind = 'Cannot find ';
  sError = 'sError';

{$IFDEF MSWINDOWS}
var
  Registry: TRegistry;
  i: integer;
  ServerLabel: string;
{$ENDIF}

begin
{$IFDEF MSWINDOWS}
  ServerLabel := 'Server ';

  Registry := TRegistry.Create;
  try
    if Registry.OpenKey(KeyPath + 'Connect', False) then begin
      List.Clear;
      i := 1;
      while Registry.ValueExists(ServerLabel + IntToStr(i)) do begin
        List.Add(Registry.ReadString(ServerLabel + IntToStr(i)));
        Inc(i);
      end;
      Registry.CloseKey;
    end;
  finally
    Registry.Free;
  end;
{$ENDIF}
end;

{ TMyConnectDialog }

constructor {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.Create(Owner: TComponent);
begin
  inherited;

  Server.Order := 0;
  UserName.Order := 2;
  Password.Order := 3;
  FDatabaseOption := TConnectDialogOption.Create(Self, okDatabase, 4);
  FPortOption := TConnectDialogOption.Create(Self, okPort, 1);
  FDirectOption := TConnectDialogOption.Create(Self, okDirect, 5, False);
  LabelSet := lsEnglish;
end;

destructor {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.Destroy;
begin
  FDatabaseOption.Free;
  FPortOption.Free;
  FDirectOption.Free;

  inherited;
end;

procedure {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.ReadDatabaseCaptionProperty(Reader: TReader);
begin
  FDatabaseOption.Caption := Reader.ReadString;
end;

procedure {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.ReadPortCaptionProperty(Reader: TReader);
begin
  FPortOption.Caption := Reader.ReadString;
end;

procedure {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.ReadShowDatabaseProperty(Reader: TReader);
begin
  FDatabaseOption.Visible := Reader.ReadBoolean;
end;

procedure {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.ReadShowPortProperty(Reader: TReader);
begin
  FPortOption.Visible := Reader.ReadBoolean;
end;

procedure {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.DefineProperties(Filer: TFiler);
begin
  inherited;
  Filer.DefineProperty('DatabaseLabel', ReadDatabaseCaptionProperty, nil, False);
  Filer.DefineProperty('PortLabel', ReadPortCaptionProperty, nil, False);
  Filer.DefineProperty('ShowDatabase', ReadShowDatabaseProperty, nil, False);
  Filer.DefineProperty('ShowPort', ReadShowPortProperty, nil, False);
end;

function {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.Execute: boolean;
var
  OldDatabase: string;
  OldPort: integer;
  OldDirect: Boolean;
begin
  if Connection = nil then
    DatabaseError(SConnectionNotDefined);
  Assert(Connection is TCustomMyConnection);

  Result := False;
  OldDatabase := TCustomMyConnection(Connection).Database;
  if Connection is TMyConnection then begin
    OldPort := TMyConnection(Connection).Port;
    OldDirect := TMyConnection(Connection).Options.Direct;
  end
  else begin // skip warning
    OldPort := 0;
    OldDirect := True;
  end;
  try
    Result := inherited Execute;
  finally
    if not Result then begin
      TCustomMyConnection(Connection).Database := OldDatabase;
      if Connection is TMyConnection then begin
        TMyConnection(Connection).Port := OldPort;
        TMyConnection(Connection).Options.Direct := OldDirect;
      end;
    end;
  end;
end;

procedure {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.SetLabelSet(Value: TLabelSet);
begin
  inherited SetLabelSet(Value);

  InSetLabelSet := True;
  try
  {$IFDEF WIN32_64}
    if Value <> lsCustom then begin
      FDatabaseOption.Caption := GetString(6);
      FPortOption.Caption := GetString(7);
    end;
  {$ELSE}
      FDatabaseOption.Caption := 'Database';
      FPortOption.Caption := 'Port';
  {$ENDIF}
    FDirectOption.Caption := 'Mode';
  finally
    InSetLabelSet := False;
  end;
end;

function {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.DefDialogClass: TClass;
begin
  Result := TMyConnectForm;
end;

{$IFDEF MSWINDOWS}
function {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.GetKeyPath: string;
begin
  Result := KeyPath;
end;

function {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.GetServerStoreName: string;
begin
  Result := 'Server';
end;

procedure {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.SaveInfoToRegistry(Registry: TRegistry);
begin
  inherited;

  if Database.Visible then
    Registry.WriteString('Database', Connection.Database)
  else
    Registry.DeleteValue('Database');

  if Connection is TMyConnection then
    if Port.Visible then
      Registry.WriteInteger('Port', TMyConnection(Connection).Port)
    else
      Registry.DeleteValue('Port');
end;

procedure {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.LoadInfoFromRegistry(Registry: TRegistry);
begin
  inherited;

  if Database.Visible and Registry.ValueExists('Database') then
    Connection.Database := Registry.ReadString('Database');

  if Connection is TMyConnection then
    if Port.Visible and Registry.ValueExists('Port') then
      TMyConnection(Connection).Port := Registry.ReadInteger('Port');
end;
{$ENDIF}

procedure {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.GetServerList(List: TStrings);
begin
  GetMyServerList(List, False);
end;

procedure {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.GetOptions(var Options: TConnectDialogOptionArray; Ordered: Boolean = True);
begin
  SetLength(Options, 5);
  Options[0] := UserName;
  Options[1] := Password;
  Options[2] := Server;
  Options[3] := Database;
  Options[4] := Port;
  inherited GetOptions(Options, Ordered);
end;

procedure {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.SetDatabaseOption(Value: TConnectDialogOption);
begin
  FDatabaseOption.Assign(Value);
end;

procedure {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.SetPortOption(Value: TConnectDialogOption);
begin
  FPortOption.Assign(Value);
end;

procedure {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.SetDirectOption(Value: TConnectDialogOption);
begin
  FDirectOption.Assign(Value);
end;

function {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.GetDatabaseLabel: string;
begin
  Result := FDatabaseOption.Caption;
end;

procedure {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.SetDatabaseLabel(Value: string);
begin
  FDatabaseOption.Caption := Value;
end;

function {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.GetPortLabel: string;
begin
  Result := FPortOption.Caption;
end;

procedure {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.SetPortLabel(Value: string);
begin
  FPortOption.Caption := Value;
end;

function {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.GetShowDatabase: Boolean;
begin
  Result := FDatabaseOption.Visible;
end;

procedure {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.SetShowDatabase(Value: Boolean);
begin
  FDatabaseOption.Visible := Value;
end;

function {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.GetShowPort: Boolean;
begin
  Result := FPortOption.Visible;
end;

procedure {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.SetShowPort(Value: Boolean);
begin
  FPortOption.Visible := Value;
end;

function {$IFDEF FMX}TMyConnectDialogFmx{$ELSE}TMyConnectDialog{$ENDIF}.GetConnection: TCustomMyConnection;
begin
  Result := (inherited Connection) as TCustomMyConnection;
end;

initialization
{$IFDEF FMX}
  if not Assigned(DefConnectDialogClassProc) then
{$ENDIF}
    DefConnectDialogClassProc := DefConnectDialogClass;
{$IFDEF VER16P}
{$IFDEF FMX}
  GroupDescendentsWith(TMyConnectDialogFmx, TFmxObject);
{$ELSE}
  GroupDescendentsWith(TMyConnectDialog, TControl);
{$ENDIF}
{$ENDIF}

end.
