unit ULEdFrm;
{ Ancestor for all TULxObj objects (see ULObju.pas) edit
  forms. Should not be used directly but through TULXEditForm.
  Here is implemented common functionality for all ULObjects.
  Both ULEDFRM and ULXEDFRM are in object repository. }
interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls,
  MyType, UlanType, ULRecTyp, ULObju, PropUtl{v0.13}, WinUtl, ULEdUtl{/v0.13};

type
  TULEditForm = class(TForm)
    procedure FormActivate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  protected
    FOKBtn: TButton;
    FCancelBtn: TButton;
    {v0.14}
    FParamBtn: TButton;
    {/v0.14}
    {v0.13}
    FObjRootFileDir: string;
      { Path of the file from which is the Obj,
        used to create relative filenames set to Text properties. }
    {/v0.13}
    procedure ComponentsToObj;virtual;
      { Copy values of visual edit components to properties of Obj TULObj }
    procedure ObjToComponents;virtual;
      { Copy values of properties of Obj TULObj to visual edit components }
    procedure FindBtns;
  public
    { Public declarations }
    Obj: TULObj;
    procedure SetObj(AObj: TULObj);
    procedure WMAppMessage(var Msg: TMessage); message WM_APPMESSAGE;
    procedure WMCommand(var Msg: TWMCommand); message WM_COMMAND;
    procedure WMKeyDown(var Msg: TWMKey); message WM_KEYDOWN;{windows messages}
    procedure WndProc(var Message: TMessage); override;
    constructor Create(AOwner: TComponent); reintroduce;
    destructor Destroy; override;
    function CloseQuery: boolean; override;
    {v0.13}
    procedure DoOnOK;
    procedure DoOnCancel;
    {/v0.13}
    {v0.14}
    procedure DoOnParam;
    {/v0.14}
  end;

var
  ULEditForm: TULEditForm;

implementation

{$R *.DFM}

constructor TULEditForm.Create(AOwner: TComponent);
var o: TULObj;
begin
  inherited Create(AOwner);
  o := CurULObj;
  CurULObj := nil;
  SetObj(o);
{  Obj.UserRegister(Self);}
end;

procedure TULEditForm.ObjToComponents;
begin
  ULObjToForm(Obj, Self, [foCaption], FObjRootFileDir);
end;

(*
var
  c: TObject;
  pn, n: shortstring;
  v: string;
  i, j: integer;
{v0.13}
  dt: TDateTime;
{/v0.13}
begin
  if Obj = nil then
    exit;
  {v0.13}
  GetDir(0, FObjRootFileDir);
  {/v0.13}
{  i := 0;}
  Caption := Obj.ObjDesc.Caption;
  for i := 0 to Obj.ObjDesc.FieldCount - 1 do begin
    pn := Obj.ObjDesc.Fields[i].Name;
    v := Obj.Fields[i].UsrValue;
    n := pn + 'Edit';
    for j := 0 to ComponentCount - 1 do begin
      c := Components[j];
      if c is TEdit then begin
        with c as TEdit do {v0.13 if force or (not Modified) then{/v0.13} begin
          if Name = n then begin
            {v0.13}
            if Obj.Fields[i].FldDesc.IsFileName then begin
              Text := RelativeFileName(FObjRootFileDir, v);
            end else
            {/v0.13}
            begin
              Text := v;
            end;
          end;
        end;
      end else if c is TComboBox then begin
        with c as TComboBox do {v0.13 if force or (not Modified) then{/v0.13} begin
          if Name = n then begin
            FillEnumNames(Obj, pn, Items);
            Text := v;
          end;
        end;
      end else if c is TCheckBox then {v0.13 if force or (not Modified) then{/v0.13} begin
        with c as TCheckBox do begin
          if Name = n then begin
            Checked := (v = 'True');
          end;
        end;
      end;
    end;
  end;
end;
*)

procedure TULEditForm.FindBtns;
var
  c: TComponent;
  i: integer;
begin
  for i := 0 to ComponentCount - 1 do begin
    c := Components[i];
    if c is TButton then with c as TButton do begin
      if ModalResult = mrOK {Caption = '&OK'} then
        FOKBtn := TButton(c);
      if ModalResult = mrCancel {Caption = '&Cancel'} then
        FCancelBtn := TButton(c);
      {v0.14}
      if Caption = '&Parameters' then
        FParamBtn := TButton(c);
    end;
  end;
end;

procedure TULEditForm.ComponentsToObj;
{v0.13}
begin
  FormToULObj(Self, Obj, [foCaption], FObjRootFileDir);
end;
{/v0.13
var
  c: TObject;
  n: shortstring;
  v: string;
  i: integer;
  f: TULObjField;
  d: string;
  dch:boolean;

begin
  if Obj = nil then
    exit;
  for i := 0 to ComponentCount - 1 do begin
    c := TObject(Components[i]);
    if c is TEdit then begin
      with c as TEdit do begin
        n := copy(Name, 1, length(Name) - 4);
        v := Text;
        f := Obj.FindField(n);
        if f.FldDesc.IsFileName then begin
          if RelativeFileName(FObjRootFileDir, f.UsrValue) <> v then begin
            f.UsrValue := v;
          end;
        end else begin
          f.UsrValue := v;
        end;
      end;
    end else if c is TComboBox then begin
      with c as TComboBox do begin
        n := copy(Name, 1, length(Name) - 4);
        v := Text;
        Obj.FindField(n).UsrValue := v;
      end;
    end else if c is TCheckBox then begin
      with c as TCheckBox do begin
        n := copy(Name, 1, length(Name) - 4);
        if Checked then
          v := 'True'
        else
          v := 'False';
        Obj.FindField(n).UsrValue := v;
      end;
    end;
  end;
  SendMessage(Application.MainForm.Handle, WM_APPMESSAGE, cmULObjAfterEdit,
    longint(Obj));
end;
}


procedure TULEditForm.WndProc(var Message: TMessage);
begin
  case Message.Msg of      {windowProc}
    WM_CHAR, WM_KeyDown{, WM_SYSKEYDOWN, WM_COMMAND, WM_SYSCOMMAND}: begin
      if Message.WParam = vk_Return then begin
        Message.Result := 0;
        PostMessage(Handle, WM_Command, 0, FOKBtn.Handle);
      end;
    end;
  end;
  inherited;
end;

procedure TULEditForm.WMKeyDown(var Msg: TWMKey);
begin
  if Msg.CharCode = vk_Return then begin
    Msg.Result := 0;
    PostMessage(Handle, WM_Command, 0, FOKBtn.Handle);
  end;
end;

procedure TULEditForm.WMCommand(var Msg: TWMCommand);
{var i: integer;}
begin
  if Msg.NotifyCode = 0 then begin
    if (FOKBtn <> nil) and (FOKBtn.Handle = Msg.Ctl) then begin
      {v0.13}
      DoOnOK;
      {/v0.13
      if not (fsModal in FormState) then begin
        if Obj <> nil then begin
          ComponentsToObj;
          Obj.SetFlag(rfJustCreated, false);
          SetObj(nil);
        end;
        Release;
      end;
      }
    end;
    if (FCancelBtn <> nil) and (FCancelBtn.Handle = Msg.Ctl) then begin
      {v0.13}
      DoOnCancel;
      {/v0.13
      if not (fsModal in FormState) then begin
        ObjToComponents;
        if (Obj <> nil) and Obj.IsFlagSet(rfJustCreated) then begin
          Obj.Free;
          SetObj(nil);
        end;
        Release;
      end;
      }
    end;
    {v0.14}
    if (FParamBtn <> nil) and (FParamBtn.Handle = Msg.Ctl) then begin
      DoOnParam;
    end;
    {/v0.14}
  end;
  inherited;
end;

{v0.13}
procedure TULEditForm.DoOnOK;
begin
  if not (fsModal in FormState) then begin
    if Obj <> nil then begin
      ComponentsToObj;
      Obj.SetFlag(rfJustCreated, false);
      SetObj(nil);
    end;
    Release;
  end;
end;

procedure TULEditForm.DoOnCancel;
begin
  if not (fsModal in FormState) then begin
    ObjToComponents;
    if (Obj <> nil) and Obj.IsFlagSet(rfJustCreated) then begin
      Obj.Free;
      SetObj(nil);
    end;
    Release;
  end;
end;
{/v0.13}
{v0.14}
procedure TULEditForm.DoOnParam;
begin
  if Obj <> nil then
    ComponentsToObj;
end;
{/v0.14}

procedure TULEditForm.WMAppMessage(var Msg: TMessage);
begin
  case Msg.wParam of

    cmULObjCanDestroy: begin
      if TULObj(Msg.lParam) = Obj then
        Msg.Result := 1;
    end;

    cmULObjUpdated: begin
      if TULObj(Msg.lParam) = Obj then begin
        {if not Modified then
          ObjToComponents;}
        {v0.13}
        {ObjToComponents(false);}
        {/v0.13}
      end;
    end;

    cmULObjDestroyed: begin
      if TULObj(Msg.lParam) = Obj then begin
        Obj := nil;
        Release;
      end;
    end;

    cmULObjEditFormBringToFront: begin
      if TULObj(Msg.lParam) = Obj then begin
        Msg.Result := 1;
        BringToFront;
      end;
    end;
  end;
end;

procedure TULEditForm.SetObj(AObj: TULObj);
begin
  if Obj <> nil then
    Obj.UserUnregister(Self);
  Obj := AObj;
  if Obj <> nil then begin
    Obj.UserRegister(Self);
    FObjRootFileDir := Obj.RootFileDir;
  end else begin
    FObjRootFileDir := '';
  end;
end;

destructor TULEditForm.Destroy;
begin
  SetObj(nil);
  inherited Destroy;
end;

function TULEditForm.CloseQuery: boolean;
begin
  {$IFNDEF CONSOLE}
  if (ModalResult = mrOK) and (Obj <> nil) then begin
    Result := (Obj.IsValidInput(Self));
    if Result then begin
      Result := (SendMessage(Application.MainForm.Handle, WM_APPMESSAGE, cmULEditFormCloseQuery,
        longint(Self)) = 0);
      if Result then begin
        ComponentsToObj;
      end;
    end;
  end else begin
    Result := inherited CloseQuery;
  end;
  {$ENDIF}
end;

procedure TULEditForm.FormActivate(Sender: TObject);
begin
  ObjToComponents;
  FindBtns;
  KeyPreview := true;
end;

procedure TULEditForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;

procedure TULEditForm.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
{  if Key = vk_Return then begin
    Key := 0;
    PostMessage(Handle, WM_Command, 0, FOKBtn.Handle);
  end;
}
end;

procedure TULEditForm.FormKeyPress(Sender: TObject; var Key: Char);
{var i:integer;}
begin
{  i := 0;}
end;

procedure TULEditForm.FormCreate(Sender: TObject);
begin
  KeyPreview := true;
end;

end.
