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,
  UtlType, PropUtl, WinUtl, BtnEdit,
  ULRecTyp, ULObju, ULEdUtl{, UlanType}
  ;

{!! SEE ULObjAct.ChildBtnEditClick for editing the values from ULStringGrid }

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}
    {v0.24}
    FInfo:longint;
    FModified: boolean;
    {/v0.24}
    {v0.25}
    FObj: TULObj;
    {/v0.25}
    procedure ComponentsToObj;virtual;
      { Copy values of visual edit components to properties of Obj TULObj }
    procedure ObjToComponents(AlsoToFocused:boolean);virtual;{uldrfrmu}
      { Copy values of properties of Obj TULObj to visual edit components }
    procedure FindBtns;
    {v0.24}
    procedure CMChanged(var Msg:TCMChanged);message CM_CHANGED;
    procedure BtnEditClick(Sender: TObject);
    {/v0.24}
    {v0.25}
    procedure SetObj(AObj: TULObj);
    function GetObj: TULObj;
    {/v0.25}
    {v0.47}
    procedure FindBtnEdits;
    {/v0.47}
    {v0.53}
    procedure SetModified(OnOff: boolean);virtual;
    {/v0.53}
  public
    { Public declarations }
    {v0.25}
    {/v0.25
    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}
    {v0.24}
    property Modified: boolean read FModified {v0.53} write SetModified{/v0.53};
    {/v0.24}
    {v0.25}
    property Obj: TULObj read GetObj write SetObj;
    {/v0.25}
  end;

var
  ULEditForm: TULEditForm;

implementation

{$R *.DFM}

constructor TULEditForm.Create(AOwner: TComponent);
var o: TULObj;
{v0.24}
{v0.47}{/v0.47 c: TControl;
  i: integer;}
{/v0.24}
begin
  inherited Create(AOwner);
  {v0.25}
  if CurULObj <> nil then
  {/v0.25}
  begin
    o := CurULObj;
    CurULObj := nil;
    SetObj(o);
  end;
{  Obj.UserRegister(Self);}
  KeyPreview := true;
  {v0.24}
  {v0.47 moved to form activate}
  {/v0.47
  for i := 0 to ControlCount - 1 do begin
    c := Controls[i];
    if c is TBtnEdit then begin
      TBtnEdit(c).OnBtnClick := BtnEditClick;
      TBtnEdit(c).EmptyAllowed := true;
    end;
  end;}
  {/v0.24}
end;

procedure TULEditForm.ObjToComponents(AlsoToFocused:boolean);{language}
begin
  {v0.24}
  if not AlsoToFocused then begin
    ULObjToForm(Obj, Self, [foCaption, foExcludeFocused], FObjRootFileDir)
  end else
  {/v0.24}
  begin
    ULObjToForm(Obj, Self, [foCaption], FObjRootFileDir)
  end;
  {v0.24}
  FModified := false; {perform}
  {/v0.24}
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}
      {v0.47}
      if c.Name = 'ParamsBtn' then begin
        FParamBtn := TButton(c);
      end;
      {/v0.47
      if Caption = '&Parameters' then
        FParamBtn := TButton(c);}
    end;
  end;
end;

procedure TULEditForm.ComponentsToObj;
{v0.13}
begin
  FormToULObj(Self, Obj, [foCaption], FObjRootFileDir);
  {v0.53}
  Modified := false;
  {/v0.53}
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;                    {amorfrmu}
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;
      SetObj(nil);
    end;
    Release;
  end;
  {v0.24}
  ModalResult := mrOK;
  {/v0.24}
end;

procedure TULEditForm.DoOnCancel;
{v0.24}
var o:TULObj;
{/v0.24}
begin
  if not (fsModal in FormState) then begin
    ObjToComponents(true);
    if (Obj <> nil) and Obj.JustCreated then begin
      {v0.23}{/v0.23
      Obj.Free;}
      {v0.24}
      o := Obj;
      SetObj(nil);
      o.Free;
      {/v0.24
      SetObj(nil);}
    end;
    Release;
  end;
end;
{/v0.13}
{v0.14}
procedure TULEditForm.DoOnParam;
begin
  if Obj <> nil then begin
    ComponentsToObj;
    {v0.47}
    Obj.Browse;
    {/v0.47}
  end;
end;
{/v0.14}

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

    cmULObjCanDestroy: begin
      {v0.23}{/v0.23
      if TULObj(Msg.lParam) = Obj then
        Msg.Result := 1;}
    end;

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

    cmULObjDestroyed: begin
      if TULObj(Msg.lParam) = Obj then begin
        {v0.23}
        SetObj(nil);
        {/v0.23
        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
  {v0.24}
  if AObj = {v0.25}FObj{/v0.25 Obj and all below:} then
    exit;
  {/v0.24}
  if FObj <> nil then begin
    FObj.UserUnregister(Self);
  end;
  FObj := AObj;
  if FObj <> nil then begin
    FObj.UserRegister(Self);
    FObjRootFileDir := FObj.RootFileDir;
  end else begin
    FObjRootFileDir := '';
  end;
end;

destructor TULEditForm.Destroy;
begin
  {v0.25}
  Obj := nil;
  {/v0.25
  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.FindBtnEdits;
var
  i: integer;
  c: TControl;
begin
  for i := 0 to ControlCount - 1 do begin
    c := Controls[i];
    if c is TBtnEdit then begin
      TBtnEdit(c).OnBtnClick := BtnEditClick;
      TBtnEdit(c).EmptyAllowed := true;
    end;
  end;
end;

procedure TULEditForm.FormActivate(Sender: TObject);
begin
  {v0.47}
  FindBtnEdits;
  {/v0.47}
  ObjToComponents(true);
  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, FOKBt.Handle);
  end;
}
end;

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

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

{v0.24}
procedure TULEditForm.BtnEditClick(Sender: TObject);
var
  e: TBtnEdit;
  f: TULObjField;
  s: string;
  d: string;
  {v0.36}
  ext: string;
  n: string;
  {/v0.36}
  {v0.44}
  l: integer;
  {/v0.44}
begin {ulmtype}
  e := TBtnEdit(TButton(Sender).Owner);{ulobjact}
  f := Obj.Fields[e.Tag];
  if f.FldDesc.IsFileName then begin
    {v0.50}
    f.DefDirNeeded;
    {/v0.50}
    {v0.36}
    FileNameSplit(e.Text, d, n, ext);
    if d = '' then begin
      d := f.FldDesc.DefDir;
      if d = '' then
        d := FObjRootFileDir;
    end;
    if ext = '' then
      ext := f.FldDesc.DefExt;
    s := AbsoluteFileName(d, n, ext);
    {/v0.36
    if ExtractFilePath(e.Text) = '' then begin
      d := f.FldDesc.DefDir;
      if d = '' then
        d := FObjRootFileDir;
      s := AbsoluteFileName(d, e.Text);
    end else begin
      d := '';
      s := e.Text;
    end;
    }
    if f.FieldFileNameOpenSelect(s) then begin
      e.Text := RelativeFileName(d, s{v0.36}, ext{/v0.36});
    end;
  end else if f.FldDesc.IsDir then begin
    s := e.Text;{ulstringgrid}
    if f.DirSelect(s) then begin{ulobju}
      e.Text := s;
    end;
  end{v0.44} else if f.FldDesc.IsSetType then begin
    {checklistfrm}
    {v0.47}
    if e.Text = '' then
      l := 0
    else
    {/v0.47}
      l := StrToInt(e.Text);
    if f.FldDesc.CheckListBoxFormExecute(l) then begin
      e.Text := IntToStr(l);
    end;
  { called for ULObj Set properties from uledfrm,ulstringgrid }

  end{/v0.44};
end;

procedure TULEditForm.CMChanged(var Msg:TCMChanged);
begin
  FInfo := 0;
  {v0.53}
  Modified := true;
  {/v0.53
  FModified := true;}
end;
{/v0.24}
{v0.53}
procedure TULEditForm.SetModified(OnOff: boolean);
begin
  if OnOff then begin
    FModified := true;
  end else begin
    FModified := false;
  end;
end;
{/v0.53}

{v0.25}
function TULEditForm.GetObj: TULObj;
begin
  if FObj = nil then begin
    Obj := CurULObj;
    CurULObj := nil;
  end;
  Result := FObj;
end;
{/v0.25}


end.
