unit U_ConnectComplWith;

interface

uses
  Windows, U_LNG, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, cxLookAndFeelPainters, ComCtrls, StdCtrls, cxButtons, ExtCtrls,
  RzPanel,

  U_BaseCommon, U_BaseConstants, U_Common, U_SCSComponent, cxControls, cxContainer, cxEdit,
  cxTextEdit, cxMaskEdit, cxSpinEdit, RzButton, RzRadChk, ToolWin, ImgList,
  RzTreeVw, siComp, siLngLnk, RapTree, Mask, RzEdit, cxGraphics, cxLookAndFeels,
  Menus;

type
  TConnectComplWithFormMode = (
                               ccwConnectComplWith,
                               ccwDefineReplaceCompon,
                               ccwDefineReplaceCableCanal,
                               ccwDefineCableCanalConnector,
                               ccwDefineCableForJoinToPoints,
                               ccwGetComponentFromNB,
                               ccwDefineTubeConnector // Tolik 15/11/2021 --
                               );

  TF_ConnectComplWith = class(TForm)
    RzPanel1: TRzPanel;
    Panel_OkCancel: TRzPanel;
    Button_OK: TcxButton;
    Button_Cancel: TcxButton;
    pnApplyForCurrList: TRzPanel;
    cbApplyForCurrList: TRzCheckBox;
    pnConnectBy: TRzPanel;
    pnComponents: TRzPanel;
    Panel_FullMorePercent: TRzPanel;
    Label1: TLabel;
    Label2: TLabel;
    SpinEdit_FullMorePercent: TcxSpinEdit;
    GroupBox_ConnectWith: TRzGroupBox;
    ListView_ConnectWith: TListView;
    Panel_ComponFullnessPercent: TRzPanel;
    Label_ComponFullness: TLabel;
    Splitter: TSplitter;
    GroupBox_ConnectBy: TRzGroupBox;
    lbNBNodeInfo: TLabel;
    pnReplaceCanalsInfo: TRzPanel;
    GroupBox_ReplaceInfo: TRzGroupBox;
    Memo_ReplaceInfo: TMemo;
    splReplaceInfo: TSplitter;
    gbComponentsToReplace: TRzGroupBox;
    lvComponentsToBeReplace: TListView;
    tvComponentsToBeReplace: TRzCheckTree;
    splReplaceCanalsInfo: TSplitter;
    cbApplyForComplects: TRzCheckBox;
    cbLeaveComplectsInTarget: TRzCheckBox;
    lng_Forms: TsiLangLinked;
    pnNewComponIndex: TPanel;
    Label3: TLabel;
    neNewComponIndex: TRzNumericEdit;
    Label4: TLabel;
    cbApplyForCurrProj: TRzCheckBox;
    cbApplyForOnlySelected: TRzCheckBox;
    procedure FormHide(Sender: TObject);
    procedure ListView_ConnectWithChange(Sender: TObject; Item: TListItem;
      Change: TItemChange);
    procedure ListView_ConnectByChange(Sender: TObject; Item: TListItem;
      Change: TItemChange);
    procedure Button_OKClick(Sender: TObject);
    procedure Panel_OkCancelResize(Sender: TObject);
    procedure SpinEdit_FullMorePercentPropertiesChange(Sender: TObject);
    procedure ListView_ConnectWithSelectItem(Sender: TObject;
      Item: TListItem; Selected: Boolean);
    procedure lvComponentsToBeReplaceSelectItem(Sender: TObject;
      Item: TListItem; Selected: Boolean);
    procedure tvComponentsToBeReplaceStateChange(Sender: TObject;
      Node: TTreeNode; NewState: TRzCheckState);
    procedure tvComponentsToBeReplaceChange(Sender: TObject;
      Node: TTreeNode);
    procedure SpinEdit_FullMorePercentKeyPress(Sender: TObject;
      var Key: Char);
    procedure cbApplyForCurrListClick(Sender: TObject);
    procedure cbApplyForCurrProjClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    GForm: TForm;
    FFormMode: TConnectComplWithFormMode;

    FCanChangeTreeInMainForm: Boolean;
    FCurrNode: TTreeNode;
    FComponent: TSCSComponent;
    FConnectCompon: TSCSComponent;

    FAllCableCanals: TSCSComponents;
    FCableCanalsToCanReplace: TSCSComponents;
    FCableCanalsToBeReplace: TSCSComponents;
    FMaxCableCanalToReplaceVolume: Double;
    FMinNBCableCanalVolume: Double;

    FReplaceComponent: TSCSComponent;
    FEditComponent: TSCSComponent;
    FNBComponent: TSCSComponent;
    FNBComponentTypeGUID: String;
    FNBComponentType: TNBComponentType;
    FPointComponentFrom: TSCSComponent;
    FPointComponentTo: TSCSComponent;

    FFromResources: Boolean;

    FSavedNBlvTemplatesSelectItem: TLVSelectItemEvent;
    FSavedNBpcObjectsChange: TNotifyEvent;
    FSavedNBtvComponGroupsChange: TFTVChangedEvent;

    FNormBase: TForm;

    procedure ActivateFNormBase(ACompTypesToFilter: TStringList; const ACompTypeSysName: string);
    procedure HideCableCanalPanels(AHide: Boolean);
    procedure LoadCanalsToBeReplace;
    procedure PrepareBeforeShow;
    procedure SetControls;

    // Event Handlers
    procedure Tree_CatalogChange(Sender: TObject; Node: TTreeNode);
    procedure Tree_CatalogDblClick(Sender: TObject);
    procedure NBlvTemplatesSelectItem(Sender: TObject; Item: TListItem; Selected: Boolean);
    procedure NBlvTemplatesDblClick(Sender: TObject);
    procedure NBpcObjectsChange(Sender: TObject);
    procedure NBtvComponGroupsChange(Sender: TObject; Node: TFlyNode);

    procedure AfterChangeNBCompon;
    procedure AfterDblClickNBCompon;
    procedure OnApplyForAllChanged;
  public

    constructor Create(AOwner: TComponent; AForm: TForm);
    destructor  Destroy; override;

    procedure ConnectComplWith(ACurrNode: TTreeNode);
    function DefineReplaceComponent(ACanReplace: TSCSComponents; var ACanReplaceIndex: Integer; AFromResources: Boolean): TSCSComponent;
    function DefineReplaceCableCanal(ACableCanals: TSCSComponents; var AReplaceCableCanals: TSCSComponents): TSCSComponent;
    function DefineCableCanalConnector(ACableCanal: TSCSComponent; AIDCurrConnector: Integer): TSCSComponent;
    //Tolik 15/11/2021 --
    function DefineTubeConnector(ATube: TSCSComponent; AIDCurrConnector: Integer): TSCSComponent;
    //
    function DefineCableForJoinToPoints(APointComponFrom, APointComponTo: TSCSComponent; ADefCableGUID: String = ''): TSCSComponent;
    function GetComponentFromNB(AIDCurrComponent: Integer; AByGUIDComponentType: String): TSCSComponent;

    //procedure ClearListView(AListView: TListView);
    procedure FillListViewBySCSComponents(AListView: TListView; ASCSComponents: TSCSComponents);
    function GetInterfListThatCanConnectCompons(ACompon1, ACompon2: TSCSComponent): TList;
    //function GetComponsThatCanConnectCompons(ACompon1, ACompon2: TSCSComponent): TList;
  end;

//var
//  F_ConnectComplWith: TF_ConnectComplWith;

implementation
Uses U_Main, Unit_DM_SCS;
{$R *.dfm}

{ TF_ConnectComplWith }

constructor TF_ConnectComplWith.Create(AOwner: TComponent; AForm: TForm);
begin
  GForm := AForm;
  Inherited Create(AOwner);

  lbNBNodeInfo.Caption := '';
end;

procedure TF_ConnectComplWith.FormCreate(Sender: TObject);
begin
  FFromResources := false;
end;


destructor TF_ConnectComplWith.Destroy;
begin

  inherited;
end;

procedure TF_ConnectComplWith.FormHide(Sender: TObject);
begin
    try
      ListView_ConnectWith.Clear; //ClearListView(ListView_ConnectWith);

      //FComponent.Free;
      //FConnectCompon.Free;
      FNormBase.Free;

      //*** Перейти на ветвь
      if Assigned(FCurrNode) then
        TF_Main(GForm).Tree_Catalog.Selected := FCurrNode;
      FCurrNode := nil;
      //HideCableCanalPanels;
    except
      on E: Exception do AddExceptionToLog('TF_ConnectComplWith.FormHide: '+E.Message);
    end;
end;



procedure TF_ConnectComplWith.ListView_ConnectWithChange(Sender: TObject;
  Item: TListItem; Change: TItemChange);
var Node: TTreeNode;
    FullnessPercent: Double;
    ComponentWithMaxFullness: TSCSComponent;
    CurrVolume: Double;
    i: Integer;
begin   (*
    try
      //FConnectCompon.LoadComponentByID(Integer(Item.Data^));
      //FConnectCompon.LoadAllSCSComplects(cdNone);
      Label_ComponFullness.Caption := '';
      Memo_ReplaceInfo.Lines.Clear;
      if Assigned(Item) then
        begin
            FConnectCompon := nil;
            FConnectCompon := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(Integer(Item.Data^));
            case FFormMode of
              ccwDefineReplaceCableCanal:
                  if Assigned(FConnectCompon) then
                    begin
                        FullnessPercent := FConnectCompon.GetFullnessPercentCableCanal;
                        CurrVolume := FConnectCompon.GetVolume(gtFemale);
                        ComponentWithMaxFullness := FConnectCompon;

                        //*** Найти компонент с таким же вместимым объемом, но с большей заполненностью
                        for i := 0 to FCableCanalsToReplace.Count - 1 do
                          if Assigned(FCableCanalsToReplace[i]) then
                            if FCableCanalsToReplace[i].ID <> FConnectCompon.ID then
                              if FCableCanalsToReplace[i].GetFullnessPercentCableCanal > FullnessPercent then
                                if Abs(FCableCanalsToReplace[i].GetVolume(gtFemale) - CurrVolume) < 0.01 then
                                  begin
                                      FullnessPercent := FCableCanalsToReplace[i].GetFullnessPercentCableCanal;
                                      ComponentWithMaxFullness := FCableCanalsToReplace[i];
                                  end;


                        if (FullnessPercent <> -1) and (SpinEdit_FullMorePercent.Value <> 0) then
                          begin
                              FMinNBCableCanalVolume := -1;
                              FMinNBCableCanalVolume := RoundX(ComponentWithMaxFullness.GetCablesVolume * (100/SpinEdit_FullMorePercent.Value), 3);
                              Label_ComponFullness.Caption := 'Компонент "'+FConnectCompon.Name+'" с сечением '+FloatTostr(FConnectCompon.GetVolume(gtFemale))+' см2 заполнен на '+FloatTostr(FConnectCompon.GetFullnessPercentCableCanal)+' %';

                              Memo_ReplaceInfo.Lines.Text := 'Замена кабельных каналов, для коеффициента заполненности кабельнх каналов '+SpinEdit_FullMorePercent.Text+' %, с сечением '+FloatTostr(CurrVolume)+' см2.'+#10+#13+
                                                           'Требуется заменяемый кабельный канал с сечением от '+FloatToStr(FMinNBCableCanalVolume)+' см2';

                              {
                              FMinNBCableCanalVolume := RoundX(ComponentWithMaxFullness.GetCablesVolume * (100/SpinEdit_FullMorePercent.Value), 3);
                              Label_ComponFullness.Caption := 'Компонент "'+FConnectCompon.Name+'" с сечением '+FloatTostr(FConnectCompon.GetVolume(gtFemale))+' см2 заполнен на '+FloatTostr(FConnectCompon.GetFullnessPercentCableCanal)+' %';

                              Label_ReplaceInfo.Caption := 'Замена кабельных каналов, для коеффициента заполненности кабельнх каналов '+SpinEdit_FullMorePercent.Text+' %, с сечением '+FloatTostr(CurrVolume)+' см2.'+#10+#13+
                                                           'Требуется заменяемый кабельный канал с сечением от '+FloatToStr(FMinNBCableCanalVolume)+' см2';
                              }
                          end;
                    end;
            end;

            if FCanChangeTreeInMainForm then
              if Assigned(FConnectCompon) then
                begin
                    Node := nil;
                    Node := TF_Main(GForm).FindComponOrDirInTree(FConnectCompon.ID, true);
                    if Assigned(Node) then
                      TF_Main(GForm).Tree_Catalog.Selected := Node;
                end;
        end;
    except
      on E: Exception do AddExceptionToLog('TF_ConnectComplWith.ListView_ConnectWithChange: '+E.Message);
    end; *)
end;


procedure TF_ConnectComplWith.ListView_ConnectWithSelectItem(
  Sender: TObject; Item: TListItem; Selected: Boolean);
var Node: TTreeNode;
    FullnessPercent: Double;
    ComponentWithMaxFullness: TSCSComponent;
    CurrVolume: Double;
    i: Integer;
begin
  try
    //FConnectCompon.LoadComponentByID(Integer(Item.Data^));
    //FConnectCompon.LoadAllSCSComplects(cdNone);
    Label_ComponFullness.Caption := '';
    Memo_ReplaceInfo.Lines.Clear;
    if Assigned(Item) then
    begin
      FConnectCompon := nil;
      FConnectCompon := Item.Data; //TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(Integer(Item.Data^));
      case FFormMode of
        ccwDefineReplaceCableCanal:
          if Assigned(FConnectCompon) then
          begin
            FullnessPercent := FConnectCompon.GetFullnessPercentCableCanal;
            CurrVolume := FConnectCompon.GetVolume(gtFemale);

            FMinNBCableCanalVolume := Round3(FConnectCompon.GetCablesVolume * (100/SpinEdit_FullMorePercent.Value));
            Label_ComponFullness.Caption := cConnectComplWith_Msg1_1+' "'+FConnectCompon.Name+'" '+cConnectComplWith_Msg1_2+' '+
                                            FloatTostr(RoundCP(FloatInUOM(FConnectCompon.GetVolume(gtFemale), umSM, TF_Main(GForm).FUOMMin, 2)))+' '+
                                            GetNameUOM2(TF_Main(GForm).FUOMMin)+
                                            ' '+cConnectComplWith_Msg1_4+' '+FloatTostr(RoundCP(FConnectCompon.GetFullnessPercentCableCanal))+' %';

            Memo_ReplaceInfo.Lines.Text := cConnectComplWith_Msg2_1+' "'+FConnectCompon.Name+'", '+cConnectComplWith_Msg2_2+' '+SpinEdit_FullMorePercent.Text+' %, '+
              cConnectComplWith_Msg2_3+' '+FloatTostr(RoundCP(FloatInUOM(CurrVolume, umSM, TF_Main(GForm).FUOMMin, 2)))+' '+GetNameUOM2(TF_Main(GForm).FUOMMin)+'.'+#10+#13+
                                           cConnectComplWith_Msg2_5+' '+FloatToStr(RoundCP(FloatInUOM(FMinNBCableCanalVolume, umSM, TF_Main(GForm).FUOMMin, 2)))+' '+GetNameUOM2(TF_Main(GForm).FUOMMin);

            (*
            FullnessPercent := FConnectCompon.GetFullnessPercentCableCanal;
            CurrVolume := FConnectCompon.GetVolume(gtFemale);
            ComponentWithMaxFullness := FConnectCompon;

            //*** Найти компонент с таким же вместимым объемом, но с большей заполненностью
            for i := 0 to FCableCanalsToCanReplace.Count - 1 do
              if Assigned(FCableCanalsToCanReplace[i]) then
                if FCableCanalsToCanReplace[i].ID <> FConnectCompon.ID then
                  if FCableCanalsToCanReplace[i].GetFullnessPercentCableCanal > FullnessPercent then
                    if Abs(FCableCanalsToCanReplace[i].GetVolume(gtFemale) - CurrVolume) < 0.01 then
                      begin
                          FullnessPercent := FCableCanalsToCanReplace[i].GetFullnessPercentCableCanal;
                          ComponentWithMaxFullness := FCableCanalsToCanReplace[i];
                      end;


            if (FullnessPercent <> -1) and (SpinEdit_FullMorePercent.Value <> 0) then
              begin
                  FMinNBCableCanalVolume := -1;
                  FMinNBCableCanalVolume := RoundX(ComponentWithMaxFullness.GetCablesVolume * (100/SpinEdit_FullMorePercent.Value), 3);
                  Label_ComponFullness.Caption := 'Компонент "'+FConnectCompon.Name+'" с сечением '+FloatTostr(FConnectCompon.GetVolume(gtFemale))+' см2 заполнен на '+FloatTostr(FConnectCompon.GetFullnessPercentCableCanal)+' %';

                  Memo_ReplaceInfo.Lines.Text := 'Замена кабельных каналов, для коеффициента заполненности кабельнх каналов '+SpinEdit_FullMorePercent.Text+' %, с сечением '+FloatTostr(CurrVolume)+' см2.'+#10+#13+
                                               'Требуется заменяемый кабельный канал с сечением от '+FloatToStr(FMinNBCableCanalVolume)+' см2';

                  {
                  FMinNBCableCanalVolume := RoundX(ComponentWithMaxFullness.GetCablesVolume * (100/SpinEdit_FullMorePercent.Value), 3);
                  Label_ComponFullness.Caption := 'Компонент "'+FConnectCompon.Name+'" с сечением '+FloatTostr(FConnectCompon.GetVolume(gtFemale))+' см2 заполнен на '+FloatTostr(FConnectCompon.GetFullnessPercentCableCanal)+' %';

                  Label_ReplaceInfo.Caption := 'Замена кабельных каналов, для коеффициента заполненности кабельнх каналов '+SpinEdit_FullMorePercent.Text+' %, с сечением '+FloatTostr(CurrVolume)+' см2.'+#10+#13+
                                               'Требуется заменяемый кабельный канал с сечением от '+FloatToStr(FMinNBCableCanalVolume)+' см2';
                  }
              end;   *)
          end;
      end;

      if FCanChangeTreeInMainForm then
        if Assigned(FConnectCompon) then
        begin
          Node := nil;
          Node := TF_Main(GForm).FindComponOrDirInTree(FConnectCompon.ID, true);
          if Assigned(Node) then
            TF_Main(GForm).Tree_Catalog.Selected := Node;
        end;
    end;
  except
    on E: Exception do AddExceptionToLog('TF_ConnectComplWith.ListView_ConnectWithSelectItem: '+E.Message);
  end;
end;



procedure TF_ConnectComplWith.ListView_ConnectByChange(Sender: TObject;
  Item: TListItem; Change: TItemChange);
begin
    //
end;

{
// ##### Очищает ListView #####
procedure TF_ConnectComplWith.ClearListView(AListView: TListView);
var i: Integer;
    ListItem: TListItem;
begin
    try
      for i := 0 to AListView.Items.Count - 1 do
        begin
            ListItem := AListView.Items[i];
            if ListItem.Data <> nil then
              FreeMem(ListItem.Data);
        end;
      AListView.Items.Clear;
    except
      on E: Exception do AddExceptionToLog('TF_ConnectComplWith.ClearListView: '+E.Message);
    end;
end; }


procedure TF_ConnectComplWith.FillListViewBySCSComponents(AListView: TListView; ASCSComponents: TSCSComponents);
var i: Integer;
    //ptrID: ^Integer;
    ListItem: TListItem;
    OnChangeEvent: TLVChangeEvent;
begin
  if Not Assigned(ASCSComponents) then
    Exit; //// EXIT ////
  if Not Assigned(AListView) then
    Exit; //// EXIT ////

  AListView.Items.BeginUpdate;
  OnChangeEvent := AListView.OnChange;
  AListView.OnChange := nil;
  try
    for i := 0 to ASCSComponents.Count - 1 do
      if Assigned(ASCSComponents[i]) then
      begin
        ListItem := AListView.Items.Add;
        //GetMem(ptrID, SizeOf(Integer));
        //ptrID^ := ASCSComponents[i].ID;
        ListItem.Data := ASCSComponents[i]; //ptrID;
        ListItem.Caption := ASCSComponents[i].GetNameForVisible(false);
        case ASCSComponents[i].IsLine of
          biTrue:
              ListItem.ImageIndex := tciiComponLine;
          biFalse:
              ListItem.ImageIndex := tciiComponCon;
        end;
      end;
      SetControls;
  finally
    AListView.OnChange := OnChangeEvent;
    if AListView.Items.Count > 0 then
      AListView.Selected := AListView.Items[0];
    OnChangeEvent(AListView, AListView.Selected, ctText);
    AListView.Items.EndUpdate;
  end;
end;

procedure TF_ConnectComplWith.HideCableCanalPanels(AHide: Boolean);
begin
  splReplaceCanalsInfo.Enabled := Not AHide;
  splReplaceCanalsInfo.Visible := Not AHide;
  pnReplaceCanalsInfo.Visible := Not AHide;

  //Panel_FullMorePercent.Visible := Not AHide;
  //Panel_ComponFullnessPercent.Visible := Not AHide;
  pnComponents.Visible := Not AHide;

  Panel_FullMorePercent.Visible := Not AHide;
  Panel_ComponFullnessPercent.Visible := Not AHide;
end;

procedure TF_ConnectComplWith.LoadCanalsToBeReplace;
var
  i, j, k: Integer;
  CanalToReplace: TSCSComponent;
  NBComponent: TSCSComponent;
  MinNBCableCanalVolume: Double;

  CurrCanal: TSCSComponent;
  LookedCanals: TSCSComponents;

  ComponNode: TTreeNode;
  GrpNode: TTreeNode;
begin
  NBComponent := nil;
  lvComponentsToBeReplace.Items.Clear;
  FCableCanalsToBeReplace.Clear;
  tvComponentsToBeReplace.Items.Clear;

  if Assigned(FNormBase) and (TF_Main(FNormBase).GSCSBase.SCSComponent.ID > 0) then
  begin
    NBComponent := TF_Main(FNormBase).GSCSBase.SCSComponent;
    if NBComponent.Interfaces.Count = 0 then
      NBComponent.LoadInterfaces(-1, false);
    if NBComponent.ChildComplects.Count = 0 then
        NBComponent.LoadChildComplects(true, true, true);

    for i := 0 to FCableCanalsToCanReplace.Count - 1 do
    begin
      CanalToReplace := FCableCanalsToCanReplace[i];
      MinNBCableCanalVolume := Round3(CanalToReplace.GetCablesVolume * (100/SpinEdit_FullMorePercent.Value));
      if (NBComponent.GetVolume(gtFemale) - NBComponent.GetCablesVolume) >= MinNBCableCanalVolume then
        FCableCanalsToBeReplace.Add(CanalToReplace);
    end;

    //*** Розгруппировать в CheckTreeView
    LookedCanals := TSCSComponents.Create(false);
    try
      for i := 0 to FCableCanalsToCanReplace.Count - 1 do
      begin
        CurrCanal := FCableCanalsToCanReplace[i];
        for j := 0 to FCableCanalsToCanReplace.Count - 1 do
        begin
          CanalToReplace := FCableCanalsToCanReplace[j];

          if CanalToReplace.GuidNB = CurrCanal.GuidNB then
            if LookedCanals.IndexOf(CanalToReplace) = -1 then
            begin
              // Найти ветвь с таким типом компоненты
              GrpNode := nil;
              for k := 0 to tvComponentsToBeReplace.Items.Count - 1 do
              begin
                ComponNode := tvComponentsToBeReplace.Items[k];
                if ComponNode.Data <> nil then
                  if TSCSComponent(ComponNode.Data).GuidNB = CanalToReplace.GuidNB then
                  begin
                    GrpNode := ComponNode.Parent;
                    Break; ///// BREAK /////
                  end;
              end;
              if GrpNode = nil then
              begin
                GrpNode := tvComponentsToBeReplace.Items.Add(nil, cConnectComplWith_Msg3+' "'+CanalToReplace.Name+'"');
                GrpNode.Data := nil;
                GrpNode.ImageIndex := tciiSCSLineGroup;
                GrpNode.SelectedIndex := GrpNode.ImageIndex;
                GrpNode.StateIndex := Ord(csChecked);
              end;
              if GrpNode <> nil then
              begin
                ComponNode := tvComponentsToBeReplace.Items.AddChild(GrpNode, CanalToReplace.GetNameForVisible(false));
                //ComponNode.c
                ComponNode.Data := CanalToReplace;
                ComponNode.ImageIndex := tciiComponLine;
                ComponNode.SelectedIndex := ComponNode.ImageIndex;
                ComponNode.StateIndex := Ord(csChecked);

                if Not GrpNode.Expanded then
                  GrpNode.Expanded := true;
              end;
              LookedCanals.Add(CanalToReplace);
            end;
        end;
      end;
    finally
      LookedCanals.Free;
    end;

    
    FillListViewBySCSComponents(lvComponentsToBeReplace, FCableCanalsToBeReplace);
    for i := 0 to lvComponentsToBeReplace.Items.Count - 1 do
      lvComponentsToBeReplace.Items[i].Checked := true;
  end;
  SetControls;
end;

function TF_ConnectComplWith.GetInterfListThatCanConnectCompons(ACompon1, ACompon2: TSCSComponent): TList;
var ResList: TList;
    i, j: Integer;
    InterfList1, InterfList2: TSCSInterfaces;
    Interf1, Interf2: TSCSInterface;
    ptrID: ^Integer;

    function SelectInterfacesFromComponent(AComponent: TSCSComponent): TSCSInterfaces;
    var ResList: TSCSInterfaces;
        ChildCompon : TSCSComponent;
        i: integer;
    begin
        Result := nil;
        ResList := TSCSInterfaces.Create(false);
        ResList.Assign(AComponent.Interfaces, laOr);
        for i := 0 to AComponent.ChildComplects.Count - 1 do
          begin
              ChildCompon := AComponent.ChildComplects[i];
              ResList.Assign(ChildCompon.Interfaces, laOr);
          end;
        Result := ResList;
    end;



begin
  Result := nil;
  try
    ResList := TList.Create;
    InterfList1 := SelectInterfacesFromComponent(ACompon1);
    InterfList2 := SelectInterfacesFromComponent(ACompon2);
    try
      for i := 0 to InterfList1.Count - 1 do
      begin
        Interf1 := InterfList1[i];
        if Interf1.TypeI = itFunctional then
          if CheckNoIDInList(Interf1.ID_Interface, ResList) then
            for j := 0 to InterfList1.Count - 1 do
            begin
              Interf2 := InterfList2[j];
              if Interf1.TypeI = itFunctional then
                if TF_Main(GForm).CheckInterf(Interf1, Interf2, cntUnion, nil, nil) then
                begin
                  New(ptrId);
                  ptrID^ := Interf1.ID_Interface;
                  ResList.Add(ptrID);
                end;
            end;
      end;
    finally
      FreeAndNil(InterfList1);
      FreeAndNil(InterfList2);
    end;
    Result := ResList;
  except
    on E: Exception do AddExceptionToLog('TF_ConnectComplWith.GetInterfListThatCanConnectCompons: '+E.Message);
  end;
end;


{
function TF_ConnectComplWith.GetComponsThatCanConnectCompons(ACompon1, ACompon2: TSCSComponent): TList;
var CanConnectInterfaces: TList;
    NBComponents: TList;
    NBCompon: TSCSComponent;
    i: Integer;
    ResList: TList;
begin
    Result := nil;
    try
      ResList := TList.Create;

      NBComponents := TList.Create;
      CanConnectInterfaces := GetInterfListThatCanConnectCompons(ACompon1, ACompon2);
      try
        //*** Отбор компонентов с НБ по интерфейсам
        with TF_Main(GForm).FNormBase.DM do
          begin
              ChangeSQLQuery(scsQSelect, ' select component.id, name from component, interface_relation '+
                                           ' where (isLine = '''+IntToStr(biFalse)+''') and (component.id = id_component) and '+
                                                 ' (id_interface = :id_interface) ');
              for i := 0 to CanConnectInterfaces.Count - 1 do
                begin
                    scsQSelect.Close;
                    scsQSelect.SetParamAsInteger('id_Interface', Integer(CanConnectInterfaces[i]^));
                    scsQSelect.ExecQuery;
                    while Not scsQSelect.Eof do
                      begin
                          NBCompon := TSCSComponent.Create(F_NormBase);
                          NBCompon.LoadComponentByID(scsQSelect.GetFNAsInteger('id'), false);
                          NBCompon.LoadInterfaces(-1, false);
                          
                      end;
                    scsQSelect.Close;
                end;

          end;

      finally
        FreeList(CanConnectInterfaces);
      end;
    except
      on E: Exception do AddExceptionToLog('TF_ConnectComplWith.GetComponsThatCanConnectCompons: '+E.Message);
    end;
end;
}

procedure TF_ConnectComplWith.ActivateFNormBase(ACompTypesToFilter: TStringList; const ACompTypeSysName: string);
begin
  pnNewComponIndex.Visible := FFormMode = ccwDefineCableForJoinToPoints;
  if pnNewComponIndex.Visible then
    neNewComponIndex.Value := 0;

  GGDBMode := bkNormBase;
  FNormBase := TF_Main.Create(Self, bkNormBase, fmConnections, GroupBox_ConnectBy);
  if TF_Main(FNormBase).gbTemplateGroups.GroupCount = 0 then
    TF_Main(FNormBase).LoadTemplateGroups;

  TF_Main(FNormBase).FNormBase := F_NormBase;
  TF_Main(FNormBase).FProjectMan := F_ProjMan;

  TF_Main(FNormBase).Visible := false;
  TF_Main(FNormBase).ToolBar_Tree.Visible := false;

  TF_Main(FNormBase).GSCSBase.NBSpravochnik.Assign(F_NormBase.GSCSBase.NBSpravochnik);
  TF_Main(FNormBase).HideTemplateItems(ACompTypesToFilter, true);
  TF_Main(FNormBase).HideTemplateEditingControls;

  TF_Main(FNormBase).Panel_Addition.Visible := false;
  TF_Main(FNormBase).Panel_OKCancel.Visible := false;
  //TF_Main(FNormBase).Parent := GroupBox_ConnectBy;
  TF_Main(FNormBase).Align := alClient;
  TF_Main(FNormBase).EnableDisableEdit(false);
  TF_Main(FNormBase).Tree_Catalog.PopupMenu := nil;
  TF_Main(FNormBase).Tree_Catalog.OnChange := Tree_CatalogChange;
  TF_Main(FNormBase).Tree_Catalog.OnDblClick := Tree_CatalogDblClick;

  FSavedNBlvTemplatesSelectItem := TF_Main(FNormBase).lvTemplatesSelectItem; //TF_Main(FNormBase).lvTemplates.OnSelectItem;
  FSavedNBpcObjectsChange := TF_Main(FNormBase).pcObjects.OnChange;
  FSavedNBtvComponGroupsChange := TF_Main(FNormBase).tvComponGroups.OnChange;

  TF_Main(FNormBase).lvTemplates.OnSelectItem := NBlvTemplatesSelectItem;
  TF_Main(FNormBase).lvTemplates.OnDblClick := NBlvTemplatesDblClick;

  TF_Main(FNormBase).SetEventsToLVTemplate(NBlvTemplatesSelectItem, NBlvTemplatesDblClick);
  TF_Main(FNormBase).pcObjects.OnChange := NBpcObjectsChange;
  TF_Main(FNormBase).tvComponGroups.OnChange := NBtvComponGroupsChange;

  FreeAndNil(TF_Main(FNormBase).PopupMenu_Catalog);

  //26.05.2009 TF_Main(FNormBase).GSCSBase.NBSpravochnik.Assign(F_NormBase.GSCSBase.NBSpravochnik);

  if ACompTypesToFilter <> nil then
    TF_Main(FNormBase).SetFilterBlockForCompType(ACompTypesToFilter);

  TF_Main(FNormBase).pcObjects.MultiLine := true;
  if ACompTypeSysName <> '' then
  begin
    TF_Main(FNormBase).InitComponGroup(ACompTypeSysName);
    if GetGUIDFromComboBoxRz(TF_Main(FNormBase).cbGroupCompType) <> ACompTypeSysName then
      TF_Main(FNormBase).tsComponGroups.TabVisible := false;
  end
  else
  // Tolik 24/01/2020
  //TF_Main(FNormBase).tsComponGroups.TabVisible := false;
  begin
    TF_Main(FNormBase).tsComponGroups.TabVisible := false;
    TF_Main(FNormBase).pcObjects.ActivePageIndex := 1;
  end;
  //
  TF_Main(FNormBase).Visible := true;
end;

procedure TF_ConnectComplWith.PrepareBeforeShow;
begin
  FFromResources := false;
end;

procedure TF_ConnectComplWith.SetControls;
var
  ShowConnectWith: Boolean;
  CablesToReplaceCount: Integer;
  i: Integer;
begin
  if FFormMode = ccwDefineReplaceCableCanal then
  begin
    HideCableCanalPanels(false);

    CablesToReplaceCount := 0;
    //for i := 0 to lvComponentsToBeReplace.Items.Count - 1 do
    //  if lvComponentsToBeReplace.Items[i].Checked then
    //    Inc(CablesToReplaceCount);
    for i := 0 to tvComponentsToBeReplace.Items.Count - 1 do
      if tvComponentsToBeReplace.ItemState[i] = csChecked then
        Inc(CablesToReplaceCount);

    //if ListView_ConnectWith.Items.Count > 0 then
    if CablesToReplaceCount > 0 then
      Button_OK.Enabled := true
    else
      Button_OK.Enabled := false;
  end
  else
  begin
    HideCableCanalPanels(true);
    Button_OK.Enabled := true;

    ShowConnectWith := false;
    if FFormMode = ccwConnectComplWith then
      ShowConnectWith := true;
    pnComponents.Visible := ShowConnectWith;
  end;

  ShowConnectWith := true;
  if FFormMode = ccwDefineCableCanalConnector then
    ShowConnectWith := false;

  GroupBox_ConnectWith.Visible := ShowConnectWith;
  Splitter.Visible := ShowConnectWith;

  cbApplyForCurrList.Checked := false;
  cbApplyForCurrProj.Checked := false;
  //17.08.2012 cbApplyForCurrListClick(cbApplyForCurrList);
  cbApplyForOnlySelected.Checked := false;
  if GCadForm <> nil then
    if GCadForm.PCad.SelectedCount > 1 then
      cbApplyForOnlySelected.Checked := true;
  OnApplyForAllChanged; //17.08.2012
  pnApplyForCurrList.Visible := false;
end;

procedure TF_ConnectComplWith.Tree_CatalogChange(Sender: TObject; Node: TTreeNode);
//var
//  NBCompon: TSCSComponent;
//  NBCanalVolume: Double;
begin
  //TF_Main(FNormBase).Tree_CatalogChange(Sender, Node);
  //Sleep(TF_Main(FNormBase).Timer_TreeCatalogChange.Interval+1);
  //Application.ProcessMessages;
  TF_Main(FNormBase).Timer_TreeCatalogChangeTimer(TF_Main(FNormBase).Timer_TreeCatalogChange);

  AfterChangeNBCompon; //25.05.2009

  {//25.05.2009
  lbNBNodeInfo.Caption := '';
  case FFormMode of
    ccwDefineReplaceCableCanal:
      begin
        NBCompon := TF_Main(FNormBase).GSCSBase.SCSComponent;
        if NBCompon.ID > 0 then
        begin
          if NBCompon.ComponentType.SysName <> ctsnCableChannel then
            lbNBNodeInfo.Caption := '"'+NBCompon.Name+'" '+cConnectComplWith_Msg4_1
          else
          begin
            if NBCompon.Interfaces.Count = 0 then
              NBCompon.LoadInterfaces(-1, false);
            NBCanalVolume := NBCompon.GetVolume(gtFemale);
            lbNBNodeInfo.Caption := cConnectComplWith_Msg4_2+' "'+NBCompon.Name+'" '+FloatToStr(RoundCP(FloatInUOM(NBCanalVolume, umSM, TF_Main(GForm).FUOMMin, 2)))+' '+GetNameUOM2(TF_Main(GForm).FUOMMin)+'.';
          end;
        end;
        LoadCanalsToBeReplace;
      end;
    ccwGetComponentFromNB:
      if FNBComponentTypeGUID <> '' then
        lbNBNodeInfo.Caption := cConnectComplWith_Msg5+': '+TF_Main(FNormBase).GSCSBase.SCSComponent.ComponentType.Name;
  end;}
end;

procedure TF_ConnectComplWith.Tree_CatalogDblClick(Sender: TObject);
begin
  AfterDblClickNBCompon; //25.05.2009
  {//25.05.2009
  if (FFormMode = ccwDefineCableCanalConnector) or
     (FFormMode = ccwDefineCableForJoinToPoints) or
     (FFormMode = ccwGetComponentFromNB) then
    Button_OK.Click;
  }
end;

procedure TF_ConnectComplWith.NBlvTemplatesSelectItem(Sender: TObject; Item: TListItem; Selected: Boolean);
begin
  if Assigned(FSavedNBlvTemplatesSelectItem) then
    FSavedNBlvTemplatesSelectItem(Sender, Item, Selected);

  AfterChangeNBCompon;
end;

procedure TF_ConnectComplWith.NBlvTemplatesDblClick(Sender: TObject);
begin
  AfterDblClickNBCompon;
end;

procedure TF_ConnectComplWith.NBpcObjectsChange(Sender: TObject);
begin
  if Assigned(FSavedNBpcObjectsChange) then
  begin
    FSavedNBpcObjectsChange(TF_Main(FNormBase).pcObjects);
    if TF_Main(FNormBase).Timer_TreeCatalogChange.Enabled then
      TF_Main(FNormBase).Timer_TreeCatalogChangeTimer(TF_Main(FNormBase).Timer_TreeCatalogChange);
  end;

  AfterChangeNBCompon;
end;

procedure TF_ConnectComplWith.NBtvComponGroupsChange(Sender: TObject; Node: TFlyNode);
begin
  if Assigned(FSavedNBtvComponGroupsChange) then
    FSavedNBtvComponGroupsChange(Sender, Node);

  AfterChangeNBCompon;
end;

procedure TF_ConnectComplWith.AfterChangeNBCompon;
var
  NBCompon: TSCSComponent;
  NBCanalVolume: Double;
  SprCompType: TNBComponentType;
begin
  lbNBNodeInfo.Caption := '';
  NBCompon := TF_Main(FNormBase).GSCSBase.SCSComponent;
  case FFormMode of
    ccwDefineReplaceCableCanal:
      begin
        if NBCompon.ID > 0 then
        begin
          if NBCompon.ComponentType.SysName <> ctsnCableChannel then
            lbNBNodeInfo.Caption := '"'+NBCompon.Name+'" '+cConnectComplWith_Msg4_1
          else
          begin
            if NBCompon.Interfaces.Count = 0 then
              NBCompon.LoadInterfaces(-1, false);
            NBCanalVolume := NBCompon.GetVolume(gtFemale);
            lbNBNodeInfo.Caption := cConnectComplWith_Msg4_2+' "'+NBCompon.Name+'" '+FloatToStr(RoundCP(FloatInUOM(NBCanalVolume, umSM, TF_Main(GForm).FUOMMin, 2)))+' '+GetNameUOM2(TF_Main(GForm).FUOMMin)+'.';
          end;
        end;
        LoadCanalsToBeReplace;
      end;
    ccwGetComponentFromNB:
      if FNBComponentTypeGUID <> '' then
        lbNBNodeInfo.Caption := cConnectComplWith_Msg5+': '+TF_Main(FNormBase).GSCSBase.SCSComponent.ComponentType.Name;
    ccwDefineCableForJoinToPoints:
      begin
        if pnNewComponIndex.Visible then
        begin
          SprCompType := F_ProjMan.GSCSBase.CurrProject.Spravochnik.GetComponentTypeWithAssign(NBCompon.GUIDComponentType, F_NormBase.GSCSBase.NBSpravochnik);
          if SprCompType <> nil then
            neNewComponIndex.IntValue := SprCompType.ComponentType.ComponentIndex + 1
          else
            neNewComponIndex.IntValue := 0;
        end;
      end;
  end;
end;

procedure TF_ConnectComplWith.AfterDblClickNBCompon;
begin
  if (FFormMode = ccwDefineCableCanalConnector) or
     (FFormMode = ccwDefineCableForJoinToPoints) or
     (FFormMode = ccwGetComponentFromNB) then
    Button_OK.Click;
end;

procedure TF_ConnectComplWith.ConnectComplWith(ACurrNode: TTreeNode);
var CurrNode: TTreeNode;
    ListItem: TListItem;
    NodeDat: PObjectData;
    //ptrID: ^Integer;
    SCSComplect: TSCSComponent;
begin
    FCurrNode := ACurrNode;
    FFormMode := ccwConnectComplWith;
    PrepareBeforeShow;
    SetControls;
    try
      Caption := cConnectComplWith_Msg6;
      //*** Сформировать Список Компонентов
      CurrNode := ACurrNode.Parent;
      CurrNode := CurrNode.getFirstChild;

      GroupBox_ConnectWith.Caption := cConnectComplWith_Msg7_1;
      GroupBox_ConnectBy.Caption := cConnectComplWith_Msg7_2;

      ListView_ConnectWith.OnChange := nil;
      try
        while CurrNode <> nil do
          begin
              if CurrNode <> FCurrNode then
                begin
                    NodeDat := CurrNode.Data;
                    //New(ptrID);
                    //ptrID^ := NodeDat.ObjectID;

                    SCSComplect := nil;
                    SCSComplect := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(NodeDat.ObjectID);
                    if Assigned(SCSComplect) then
                    begin
                      ListItem := ListView_ConnectWith.Items.Add;
                      ListItem.Caption := CurrNode.Text;
                      ListItem.ImageIndex := CurrNode.ImageIndex;
                      ListItem.Data := SCSComplect; //ptrID;
                    end;
                end;
              CurrNode := CurrNode.GetNextSibling;
          end;
      finally
        ListView_ConnectWith.OnChange := ListView_ConnectWithChange;
      end;
      FCanChangeTreeInMainForm := false;

      //FComponent := TSCSComponent.Create(GForm);
      //FComponent.LoadComponentByID(PObjectData(FCurrNode.Data).ObjectID, false);
      //FComponent.LoadAllSCSComplects(cdNone);
      FComponent := nil;
      FComponent := {FCurrNode.Data; //}TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(PObjectData(FCurrNode.Data).ObjectID);
      if Not Assigned(FComponent) then
        Exit; //// EXIT ////

      //FConnectCompon := TSCSComponent.Create(GForm);
      FConnectCompon := nil;
      ActivateFNormBase(nil, '');

      ShowModal;
    except
      on E: Exception do AddExceptionToLog('TF_ConnectComplWith.ConnectComplWith: '+E.Message);
    end;
end;


function TF_ConnectComplWith.DefineReplaceComponent(ACanReplace: TSCSComponents;
  var ACanReplaceIndex: Integer; AFromResources: Boolean): TSCSComponent;
var
  i: Integer;
  CompTypeGUIDs: TStringList;
  Compon: TSCSComponent;
begin
  Result := nil;
  FFormMode := ccwDefineReplaceCompon;
  PrepareBeforeShow;
  FFromResources := AFromResources;
  SetControls; //HideCableCanalPanels;

  Caption := cConnectComplWith_Msg8_1;
  FConnectCompon := nil;
  FReplaceComponent := nil;
  FNBComponent := nil;
  ACanReplaceIndex := -1;
  if Assigned(ACanReplace) then
    if ACanReplace.Count > 0 then
    begin
      GroupBox_ConnectWith.Caption := cConnectComplWith_Msg8_2;
      GroupBox_ConnectBy.Caption := cConnectComplWith_Msg8_3;

      FillListViewBySCSComponents(ListView_ConnectWith, ACanReplace);

      CompTypeGUIDs := TStringList.Create;
      CompTypeGUIDs.Sorted := true;
      for i := 0 to ACanReplace.Count - 1 do
      begin
        Compon := ACanReplace[i];
        if CompTypeGUIDs.IndexOf(Compon.GUIDComponentType) = -1 then
          CompTypeGUIDs.Add(Compon.ComponentType.SysName);
      end;

      FCanChangeTreeInMainForm := false;
      ActivateFNormBase(CompTypeGUIDs, '');

      FreeAndNil(CompTypeGUIDs);

      if ACanReplace.Count > 0 then
      begin
        pnApplyForCurrList.Visible := true;
        cbApplyForComplects.Visible := ACanReplace[0].IsLine = biFalse;
        cbLeaveComplectsInTarget.Visible := ACanReplace[0].IsLine = biFalse;

        //17.08.2012 cbApplyForCurrList.Enabled := Not AFromResources;
        cbApplyForCurrProj.Enabled := Not AFromResources;
        //17.08.2012 cbApplyForOnlySelected.Enabled := Not AFromResources;
        OnApplyForAllChanged;//17.08.2012

        //Tolik 22/04/2021 --
        {if AFromResources then
          cbApplyForCurrList.Checked := true;}

        if AFromResources then
        begin
          cbApplyForCurrList.Checked := true;
          if TF_Main(GForm).F_ReportForm.isDropComponent then
            TF_Main(FNormBase).SelectComponInPCObjectsByGUID(GDropComponent.GuidNB)
          else
            TF_Main(FNormBase).SelectComponInPCObjectsByGUID(ACanReplace[0].GuidNB);
        end
        else
        //

        //pnApplyForCurrList.Visible := false;
        //if (ACanReplace[0].ComponentType.SysName <> ctsnCable) then
        //  pnApplyForCurrList.Visible := true; //ACanReplace[0].Parent is TSCSCatalog;

        TF_Main(FNormBase).SelectComponInPCObjectsByGUID(ACanReplace[0].GuidNB); //03.06.2009 TF_Main(FNormBase).SelectComponByGUIDInTree(ACanReplace[0].GuidNB);
      end;

      if ShowModal = mrOK then
      begin
        Result := FNBComponent;
        ACanReplaceIndex := ACanReplace.IndexOf(FReplaceComponent);
      end;
    end;
end;

function TF_ConnectComplWith.DefineReplaceCableCanal(ACableCanals: TSCSComponents; var AReplaceCableCanals: TSCSComponents): TSCSComponent;
var i: Integer;
    TreeNode: TTreeNode;
begin
    Result := nil;
    FFormMode := ccwDefineReplaceCableCanal;
    //SetControls; //HideCableCanalPanels;
    PrepareBeforeShow;

    FNBComponent := nil;
    Caption := cConnectComplWith_Msg9_1;
    GroupBox_ConnectWith.Caption := cConnectComplWith_Msg9_2; //'Заменяемые кабельные каналы';
    GroupBox_ConnectBy.Caption := cConnectComplWith_Msg9_3; // с сечением от '+FloatToStr(AWithMinPercent)+' см2';
    pnReplaceCanalsInfo.Visible := true;
    Panel_FullMorePercent.Visible := true;
    Panel_ComponFullnessPercent.Visible := true;
    Label_ComponFullness.Caption := '';
    Memo_ReplaceInfo.Lines.Clear;

    FMinNBCableCanalVolume := -1;
    //FullnessPercent := -1;

    FAllCableCanals := ACableCanals;
    FCableCanalsToCanReplace := TSCSComponents.Create(false);
    FCableCanalsToBeReplace := TSCSComponents.Create(false);
    FCanChangeTreeInMainForm := true;
    try
      SpinEdit_FullMorePercent.Value := TF_Main(GForm).GSCSBase.CurrProject.CurrList.Setting.CableCanalFullnessKoef;
      SpinEdit_FullMorePercent.Properties.MaxValue := Round(SpinEdit_FullMorePercent.Value);
      SpinEdit_FullMorePercent.Properties.MinValue := 1;
      ActivateFNormBase(GCompTypeSysNameCableChannels, ctsnCableChannel);

      SetControls;
      if ShowModal = mrOK then
      begin
        Result := FNBComponent;

        //*** Опредлить заменяемые каб. каналы
        for i := 0 to tvComponentsToBeReplace.Items.Count - 1 do
        begin
          TreeNode := tvComponentsToBeReplace.Items[i];
          if TreeNode.Data <> nil then
            if tvComponentsToBeReplace.ItemState[i] = csChecked then
              AReplaceCableCanals.Add(TSCSComponent(TreeNode.Data));
        end;

        //for i := 0 to lvComponentsToBeReplace.Items.Count - 1 do
        //begin
        //  ListItem := lvComponentsToBeReplace.Items[i];
        //  if ListItem.Checked then
        //    AReplaceCableCanals.Add(TSCSComponent(ListItem.Data));
        //end;


        //for i := 0 to FCableCanalsToBeReplace.Count - 1 do
        //  if Assigned(FCableCanalsToBeReplace[i]) then
        //    //if Abs(FCableCanalsToBeReplace[i].GetVolume(gtFemale) - FReplaceComponent.GetVolume(gtFemale)) <= 0.01 then
        //    begin
        //      AReplaceCableCanals.Add(FCableCanalsToBeReplace[i]);
        //    end;
      end;
    finally
      FCableCanalsToCanReplace.Free;
      FCableCanalsToBeReplace.Free;
    end;
end;


function TF_ConnectComplWith.DefineCableCanalConnector(ACableCanal: TSCSComponent;
  AIDCurrConnector: Integer): TSCSComponent;
begin
  Result := nil;
  FNBComponent := nil;
  FFormMode := ccwDefineCableCanalConnector;
  PrepareBeforeShow;
  SetControls; //HideCableCanalPanels;

  Caption := cConnectComplWith_Msg10;
  GroupBox_ConnectBy.Caption := '';

  FReplaceComponent := nil;
  FEditComponent := nil;
  if Assigned(ACableCanal) then
  begin
    FEditComponent := ACableCanal;
    ActivateFNormBase(nil, ctsnCableChannelElement);
    if AIDCurrConnector <> 0 then
      TF_Main(FNormBase).SelectComponByIDInTree(AIDCurrConnector);

    if ShowModal = mrOk then
    begin
      if Assigned(FNBComponent) then
        Result := FNBComponent;
    end;
  end;
end;

// Tolik 15/11/2021 --
function TF_ConnectComplWith.DefineTubeConnector(ATube: TSCSComponent; AIDCurrConnector: Integer): TSCSComponent;
begin
  Result := nil;
  FNBComponent := nil;
  FFormMode := ccwDefineTubeConnector; //ccwDefineCableCanalConnector;
  PrepareBeforeShow;
  SetControls; //HideCableCanalPanels;

  Caption := cConnectComplWith_TubeMsg10;
  GroupBox_ConnectBy.Caption := '';

  FReplaceComponent := nil;
  FEditComponent := nil;
  if Assigned(ATube) then
  begin
    FEditComponent := ATube;
    ActivateFNormBase(nil, ctsnTubeElement);
    if AIDCurrConnector <> 0 then
      TF_Main(FNormBase).SelectComponByIDInTree(AIDCurrConnector);

    if ShowModal = mrOk then
    begin
      if Assigned(FNBComponent) then
        Result := FNBComponent;
    end;
  end;
end;
//

function TF_ConnectComplWith.DefineCableForJoinToPoints(APointComponFrom, APointComponTo: TSCSComponent; ADefCableGUID: String = ''): TSCSComponent;
var
  SprCompType: TNBComponentType;
begin
  Result := nil;
  FNBComponent := nil;
  FFormMode := ccwDefineCableForJoinToPoints;
  PrepareBeforeShow;
  SetControls; //HideCableCanalPanels;

  Caption := cConnectComplWith_Msg11;
  GroupBox_ConnectBy.Caption := '';

  ActivateFNormBase(GCompTypeSysNameCables, ctsnCable);

  FNBComponentTypeGUID := '';
  FPointComponentFrom := APointComponFrom;
  FPointComponentTo := APointComponTo;

  if ADefCableGUID <> '' then
  begin
    TF_Main(FNormBase).SelectComponInPCObjectsByGUID(ADefCableGUID);  //03.06.2009 TF_Main(FNormBase).SelectComponByGUIDInTree(ADefCableGUID);
    AfterChangeNBCompon; //07.02.2011
  end;

  if ShowModal = mrOk then
  begin
    if Assigned(FNBComponent) then
    begin
      Result := FNBComponent;
      if neNewComponIndex.Value > 0 then
      begin
        SprCompType := F_ProjMan.GSCSBase.CurrProject.Spravochnik.GetComponentTypeWithAssign(FNBComponent.GUIDComponentType, F_NormBase.GSCSBase.NBSpravochnik);
        if SprCompType <> nil then
          SprCompType.ComponentType.ComponentIndex := neNewComponIndex.IntValue-1;
      end;
    end;
  end;
end;

function TF_ConnectComplWith.GetComponentFromNB(AIDCurrComponent: Integer; AByGUIDComponentType: String): TSCSComponent;
begin
  Result := nil;
  FNBComponent := nil;
  FFormMode := ccwGetComponentFromNB;
  PrepareBeforeShow;
  SetControls; //HideCableCanalPanels;

  Caption := cConnectComplWith_Msg12;
  GroupBox_ConnectBy.Caption := '';

  BeginProgress;
  try
    ActivateFNormBase(nil, '');
    if AIDCurrComponent <> 0 then
      TF_Main(FNormBase).SelectComponInPCObjects(AIDCurrComponent);  //03.06.2009 TF_Main(FNormBase).SelectComponByIDInTree(AIDCurrComponent);
  finally
    EndProgress;
  end;

  FNBComponentTypeGUID := AByGUIDComponentType;
  FNBComponentType := nil;
  if FNBComponentTypeGUID <> '' then
   FNBComponentType := F_NormBase.GSCSBase.NBSpravochnik.GetComponentTypeByGUID(FNBComponentTypeGUID);

  if ShowModal = mrOk then
  begin
    if Assigned(FNBComponent) then
    begin
      Result := FNBComponent;
    end;
  end;
end;

procedure TF_ConnectComplWith.Button_OKClick(Sender: TObject);
var NBCompon: TSCSComponent;
    CrossConnectRes: TCrossConnectRes;
    //ComponList1: TSCSComponents;
    //ComponList2: TSCSComponents;
    //SCSCompon1, SCSCompon2: TSCSComponent;
    //ptrComplect: PComplect;
    i, j: Integer;

    //ParentNode: TTreeNode;
    //ParentCompon: TSCSComponent;
    //NewIDCompon: Integer;
    //NewCompon: TSCSComponent;
    //NewComponNode: TTreeNode;
    //ConnectInterfRes: TConnectInterfRes;
    //ConnectCount: Integer;
    CanConnect: Boolean;
    CheckReplaceComponResults: TCheckReplaceComponResults;
    ConnectInterfRes1: TConnectInterfRes;
    ConnectInterfRes2: TConnectInterfRes;

    SrtMessage: String;
    // Tolik 01/07/2019 --
    NbNode: TTreeNode;
    FindCompon: TSCSComponent;

  procedure AddMessageToStr(AMessage: String);
  begin
    if SrtMessage <> '' then
      SrtMessage := SrtMessage + #13+#10;
    SrtMessage := SrtMessage + AMessage;
  end;

begin
  try
    ModalResult := mrNone;
    SrtMessage := '';
    case FFormMode of
      ccwConnectComplWith:
        begin
          if Not Assigned(FConnectCompon) then
          begin
            ModalResult := mrNone;
            Exit; //// EXIT ////
          end;

          NBCompon := TSCSComponent.Create(F_NormBase);
          NBCompon.Assign(TF_Main(FNormBase).GSCSBase.SCSComponent, true, true);

          BeginProgress;
          try
            CrossConnectRes := TF_Main(GForm).F_ChoiceConnectSide.ConnectCrossWithModules(NBCompon, FComponent, FConnectCompon, false);

            if Not CrossConnectRes.Successful then
            begin
              ShowMessageByType(Self.Handle, smtDisplay, cConnectComplWith_Msg13_1+' "'+NBCompon.Name+'" '+cConnectComplWith_Msg13_2,
                                            Application.Title, MB_OK or MB_ICONINFORMATION);
              ModalResult := mrNone;
            end
            else
              ModalResult := mrOk;
          finally
            EndProgress;
            NBCompon.Free;
          end;
        end;

      {ccwConnectComplWith:
        begin
          ParentCompon := nil;
          if (Not Assigned(FConnectCompon)) or (Not Assigned(FConnectCompon)) then
          begin
            ModalResult := mrNone;
            Exit; //// EXIT ////
          end;

          ConnectCount := 0;
          NBCompon := TSCSComponent.Create(F_NormBase);
          NBCompon.Assign(TF_Main(FNormBase).GSCSBase.SCSComponent);
          try
            if NBCompon.ID = 0 then
            begin
              ShowMessageByType(Self.Handle, smtDisplay, 'Не выбран компонент которым нужно вести соединение',
                                            Application.Title, MB_OK or MB_ICONINFORMATION);
              ModalResult := mrNone;
              Exit; ///// EXIT /////
            end;

            ComponList1 := TSCSComponents.Create(false);
            ComponList2 := TSCSComponents.Create(false);

            ParentNode := FCurrNode.Parent;
            ParentCompon := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(PObjectData(ParentNode.Data).ObjectID);
            if Assigned(ParentCompon) then
              try
                ComponList1.Add(FComponent);
                ComponList1.Assign(FComponent.ChildReferences, laOr);
                ComponList2.Add(FConnectCompon);
                ComponList2.Assign(FConnectCompon.ChildReferences, laOr);

                ComponList1.Pack;
                ComponList2.Pack;
                for i := 0 to ComponList1.Count - 1 do
                  ComponList1[i].ServCanConnect := true;
                for i := 0 to ComponList2.Count - 1 do
                  ComponList2[i].ServCanConnect := true;

                NBCompon.LoadInterfaces(-1, false);

                if ParentNode <> nil then
                  for i := 0 to ComponList1.Count - 1 do
                  begin
                    SCSCompon1 := ComponList1[i];
                    if NBCompon.EmConnectTo(SCSCompon1) then
                    begin
                      for j := 0 to ComponList2.Count - 1 do
                        begin
                          SCSCompon2 := ComponList2[j];
                          if (SCSCompon2.ServCanConnect) and (NBCompon.EmConnectTo(SCSCompon2)) then
                          begin
                            NewIDCompon := TF_MAIN(GForm).CopyComponentFromNbToPm(F_NormBase, GForm, ParentNode, NBCompon.ID, ckCompl);
                            NewCompon := nil;
                            NewCompon := TF_MAIN(GForm).GSCSBase.CurrProject.GetComponentFromReferences(NewIDCompon);
                            if Assigned(NewCompon) then
                            begin
                              ptrComplect := ParentCompon.ComplectWithOnlyObject(NewCompon);
                              ptrComplect.ID := TF_Main(GForm).AppendToComponRel(ParentCompon.ID, NewCompon.ID, 1, cntComplect);
                              NewComponNode := TF_Main(GForm).FindComponOrDirInTree(NewIDCompon, true);
                              if Assigned(NewComponNode) then
                                PObjectData(NewComponNode).ID_CompRel := ptrComplect.ID;
                              //TF_Main(GForm).F_ChoiceConnectSide.OnAfterConnectCompons(ParentCompon, NewCompon);


                              NBCompon.EmDisconnect(SCSCompon1);
                              NBCompon.EmDisconnect(SCSCompon2);


                              //ConnectInterfRes := TF_Main(GForm).F_ChoiceConnectSide.ConnectInterfaces(NewCompon, SCSCompon1, -1, -1, cnkVarious, false, smtNone, false);
                              ConnectInterfRes := NewCompon.JoinTo(SCSCompon1, -1, -1);
                              if ConnectInterfRes.CanConnect then
                              begin
                                //ConnectInterfRes := TF_Main(GForm).F_ChoiceConnectSide.ConnectInterfaces(NewCompon, SCSCompon2, -1, -1, cnkVarious, false, smtNone, false);
                                ConnectInterfRes := NewCompon.JoinTo(SCSCompon2, -1, -1);
                                if ConnectInterfRes.CanConnect then
                                  Inc(ConnectCount);

                                ClearList(NBCompon.Interfaces);
                                NBCompon.LoadInterfaces(-1, false);

                                SCSCompon1.ServCanConnect := false;
                                SCSCompon2.ServCanConnect := false;

                                Break; //// BREAK ////
                              end;
                              //else
                                //TF_Main(GForm).DelCompon(NewCompon, true, true, true);
                            end;
                            NBCompon.EmDisconnect(SCSCompon2);
                          end;
                        end;
                        NBCompon.EmDisconnect(SCSCompon1);
                    end;
                  end;
              finally
                ComponList1.Free;
                ComponList2.Free;
              end;

            if ConnectCount = 0 then
              begin
                  ShowMessageByType(Self.Handle, smtDisplay, 'Компонент "'+NBCompon.Name+'" не подходит для соединения, выберите другой',
                                                Application.Title, MB_OK or MB_ICONINFORMATION);
                  ModalResult := mrNone;
              end
            else
              begin
                  if Assigned(NewCompon) then
                    TF_Main(GForm).F_ChoiceConnectSide.OnAfterConnectCompons(ParentCompon, NewCompon);
                  ModalResult := mrOk;
              end;
          finally
            NBCompon.Free;
          end;
        end; }
      ccwDefineReplaceCompon:
          if Assigned(FConnectCompon) then
          begin
          //Tolik 01/07/2019 - -
          //  NBCompon := TSCSComponent.Create(F_NormBase);

          //  NBCompon.Assign(TF_Main(FNormBase).GSCSBase.SCSComponent, true, true);
          NBCompon := nil;
          FindCompon := nil;
          NbNode := nil;

         // NbNode := Tf_Main(F_NormBase).FindComponOrDirInTree(TF_Main(FNormBase).GSCSBase.SCSComponent.ID,False);
          NbNode := Tf_Main(F_NormBase).FindComponOrDirInTree(TF_Main(FNormBase).GSCSBase.SCSComponent.ID, True);

          if nbNode <> nil then
            FindCompon := Tf_Main(F_NormBase).GetComponentFromNode(NbNode);

          if FindCompon <> nil then
          begin
            //FindCompon.LoadChildComplects(true, true, true);
            NBCompon := TSCSComponent.Create(F_NormBase);
            NBCompon.Assign(FindCompon, true, true);
            //NBCompon.LoadChildComplects(true, true, true);
          end;
          //
            if NBCompon.ID = 0 then
            begin
              ShowMessageByType(Self.Handle, smtDisplay, cConnectComplWith_Msg14,
                                            Application.Title, MB_OK or MB_ICONINFORMATION);
              ModalResult := mrNone;
              NBCompon.Free; // Tolik 18/05/2018 --
              Exit; ///// EXIT /////
            end;
            if NBCompon.Interfaces.Count = 0 then
              NBCompon.LoadInterfaces;
            if NBCompon.ChildComplects.Count = 0 then
              NBCompon.LoadChildComplects(true, true, true);


            //26.05.2009 if FConnectCompon.GUIDComponentType <> NBCompon.GUIDComponentType then
            if FConnectCompon.ComponentType.SysName <> NBCompon.ComponentType.SysName then
            begin
              ShowMessageByType(Self.Handle, smtDisplay, cConnectComplWith_Msg15_1+' "'+FConnectCompon.Name+'" '+cConnectComplWith_Msg15_2+' "'+NBCompon.Name+'", '+cConnectComplWith_Msg15_3,
                                            cConnectComplWith_Msg15_4, MB_OK or MB_ICONINFORMATION);
              NBCompon.Free;
              ModalResult := mrNone;
            end
            else
            begin
              CheckReplaceComponResults := FConnectCompon.CanReplaceWithNBCompon(NBCompon, cbLeaveComplectsInTarget.Checked);

              SrtMessage := '';
              if crcrBadFunctionalInterfaces in CheckReplaceComponResults then
                if GUseVisibleInterfaces then
                  AddMessageToStr(cConnectComplWith_Msg16_1)
                else
                  AddMessageToStr(cConnectComplWith_Msg16_1_1);
              if GUseVisibleInterfaces then
              begin
                if crcrBadContructiveInterfaces in CheckReplaceComponResults then
                  AddMessageToStr(cConnectComplWith_Msg16_2);
                if crcrCannotComplectToParentByParams in CheckReplaceComponResults then
                  AddMessageToStr(cConnectComplWith_Msg16_3+' "'+FConnectCompon.GetParentComponent.GetNameForVisible+'"');
                if crcrCannotComplectChildrenByParams in CheckReplaceComponResults then
                  AddMessageToStr(cConnectComplWith_Msg16_4+' "'+FConnectCompon.GetNameForVisible+'"');
                if crcrSmallCanal in CheckReplaceComponResults then
                begin
                  if FConnectCompon.ComponentType.SysName = ctsnCableChannel then
                    AddMessageToStr(cConnectComplWith_Msg16_5+' "'+FConnectCompon.GetNameForVisible+'"')
                  else
                  if (FConnectCompon.Parent is TSCSComponent) and (TSCSComponent(FConnectCompon.Parent).ComponentType.SysName = ctsnCableChannel) then
                    AddMessageToStr(cConnectComplWith_Msg16_6+' "'+TSCSComponent(FConnectCompon.Parent).GetNameForVisible+'"');
                end;
              end;

              if SrtMessage <> '' then
              begin
                SrtMessage := cConnectComplWith_Msg17_2+':'+#13+#10 + SrtMessage;

                ShowMessageByType(Self.Handle, smtDisplay, cConnectComplWith_Msg17_1+' "'+FConnectCompon.Name+'" '+cConnectComplWith_Msg15_2+' "'+NBCompon.Name+'"'+
                                            SrtMessage,
                                            cConnectComplWith_Msg17_3, MB_OK or MB_ICONINFORMATION);
                NBCompon.Free;
                ModalResult := mrNone;
              end
              else
              begin
                FReplaceComponent := FConnectCompon;
                FNBComponent := NBCompon;
                ModalResult := mrOk;
              end;

              {//04.06.2009
              if crcrSuccessful in CheckReplaceComponResults then
              begin
                FReplaceComponent := FConnectCompon;
                FNBComponent := NBCompon;
                ModalResult := mrOk;
              end
              else
              begin
                if crcrBadFunctionalInterfaces in CheckReplaceComponResults then
                  AddMessageToStr(cConnectComplWith_Msg16_1);
                if crcrBadContructiveInterfaces in CheckReplaceComponResults then
                  AddMessageToStr(cConnectComplWith_Msg16_2);
                if crcrCannotComplectToParentByParams in CheckReplaceComponResults then
                  AddMessageToStr(cConnectComplWith_Msg16_3+' "'+FConnectCompon.GetParentComponent.GetNameForVisible+'"');
                if crcrCannotComplectChildrenByParams in CheckReplaceComponResults then
                  AddMessageToStr(cConnectComplWith_Msg16_4+' "'+FConnectCompon.GetNameForVisible+'"');
                if crcrSmallCanal in CheckReplaceComponResults then
                begin
                  if FConnectCompon.ComponentType.SysName = ctsnCableChannel then
                    AddMessageToStr(cConnectComplWith_Msg16_5+' "'+FConnectCompon.GetNameForVisible+'"')
                  else
                  if (FConnectCompon.Parent is TSCSComponent) and (TSCSComponent(FConnectCompon.Parent).ComponentType.SysName = ctsnCableChannel) then
                    AddMessageToStr(cConnectComplWith_Msg16_6+' "'+TSCSComponent(FConnectCompon.Parent).GetNameForVisible+'"');
                end;

                if SrtMessage <> '' then
                  SrtMessage := cConnectComplWith_Msg17_2+':'+#13+#10 + SrtMessage;

                ShowMessageByType(Self.Handle, smtDisplay, cConnectComplWith_Msg17_1+' "'+FConnectCompon.Name+'" на "'+NBCompon.Name+'"'+
                                              SrtMessage,
                                              cConnectComplWith_Msg17_3, MB_OK or MB_ICONINFORMATION);
                NBCompon.Free;
                ModalResult := mrNone;
              end;}
            end;
          end
          else
          begin
            ShowMessageByType(Self.Handle, smtDisplay, cConnectComplWith_Msg18_1,
                                                  cConnectComplWith_Msg18_2, MB_OK or MB_ICONINFORMATION);
            ModalResult := mrNone;
          end;
      ccwDefineReplaceCableCanal:
        if Assigned(FConnectCompon) and (FMinNBCableCanalVolume <> -1) then
        begin
          ModalResult := mrOk;

          FNBComponent := TSCSComponent.Create(F_NormBase);
          FNBComponent.Assign(TF_Main(FNormBase).GSCSBase.SCSComponent, true, true);
          
          {
            if TF_Main(FNormBase).GSCSBase.SCSComponent.ID = 0 then
              begin
                  ShowMessageByType(Self.Handle, smtDisplay, 'Не выбран заменитель',
                                                Application.Title, MB_OK or MB_ICONINFORMATION);
                  ModalResult := mrNone;
                  Exit; ///// EXIT /////
              end;
            if TF_Main(FNormBase).GSCSBase.SCSComponent.ID_ComponentType = ctCableCanal then
              begin
                  NBCompon := TSCSComponent.Create(F_NormBase);
                  NBCompon.Assign(TF_Main(FNormBase).GSCSBase.SCSComponent);

                  if NBCompon.Interfaces.Count = 0 then
                    NBCompon.LoadInterfaces;
                  if NBCompon.ChildComplects.Count = 0 then
                    NBCompon.LoadChildComplects(true, true);

                  if (NBCompon.GetVolume(gtFemale) - NBCompon.GetCablesVolume) >= FMinNBCableCanalVolume then
                    begin
                        FReplaceComponent := FConnectCompon;
                        FNBComponent := NBCompon;
                        ModalResult := mrOk;
                    end
                  else
                    ShowMessageByType(Self.Handle, smtDisplay, 'Сечение компоненты "'+NBCompon.Name+'" составляет '+FloatToStr(NBCompon.GetVolume(gtFemale) - NBCompon.GetCablesVolume)+' см2'+#10+#13+
                        'Сечение заменительного кабельного канала должно быть от '+FloatToStr(FMinNBCableCanalVolume)+' см2', 'Замена кабельных каналов', MB_OK or MB_ICONINFORMATION);
              end
            else
              ShowMessageByType(Self.Handle, smtDisplay, 'Компонент "'+TF_Main(FNormBase).GSCSBase.SCSComponent.Name+'" не является кабельным каналом', 'Замена кабельных каналов', MB_OK or MB_ICONINFORMATION);
               }
        end
        else
        begin
          ShowMessageByType(Self.Handle, smtDisplay, cConnectComplWith_Msg19_1,
                                        cConnectComplWith_Msg19_2, MB_OK or MB_ICONINFORMATION);
        end;
      ccwDefineCableCanalConnector:
        begin
          if TF_Main(FNormBase).GSCSBase.SCSComponent.ComponentType.SysName = ctsnCableChannelElement then
          begin
            NBCompon := TSCSComponent.Create(F_NormBase);
            NBCompon.Assign(TF_Main(FNormBase).GSCSBase.SCSComponent, true, true);
            NBCompon.LoadChildComplectsQuick(true, true, true);

            CanConnect := false;
            if NBCompon.Properties.Count = 0 then
              NBCompon.LoadProperties;
            if NBCompon.GetPropertyValueAsInteger(pnCableCanalElemetType) = contNone then
            begin
              MessageModal(cConnectComplWith_Msg20_1+' "'+NBCompon.GetNameForVisible+'" '+cConnectComplWith_Msg20_2,
                ApplicationName, MB_ICONINFORMATION or MB_OK);
              NBCompon.Free;
              Exit; ///// EXIT /////
            end;

            //if FEditComponent.EmConnectTo(NBCompon) then // Side1
              //if FEditComponent.EmConnectTo(NBCompon) then  // Side2
            if CheckJoinComponentToWithComplects(FEditComponent, NBCompon, -1, -1) then
            begin
              CanConnect := true;
              FNBComponent := NBCompon;
              ModalResult := mrOk;
            end;
            //FEditComponent.EmDisconnect(NBCompon);
            //FEditComponent.EmDisconnect(NBCompon);

            if Not CanConnect then
            begin
              NBCompon.Free;
              ShowMessageByType(Self.Handle, smtDisplay, cConnectComplWith_Msg21_1+' "'+TF_Main(FNormBase).GSCSBase.SCSComponent.Name+'" '+cConnectComplWith_Msg21_2+' "'+FEditComponent.Name+'"', Application.Title, MB_OK or MB_ICONINFORMATION);
            end;
          end
          else
            ShowMessageByType(Self.Handle, smtDisplay, cConnectComplWith_Msg22_1+' "'+TF_Main(FNormBase).GSCSBase.SCSComponent.Name+'" '+cConnectComplWith_Msg22_2, Application.Title, MB_OK or MB_ICONINFORMATION);
        end;
      //Tolik 15/11/2021 --
      ccwDefineTubeConnector:
      begin
        if TF_Main(FNormBase).GSCSBase.SCSComponent.ComponentType.SysName = ctsnTubeElement then
          begin
            NBCompon := TSCSComponent.Create(F_NormBase);
            NBCompon.Assign(TF_Main(FNormBase).GSCSBase.SCSComponent, true, true);
            NBCompon.LoadChildComplectsQuick(true, true, true);

            FNBComponent := NBCompon;
            ModalResult := mrOk;
            {
            CanConnect := false;
            if NBCompon.Properties.Count = 0 then
              NBCompon.LoadProperties;
            if NBCompon.GetPropertyValueAsInteger(pnCableCanalElemetType) = contNone then
            begin
              MessageModal(cConnectComplWith_Msg20_1+' "'+NBCompon.GetNameForVisible+'" '+cConnectComplWith_Msg20_2,
                ApplicationName, MB_ICONINFORMATION or MB_OK);
              NBCompon.Free;
              Exit; ///// EXIT /////
            end;
            }

            //if FEditComponent.EmConnectTo(NBCompon) then // Side1
              //if FEditComponent.EmConnectTo(NBCompon) then  // Side2
            {
            if CheckJoinComponentToWithComplects(FEditComponent, NBCompon, -1, -1) then
            begin
              CanConnect := true;
              FNBComponent := NBCompon;
              ModalResult := mrOk;
            end;
            }
            //FEditComponent.EmDisconnect(NBCompon);
            //FEditComponent.EmDisconnect(NBCompon);
            {
            if Not CanConnect then
            begin
              NBCompon.Free;
              ShowMessageByType(Self.Handle, smtDisplay, cConnectComplWith_Msg21_1+' "'+TF_Main(FNormBase).GSCSBase.SCSComponent.Name+'" '+cConnectComplWith_Msg21_2+' "'+FEditComponent.Name+'"', Application.Title, MB_OK or MB_ICONINFORMATION);
            end;
            }
          end
          else
            ShowMessageByType(Self.Handle, smtDisplay, cConnectComplWith_Msg22_1+' "'+TF_Main(FNormBase).GSCSBase.SCSComponent.Name+'" '+cConnectComplWith_TubeMsg22_2, Application.Title, MB_OK or MB_ICONINFORMATION);
      end;
      //
      ccwDefineCableForJoinToPoints:
        begin
          if (TF_Main(FNormBase).GSCSBase.SCSComponent <> nil) and
             (TF_Main(FNormBase).GSCSBase.SCSComponent.ID > 0) then
          begin
            if TF_Main(FNormBase).GSCSBase.SCSComponent.IsLine = biFalse then
            begin
              MessageModal(cConnectComplWith_Msg23_1+' "'+TF_Main(FNormBase).GSCSBase.SCSComponent.GetNameForVisible+'" '+cConnectComplWith_Msg23_2, ApplicationName, MB_ICONINFORMATION or MB_OK);
              Exit; ///// EXIT /////
            end;

            NBCompon := TSCSComponent.Create(F_NormBase);
            NBCompon.Assign(TF_Main(FNormBase).GSCSBase.SCSComponent, true, true);

            ConnectInterfRes1.CanConnect := true;
            ConnectInterfRes2.CanConnect := true;
            if FPointComponentFrom <> nil then
              ConnectInterfRes1 := FPointComponentFrom.CheckJoinTo(NBCompon, -1, -1);
            if FPointComponentTo <> nil then
              ConnectInterfRes2 := FPointComponentTo.CheckJoinTo(NBCompon, -1, -1);
            if ConnectInterfRes1.CanConnect and ConnectInterfRes2.CanConnect then
            begin
              ModalResult := mrOk;
              FNBComponent := NBCompon;
            end
            else
            begin
              if Not ConnectInterfRes1.CanConnect then
                AddMessageToStr(cConnectComplWith_Msg24_3+' "'+FPointComponentFrom.GetNameForVisible+'" ');
              if Not ConnectInterfRes2.CanConnect then
                AddMessageToStr(cConnectComplWith_Msg24_4+' "'+FPointComponentTo.GetNameForVisible+'" ');
              if SrtMessage <> '' then
                SrtMessage := cConnectComplWith_Msg24_1+' "'+NBCompon.GetNameForVisible+'" '+cConnectComplWith_Msg24_2+':'+#13+#10 + SrtMessage;

              ShowMessageByType(Self.Handle, smtDisplay, SrtMessage, ApplicationName, MB_OK or MB_ICONINFORMATION);
              NBCompon.Free;
            end;
          end;
        end;
      ccwGetComponentFromNB:
        begin
          if (TF_Main(FNormBase).GSCSBase.SCSComponent <> nil) and
             (TF_Main(FNormBase).GSCSBase.SCSComponent.ID > 0) then
          begin
            if (FNBComponentType = nil) or
               (TF_Main(FNormBase).GSCSBase.SCSComponent.ComponentType.GUID = FNBComponentType.ComponentType.GUID) then
            begin
              FNBComponent := TSCSComponent.Create(F_NormBase);
              FNBComponent.Assign(TF_Main(FNormBase).GSCSBase.SCSComponent, true, true);
              ModalResult := mrOk;
            end
            else
            if FNBComponentType <> nil then
              MessageModal(cConnectComplWith_Msg25_1+' "'+TF_Main(FNormBase).GSCSBase.SCSComponent.Name+
                           '" '+cConnectComplWith_Msg25_2+' "'+FNBComponentType.ComponentType.Name+'".', ApplicationName, MB_OK or MB_ICONINFORMATION);
          end
          else
            MessageModal(cConnectComplWith_Msg26, ApplicationName, MB_OK or MB_ICONINFORMATION);
        end;
    end;
  except
    on E: Exception do AddExceptionToLog('TF_ConnectComplWith.Button_OKClick: '+E.Message);
  end;
end;

{
procedure TF_ConnectComplWith.Button_OKClick(Sender: TObject);
var NBCompon: TSCSComponent;
    ComponList1: TSCSComponents;
    ComponList2: TSCSComponents;
    SCSCompon1, SCSCompon2: TSCSComponent;
    i, j: Integer;

    ParentNode: TTreeNode;
    ParentCompon: TSCSComponent;
    NewIDCompon: Integer;
    NewCompon: TSCSComponent;
    ConnectInterfRes: TConnectInterfRes;
    ConnectCount: Integer;
begin
    try
      ConnectCount := 0;
      NBCompon := TSCSComponent.Create(F_NormBase);
      NBCompon.Assign(TF_Main(FNormBase).GSCSBase.SCSComponent);
      try
        if NBCompon.ID = 0 then
          begin
              ShowMessageByType(Self.Handle, smtDisplay, 'Не выбран компонент которым нужно вести соединение',
                                            Application.Title, MB_OK or MB_ICONINFORMATION);
              ModalResult := mrNone;
              Exit; ///// EXIT /////
          end;

        ComponList1 := TSCSComponents.Create(false);
        ComponList2 := TSCSComponents.Create(false);

        ParentNode := FCurrNode.Parent;
        ParentCompon := TSCSComponent.Create(GForm);
        ParentCompon.LoadComponentByID(PObjectData(ParentNode.Data).ObjectID, false);
        try
          ComponList1.Add(FComponent);
          ComponList1.Assign(FComponent.AllSCSComplects, laOr);
          ComponList2.Add(FConnectCompon);
          ComponList2.Assign(FConnectCompon.AllSCSComplects, laOr);

          NBCompon.LoadInterfaces(-1, false);

          if ParentNode <> nil then
            for i := 0 to ComponList1.Count - 1 do
              begin
                  SCSCompon1 := ComponList1[i];
                  if NBCompon.EmConnectTo(SCSCompon1) then
                    begin
                        for j := 0 to ComponList2.Count - 1 do
                          begin
                              SCSCompon2 := ComponList2[j];
                              if (SCSCompon2.ID <> 0) and (NBCompon.EmConnectTo(SCSCompon2)) then
                                begin
                                    NewIDCompon := TF_MAIN(GForm).CopyComponentFromNbToPm((F_NormBase), GForm, ParentNode, NBCompon.ID, ckCompl);
                                    NewCompon := TSCSComponent.Create(GForm);
                                    NewCompon.LoadComponentByID(NewIDCompon, false);
                                    NewCompon.LoadInterfaces(-1, false);
                                    try
                                      TF_Main(GForm).AppendToComponRel(ParentCompon.ID, NewCompon.ID, 1, cntComplect);
                                      TF_Main(GForm).F_ChoiceConnectSide.OnAfterConnectCompons(ParentCompon, NewCompon);


                                      NBCompon.EmDisconnect(SCSCompon1);
                                      NBCompon.EmDisconnect(SCSCompon2);


                                      ConnectInterfRes := TF_Main(GForm).F_ChoiceConnectSide.ConnectInterfaces(NewCompon, SCSCompon1, -1, -1, cnkVarious, false, smtNone, false);
                                      if ConnectInterfRes.CanConnect then
                                        begin
                                            ConnectInterfRes := TF_Main(GForm).F_ChoiceConnectSide.ConnectInterfaces(NewCompon, SCSCompon2, -1, -1, cnkVarious, false, smtNone, false);
                                            if ConnectInterfRes.CanConnect then
                                              Inc(ConnectCount);

                                            ClearList(NBCompon.Interfaces);
                                            NBCompon.LoadInterfaces(-1, false);

                                            SCSCompon1.Clear;
                                            SCSCompon2.Clear;

                                            Break; //// BREAK ////
                                        end;
                                    finally
                                      NewCompon.Free;
                                    end;
                                    NBCompon.EmDisconnect(SCSCompon2);
                                end;
                          end;
                        NBCompon.EmDisconnect(SCSCompon1);
                    end;
              end;
        finally
          ComponList1.Free;
          ComponList2.Free;
        end;

        if ConnectCount = 0 then
          begin
              ShowMessageByType(Self.Handle, smtDisplay, 'Компонент "'+NBCompon.Name+'" не подходит для соединения, выберите другой',
                                            Application.Title, MB_OK or MB_ICONINFORMATION);
              ModalResult := mrNone;
          end;
      finally
        NBCompon.Free;
      end;
    except
      on E: Exception do AddExceptionToLog('TF_ConnectComplWith.Button_OKClick: '+E.Message);
    end;
end;
}

procedure TF_ConnectComplWith.Panel_OkCancelResize(Sender: TObject);
begin
    SetMiddleControlChilds(TControl(Sender), TControl(Self));
end;

procedure TF_ConnectComplWith.SpinEdit_FullMorePercentPropertiesChange(
  Sender: TObject);
var i: Integer;
    ComponWithMaxVolume: TSCSComponent;
    ItemIndex: Integer;
begin
  if SpinEdit_FullMorePercent.Value < 1 then
  begin
    SpinEdit_FullMorePercent.Properties.OnChange := nil;
    try
      SpinEdit_FullMorePercent.Value := 1;
    finally
      SpinEdit_FullMorePercent.Properties.OnChange := SpinEdit_FullMorePercentPropertiesChange;
    end;
  end;

  //*** Найти каб. каналы заполненные более чем на измененный процент
  FCableCanalsToCanReplace.Clear;
  FMaxCableCanalToReplaceVolume := 0;
  FMinNBCableCanalVolume := 0;
  ComponWithMaxVolume := nil;
  Label_ComponFullness.Caption := '';
  for i := 0 to FAllCableCanals.Count - 1 do
    if Assigned(FAllCableCanals[i]) then
      if FAllCableCanals[i].GetFullnessPercentCableCanal >= TcxSpinEdit(Sender).Value then
        FCableCanalsToCanReplace.Add(FAllCableCanals[i]);

  try
    TF_Main(GForm).LockTreeAndGrid(true);
    ItemIndex := 0;
    if ListView_ConnectWith.Items.Count > 0 then
    begin
      ItemIndex := ListView_ConnectWith.Items[0].Index;
      //ClearListView(ListView_ConnectWith);
      ListView_ConnectWith.Clear;
    end;
    FillListViewBySCSComponents(ListView_ConnectWith, FCableCanalsToCanReplace);
    if ListView_ConnectWith.Items.Count > 0 then
      if ItemIndex <= ListView_ConnectWith.Items.Count - 1 then
        ListView_ConnectWith.Selected := ListView_ConnectWith.Items[ItemIndex];
  finally
    TF_Main(GForm).LockTreeAndGrid(false);
  end;

  LoadCanalsToBeReplace;
end;

procedure TF_ConnectComplWith.lvComponentsToBeReplaceSelectItem(
  Sender: TObject; Item: TListItem; Selected: Boolean);
var
  Compon: TSCSComponent;
  CmponNode: TTreeNode;
begin
  if Assigned(Item) then
  begin
    Compon := Item.Data;
    if Assigned(Compon) then
    begin
      CmponNode := Compon.TreeViewNode;
      if CmponNode = nil then
        CmponNode := TF_Main(GForm).FindComponOrDirInTree(Compon.ID, true);
      if CmponNode <> nil then
        TF_Main(GForm).Tree_Catalog.Selected := CmponNode;
    end;
  end;
end;

procedure TF_ConnectComplWith.tvComponentsToBeReplaceStateChange(
  Sender: TObject; Node: TTreeNode; NewState: TRzCheckState);
begin
  SetControls;
end;

procedure TF_ConnectComplWith.tvComponentsToBeReplaceChange(
  Sender: TObject; Node: TTreeNode);
var
  SCSComponent: TSCSComponent;
  ComponNode: TTreeNode;
begin
  SCSComponent := nil;
  ComponNode := nil;

  if Node <> nil then
    if Node.Data <> nil then
    begin
      SCSComponent := TSCSComponent(Node.Data);
      if Assigned(SCSComponent) then
      begin
        ComponNode := SCSComponent.TreeViewNode;
        if ComponNode = nil then
          ComponNode := TF_Main(GForm).FindComponOrDirInTree(SCSComponent.ID, true);
        if ComponNode <> nil then
          TF_Main(GForm).Tree_Catalog.Selected := ComponNode;
      end;
    end;
end;

procedure TF_ConnectComplWith.SpinEdit_FullMorePercentKeyPress(
  Sender: TObject; var Key: Char);
begin
  //if SpinEdit_FullMorePercent.EditText = '' then
  //  if Key = '0' then
  //    Key := #0;
end;

procedure TF_ConnectComplWith.OnApplyForAllChanged;
begin
  cbApplyForComplects.Enabled := cbApplyForCurrList.Checked or cbApplyForCurrProj.Checked;
  cbApplyForCurrList.Enabled := Not cbApplyForCurrProj.Checked and Not FFromResources;
  cbApplyForOnlySelected.Enabled := Not FFromResources and (cbApplyForCurrList.Checked or cbApplyForCurrProj.Checked);
end;

procedure TF_ConnectComplWith.cbApplyForCurrListClick(Sender: TObject);
begin
  //cbApplyForComplects.Enabled := TRzCheckBox(Sender).Checked;
  OnApplyForAllChanged;
end;

procedure TF_ConnectComplWith.cbApplyForCurrProjClick(Sender: TObject);
begin
  OnApplyForAllChanged;
end;


end.

