//////////////////////////////////////////////////
//  MySQL Data Access Components
//  Copyright © 1998-2025 Devart. All right reserved.
//  MySQL Design
//////////////////////////////////////////////////
{$IFNDEF CLR}

{$I MyDac.inc}

unit MyDesign;
{$ENDIF}

interface

uses
{$IFDEF MSWINDOWS}
  Windows, Messages, Registry,
{$ENDIF}
  Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, MyDacVcl,
{$IFDEF CLR}
  Borland.Vcl.Design.DesignEditors, Borland.Vcl.Design.DesignIntf,
  Borland.Vcl.Design.FldLinks,
{$ELSE}
{$IFDEF FPC}
  PropEdits, ComponentEditors,
{$ELSE}
  {$IFDEF VER6P}DesignIntf, DesignEditors,{$ELSE}DsgnIntf,{$ENDIF}
  {$IFNDEF BCB}{$IFDEF VER5P}FldLinks,{$ENDIF} ColnEdit,{$ENDIF}
{$ENDIF}
{$ENDIF}
{$IFDEF DBTOOLS}
  DBToolsClient,
{$ENDIF}
{$IFNDEF STD}
  MyLoader,
{$ENDIF}
  SysUtils, Classes, TypInfo, CRTypes, CRDesign, DADesign, DBAccess, MyAccess;

{ ------------  MyDac property editors ----------- }
type
{ TMyConnectionOptionsCharsetEditor }

  TMyConnectionOptionsCharsetEditor = class (TStringProperty)
  public
    function GetAttributes: TPropertyAttributes; override;
    procedure GetValues(Proc: TGetStrProc); override;
    function AutoFill: boolean; override;
  end;

  TMyServerNamePropertyEditor = class (TStringProperty)
  public
    function GetAttributes: TPropertyAttributes; override;
    procedure GetValues(Proc: TGetStrProc); override;
    function AutoFill: Boolean; override;
  end;

  TPemFileNameProperty = class(TStringProperty)
  protected
    procedure GetDialogOptions(Dialog: TOpenDialog); virtual;
  public
    procedure Edit; override;
    function GetAttributes: TPropertyAttributes; override;
  end;

{$IFNDEF STD}
  TMyTableNamesEditor = class (TStringProperty)
  public
    function GetAttributes: TPropertyAttributes; override;
    procedure Edit; override;
  end;

  TMyStoredProcNamesEditor = class (TStringProperty)
  public
    function GetAttributes: TPropertyAttributes; override;
    procedure Edit; override;
  end;
{$ENDIF}

  TMyTableOptionsHandlerIndexEditor = class (TStringProperty)
  public
    function GetAttributes: TPropertyAttributes; override;
    procedure GetValues(Proc: TGetStrProc); override;
    function AutoFill: boolean; override;
  end;

  TMyConnectDialogPropertyEditor = class(TComponentProperty)
  private
    FCheckProc: TGetStrProc;
    procedure CheckComponent(const Value: string);
  public
    procedure GetValues(Proc: TGetStrProc); override;
  end;

{ ------------  MyDac component editors ----------- }
  TMyConnectionEditor = class(TDAConnectionEditor)
  protected
    procedure InitVerbs; override;
  {$IFNDEF STD}
    procedure Convert;
  {$ENDIF}
  end;

  TMyCommandEditor = class(TDASQLEditor)
  protected
    procedure InitVerbs; override;
  end;

  TMyDataSetEditor = class(TDAComponentEditor);

  TMyQueryEditor = class(TMyDataSetEditor)
  protected
    procedure InitVerbs; override;
  end;

  TMyTableEditor = class(TMyDataSetEditor)
  protected
    procedure InitVerbs; override;
  end;

  TMyStoredProcEditor = class(TMyDataSetEditor)
  protected
    procedure InitVerbs; override;
  end;

  TMyUpdateSQLEditor = class(TDAUpdateSQLEditor)
  protected
    procedure InitVerbs; override;
  end;

{$IFNDEF STD}
  TMyServerControlEditor = class (TDAComponentEditor)
  protected
    FServiceNames: TStringList;
    procedure InitVerbs; override;

  public
    constructor Create(AComponent: TComponent; 
      ADesigner: {$IFDEF FPC}TComponentEditorDesigner{$ELSE}{$IFDEF VER6P}IDesigner{$ELSE}IFormDesigner{$ENDIF}{$ENDIF}); override;
    destructor Destroy; override;

    function GetVerbCount: integer; override;
    function GetVerb(Index: integer): string; override;
    procedure ExecuteVerb(Index: integer); override;
  end;
{$ENDIF}

  TMyScriptEditor = class(TDAScriptEditor)
  protected
    procedure InitVerbs; override;
  end;

{$IFNDEF STD}
  TMyDumpEditor = class(TDAComponentEditor)
  protected
    procedure InitVerbs; override;
  end;

  TMyBackupEditor = class (TDAComponentEditor)
  public
    procedure Edit; override;
  end;
{$ENDIF}

{$IFNDEF FPC}
  TMyConnectionList = class (TDAConnectionList)
  protected
    function GetConnectionType: TCustomDAConnectionClass; override;
  end;

{$IFDEF VER6P}
  TMyDesignNotification = class(TDADesignNotification)
  public
    function CreateConnectionList: TDAConnectionList; override;
    function GetConnectionPropertyName: string; override;
  {$IFNDEF STD}
    procedure SelectionChanged(const ADesigner: IDesigner;
      const ASelection: IDesignerSelections); override;
  {$ENDIF}
    procedure ItemInserted(const ADesigner: IDesigner; AItem: TPersistent); override;
  end;
{$ENDIF}
{$ENDIF}

procedure Register;

implementation

uses
{$IFDEF MSWINDOWS}
  {$IFNDEF FPC}
  MyMenu, WinSvc, SvcMgr,
  {$ELSE}
  daemonapp,
  {$ENDIF}
{$ENDIF}
{$IFDEF CLR}
  WinUtils,
{$ELSE}
  {$IFNDEF FPC}ToolsAPI,{$ENDIF}
{$ENDIF}
  CRFunctions, DB,
  {$IFNDEF STD}DALoader, MyEmbConnection, MyServerControl, MyDump, MyBackup,{$ENDIF}
  MyClasses, MyScript, MyConnectionEditor, MyCommandEditor, MyQueryEditor, DATableEditor,
  MyStoredProcEditor, MyTableEditor, MyUpdateSQLEditor, DAScriptEditor,
{$IFNDEF STD}
  MyDumpEditor, MyServerControlEditor,
{$ENDIF}
  MyDesignUtils
{$IFNDEF STD}
  , MyNamesEditor
{$ENDIF};

{ TMyConnectionOptionsCharsetEditor }

function TMyConnectionOptionsCharsetEditor.GetAttributes: TPropertyAttributes;
begin
  Result := [paValueList];
end;

function TMyConnectionOptionsCharsetEditor.AutoFill: boolean;
begin
  Result := False;
end;

procedure TMyConnectionOptionsCharsetEditor.GetValues(Proc: TGetStrProc);
var
  List: TStringList;
  Connection: TCustomMyConnection;
  i: integer;
begin
  Connection := TDBAccessUtils.FOwner(TCustomMyConnectionOptions(GetComponent(0))) as TCustomMyConnection;
  if Connection = nil then
    Exit;

  List := TStringList.Create;
  try
    Connection.GetCharsetNames(List);
    List.Sort;

    for i := 0 to List.Count - 1 do
      Proc(List[i]);
  finally
    List.Free;
  end;
end;

{ TPemFileNameProperty }

procedure TPemFileNameProperty.GetDialogOptions(Dialog: TOpenDialog);
begin
{$IFDEF MSWINDOWS}
  Dialog.Filter := 'Pem Files (*.pem)|*.pem|All Files (*.*)|*.*';
{$ELSE}
  Dialog.Filter := 'All Files (*)|*';
{$ENDIF}
  Dialog.Options := Dialog.Options + [ofFileMustExist];
end;

procedure TPemFileNameProperty.Edit;
var
  OpenDialog: TOpenDialog;
begin
  OpenDialog := TOpenDialog.Create(nil);
  GetDialogOptions(OpenDialog);
  if OpenDialog.Execute then
    SetValue(OpenDialog.FileName);
  OpenDialog.Free;
end;

function TPemFileNameProperty.GetAttributes: TPropertyAttributes;
begin
  Result := [paRevertable, paDialog, paMultiSelect];
end;

{ TMyServerNamePropertyEditor }

function TMyServerNamePropertyEditor.GetAttributes: TPropertyAttributes;
begin
  Result := [paValueList];
end;

function TMyServerNamePropertyEditor.AutoFill: Boolean;
begin
  Result := False;
end;

procedure TMyServerNamePropertyEditor.GetValues(Proc: TGetStrProc);
var
  i: integer;
  OldCursor: TCursor;
  sl: TStringList;
begin
  sl := nil;
  OldCursor := Screen.Cursor;
  try
    Screen.Cursor := crSQLWait;
    sl := TStringList.Create;
    MyAccess.GetServerList(sl);

    for i := 0 to sl.Count - 1 do
      Proc(sl[i]);
  finally
    Screen.Cursor := OldCursor;
    sl.Free;
  end;
end;

{$IFNDEF STD}
{ TMyTableNamesEditor }

function TMyTableNamesEditor.GetAttributes: TPropertyAttributes;
begin
  Result := [paDialog];
end;

procedure TMyTableNamesEditor.Edit;
var
  Comp: TComponent;
  Conn: TCustomDAConnection;

begin
  Comp := TComponent(GetComponent(0));
  Conn := TMyDesignUtils.GetConnection(Comp);
  if Conn = nil then
    Exit;

  with TMyNamesForm.Create(nil, TMyDesignUtils) do
    try
      Connection := Conn;
      Mode := nmTables;
      if Comp is TMyServerControl then
        Names := TMyServerControl(Comp).TableNames
      else
      if Comp is TMyDump then
        Names := TMyDump(Comp).TableNames
      else
      if Comp is TMyBackup then
        Names := TMyBackup(Comp).TableNames
      else
        Assert(False);

      ShowModal;
      if ModalResult = mrOk then begin
        if Comp is TMyServerControl then
          TMyServerControl(Comp).TableNames := Names
        else
        if Comp is TMyDump then
          TMyDump(Comp).TableNames := Names
        else
        if Comp is TMyBackup then
          TMyBackup(Comp).TableNames := Names
        else
          Assert(False);
      end;

  finally
    Free;
  end;
end;

{ TMyStoredProcNamesEditor }

function TMyStoredProcNamesEditor.GetAttributes: TPropertyAttributes;
begin
  Result := [paDialog];
end;

procedure TMyStoredProcNamesEditor.Edit;
var
  Comp: TComponent;
  Conn: TCustomDAConnection;

begin
  Comp := TComponent(GetComponent(0));
  Conn := TMyDesignUtils.GetConnection(Comp);
  if Conn = nil then
    Exit;

  with TMyNamesForm.Create(nil, TMyDesignUtils) do
    try
      Connection := Conn;
      Mode := nmSProc;
      if Comp is TMyDump then begin
        Connection := TMyDump(Comp).Connection;
        Names := TMyDump(Comp).StoredProcNames;
      end
      else
        Assert(False);

      ShowModal;
      if ModalResult = mrOk then begin
        if Comp is TMyDump then
          TMyDump(Comp).StoredProcNames := Names
        else
          Assert(False);
      end;

  finally
    Free;
  end;
end;
{$ENDIF}

{ TMyTableOptionsHandlerIndexEditor }

function TMyTableOptionsHandlerIndexEditor.GetAttributes: TPropertyAttributes;
begin
  Result := [paValueList];
end;

procedure TMyTableOptionsHandlerIndexEditor.GetValues(Proc: TGetStrProc);
var
  Connection: TCustomMyConnection;
  DataSet: TCustomMyTable;
  TableName: string;
  List: TStrings;
  i: integer;
begin
  DataSet := TDBAccessUtils.FOwner(GetComponent(0) as TMyTableOptions) as TCustomMyTable;
  if DataSet = nil then
    Exit;
  Connection := DataSet.Connection as TCustomMyConnection;
  if Connection = nil then
    Exit;
  TableName := DataSet.TableName;
  if TableName = '' then
    Exit;
  List := TStringList.Create;
  try
    GetIndexNames(Connection, List, TableName);
    for i := 0 to List.Count - 1 do
      if UpperCase(List[i]) = 'PRIMARY' then begin
        List[i] := '`' + List[i] + '`';
        break;
      end;
    for i := 0 to List.Count - 1 do
      Proc(List[i]);
  finally
    List.Free;
  end;
end;

function TMyTableOptionsHandlerIndexEditor.AutoFill: boolean;
begin
  Result := False;
end;

{ TMyConnectDialogPropertyEditor }

procedure TMyConnectDialogPropertyEditor.CheckComponent(const Value: string);
var
  Component: TComponent;
begin
  Component := {$IFDEF FPC}PropertyHook{$ELSE}Designer{$ENDIF}.GetComponent(Value);
  if Component <> nil then begin
    if not ({$IFDEF VER17P}(GetIsClassByName(Component, 'TMyConnectDialogFmx')) or {$ENDIF}(Component is TMyConnectDialog)) then
      Exit;
  end;
  FCheckProc(Value);
end;

procedure TMyConnectDialogPropertyEditor.GetValues(Proc: TGetStrProc);
begin
  FCheckProc := Proc;
  inherited GetValues(CheckComponent);
end;

{ TMyConnectionEditor }

procedure TMyConnectionEditor.InitVerbs;
{$IFNDEF STD}
{$IFNDEF FPC}
var
  s: string;
{$ENDIF}
{$ENDIF}
begin
  inherited;
  AddVerb('Connection Editor...', TMyConnectionEditorForm, TMyDesignUtils);
{$IFNDEF STD}  
{$IFNDEF FPC}
  if Designer <> nil then begin
    if Component is TMyConnection then
      s := 'Convert to TMyEmbConnection'
    else
      s := 'Convert to TMyConnection';
    AddVerb(s, Convert);
  end;
{$ENDIF}
{$ENDIF}
{$IFDEF DBTOOLS}
  AddDBToolsVerbs([dbtFindInDatabaseExplorer]);
{$ENDIF}
end;

{$IFNDEF STD}
procedure TMyConnectionEditor.Convert;
begin
{$IFNDEF FPC}
  if Designer <> nil then
    if Component is TMyConnection then
      ConvertToClass(Self.Designer, Component, TMyEmbConnection)
    else
      ConvertToClass(Self.Designer, Component, TMyConnection);
{$ENDIF}
end;
{$ENDIF}

{ TMyCommandEditor }

procedure TMyCommandEditor.InitVerbs;
begin
  inherited;
  AddVerb('MyCommand E&ditor...', TMyCommandEditorForm, TMyDesignUtils);
{$IFDEF DBTOOLS}     
  AddDBToolsVerbs([dbtEditSql, dbtDebugSql]);
{$ENDIF}
end;

{ TMyQueryEditor }

procedure TMyQueryEditor.InitVerbs;
begin
  AddVerb('Fields &Editor...', ShowFieldsEditor);
  AddVerb('MyQuery E&ditor...', TMyQueryEditorForm, TMyDesignUtils);
  AddVerb('Data Editor...', ShowDataEditor);
{$IFDEF DBTOOLS}
  AddDBToolsVerbs([dbtEditSelectSql, dbtEditInsertSql, dbtEditUpdateSql, dbtEditDeleteSql, dbtEditLockSql, dbtEditRefreshSql, dbtQueryBuilder, dbtDebugSql, dbtRetrieveData, dbtEditRecCountSQL]);
{$ENDIF}

  inherited;
end;

{ TMyTableEditor }

procedure TMyTableEditor.InitVerbs;
begin
  AddVerb('Fields &Editor...', ShowFieldsEditor);
  AddVerb('MyTable E&ditor...', TMyTableEditorForm, TMyDesignUtils);
  AddVerb('Data Editor...', ShowDataEditor);
{$IFDEF DBTOOLS}
  AddDBToolsVerbs([dbtEditDatabaseObject, dbtFindInDatabaseExplorer]);
{$ENDIF}

  inherited;
end;

procedure TMyStoredProcEditor.InitVerbs;
begin
  AddVerb('Fields &Editor...', ShowFieldsEditor);
  AddVerb('MyStoredProc E&ditor...', TMyStoredProcEditorForm, TMyDesignUtils);
  AddVerb('Data Editor...', ShowDataEditor);
{$IFDEF DBTOOLS}
  AddDBToolsVerbs([dbtFindInDatabaseExplorer, dbtEditInsertSql, dbtEditUpdateSql, dbtEditDeleteSql, dbtEditLockSql, dbtEditRefreshSql, dbtDebugSql, dbtCompile, dbtCompileDebug, dbtEditRecCountSQL]);
{$ENDIF}

  inherited;
end;

procedure TMyUpdateSQLEditor.InitVerbs;
begin
  AddVerb('MyUpdateSQL E&ditor...', TMyUpdateSQLEditorForm, TMyDesignUtils);
{$IFDEF DBTOOLS}
  AddDBToolsVerbs([dbtEditInsertSql, dbtEditUpdateSql, dbtEditDeleteSql, dbtEditLockSql, dbtEditRefreshSql]);
{$ENDIF}

  inherited;
end;

{ TMyServerControlEditor }
{$IFNDEF STD}
constructor TMyServerControlEditor.Create(AComponent: TComponent; 
  ADesigner: {$IFDEF FPC}TComponentEditorDesigner{$ELSE}{$IFDEF VER6P}IDesigner{$ELSE}IFormDesigner{$ENDIF}{$ENDIF});
begin
  inherited;
  FServiceNames := TStringList.Create;
end;

destructor TMyServerControlEditor.Destroy;
begin
  FServiceNames.Free;
  inherited;
end;

procedure TMyServerControlEditor.InitVerbs;
begin
  inherited;
  AddVerb('MyServerControl E&ditor...', TMyServerControlEditorForm, TMyDesignUtils);
end;

function TMyServerControlEditor.GetVerbCount: integer;
{$IFDEF MSWINDOWS}
var
  Status: TCurrentStatus;
  i: integer;
{$ENDIF}
begin
  Result := 1;

{$IFDEF MSWINDOWS}
  if TMyServerControl(Component).Connection <> nil then begin
    try
      TMyServerControl(Component).GetServiceNames(FServiceNames);
      for i := FServiceNames.Count - 1 downto 0 do begin
        Status := TCurrentStatus(Integer(FServiceNames.Objects[i]));
        if (Status <> csRunning) and (Status <> csStopped) then
          FServiceNames.Delete(i);
      end;
      Result := Result + FServiceNames.Count;
    except
      // Win9x or something else
      // Silent
    end;
  end;
{$ENDIF}
end;

function TMyServerControlEditor.GetVerb(Index: integer): string;
{$IFDEF MSWINDOWS}
var
  Status: TCurrentStatus;
  ServiceName, Server: string;
{$ENDIF}
begin
  case Index of
    0: Result := inherited GetVerb(Index);
  {$IFDEF MSWINDOWS}
    else
    begin
      Status := TCurrentStatus(Integer(FServiceNames.Objects[Index - 1]));
      ServiceName := FServiceNames[Index - 1] + ' at ';
      Server := Trim(TMyServerControl(Component).Connection.Server);
      if  Server <> '' then
        ServiceName := ServiceName + Server
      else
        ServiceName := ServiceName + 'localhost';

      if Status = csRunning then
        Result := 'Stop ' + ServiceName
      else
        Result := 'Start ' + ServiceName;
    end;
  {$ENDIF}
  end;
end;

procedure TMyServerControlEditor.ExecuteVerb(Index: integer);
{$IFDEF MSWINDOWS}
var
  Status: TCurrentStatus;
{$ENDIF}
begin
  case Index of
    0: inherited;
  {$IFDEF MSWINDOWS}
    else
    begin
      Status := TCurrentStatus(Integer(FServiceNames.Objects[Index - 1]));
      if Status = csRunning then
        TMyServerControl(Component).ServiceStop(FServiceNames[Index - 1])
      else
        TMyServerControl(Component).ServiceStart(FServiceNames[Index - 1]);
    end;
  {$ENDIF}
  end;
end;
{$ENDIF}

{ TMyScriptEditor }

procedure TMyScriptEditor.InitVerbs;
begin
  inherited;
  AddVerb('MyScript E&ditor...', TDAScriptEditorForm, TMyDesignUtils);
{$IFDEF DBTOOLS}
  AddDBToolsVerbs([dbtEditSql, dbtDebugSql]);
{$ENDIF}
end;

{$IFNDEF STD}
{ TMyDumpEditor }

procedure TMyDumpEditor.InitVerbs;
begin
  inherited;
  AddVerb('MyDump E&ditor...', TMyDumpEditorForm, TMyDesignUtils);
end;

procedure TMyBackupEditor.Edit;
begin
  (TDefaultEditor.Create(Component, Designer) as {$IFNDEF FPC}IComponentEditor{$ELSE}TComponentEditor{$ENDIF}).Edit;
end;
{$ENDIF}

{$IFNDEF FPC}
{ TMyConnectionList }

function TMyConnectionList.GetConnectionType: TCustomDAConnectionClass;
begin
  Result := TCustomMyConnection;
end;

{$IFDEF VER6P}
function TMyDesignNotification.CreateConnectionList: TDAConnectionList;
begin
  Result := TMyConnectionList.Create;
end;

function TMyDesignNotification.GetConnectionPropertyName: string;
begin
  Result := 'Connection';
end;

procedure TMyDesignNotification.ItemInserted(const ADesigner: IDesigner; AItem: TPersistent);
begin
  if (AItem <> nil) and ((AItem is TCustomMyDataSet) or (AItem is TMyCommand) or
    (AItem is TMyScript) or
  {$IFNDEF STD}
    (AItem is TMyLoader) or
    (AItem is TMyDump) or
    (AItem is TMyBackup) or
  {$ENDIF}
    (AItem is TMyMetaData) or
    (AItem is TMyDataSource)) then
    FItem := AItem;
end;

{$IFNDEF STD}
procedure TMyDesignNotification.SelectionChanged(const ADesigner: IDesigner; const ASelection: IDesignerSelections);
{$IFDEF CLR}
begin
end;
{$ELSE}
var
  ModuleServices: IOTAModuleServices;
  CurrentModule: IOTAModule;
  Project: IOTAProject;
  ProjectOptions: IOTAProjectOptions;
  DelphiPath: string;
  s: string;

  {OptionNames: TOTAOptionNameArray;
  i: integer;}
begin
  //OFS('TMyDesignNotification.SelectionChanged=============');

  CurrentProjectOutputDir := '';

{$IFDEF CLR}
  ModuleServices := BorlandIDE.ModuleServices;
{$ELSE}
  ModuleServices :=BorlandIDEServices as IOTAModuleServices;
{$ENDIF}

  CurrentModule := ModuleServices.CurrentModule;
  //OFS('  CurrentModule.FileName = ' + CurrentModule.FileName);
  if CurrentModule.OwnerCount = 0 then
    Exit;

  Project := CurrentModule.Owners[0];
  ProjectOptions := Project.ProjectOptions;

  {OFS('  Project.FileName = ' + Project.FileName);
  OptionNames := ProjectOptions.GetOptionNames;
  for i := Low(OptionNames) to High(OptionNames) do begin
    s := OptionNames[i].Name;
    try
      s := s + '=' + ProjectOptions.Values[s];
    except
    end;
    OFS(s);
  end;}


  CurrentProjectOutputDir := Trim(ProjectOptions.Values['OutputDir']);
  //OFS('  ' + CurrentProjectOutputDir);

  // CurrentProjectOutputDir may be:
  //   - fixed path "c:\qqq\ccc"
  //   - relative path from project dpr-file "./qqq/ccc" or "..\ccc\qqq"
  //   ? empty path "", equal to $(DELPHI)/Projects
  //   ? relative path from $(DELPHI)/Projects "qqq/ccc"

{  if (CurrentProjectOutputDir <> '') and ((CurrentProjectOutputDir[1] = '/') or (CurrentProjectOutputDir[1] = '\')) then
    CurrentProjectOutputDir := Copy(CurrentProjectOutputDir, 2)
 }
  if (CurrentProjectOutputDir <> '') then begin
    if (CurrentProjectOutputDir[1] = '.') then begin // relative path
    s := Trim(ExtractFilePath(Project.FileName));
    if s = '' then
      CurrentProjectOutputDir := ''
    else
      CurrentProjectOutputDir := IncludeTrailingBackslash(s) + CurrentProjectOutputDir;
    end
    else
    if Pos('$(DELPHI)', UpperCase(CurrentProjectOutputDir)) > 0 then begin
      DelphiPath := GetEnvironmentVariable('DELPHI');
      CurrentProjectOutputDir := StringReplace(CurrentProjectOutputDir, '$(DELPHI)', DelphiPath, [rfReplaceAll, rfIgnoreCase]);
  end;
  end
  else
    CurrentProjectOutputDir := Trim(ExtractFilePath(Project.FileName));
  //OFS('  ' + CurrentProjectOutputDir);
end;
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}

procedure Register;
begin
  // Register property editors
{$IFNDEF STD}
  RegisterPropertyEditor(TypeInfo(TStrings), TMyEmbConnection, 'Params', TDAPropertyEditor);
{$ENDIF}
  RegisterPropertyEditor(TypeInfo(String), TCustomMyConnectionOptions, 'Charset', TMyConnectionOptionsCharsetEditor);
{$IFNDEF STD}
  RegisterPropertyEditor(TypeInfo(TCustomConnectDialog), TMyEmbConnection, 'ConnectDialog', TMyConnectDialogPropertyEditor);
{$ENDIF}
{$IFDEF HAVE_OPENSSL}
  RegisterPropertyEditor(TypeInfo(String), TMyConnectionSSLOptions, 'Key', TPemFileNameProperty);
  RegisterPropertyEditor(TypeInfo(String), TMyConnectionSSLOptions, 'Cert', TPemFileNameProperty);
  RegisterPropertyEditor(TypeInfo(String), TMyConnectionSSLOptions, 'CACert', TPemFileNameProperty);
{$ENDIF}

  RegisterPropertyEditor(TypeInfo(Boolean), TMyConnection, 'Embedded', nil);
  RegisterPropertyEditor(TypeInfo(string), TMyConnection, 'Server', TMyServerNamePropertyEditor);
  RegisterPropertyEditor(TypeInfo(TCustomConnectDialog), TMyConnection, 'ConnectDialog', TMyConnectDialogPropertyEditor);

  RegisterPropertyEditor(TypeInfo(TStrings), TMyQuery, 'SQL', TDAPropertyEditor);
  RegisterPropertyEditor(TypeInfo(TStrings), TMyQuery, 'SQLDelete', TDAPropertyEditor);
  RegisterPropertyEditor(TypeInfo(TStrings), TMyQuery, 'SQLInsert', TDAPropertyEditor);
  RegisterPropertyEditor(TypeInfo(TStrings), TMyQuery, 'SQLLock', TDAPropertyEditor);
  RegisterPropertyEditor(TypeInfo(TStrings), TMyQuery, 'SQLRecCount', TDAPropertyEditor);
  RegisterPropertyEditor(TypeInfo(TStrings), TMyQuery, 'SQLRefresh', TDAPropertyEditor);
  RegisterPropertyEditor(TypeInfo(TStrings), TMyQuery, 'SQLUpdate', TDAPropertyEditor);
  RegisterPropertyEditor(TypeInfo(Boolean), TMyDataSetOptions, 'TrimFixedChar', nil);

  RegisterPropertyEditor(TypeInfo(TStrings), TMyCommand, 'SQL', TDAPropertyEditor);

  RegisterPropertyEditor(TypeInfo(TStrings), TMyScript, 'SQL', TDAPropertyEditor);
{$IFNDEF STD}
  RegisterPropertyEditor(TypeInfo(TDAColumnDataType), TMyColumn, 'DataType', nil);
{$ENDIF}

  RegisterPropertyEditor(TypeInfo(TStrings), TMyStoredProc, 'SQL', nil);
  RegisterPropertyEditor(TypeInfo(TStrings), TMyStoredProc, 'SQLDelete', TDAPropertyEditor);
  RegisterPropertyEditor(TypeInfo(TStrings), TMyStoredProc, 'SQLInsert', TDAPropertyEditor);
  RegisterPropertyEditor(TypeInfo(TStrings), TMyStoredProc, 'SQLLock', TDAPropertyEditor);
  RegisterPropertyEditor(TypeInfo(TStrings), TMyStoredProc, 'SQLRecCount', TDAPropertyEditor);
  RegisterPropertyEditor(TypeInfo(TStrings), TMyStoredProc, 'SQLRefresh', TDAPropertyEditor);
  RegisterPropertyEditor(TypeInfo(TStrings), TMyStoredProc, 'SQLUpdate', TDAPropertyEditor);

  RegisterPropertyEditor(TypeInfo(TStrings), TMyUpdateSQL, 'InsertSQL', TDAPropertyEditor);
  RegisterPropertyEditor(TypeInfo(TStrings), TMyUpdateSQL, 'ModifySQL', TDAPropertyEditor);
  RegisterPropertyEditor(TypeInfo(TStrings), TMyUpdateSQL, 'DeleteSQL', TDAPropertyEditor);
  RegisterPropertyEditor(TypeInfo(TStrings), TMyUpdateSQL, 'RefreshSQL', TDAPropertyEditor);
  RegisterPropertyEditor(TypeInfo(TStrings), TMyUpdateSQL, 'LockSQL', TDAPropertyEditor);

{$IFNDEF STD}
  RegisterPropertyEditor(TypeInfo(string), TMyServerControl, 'TableNames', TMyTableNamesEditor);
  RegisterPropertyEditor(TypeInfo(string), TMyDump, 'TableNames', TMyTableNamesEditor);
  RegisterPropertyEditor(TypeInfo(string), TMyDump, 'StoredProcNames', TMyStoredProcNamesEditor);
  RegisterPropertyEditor(TypeInfo(string), TMyBackup, 'TableNames', TMyTableNamesEditor);
{$ENDIF}

  RegisterPropertyEditor(TypeInfo(string), TMyTableOptions, 'HandlerIndex', TMyTableOptionsHandlerIndexEditor);

  // Register component editors
  DARegisterComponentEditor(TCustomMyConnection, TMyConnectionEditor, TMyConnectionEditorForm, TMyDesignUtils);
  DARegisterComponentEditor(TMyCommand, TMyCommandEditor, TMyCommandEditorForm, TMyDesignUtils);
  DARegisterComponentEditor(TMyQuery, TMyQueryEditor, TMyQueryEditorForm, TMyDesignUtils);
  DARegisterComponentEditor(TMyTable, TMyTableEditor, TMyTableEditorForm, TMyDesignUtils);
  DARegisterComponentEditor(TMyStoredProc, TMyStoredProcEditor, TMyStoredProcEditorForm, TMyDesignUtils);
  DARegisterComponentEditor(TMyUpdateSQL, TMyUpdateSQLEditor, TMyUpdateSQLEditorForm, TMyDesignUtils);
  DARegisterComponentEditor(TMyScript, TMyScriptEditor, TDAScriptEditorForm, TMyDesignUtils);
{$IFNDEF STD}
  DARegisterComponentEditor(TMyServerControl, TMyServerControlEditor, TMyServerControlEditorForm, TMyDesignUtils);
  DARegisterComponentEditor(TMyBackup, TMyBackupEditor, nil, TMyDesignUtils);
  DARegisterComponentEditor(TMyLoader, TDALoaderEditor, nil, TMyDesignUtils);
  DARegisterComponentEditor(TMyDump, TMyDumpEditor, TMyDumpEditorForm, TMyDesignUtils);
{$ENDIF}
  DARegisterComponentEditor(TMyMetaData, TDAComponentEditor, nil, TMyDesignUtils);
{$IFNDEF FPC}
  RegisterComponentEditor(TMyDataSource, TCRDataSourceEditor);
{$ENDIF}

{$IFDEF MSWINDOWS}
{$IFNDEF FPC}
  Menu.AddItems({$IFDEF CLR}WinUtils{$ELSE}SysInit{$ENDIF}.HInstance);
{$ENDIF}
{$ENDIF}
end;

{$IFNDEF FPC}
{$IFDEF VER6P}
var
  Notificator: IDesignNotification;
{$ENDIF}
{$ENDIF}

initialization
{$IFDEF DBTOOLS}
  if not Assigned(DBTools) then
    DBTools := TDBTools.Create;
{$ENDIF}

{$IFDEF VER6P}
{$IFNDEF FPC}
  Notificator := TMyDesignNotification.Create;
  RegisterDesignNotification(Notificator);
{$ENDIF}
{$ENDIF}

finalization
{$IFDEF VER6P}
{$IFNDEF FPC}
  UnRegisterDesignNotification(Notificator);
  Notificator := nil;
{$ENDIF}
{$ENDIF}

end.
