unit U_ChoiceComponType;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, RzButton, ExtCtrls, RzPanel, kbmMemTable,

  U_BaseConstants, U_BaseCommon, U_SCSComponent, RzCmboBx, siComp, siLngLnk;

type
  TF_ChoiceComponType = class(TForm)
    gbOkCancel: TRzPanel;
    btOk: TRzBitBtn;
    btCancel: TRzBitBtn;
    pnMain: TRzPanel;
    pnSysName: TRzPanel;
    pnCompType: TRzPanel;
    Label1: TLabel;
    Label2: TLabel;
    cbSysName: TRzComboBox;
    cbCompType: TRzComboBox;
    lng_Forms: TsiLangLinked;
    Timer_OpenComboSysName: TTimer;
    Timer_SetFocusCompType: TTimer;
    procedure gbOkCancelResize(Sender: TObject);
    procedure cbSysNameChange(Sender: TObject);
    procedure btOkClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure Timer_OpenComboSysNameTimer(Sender: TObject);
    procedure cbSysNameKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure cbCompTypeKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure cbSysNameClick(Sender: TObject);
    procedure cbSysNameSelEndOk(Sender: TObject);
    procedure Timer_SetFocusCompTypeTimer(Sender: TObject);

  private
    GForm: TForm;
    FSpravochnik: TSpravochnik;
    procedure OpenComboCompType(AIgnoreComboSysName: Boolean);
    procedure OnSelectComboItemSysName;
  public
    Constructor Create(AOwner: TComponent; AForm: TForm);
    Destructor Destroy; override;

    function Execute: string;
  end;

  function ExecuteChoiceComponType(AFormOwner: TForm): string;

//var
//  Form1: TForm1;

implementation

uses U_Main, Unit_DM_SCS;

{$R *.dfm}

constructor TF_ChoiceComponType.Create(AOwner: TComponent; AForm: TForm);
begin
  GForm := AForm;
  inherited Create(AOwner);
end;

destructor TF_ChoiceComponType.Destroy;
begin
  inherited;
end;

function TF_ChoiceComponType.Execute: string;
var
  MemTableSysName: TkbmMemTable;
  i: Integer;
  //CompTypeCount: Integer;
  //CompTypeName: String;
begin
  Result := '';
  try
    FSpravochnik := TF_Main(GForm).GetSpravochnik;

    cbSysName.Items.BeginUpdate;
    try
      ClearComboBoxRz(cbSysName);
      //ClearComboBoxRz(cbCompType);

      // системные имена в комбарь
      cbSysName.Sorted := true;
      AddIDGUIDToComboRz(0, '', '', cbSysName);
      MemTableSysName := TF_Main(GForm).F_MakeEditComponentType.mtSysNames;
      MemTableSysName.DisableControls;
      try
        MemTableSysName.First;
        while Not MemTableSysName.Eof do
        begin

          // Если для системного имени есть такой тип
          if FSpravochnik.GetComponentTypeObjBySysName(MemTableSysName.FieldByName(fnSysName).AsString) <> nil then
            AddIDGUIDToComboRz(0, MemTableSysName.FieldByName(fnSysName).AsString,
                MemTableSysName.FieldByName(fnDescription).AsString, cbSysName);
          MemTableSysName.Next;
        end;
      finally
        MemTableSysName.EnableControls;
      end;
      cbSysName.ItemIndex := 0;
    finally
      cbSysName.Items.EndUpdate;
    end;

    cbSysNameChange(cbSysName);

    if ShowModal = mrOk then
      Result := GetGUIDFromComboBoxRz(cbCompType);

    if cbSysName.DroppedDown then
      cbSysName.DroppedDown := false;
    if cbCompType.DroppedDown then
      cbCompType.DroppedDown := false;
  except
    on E: Exception do AddExceptionToLogEx('TF_ChoiceComponType.Execute', E.Message);
  end;
end;

procedure TF_ChoiceComponType.OpenComboCompType(AIgnoreComboSysName: Boolean);
begin
  try
    //raise Exception.Create('Test');

    cbCompType.DroppedDown := (AIgnoreComboSysName or (cbSysName.DroppedDown = false)) and
                              (cbCompType.Items.Count > 1);
  except
    on E: Exception do AddExceptionToLogEx(Self.ClassName+'.OpenComboCompType', E.Message);
  end;
end;

procedure TF_ChoiceComponType.OnSelectComboItemSysName;
begin
  OpenComboCompType(true);
  if cbCompType.DroppedDown then
    cbCompType.SetFocus;
end;

procedure TF_ChoiceComponType.gbOkCancelResize(Sender: TObject);
begin
  SetMiddleControlChilds(TControl(Sender), TControl(Self));
end;

procedure TF_ChoiceComponType.cbSysNameChange(Sender: TObject);
var
  SelectedSysName: String;
  i: Integer;
  SprCompType: TNBComponentType;
  //pnCompTypeOldVisible: Boolean;
begin
  try
    SelectedSysName := GetGUIDFromComboBoxRz(cbSysName);

    cbCompType.Items.BeginUpdate;
    try
      ClearComboBoxRz(cbCompType);
      cbCompType.Sorted := true;
      if SelectedSysName <> '' then
      begin
        // Загружаем все типы компонентов с нужным системным именем
        if FSpravochnik <> nil then
        begin
          for i := 0 to FSpravochnik.ComponentTypes.Count - 1 do
          begin
            SprCompType := TNBComponentType(FSpravochnik.ComponentTypes[i]);
            if SprCompType.ComponentType.SysName = SelectedSysName then
              AddIDGUIDToComboRz(SprCompType.ComponentType.ID,
                SprCompType.ComponentType.GUID, SprCompType.ComponentType.Name, cbCompType);
          end;
        end;
      end;

      if cbCompType.Items.Count > 0 then
        cbCompType.ItemIndex := 0;
    finally
      cbCompType.Items.EndUpdate;
    end;

    // Если количество типов компонент больше 1-цы, то отображаем выбор
    pnCompType.Visible := cbCompType.Items.Count > 0;
    pnMain.AutoSize := true;
    pnMain.AutoSize := false;
    Self.AutoSize := true;
    Self.AutoSize := false;

    OpenComboCompType(false);
  except
    on E: Exception do AddExceptionToLogEx('TF_ChoiceComponType.cbSysNameSelect', E.Message);
  end;
end;

procedure TF_ChoiceComponType.btOkClick(Sender: TObject);

  procedure ShowRequiredMessg(const AMessg: string);
  begin
    ModalResult := mrNone;
    MessageInfo(AMessg);
  end;
begin
  try
    if GetGUIDFromComboBoxRz(cbSysName) = '' then
    begin
      ShowRequiredMessg(cChoiceComponType_Msg1);
      cbSysName.SetFocus;
    end;
  except
    on E: Exception do AddExceptionToLogEx('TF_ChoiceComponType.btOkClick', E.Message);
  end;
end;

procedure TF_ChoiceComponType.FormShow(Sender: TObject);
begin
  cbSysName.SetFocus;
  Timer_OpenComboSysName.Enabled := true;
end;

procedure TF_ChoiceComponType.Timer_OpenComboSysNameTimer(Sender: TObject);
begin
  TTimer(Sender).Enabled := false;

  if cbSysName.DroppedDown then
    cbSysName.DroppedDown := false;

  if cbSysName.Items.Count > 1 then
    cbSysName.DroppedDown := true;
end;

procedure TF_ChoiceComponType.cbSysNameKeyDown(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
  // Когда соседний ComboBox открыт, то не происходит переключение фокуса по Tab
  if Key = VK_TAB then
    if cbCompType.DroppedDown then
      cbCompType.SetFocus;
  if Key = VK_RETURN then
  begin
    // OnSelectComboItemSysName; -> cbSysNameSelEndOk 
  end;
end;

procedure TF_ChoiceComponType.cbSysNameClick(Sender: TObject);
begin
  //OnSelectComboItemSysName;
end;


procedure TF_ChoiceComponType.cbCompTypeKeyDown(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
  // Когда ComboBox открыт, то по Tab переходить на Combo cbSysName
  if Key = VK_TAB then
    if cbCompType.DroppedDown then
    begin
      cbCompType.Items.BeginUpdate;
      try
        cbSysName.SetFocus;

        if Not cbCompType.DroppedDown then
          cbCompType.DroppedDown := true;
      finally
        cbCompType.Items.EndUpdate;
      end;
    end;
end;


function ExecuteChoiceComponType(AFormOwner: TForm): string;
var
  F_ChoiceComponType: TF_ChoiceComponType;
begin
  Result := '';
  try
    F_ChoiceComponType :=  TF_ChoiceComponType.Create(Application, AFormOwner);
    try
      Result := F_ChoiceComponType.Execute;
    finally
      F_ChoiceComponType.Free;
    end;
  except
    on E: Exception do AddExceptionToLogEx('ExecuteChoiceComponType', E.Message);
  end;
end;

procedure TF_ChoiceComponType.cbSysNameSelEndOk(Sender: TObject);
begin
  try
    if cbSysName.DroppedDown then
      Timer_SetFocusCompType.Enabled := true;
  except
    on E: Exception do AddExceptionToLogExt(ClassName, MethodName(@TF_ChoiceComponType.cbSysNameSelEndOk), E.Message);
  end;
end;

procedure TF_ChoiceComponType.Timer_SetFocusCompTypeTimer(Sender: TObject);
begin
  TTimer(Sender).Enabled := false;

  OnSelectComboItemSysName;
end;

end.
