unit U_MakeEditCrossConnection;

interface

uses
  Windows, U_LNG, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Contnrs,

  U_BaseCommon, U_BaseConstants, U_Common, U_SCSClasses, U_SCSComponent, U_SCSLists, U_TrunkSCS, U_ESCadClasess, U_AnswerToQuast,
  ComCtrls, RzButton, ExtCtrls, RzPanel,
  StdCtrls, RzRadGrp, cxRadioGroup, ActnList, ActnMan, ImgList, XPMenu,
  ToolWin, Menus, cxControls, cxContainer, cxEdit, cxCheckBox, siComp,
  siLngLnk, RzLabel, RzGroupBar, Buttons, RzRadChk, exgrid, RapTree,
  U_Common_Classes, FlytreePro, Treecoll, IsPlugEdit, kbmMemTable, RzSplit, RzCommon,
  PlatformDefaultStyleActnCtrls;


const
  //*** NodeStateIndex
  nsiNone = -1;
  nsiEmpty = 1;
  nsiAttention = 2;
  nsiExpanded = 3;
  nsiCollapsed = 4;

  // Column Indexes
  ciInterface = 0;
  ciKolvo = 1;
  ciKolvoToConnect = 2;
  ciColor = 3;
  ciSide = 4;


type
  TF_MakeEditCrossConnection = class;

  TCrossConnectionMode = (fmNBCrossConnection,
                          fmCrossConfigurator, fmCableConfigurator,
                          fmPointObjectConfigurator);
  TConnectConfigeratorMode = (cmNone, cmByLine, cmByPoint);

  TLoadInterfacesToTree = procedure (AOnlyClear: Boolean) of object;

  TInterfInfo = class(TMyObject)
    public
      FCaption: String;
      FNode: TFlyNode;
      FInterface: TSCSInterface;
      IsBusy: Integer;
      ImageIndex: Integer;
      Kolvo: Integer;
      KolvoToConnect: Integer;
      PosFrom: Integer;
      PosTo: Integer;

      Selected: Boolean;
      Expanded: Boolean;

    procedure Assign(AInterfInfo: TInterfInfo);
    constructor Create(AInterface: TSCSInterface);
    destructor destroy; override; // Tolik 13/12/2019
  end;

  TNodeInfo = class(TMyObject)
    FObjClass: String;
    FID: Integer;
    FPosFrom: Integer;
    FPosTo: Integer;

    procedure LoadFromNodeFly(ANode: TFlyNode);
    function CmpNodeFly(ANode: TFlyNode): Boolean;
    constructor create; // Tolik 13/12/2019 --
    destructor destroy; override; // Tolik 13/12/2019 --
  end;


  TGroupComponsPanelDockManager = class(TRzPanelDockManager)
    private
      FDockSitePanel: TRzPanel;
    protected
      constructor Create( DockSite: TWinControl ); override;
      procedure PaintDockFrame( Canvas: TCanvas; Control: TControl; const ARect: TRect ); override;
  end;

  TGroupComponsPanel = class(TObject)
    private
      FControlsOwner: TComponent;
      FPanel: TRzPanel;
      FDockSitePanel: TRzPanel;
      FDockSitePanelWndProcOriginal: TWndMethod;
      FDockClientPanel: TRzPanel;
      //FPanelCaption: TRzPanel;
      FPanelTitle: TRzPanel;
      FPanelCloseBt: TRzPanel;
      FPanelContainer: TRzPanel;
      FbtClose: TSpeedButton;

      FSplitter: TSplitter;

      FToolBar: TToolBar;
      FtbMoveUp: TToolButton;
      FtbMoveDown: TToolButton;
      FtbExpand: TToolButton;
      FtbCollapse: TToolButton;
      FtbRemove: TToolButton;
      FtbSepatator: TToolButton;
      FtbFindInTree: TToolButton;
      FPopupMenu: TPopupMenu;
      FTree: TFlyTreeViewPro;

      FTimer: TTimer;
      FObjectList: TObjectList;

      //FParent: TWinControl;
      FTreeOwner: TFlyTreeViewPro;
      FFormOwner: TF_MakeEditCrossConnection;

      // Events
      FOnUserClose: TNotifyEvent;

      procedure FbtCloseClick(Sender: TObject);
      procedure FtbMoveUpOnClick(Sender: TObject);
      procedure FtbMoveDownOnClick(Sender: TObject);
      procedure FtbExpandOnClick(Sender: TObject);
      procedure FtbCollapseOnClick(Sender: TObject);
      procedure FtbRemoveOnClick(Sender: TObject);
      procedure FtbFindInTreeOnClick(Sender: TObject);
      procedure FTreeOnDblClick(Sender: TObject);

      function CreateToolButton(ACaption: String; AImageIndex: Integer; AOnClickEvent: TNotifyEvent): TToolButton;
      procedure ExpandCollapse(AIndex: Integer);
      procedure FDockSitePanelUnDock(Sender: TObject; Client: TControl;
                  NewTarget: TWinControl; var Allow: Boolean);
      procedure FDockSitePanelWndProc(var Msg: TMessage);
      procedure FTimerOnTimer(Sender: TObject);
      function GetVisible: Boolean;
      procedure MoveNode(AIndex: Integer);
      procedure SetVisible(Value: Boolean);
      procedure StartTimer(AActionCode: Integer);
    protected
      procedure DoUserClose;
    public
      property OnUserClose: TNotifyEvent read FOnUserClose write FOnUserClose;
      property Tree: TFlyTreeViewPro read FTree;
      property TreeOwner: TFlyTreeViewPro read FTreeOwner;
      property Visible: Boolean read GetVisible write SetVisible;

     function AddNodeFrom(ASrcNode: TFlyNode; ASelect: Boolean): TFlyNode;
     constructor Create(ATreeOwner: TFlyTreeViewPro; AFormOwner: TF_MakeEditCrossConnection);
     destructor Destroy; override;
     function GetComponents: TSCSComponents;
     procedure RefreshImageIndexes;
  end;

  TF_MakeEditCrossConnection = class(TForm)
    pnOkCancel: TRzGroupBox;
    btOK: TRzBitBtn;
    btCancel: TRzBitBtn;
    pnNBCrossConnLegend: TRzPanel;
    Label1: TLabel;
    gbConfiguratorKind: TRzGroupBox;
    rbCross: TcxRadioButton;
    rbCable: TcxRadioButton;
    RzPanel2: TRzPanel;
    btClose: TRzBitBtn;
    pnFromTo: TRzPanel;
    ActionManager: TActionManager;
    Act_Connect: TAction;
    Act_Disconnect: TAction;
    ilNormal: TImageList;
    XPMenu: TXPMenu;
    tbConfigurator: TToolBar;
    ToolButton1: TToolButton;
    ToolButton2: TToolButton;
    ilHot: TImageList;
    ilDisabled: TImageList;
    gbConfiguratorNotice: TRzGroupBox;
    mConfNotice: TMemo;
    pmCommon: TPopupMenu;
    N1: TMenuItem;
    N2: TMenuItem;
    pnConfiguratorKind: TRzPanel;
    RzGroupBox1: TRzGroupBox;
    rbSelectByPoint: TcxRadioButton;
    rbSelectByLine: TcxRadioButton;
    ltState: TImageList;
    Act_AddCable: TAction;
    Act_DeleteCable: TAction;
    ToolButton3: TToolButton;
    ToolButton4: TToolButton;
    N3: TMenuItem;
    N4: TMenuItem;
    lng_Forms: TsiLangLinked;
    Act_SelectInMainTree: TAction;
    N5: TMenuItem;
    pnLegend: TRzPanel;
    pnLegendLabel: TRzPanel;
    tvLegend: TTreeView;
    Label2: TLabel;
    ToolButton5: TToolButton;
    Act_DisconnectAll: TAction;
    N6: TMenuItem;
    Button1: TButton;
    Timer_TVFromSelect: TTimer;
    Timer_AfterShowPointObjectConfigurator: TTimer;
    RzSplitter1: TRzSplitter;
    gbWith: TRzGroupBox;
    tvWith__: TTreeView;
    spTo: TRzSplitter;
    gbTo: TRzGroupBox;
    tvTo__: TTreeView;
    gbFrom: TRzGroupBox;
    tvFrom__: TTreeView;
    spInterfWith: TRzSplitter;
    tvWith: TFlyTreeViewPro;
    spInterfWithSide2: TRzSplitter;
    tvInterfWithSide1: TFlyTreeViewPro;
    tvInterfWithSide2: TFlyTreeViewPro;
    spInterfFrom: TRzSplitter;
    tvFrom: TFlyTreeViewPro;
    spInterfFromSide2: TRzSplitter;
    tvInterfFromSide1: TFlyTreeViewPro;
    tvInterfFromSide2: TFlyTreeViewPro;
    spInterfTo: TRzSplitter;
    tvTo: TFlyTreeViewPro;
    tvInterfTo: TFlyTreeViewPro;
    Timer_spInterfMouseUp: TTimer;
    Timer_SetAnchorNode: TTimer;
    Timer_AfterSelectedInterfNode: TTimer;
    Act_FindConnected: TAction;
    N7: TMenuItem;
    Act_AddToGroup: TAction;
    ToolButton6: TToolButton;
    N8: TMenuItem;
    Act_FindInGroup: TAction;
    N9: TMenuItem;
    tbSelectObjectsInPM: TToolBar;
    lbLegend: TRzLabel;
    btLegend: TSpeedButton;
    btExtendedMode: TSpeedButton;
    cbSelectObjectsInPM: TRzCheckBox;
    ToolButton7: TToolButton;
    cbCanJoinFewCablesToCompon: TRzCheckBox;
    pmiInterfPath: TMenuItem;
    TimerSelectObjInPM: TTimer;
    ToolButton8: TToolButton;
    ToolButton9: TToolButton;
    Act_ExtProtocol: TAction;
    procedure btOKClick(Sender: TObject);
    procedure lvFrom_Change(Sender: TObject; Item: TListItem;
      Change: TItemChange);
    procedure pnOkCancelResize(Sender: TObject);
    procedure tvWith__Change(Sender: TObject; Node: TTreeNode);
    procedure gbConfiguratorKindResize(Sender: TObject);
    procedure rbCrossClick(Sender: TObject);
    procedure rbCableClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure btCloseClick(Sender: TObject);
    procedure Act_ConnectExecute(Sender: TObject);
    procedure Act_DisconnectExecute(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure tvFrom__Change(Sender: TObject; Node: TTreeNode);
    procedure tvTo__Change(Sender: TObject; Node: TTreeNode);
    procedure tvEnter(Sender: TObject);
    procedure rbSelectByLineClick(Sender: TObject);
    procedure rbSelectByPointClick(Sender: TObject);
    procedure tvWith__MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure tvWith__MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure tvWith__CustomDrawItem(Sender: TCustomTreeView;
      Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
    procedure Act_DeleteCableExecute(Sender: TObject);
    procedure Act_AddCableExecute(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure tvWith__Expanding(Sender: TObject; Node: TTreeNode;
      var AllowExpansion: Boolean);
    procedure tvFrom__Expanding(Sender: TObject; Node: TTreeNode;
      var AllowExpansion: Boolean);
    procedure tvTo__Expanding(Sender: TObject; Node: TTreeNode;
      var AllowExpansion: Boolean);
    procedure Act_SelectInMainTreeExecute(Sender: TObject);
    procedure lbLegendClick(Sender: TObject);
    procedure btLegendClick(Sender: TObject);
    procedure Act_DisconnectAllExecute(Sender: TObject);
    procedure tvWithDrawCell(Sender: TObject; aCanvas: TCanvas; ACol,
      ARow: Integer; Rect: TRect; State: TExGridDrawState);
    procedure tvWithExpanding(Sender: TObject; Node: TFlyNode;
      var AllowExpansion: Boolean);
    procedure tvFromChange(Sender: TObject; Node: TFlyNode);
    procedure tvFromExpanding(Sender: TObject; Node: TFlyNode;
      var AllowExpansion: Boolean);
    procedure tvWithGetNodeAttributes(Node: TFlyNode; Column: Integer;
      aFont: TFont; var BackColor: TColor; var Alignment: TAlignment);
    procedure tvToChange(Sender: TObject; Node: TFlyNode);
    procedure tvToExpanding(Sender: TObject; Node: TFlyNode;
      var AllowExpansion: Boolean);
    procedure tvWithChange(Sender: TObject; Node: TFlyNode);
    procedure Button1Click(Sender: TObject);
    procedure Timer_TVFromSelectTimer(Sender: TObject);
    procedure tvWithSelectedChanged(OldNode, NewNode: TFlyNode);
    procedure tvFromSelectedChanged(OldNode, NewNode: TFlyNode);
    procedure tvToSelectedChanged(OldNode, NewNode: TFlyNode);
    procedure pnInterfResize(Sender: TObject);
    procedure btExtendedModeClick(Sender: TObject);
    procedure Splitter1CanResize(Sender: TObject; var NewSize: Integer;
      var Accept: Boolean);
    procedure tvInterfWithSide1SelectedChanged(OldNode, NewNode: TFlyNode);
    procedure tvInterfWithSide2SelectedChanged(OldNode, NewNode: TFlyNode);
    procedure tvInterfFromSide1SelectedChanged(OldNode, NewNode: TFlyNode);
    procedure tvInterfFromSide2SelectedChanged(OldNode, NewNode: TFlyNode);
    procedure Timer_AfterShowPointObjectConfiguratorTimer(Sender: TObject);
    procedure spInterfFromSide2Change(Sender: TObject);
    procedure spInterfMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Timer_spInterfMouseUpTimer(Sender: TObject);
    procedure spInterfWithResize(Sender: TObject);
    procedure tvInterfSelectCell(Sender: TObject; ACol,
      ARow: Integer; var CanSelect: Boolean);
    procedure Timer_SetAnchorNodeTimer(Sender: TObject);
    procedure tvInterfToSelectedChanged(OldNode, NewNode: TFlyNode);
    procedure tvInterfEdited(Sender: TObject; Node: TFlyNode;
      var S: String);
    procedure tvInterfWithSide1DrawCell(Sender: TObject; aCanvas: TCanvas;
      ACol, ARow: Integer; Rect: TRect; State: TExGridDrawState);
    procedure Timer_AfterSelectedInterfNodeTimer(Sender: TObject);
    procedure tvInterfGetNodeAttributes(Node: TFlyNode;
      Column: Integer; aFont: TFont; var BackColor: TColor;
      var Alignment: TAlignment);
    procedure spInterfChange(Sender: TObject);
    procedure spInterfWithDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure tvWithDblClick(Sender: TObject);
    procedure tvFromDblClick(Sender: TObject);
    procedure tvInterfWithSide1DblClick(Sender: TObject);
    procedure tvInterfWithSide2DblClick(Sender: TObject);
    procedure tvInterfFromSide2DblClick(Sender: TObject);
    procedure Act_FindConnectedExecute(Sender: TObject);
    procedure Act_AddToGroupExecute(Sender: TObject);
    procedure Act_FindInGroupExecute(Sender: TObject);
    procedure pmCommonPopup(Sender: TObject);
    procedure TimerSelectObjInPMTimer(Sender: TObject);
    procedure Act_ExtProtocolExecute(Sender: TObject);
  private
    GForm: TForm;
    FCatalog: TSCSCatalog;
    FList: TSCSList;
    FFormMode: TCrossConnectionMode;
    FMakeEdit: TMakeEdit;

    FSCSComponent: TSCSComponent;
    FCrossConnection: TSCSCrossConnection;

    FTreeViewFrom: TFlyTreeViewPro;
    FTreeViewTo: TFlyTreeViewPro;
    FTreeViewInterf1: TFlyTreeViewPro;
    FTreeViewInterf2: TFlyTreeViewPro;

    FTreeFromExpandedInfo: TObjectList;
    FTreeToExpandedInfo: TObjectList;
    FTreeFromSelInfo: TNodeInfo;
    FTreeToSelInfo: TNodeInfo;

    FCanConnect: Boolean;
    FCanDisconnect: Boolean;
    FIsHandlingtvWith: Boolean;
    FIsInterfAction: Boolean;
    FPair1Compon1: TSCSComponent;
    FPair1Compon1Port: TSCSInterface;
    FPair1Compon1PortInfo: TInterfInfo;
    FPair1Compon2: TSCSComponent;
    FPair1Compon2Port: TSCSInterface;
    FPair1Compon2PortInfo: TInterfInfo;
    FPair2Compon1: TSCSComponent;
    FPair2Compon1Port: TSCSInterface;
    FPair2Compon1PortInfo: TInterfInfo;
    FPair2Compon2: TSCSComponent;
    FPair2Compon2Port: TSCSInterface;
    FPair2Compon2PortInfo: TInterfInfo;
    FPair1Interfaces: TRapList;
    FPair2Interfaces: TRapList;

    FLockCount: Integer;

    FPointFigureRelations: TObjectList;
    FCurrIDPointObject: Integer;
    FCurrIDPointComponent: Integer;

    FLineComponFromSide: TSCSComponent;
    FLineComponToSide: TSCSComponent;
    FPointComponentFrom: TSCSComponent;
    FPointComponentTo: TSCSComponent;
    FPointObjectFrom: TSCSCatalog;
    FPointObjecttTo: TSCSCatalog;

    FDisabledCompTypesForCableConfigurator: TStringList; //SysNames
    FConnectedLinesToPointObject: TSCSCatalogs;

    FGroupComponsPanelList: TObjectList;

    FSavedLegendHeight: Integer;
    FImageCountBeforeState: Integer;

    FTreeList: TRapList;
    FTreeAnchorNodeList: TRapList;
    FInterfTrees: TRapList;
    FInterfWithSideAtTree1: Integer;
    FInterfWithSideAtTree2: Integer;
    FInterfFromSideAtTree1: Integer;
    FInterfFromSideAtTree2: Integer;

    FLoadedInterfacesWith: Boolean;
    FLoadedInterfacesFrom: Boolean;
    FLoadedInterfacesTo: Boolean;

    FTreeViewSelInPM: TFlyTreeViewPro;

    procedure AfterConnectDiconnect;
    // Вызывается на замене ветвей в деревьях 
    procedure AfterSetDataToNode(Sender: TObject);
    function AddComponentToTreeView(ASCSComponent: TSCSComponent; AImageIndex: Integer;
                ATreeView: TFlyTreeViewPro; AParentNode: TFlyNode): TFlyNode;
    procedure AddCrossInterfacesToNode(ACrossCompon: TSCSComponent; ADestNode: TFlyNode);
    function AddInterfaceToTreeView(AInterface: TSCSInterface; AImageIndex: Integer;
                ATreeView: TFlyTreeViewPro; AParentNode: TFlyNode): TFlyNode;
    function AddInterfInfoToTree(AInterf: TSCSInterface; AInterfName: String; AIsBusy, AKolvo: Integer;
      AParentNode: TFlyNode; ATreeView: TFlyTreeViewPro; APosFrom, APosTo: Integer): TFlyNode;
    function HaveCrossComponConnection(ATopComponent, ACrossComponent: TSCSComponent): Boolean;
    procedure ChangeConfiguratorFormMode(ANewFormMode: TCrossConnectionMode);
    // Можно ли соединить интерфейсы по позициям
    function CheckJoinInterfInfos(AInterfInfo1, AInterfInfo2: TInterfInfo): Boolean;
    function CheckJoinedComponWithInterfInfo(ACompon: TSCSComponent; AInterfInfo: TInterfInfo): Boolean;
    function CheckJoinedInterfInfos(AInterfInfo1, AInterfInfo2: TInterfInfo; APtrPosKolvo: PInteger = nil): Boolean;
    function CheckJoinedInterfInfoWithNode(ANode: TFlyNode; AInterfInfo: TInterfInfo; ASkipInterfInfo: TInterfInfo=nil): Boolean;
    function CheckJoinedInterfWithInterfInfo(AInterf: TSCSInterface; AInterfInfo: TInterfInfo): Boolean;
    procedure ClearTrees;
    function ComponentConnectedWithAnyCross(AComponent: TSCSComponent): Boolean;
    function ComponentConnectedWithCross(AComponent, ACross: TSCSComponent): Boolean;
    function ComponentConnectedWithOtherCross(AComponent: TSCSComponent): Boolean;
    procedure ConnectInterfaces(AInterfInfoList1, AInterfInfoList2: TRapList);
    procedure DefineCableFirstLastComponsByTrees;
    // Определить кабели, трасса которых подключена к объекту
    procedure DefineCableWhoseTracesConnectedToObject(ATreeViewWithCables: TFlyTreeViewPro; AObject: TObject);
    procedure DefineInterfaceNodesText(ATreeView: TFlyTreeViewPro);
    procedure DefineInterfTreeViewImageIndex(ATreeView: TFlyTreeViewPro; AJoinedInterfInfoList1, AJoinedInterfInfoList2: TRapList; ACanSelectJoined: Boolean);
    procedure DefineTreeViewImageIndex(ATreeView: TFlyTreeViewPro; AJoinedComponent: TSCSComponent; AShowJoined: Boolean);
    //*** Определить иконки магистальных компонент с учетом не подключенных трассами кроссов
    procedure DefineTrunkNodeImageIndex(ASelectedTrunkNode, ATrunkNodeToDefine: TFlyNode;
                AJoinedLineComponToDestTrunk: TSCSComponent; ARefrechTree: Boolean);
    //*** Определить иконки магистальных компонент по всему дереву с учетом не подключенных трассами кроссов
    procedure DefineTVImageIndexWithTrunkNodes(ASelectedTrunkNode: TFlyNode; ADestTreeView: TFlyTreeViewPro;
                AJoinedLineComponToDestTrunk: TSCSComponent);
    procedure DelComponentFromTreeView(ATreeView: TFlyTreeViewPro; AComponent: TSCSComponent);
    procedure EnableDisableConfiguratorControls;
    procedure ExchangeInterfWithInTreeSidesIfCan;
    function FindComponInTree(AIDCompon: Integer; ATreeView: TFlyTreeViewPro; ASelect: Boolean): Boolean;
    function FindNodeByObjectInTree(ATreeView: TFlyTreeViewPro; AObject: TObject): TFlyNode;
    procedure ExpandTreeNodesByInfo(ATree: TFlyTreeViewPro; AInfoList: TObjectList; ASelInfo: TNodeInfo);
    function GetAnchorNodeFromTree(ATreeView: TFlyTreeViewPro): TFlyNode;
    function GetCatalogFromTreeView(ATreeView: TFlyTreeViewPro): TSCSCatalog;
    function GetCatalogNodeFromTreeView(ATreeView: TTreeView; ACatalog: TSCSCatalog): TTreeNode;
    // Вернет количество компонентов с ветвей, индекс имеджа в которых не подключен, или частично подключен
    function GetComponCountToJoinFromNode(ANode: TFlyNode; ALeveFromList: TList): Integer;
    function GetComponentFromNode(ATreeNode: TFlyNode): TSCSComponent;
    function GetComponentFromTreeView(ATreeView: TFlyTreeViewPro): TSCSComponent;
    function GetComponentNodeFromNodeListByWholeID(ANodeList: TObjectList; AWholeID: Integer): TFlyNode;
    function GetComponentNodeFromTreeView(ATreeView: TFlyTreeViewPro; AComponent: TSCSComponent): TFlyNode;
    function GetComponentNodeFromTreeViewByWholeID(ATreeView: TFlyTreeViewPro; AWholeID: Integer): TFlyNode;
    function GetComponJoinedCount(AComponent: TSCSComponent): Integer;
    function GetConnectedObjectsToObjectInPointObjectConfigurator(ASCSObject: TSCSCatalog): TSCSCatalogs;
    function GetDataListFromGroupComponsPanelByTree(ATree: TFlyTreeViewPro): TList;
    function GetEmptyPositionsFromInterfInfo(AInterfInfo: TInterfInfo): TSCSInterfPositions;
    function GetFocusedTreeView: TFlyTreeViewPro;
    function GetGroupComponsPanelByTree(ATree: TFlyTreeViewPro; AWithCreate: Boolean): TGroupComponsPanel;
    function GetImageStateIndex(AIndex: Integer): Integer;
    function GetInterfInfoFromNode(ANode: TFlyNode): TInterfInfo;
    function GetInterfInfoFromOtherSide(ACrossNode: TFlyNode; AInterfInfo: TInterfinfo; AIsBusy: Integer=-1): TInterfinfo;
    function GetInterfInfoFromTree(ATreeView: TFlyTreeViewPro): TInterfInfo;
    function GetInterfInfoListFromTree(ATreeView: TFlyTreeViewPro): TRapList;
    function GetInterfacesFromInterfInfoList(AInterfInfoList: TRapList; AAndFromSiblingNodes: Boolean): TSCSInterfaces;
    function GetJoinedInterfInfoFromTree(AInterfInfo: TInterfInfo; ATreeView: TFlyTreeViewPro): TRapList;
    function GetJoinedInterfInfoFromObjectTreeFirst(AInterfInfo: TInterfInfo; ATreeView: TFlyTreeViewPro): TInterfInfo;
    //15.10.2011 - вернет инфу о подключенном интерфейсе
    function GetJoinedInterfInfoFromParentNode(ANode: TFlyNode; AInterfInfo, ASkipInterfInfo: TInterfInfo): TInterfInfo;
    function GetObjectFromNode(ANode: TFlyNode; const AWithClassName: String): TObject;
    function GetObjectFromTreeView(ATreeView: TFlyTreeViewPro; const AWithClassName: String): TObject;
    function GetObjectFromFocusedTreeView: TObject;
    function GetTopComponNode(ACurrNode: TFlyNode): TFlyNode;
    function GetTopObjectFromNodeByClassName(ACurrNode: TFlyNode; AClassName: String): TObject;
    function IsThroughConfiguratorMode: Boolean;
    function IsConfiguratorMode: Boolean;
    function JoinInterfInfos(AInterfInfo1, AInterfInfo2: TInterfInfo; AInterfList1, AInterfList2: TSCSInterfaces): Boolean;
    procedure LoadComponInterfacesToTreeView(AComponentSide1, AComponentSide2: TSCSComponent;
                ACompon1InterfSide, ACompon2InterfSide: Integer; ATreeViewSide1, ATreeViewSide2: TFlyTreeViewPro);
    procedure LoadParamsToCrossConnectionRecord(ACrossConnection: TSCSCrossConnection; ASrcTreeView: TFlyTreeViewPro;
                var AIDCompRel, AIDCompon, AComponIndex: Integer; var AComponName: String);
    procedure LoadComponentsFrom;
    procedure LoadComponentsTo;
    procedure LoadComponentsWith;

    procedure LoadComponentsForPointObjectConfigurator(APointObject: TSCSCatalog);
    procedure loadComponentsToCrossConnect(ADestTreeView: TFlyTreeViewPro;
                ACrossComponent: TSCSComponent; AExistingIDCompRel, AExistingNpp: Integer);
    procedure LoadComponentsToCrossConfigurator(ADestTreeView: TFlyTreeViewPro;
                ACrossComponent: TSCSComponent; AJoinedPortToCross: TSCSInterface; AInterfInfoFromCross: TInterfInfo=nil);
    procedure LoadComponentsToCableConfigurator(ADestTreeView: TFlyTreeViewPro;
                AJoinedToCable: TSCSComponent; AJoinedObject: TSCSCatalog; ANotExpandCompons: Boolean;
                ASkipComponToSelect: TSCSComponent=nil);
    //*** Загружат подключенные (не цельные) линейные компон-ты к линейному. Подразумевается, что ALineComponent конечный
    procedure LoadConnectedLineComponentsToLine(ADestTreeView: TFlyTreeViewPro;
                ALineComponent: TSCSComponent; ALineComponNode: TFlyNode; AParantNodes: TObjectList; ACheckExisted: Boolean);
    //*** Загружат подключенные (не цельные) линейные компон-ты к линейному для всег ветвей по уровню
    procedure LoadConnectedLineComponentsToLineForSiblingNodes(ADestTreeView: TFlyTreeViewPro;
                ANode: TFlyNode; ACheckExisted: Boolean);
    procedure LoadInterfacesWith(AOnlyClear: Boolean);
    procedure LoadInterfacesFrom(AOnlyClear: Boolean);
    procedure LoadInterfacesTo(AOnlyClear: Boolean);
    procedure LockTrees(ALock: Boolean);
    procedure OnCloseGroupComponsPanel(Sender: TObject);
    procedure OnpmiInterfPathClick(Sender: TObject);
    procedure PrepareForm;
    procedure RefreshGroupComponsPanels;
    procedure ReloadInterfaces(ATreeView1, ATreeView2: TFlyTreeViewPro; AIsBusyToSelect: Integer; AProcToLoadInterf: TLoadInterfacesToTree);
    // в инфе об интерфейсах обновляет поле звязанной ветки дерева
    procedure RefreshInterfInfoRelatedOwners(ATreeView: TFlyTreeViewPro);
    procedure RemoveItemsFromInterfInfoListByOtherIsBusy(AList: TRapList; AIsBusy: Integer);
    procedure SaveExpandedInfo(ATree: TFlyTreeViewPro; AList: TObjectList);
    procedure SelectNodeByJoinedComponImageIndex(ATreeView: TFlyTreeViewPro);
    procedure SelectNodeByJoinedInterfImageIndex(ATreeView: TFlyTreeViewPro);
    //23.12.2011 - выделить подключенный интерфейс в FlyTreeViewPro
    procedure SelectJoinedInterfInfoNode(ASrcInterfTree, ASrcInterfTreeSecond, ATrgComponTree, ATrgInterfTree: TFlyTreeViewPro);
    procedure SelectJoinedToChildAtFromTree(ANode: TFlyNode);
    procedure SelectObjectInPMFromTreeView(ATreeView: TFlyTreeViewPro);
    procedure SortConfiguratorTreeView(ATreeView: TFlyTreeViewPro; ASelectCurrList: Boolean = false);
    procedure SetAnchorNodeToTree(ATreeView: TFlyTreeViewPro; ANode: TFlyNode);
    procedure SetControlsForInterfaces;
    procedure SetControlsForInterfacesByCompon(AComponment: TSCSComponent; ASplirter: TRzSplitter);
    procedure SetControlsForLegend;
    procedure SetVisibleToGruopComponPanels(AVisible: Boolean);
    Procedure SetCorrectImage(PortNode: TFlyNode);
  public
    constructor Create(AOwner: TComponent; AForm: TForm);
    destructor Destroy; override;
    function Execute(AMakeEdit: TMakeEdit; ASCSComponent: TSCSComponent;
                ACrossConnection: TSCSCrossConnection): Boolean;
    procedure ShowConnectConfigurator(ACatalog: TSCSCatalog;
                ACrossConnectionMode: TCrossConnectionMode;
                AConnectConfigeratorMode: TConnectConfigeratorMode; ALocateID: Integer = -1);
    procedure ShowPointObjectConfigurator(ACatalog: TSCSCatalog);
  end;

//var
//  F_MakeEditCrossConnection: TF_MakeEditCrossConnection;

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



{ TInterfInfo }

procedure TInterfInfo.Assign(AInterfInfo: TInterfInfo);
begin
  FInterface := AInterfInfo.FInterface;
  IsBusy := AInterfInfo.IsBusy;
  ImageIndex := AInterfInfo.ImageIndex;
  Kolvo := AInterfInfo.Kolvo;
  KolvoToConnect := AInterfInfo.KolvoToConnect;
  PosFrom := AInterfInfo.PosFrom;
  PosTo := AInterfInfo.PosTo;

  Selected := AInterfInfo.Selected;
  Expanded := AInterfInfo.Expanded;
end;

constructor TInterfInfo.Create(AInterface: TSCSInterface);
begin
  inherited create;
  FInterface := AInterface;
  IsBusy := biFalse;
  ImageIndex := -1;
  Kolvo := 0;
  KolvoToConnect := 0;
  PosFrom := 0;
  PosTo := 0;

  Selected := false;
  Expanded := false;

  FNode := nil;
end;

destructor TInterfInfo.destroy;
begin
  inherited;
end;
{ TNodeInfo }

function TNodeInfo.CmpNodeFly(ANode: TFlyNode): Boolean;
var
  DataObj: TObject;
begin
  Result := false;
  if ANode <> nil then
  begin
    DataObj := TObject(ANode.Data);
    if DataObj.ClassName = Self.FObjClass then
    begin
      if ((DataObj is TSCSCatalog) and (Self.FID = TSCSCatalog(DataObj).ID)) or
         ((DataObj is TSCSComponent) and (Self.FID = TSCSComponent(DataObj).ID)) or
         ((DataObj is TSCSInterface) and (Self.FID = TSCSInterface(DataObj).ID)) or
         ((DataObj is TInterfInfo) and (Self.FID = TInterfInfo(DataObj).FInterface.ID) and
          (Self.FPosFrom = TInterfInfo(DataObj).PosFrom) and (Self.FPosFrom = TInterfInfo(DataObj).PosFrom))
      then
        Result := true;
    end;
  end;
end;

procedure TNodeInfo.LoadFromNodeFly(ANode: TFlyNode);
var
  DataObj: TObject;
begin
  DataObj := nil;
  if (ANode <> nil) and (ANode.Data <> nil) then
    DataObj := TObject(ANode.Data);
  if DataObj <> nil then
  begin
    Self.FObjClass := DataObj.ClassName;
    if DataObj is TSCSCatalog then
      Self.FID := TSCSCatalog(DataObj).ID
    else if DataObj is TSCSComponent then
      Self.FID := TSCSComponent(DataObj).ID
    else if DataObj is TSCSInterface then
      Self.FID := TSCSInterface(DataObj).ID
    else if DataObj is TInterfInfo then
    begin
      Self.FID := TInterfInfo(DataObj).FInterface.ID;
      Self.FPosFrom := TInterfInfo(DataObj).PosFrom;
      Self.FPosTo := TInterfInfo(DataObj).PosTo;
    end;
  end
  else
    Self.FObjClass := '';
end;

constructor TNodeInfo.Create;
begin
  inherited;
end;

destructor TNodeInfo.Destroy;
begin
  inherited;
end;
{ TGroupComponsPanelDockManager }

constructor TGroupComponsPanelDockManager.Create(DockSite: TWinControl);
begin
  inherited Create(DockSite);

  FDockSitePanel := TRzPanel(DockSite);

  FFont.Name := TRzPanel(DockSite).Font.Name; 
end;

procedure TGroupComponsPanelDockManager.PaintDockFrame(Canvas: TCanvas;
  Control: TControl; const ARect: TRect);
var
  R: TRect;
  S: string;
begin
  if not FDockSitePanel.ShowDockClientCaptions then
    inherited
  else
  begin
    //S := TTextControl( Control ).Text;
    S := FDockSitePanel.Caption;
    if Control is TRzPanel then
      S := TRzPanel(Control).Caption;
    Canvas.Font := FFont;

    {if Control is TWinControl then
    begin
      if TWinControl( Control ).Focused then
      begin
        Canvas.Brush.Color := clActiveCaption;
        Canvas.Font.Color := clCaptionText;
      end
      else
      begin
        Canvas.Brush.Color := clInactiveCaption;
        Canvas.Font.Color := clInactiveCaptionText;
      end;
    end
    else
    begin
      Canvas.Brush.Color := clActiveCaption;
      Canvas.Font.Color := clCaptionText;
    end; }

    Canvas.Brush.Color := clActiveCaption;
    Canvas.Font.Color := clCaptionText;

    if FDockSitePanel.Align in [ alTop, alBottom ] then
    begin
      R := Rect( ARect.Left, ARect.Top, ARect.Left + FGrabberSize, ARect.Bottom );
      DrawVertTitle( Canvas, S, R );

      // Draw the Close X
      Canvas.Font.Name := FCloseFont.Name;
      R := Rect( ARect.Left + 1, ARect.Top + 1, ARect.Left + FGrabberSize - 2, ARect.Top + 12 );
      Canvas.TextRect( R, R.Left, R.Top, 'r' );
    end
    else
    begin
      R := Rect( ARect.Left, ARect.Top, ARect.Right, ARect.Top + FGrabberSize );
      Canvas.TextRect( R, R.Left + 2, R.Top, S );

      // Draw the Close X
      Canvas.Font.Name := FCloseFont.Name;
      R := Rect( ARect.Right - FGrabberSize - 1, ARect.Top + 1, ARect.Right - 2, ARect.Top + 12 );
      Canvas.TextRect( R, R.Left, R.Top, 'r' );
    end;
  end;
end;


{ TGroupComponsPanel }

function TGroupComponsPanel.AddNodeFrom(ASrcNode: TFlyNode; ASelect: Boolean): TFlyNode;
var
  ObjectsInGroupPanel: TList;

  function CopyNode(ASrc, AParentDest: TFlyNode): TFlyNode;
  var
    SrcChildNode: TFlyNode;
  begin
    Result := nil;
                                         
    // Если есть компоненты которые можно подключить
    if FFormOwner.GetComponCountToJoinFromNode(ASrc, ObjectsInGroupPanel) > 0 then
      // Если такой ветви нету в дереве
      if GetTreeViewNodeByDataFly(FTree, ASrc.Data, false) = nil then
      begin
        if AParentDest = nil then
          Result := FTree.Items.Add(nil, ASrc.Text)
        else
          Result := FTree.Items.AddChild(AParentDest, ASrc.Text);

        Result.Data := ASrc.Data;
        Result.ImageIndex := GetImageIndexNoConnected(ASrc.ImageIndex);
        Result.SelectedIndex := GetImageIndexNoConnected(ASrc.SelectedIndex);
        //Result.StateIndex := ASrc.StateIndex;
        Result.StateIndex := STATE_CHECKED;


        SrcChildNode := ASrc.getFirstChild;
        while SrcChildNode <> nil do
        begin
          CopyNode(SrcChildNode, Result);
          SrcChildNode := SrcChildNode.GetNextSibling;
        end;

        Result.Expanded := ASrc.Expanded;
      end;
  end;

begin
  Result := nil;
  if ASrcNode <> nil then
  begin
    ObjectsInGroupPanel := GetTreeViewDataListFly(FTree); 
    Result := CopyNode(ASrcNode, nil);
    FreeAndNil(ObjectsInGroupPanel);
  end;
  if Result <> nil then
    if ASelect then
      FTree.Selected := Result;
end;

constructor TGroupComponsPanel.Create(ATreeOwner: TFlyTreeViewPro; AFormOwner: TF_MakeEditCrossConnection);
var
  Stream: TMemoryStream;
  ParentControl: TWinControl;
  LabelCaption: TLabel;

  PanelDockManager: TGroupComponsPanelDockManager;
begin
  //FParent := AParent;
  FTreeOwner := ATreeOwner;
  FFormOwner := AFormOwner;
  FObjectList := TObjectList.Create(true);


  FPanel := TRzPanel.Create(FTreeOwner.Owner);
  FObjectList.Add(FPanel);
  FPanel.Visible := false;
  FPanel.Parent := FTreeOwner.Parent;
  FPanel.Align := alBottom;
  FPanel.Align := alTop;
  FPanel.Constraints.MinHeight := 50;
  FPanel.Height := 170;
  FPanel.BorderInner := fsNone;
  FPanel.BorderOuter := fsFlat;
  //FPanel.DockSite := true;
  //FPanel.UseDockManager := false;


  //FControlsOwner := FPanel;
  FControlsOwner := FTreeOwner.Owner;

  {// FDockSitePanel нужен для того чтобы DockClientCaption + Крестик были горизонтально
  // если FDockSitePanel.Align будет в [alTop, alBottom], то DockClientCaption будет вертикально
  // поэтому если панель клиета вешать на FPanel, в которого Align = alTop, то полоса с Caption будет вертикально
  FDockSitePanel := TRzPanel.Create(FControlsOwner);
  FObjectList.Add(FDockSitePanel);
  FDockSitePanel.Parent := FPanel;
  FDockSitePanel.Align := alClient;
  FDockSitePanel.BorderInner := fsNone;
  FDockSitePanel.BorderOuter := fsNone;
  FDockSitePanel.DockSite := True;
  //PanelDockManager := TGroupComponsPanelDockManager.Create(FDockSitePanel);
  //FDockSitePanel.DockManager := PanelDockManager;
  // перехватываем события (точнее нажатие на крестик)
  FDockSitePanelWndProcOriginal := FDockSitePanel.WindowProc;
  FDockSitePanel.WindowProc := FDockSitePanelWndProc;
  // запрещаем вытаскивание клиентов (в обработчике)
  FDockSitePanel.OnUnDock := FDockSitePanelUnDock;

  FDockClientPanel := TRzPanel.Create(FControlsOwner);
  FObjectList.Add(FDockClientPanel);
  FDockClientPanel.Parent := FPanel;
  FDockClientPanel.Caption := cMakeEditCrossConnection_Msg27_0;
  FDockClientPanel.BorderInner := fsNone;
  FDockClientPanel.BorderOuter := fsNone;
  FDockClientPanel.ManualDock(FDockSitePanel);

  ParentControl := FDockClientPanel;}

  // Панель с заглавием
  FPanelTitle := TRzPanel.Create(FControlsOwner);
  FObjectList.Add(FPanelTitle);
  FPanelTitle.Parent := FPanel;
  FPanelTitle.Align := alTop;
  FPanelTitle.Alignment := taLeftJustify;
  FPanelTitle.AlignmentVertical := avTop;
  FPanelTitle.BorderInner := fsNone;
  FPanelTitle.BorderOuter := fsNone;
  FPanelTitle.Caption := cMakeEditCrossConnection_Msg27_0;
  FPanelTitle.Color := clActiveCaption;
  FPanelTitle.Font.Color := clCaptionText;
  FPanelTitle.Height := 15;
  // панель для выравнивание кнопки "закрыть по правому краю"
  FPanelCloseBt := TRzPanel.Create(FControlsOwner);
  FObjectList.Add(FPanelCloseBt);
  FPanelCloseBt.Parent := FPanelTitle;
  FPanelCloseBt.Align := alRight;
  FPanelCloseBt.BorderInner := fsNone;
  FPanelCloseBt.BorderOuter := fsNone;
  FPanelCloseBt.Height := FPanelTitle.Height;
  FPanelCloseBt.Width := 15;
  FPanelCloseBt.ParentColor := true;
  FPanelCloseBt.ParentFont := true;
  // Кнопка закрыть
  FbtClose := TSpeedButton.Create(FControlsOwner);
  FObjectList.Add(FbtClose);
  FbtClose.Parent := FPanelCloseBt;
  FbtClose.Caption := 'X';
  FbtClose.Hint := cMakeEditCrossConnection_Msg27_5;
  FbtClose.ShowHint := true;
  FbtClose.Flat := true;
  FbtClose.Font.Color := FPanelTitle.Font.Color;
  FbtClose.Font.Style := FbtClose.Font.Style + [fsBold];
  FbtClose.Font.Name := 'Arial'; //'Marlett';
  FbtClose.Height := FPanelCloseBt.Height - 1;
  FbtClose.Width := FPanelCloseBt.Width - 1;
  FbtClose.OnClick := FbtCloseClick;


  FPanelContainer := TRzPanel.Create(FControlsOwner);
  FObjectList.Add(FPanelContainer);
  FPanelContainer.Parent := FPanel;
  FPanelContainer.Align := alClient;
  FPanelContainer.BorderInner := fsNone;
  FPanelContainer.BorderOuter := fsNone;

  ParentControl := FPanelContainer;
  

  FToolBar := TToolBar.Create(FControlsOwner);
  FObjectList.Add(FToolBar);
  FToolBar.Parent := ParentControl;
  FToolBar.Align := alTop;
  FToolBar.ButtonHeight := 20;
  FToolBar.ButtonWidth := 20;
  FToolBar.Flat := true;
  FToolBar.Images := DMCommon.ImageList_Tree;  //29.08.2011 F_ProjMan.DM.ImageList_Tree;
  FToolBar.Height := FToolBar.ButtonHeight + 2;
  FToolBar.ShowHint := true;


  {FPanelCaption := TRzPanel.Create(FControlsOwner);
  FObjectList.Add(FPanelCaption);
  FPanelCaption.BorderWidth := 0;
  FPanelCaption.Height := 17;
  FPanelCaption.Parent := ParentControl;
  FPanelCaption.Align := alTop;
  FPanelCaption.Alignment := taLeftJustify;
  FPanelCaption.AlignmentVertical := avTop;
  FPanelCaption.BorderInner := fsNone;
  FPanelCaption.BorderOuter := fsNone;
  FPanelCaption.Caption := ''; //FDockClientPanel.Caption;

  LabelCaption := TLabel.Create(FControlsOwner);
  FObjectList.Add(LabelCaption);
  //LabelCaption.AutoSize := false;
  //LabelCaption.Align := alTop;
  //LabelCaption.Height := FPanelCaption.Height - 2;
  LabelCaption.Parent := FPanelCaption;
  LabelCaption.Left := 2;
  LabelCaption.Top := -2;
  LabelCaption.Caption := FDockClientPanel.Caption;
  FPanelCaption.Height := LabelCaption.Top + LabelCaption.Height;
  LabelCaption.BringToFront;
  }


  FPopupMenu := TPopupMenu.Create(FControlsOwner);
  FObjectList.Add(FPopupMenu);
  FPopupMenu.Images := FToolBar.Images;

  FtbFindInTree := CreateToolButton(cMakeEditCrossConnection_Msg27_3, 14, FtbFindInTreeOnClick);
  FtbSepatator := CreateToolButton('-', -1, nil);
  FtbSepatator.Style := tbsSeparator;
  FtbSepatator.Width := 8;
  FtbRemove := CreateToolButton(cQuastDel, 3, FtbRemoveOnClick);

  FtbCollapse := CreateToolButton(cNameCollapseAllB, 8, FtbCollapseOnClick);
  FtbExpand := CreateToolButton(cNameExpandAllB, 7, FtbExpandOnClick);
  FtbMoveDown := CreateToolButton(cMakeEditCrossConnection_Msg27_2, 11, FtbMoveDownOnClick);
  FtbMoveUp := CreateToolButton(cMakeEditCrossConnection_Msg27_1, 10, FtbMoveUpOnClick);


  FTree := TFlyTreeViewPro.Create(FControlsOwner);
  FObjectList.Add(FTree);
  FTree.Name := '';
  FTree.Parent := ParentControl;

  FTree.Images.Assign(ATreeOwner.Images);
  FTree.Images.AddImages(F_ProjMan.DM.ImageList_FlyTree);
  FTree.ButtonSize := ATreeOwner.ButtonSize;
  FTree.ButtonCheckedIndex := tbiChecked + ATreeOwner.Images.Count;
  //FTree.ButtonCheckedIndex := ATreeOwner.ButtonCheckedIndex;
  //FTree.ButtonUnCheckedIndex := ATreeOwner.ButtonUnCheckedIndex;
  FTree.ButtonUnCheckedIndex := tbiUnchecked + ATreeOwner.Images.Count;
  //FTree.ButtonGrayedIndex := ATreeOwner.ButtonGrayedIndex;
  FTree.ButtonGrayedIndex := tbiGrayed + ATreeOwner.Images.Count;
  //FTree.ButtonOptionedIndex := ATreeOwner.ButtonOptionedIndex;
  //FTree.ButtonUnOptionedIndex := ATreeOwner.ButtonUnOptionedIndex;
  FTree.ButtonCollapsedIndex := ATreeOwner.ButtonCollapsedIndex;
  FTree.ButtonExpandedIndex := ATreeOwner.ButtonExpandedIndex;
  FTree.ButtonNonChildIndex := ATreeOwner.ButtonNonChildIndex;
  //FTree.ButtonGrayedUnChecked := ATreeOwner.ButtonGrayedUnChecked;
  //FTree.ButtonDblChecked := ATreeOwner.ButtonDblChecked;
  //FTree.ButtonGrayedDblChecked := ATreeOwner.ButtonGrayedDblChecked;
  //FTree.ButtonGrayedOptioned := ATreeOwner.ButtonGrayedOptioned;
  //FTree.ButtonGrayedUnOptioned := ATreeOwner.ButtonGrayedUnOptioned;
  FTree.ClickableColumns := ATreeOwner.ClickableColumns;
  FTree.Columns.Assign(ATreeOwner.Columns);
  FTree.DefaultRowHeight := ATreeOwner.DefaultRowHeight;
  FTree.FitColumnToClientWidth := ATreeOwner.FitColumnToClientWidth;
  FTree.FixedRows := ATreeOwner.FixedRows;
  FTree.Items.Clear;
  FTree.Indent := ATreeOwner.Indent;
  FTree.Options := ATreeOwner.Options + [goRangeSelect];//FTree.Options := ATreeOwner.Options - [goRangeSelect];
  FTree.RightClickSelect := ATreeOwner.RightClickSelect;
  FTree.ShowHint := ATreeOwner.ShowHint;
  FTree.ShowImages := ATreeOwner.ShowImages;
  FTree.ShowLogic := ATreeOwner.ShowLogic;
  FTree.StatesDrawed := ATreeOwner.StatesDrawed;
  FTree.ToolTips := ATreeOwner.ToolTips;
  //ATreeOwner.AssignTo(FTree);
  FTree.Align := alClient;
  FTree.PopupMenu := FPopupMenu;
  FTree.OnDblClick := FTreeOnDblClick;

  FSplitter := TSplitter.Create(FControlsOwner);
  FObjectList.Add(FSplitter);
  FSplitter.Parent := FTreeOwner.Parent;
  FSplitter.Align := alTop;
  FSplitter.Height := 3;

  FPanel.Visible := true;

  FTimer := TTimer.Create(FControlsOwner);
  FObjectList.Add(FTimer);
  FTimer.Enabled := false;
  FTimer.Interval := 1;
  FTimer.OnTimer := FTimerOnTimer; 
end;

function TGroupComponsPanel.CreateToolButton(ACaption: String; AImageIndex: Integer; AOnClickEvent: TNotifyEvent): TToolButton;
var
  pmItem: TMenuItem;
begin
  Result := TToolButton.Create(FControlsOwner);
  FObjectList.Add(Result);
  Result.Parent := FToolBar;

  Result.Caption := ACaption;
  Result.Hint := ACaption;
  Result.ImageIndex := AImageIndex;
  Result.Height := 18;
  Result.OnClick := AOnClickEvent;

  pmItem := TMenuItem.Create(FPopupMenu);
  //FObjectList.Add(pmItem);
  pmItem.Caption := ACaption;
  pmItem.ImageIndex := AImageIndex;
  pmItem.OnClick := AOnClickEvent;
  FPopupMenu.Items.Insert(0, pmItem);
end;

destructor TGroupComponsPanel.Destroy;
begin
  //FreeAndNil(FControlsOwner);

  FObjectList.Clear;
  FreeAndNil(FObjectList);
end;

function TGroupComponsPanel.GetComponents: TSCSComponents;
var
  Node: TFlyNode;
  NodeObject: TObject;
begin
  Result := TSCSComponents.Create(false);

  Node := GetFirstNodeFromFlyTree(FTree);
  while Node <> nil do
  begin
    if Node.StateIndex = STATE_CHECKED then
    begin
      NodeObject := TObject(Node.Data);
      if NodeObject is TSCSComponent then
        Result.Add(TSCSComponent(NodeObject));
    end;

    Node := Node.GetNext;
  end;
end;

procedure TGroupComponsPanel.RefreshImageIndexes;
var
  Node: TFlyNode;

  SrcNode: TFlyNode;
begin
  Node := GetFirstNodeFromFlyTree(FTree);
  while Node <> nil do
  begin
    SrcNode := GetTreeViewNodeByDataFly(FTreeOwner, Node.Data, false);
    if SrcNode <> nil then
    begin
      Node.Text := SrcNode.Text;
      Node.ImageIndex := GetImageIndexNoConnected(SrcNode.ImageIndex);
      Node.SelectedIndex := GetImageIndexNoConnected(SrcNode.SelectedIndex);
    end;
    Node := Node.GetNext;
  end;
end;

procedure TGroupComponsPanel.DoUserClose;
begin
  if Assigned(FOnUserClose) then
    FOnUserClose(Self);
  Free;
end;

procedure TGroupComponsPanel.ExpandCollapse(AIndex: Integer);
var
  SelectedNodes: TList;
  i: integer;
begin
  SelectedNodes := GetTreeViewSelectedNodesFly(FTree);
  for i := 0 to SelectedNodes.Count - 1 do
    case AIndex of
      1:
        ExpandNodeFly(TFlyNode(SelectedNodes[i]), true);
      -1:
        CollapseNodeFly(TFlyNode(SelectedNodes[i]), true);
    end;
  FreeAndNil(SelectedNodes);
end;

procedure TGroupComponsPanel.FDockSitePanelUnDock(Sender: TObject; Client: TControl;
  NewTarget: TWinControl; var Allow: Boolean);
begin
  Allow := false;
end;

procedure TGroupComponsPanel.FDockSitePanelWndProc(var Msg: TMessage);
var
  CanOriginalProc: Boolean;
begin
  CanOriginalProc := true;
  case Msg.Msg of
    WM_LBUTTONUP:
      begin
        if HitTestCloseControl(FDockSitePanel, SmallPointToPoint(TWMMouse(Msg).Pos)) then
        begin
          CanOriginalProc := false;
          DoUserClose;
        end;
      end;
    WM_PAINT:
      begin
        //FDockSitePanel.DockManager := nil;
        //EmptyProcedure;
      end;
    WM_SIZE:
      PostMessage(FDockSitePanel.Handle, WM_KILLFOCUS, 0, 0);
    WM_MOUSEACTIVATE: ;
      //CanOriginalProc := false;
    WM_KILLFOCUS: ;
      //CanOriginalProc := false;
    WM_NCPAINT, WM_ERASEBKGND, WM_GETTEXTLENGTH, WM_SETCURSOR,
    WM_NCHITTEST, WM_MOUSEMOVE, WM_PARENTNOTIFY,
     $0B007, $B013, $0B014, $B02C, $B034, $B036, $B038:
      ;
    else
    begin
      EmptyProcedure;
    end;
  end;

  if CanOriginalProc then
    FDockSitePanelWndProcOriginal(Msg);
end;

procedure TGroupComponsPanel.FTimerOnTimer(Sender: TObject);
begin
  TTimer(Sender).Enabled := false;

  case TTimer(Sender).Tag of
    0: // UserClose
      DoUserClose;
  end;
end;

function TGroupComponsPanel.GetVisible: Boolean;
begin
  Result := FPanel.Visible;
end;

procedure TGroupComponsPanel.MoveNode(AIndex: Integer);
var
  SelectedNodes: TList;
  i: Integer;
  SrcNode: TFlyNode;
  TrgNode: TFlyNode;
  TrgNextNode: TFlyNode;
  //NodeAttachMode: TNodeAttachMode;

  SavedSelected: TFlyNode;
begin
  // получаем ветви в порядке "сверху вниз"
  SelectedNodes := GetTreeViewSelectedNodesFly(FTree);

  // если перемещение вних, то меняем порядок ветвей на "снизу вверх"
  if AIndex = -1 then
    RotateTList(SelectedNodes);

  for i := 0 to SelectedNodes.Count - 1 do
  begin
    SrcNode := TFlyNode(SelectedNodes[i]); //FTree.Selected;
    SrcNode.Selected := false;

    TrgNode := nil;
    //NodeAttachMode := naInsert;
    case AIndex of
      1: //Up
        begin
          TrgNode := SrcNode.getPrevSibling;
          if TrgNode <> nil then
            SrcNode.MoveTo(TrgNode, naInsert);
        end;
      -1: //Down
        begin
          TrgNode := SrcNode.GetNextSibling;
          if TrgNode <> nil then
          begin
            //ExchangeObjects(TrgNode, SrcNode);
            TrgNextNode := TrgNode.GetNextSibling;
            if TrgNextNode = nil then
              SrcNode.MoveTo(TrgNode, naAdd)
            else
              SrcNode.MoveTo(TrgNextNode, naInsert);
          end;
        end;
    end;
    if TrgNode = nil then
      Break; //// BREAK ////

    {if (TrgNode <> nil) and (SrcNode <> nil) then
    begin
      SrcNode.MoveTo(TrgNode, naInsert); //FTree.Selected.Move(FTree.Selected.Index, NodeToMove.Index);
      //SelectNodeFly(FTree, FTree.Selected);
      //SavedSelected := FTree.Selected;
      //FTree.Selected := nil;
      //FTree.Selected := SavedSelected;
    end;}
  end;

  SelectTreeViewNodesFly(FTree, SelectedNodes, true);

  FreeAndNil(SelectedNodes);
end;

procedure TGroupComponsPanel.SetVisible(Value: Boolean);
begin
  FPanel.Visible := Value;
end;

procedure TGroupComponsPanel.StartTimer(AActionCode: Integer);
begin
  FTimer.Tag := AActionCode;
  FTimer.Enabled := true;
end;

procedure TGroupComponsPanel.FbtCloseClick(Sender: TObject);
begin
  StartTimer(0);
end;

procedure TGroupComponsPanel.FtbMoveUpOnClick(Sender: TObject);
begin
  MoveNode(1);
end;

procedure TGroupComponsPanel.FtbMoveDownOnClick(Sender: TObject);
begin
  MoveNode(-1);
end;

procedure TGroupComponsPanel.FtbExpandOnClick(Sender: TObject);
begin
  ExpandCollapse(1);
end;

procedure TGroupComponsPanel.FtbCollapseOnClick(Sender: TObject);
begin
  ExpandCollapse(-1);
end;

procedure TGroupComponsPanel.FtbRemoveOnClick(Sender: TObject);
var
  SelectedNodes: TList;
  NodeToSelect: TFlyNode;
  i: integer;
begin
  SelectedNodes := GetTreeViewSelectedNodesFly(FTree);
  //if FTree.Selected <> nil then
  if SelectedNodes.Count > 0 then
    if MessageModal(cMakeEditCrossConnection_Msg27_4, ApplicationName, MB_YESNO or MB_ICONQUESTION) = IDYES then
    begin
      NodeToSelect := TFlyNode(SelectedNodes[0]).getPrevSibling;
      if NodeToSelect = nil then
        TFlyNode(SelectedNodes[0]).Parent;

      for i := 0 to SelectedNodes.Count - 1 do
        TFlyNode(SelectedNodes[i]).Delete;
      //FTree.Selected.Delete;


      if FTree.Items.Count = 0 then
        StartTimer(0)
      else
      begin
        if NodeToSelect = nil then
          NodeToSelect := FTree.Items[0];
        FTree.Selected := NodeToSelect;
      end;
    end;
  FreeAndNil(SelectedNodes);
end;

procedure TGroupComponsPanel.FtbFindInTreeOnClick(Sender: TObject);
begin
  if FTree.Selected <> nil then
    GetTreeViewNodeByDataFly(FTreeOwner, FTree.Selected.Data, true);
end;

procedure TGroupComponsPanel.FTreeOnDblClick(Sender: TObject);
begin
  FtbFindInTree.Click;
end;

{ TF_MakeEditCrossConnection }

procedure TF_MakeEditCrossConnection.AfterConnectDiconnect;
var
  WithObject: TObject;
  Compon: TSCSComponent;
  SavedDataFrom: Pointer;
  SavedDataTo: Pointer;

  RestoreNodeFrom: TTreeNode;
  RestoreNodeTo: TTreeNode;
begin
  if Assigned(tvWith.Selected) then
    if TObject(tvWith.Selected.Data) is TSCSComponent then
    begin
      Compon := TSCSComponent(tvWith.Selected.Data);
      if Compon.IsLine = biTrue then
      begin
        //21.03.2008 Compon.LoadWholeComponent(true);
        Compon.LoadWholeComponent(false);
        Compon.DefineFirstLast;
      end;
    end;

  SavedDataFrom := nil;
  SavedDataTo := nil;
  if Assigned(tvFrom.Selected) then
    SavedDataFrom := tvFrom.Selected.Data;
  if Assigned(tvTo.Selected) then
    SavedDataTo := tvTo.Selected.Data;

  if FFormMode = fmCrossConfigurator then
  begin
    DefineTreeViewImageIndex(tvWith, nil, false);
    DefineTreeViewImageIndex(tvFrom, nil, false);
    DefineTreeViewImageIndex(tvTo, nil, false);
  end
  else
  if FFormMode = fmCableConfigurator then
  begin
    if rbSelectByLine.Checked then
    begin
      DefineTreeViewImageIndex(tvWith, nil, false);
      DefineTreeViewImageIndex(tvFrom, FLineComponFromSide, false);
      DefineTreeViewImageIndex(tvTo, FLineComponToSide, false);
    end
    else
    if rbSelectByPoint.Checked then
    begin
      DefineTreeViewImageIndex(tvWith, nil, false);
      DefineTreeViewImageIndex(tvFrom, FPointComponentFrom, false);
      if GetComponIdentificatorInComplex(GetComponentFromNode(tvWith.Selected)) <> -1 then
        DefineTVImageIndexWithTrunkNodes(tvWith.Selected, tvTo, FLineComponToSide)
      else
        DefineTreeViewImageIndex(tvTo, FLineComponToSide, false);
    end;
  end
  else
  if FFormMode = fmPointObjectConfigurator then
  begin
    DefineTreeViewImageIndex(tvWith, nil, false);
    DefineTreeViewImageIndex(tvFrom, TSCSComponent(GetObjectFromTreeView(tvWith, cnTSCSComponent)), false);
  end;

  //if FIsInterfAction then
  begin
    //LoadInterfacesWith(false);
    //LoadInterfacesFrom(false);
    //LoadInterfacesTo(false);

    ReloadInterfaces(tvInterfWithSide1, tvInterfWithSide2, BoolToInt(FCanConnect), LoadInterfacesWith);
    ReloadInterfaces(tvInterfFromSide1, tvInterfFromSide2, BoolToInt(FCanConnect), LoadInterfacesFrom);
    ReloadInterfaces(tvInterfTo, nil, BoolToInt(FCanConnect), LoadInterfacesTo);

    if btExtendedMode.Down then
    begin
      tvInterfWithSide1SelectedChanged(nil, tvInterfWithSide1.Selected);
      tvInterfWithSide2SelectedChanged(nil, tvInterfWithSide2.Selected);

      tvInterfFromSide1SelectedChanged(nil, tvInterfFromSide1.Selected);
      tvInterfFromSide2SelectedChanged(nil, tvInterfFromSide2.Selected);
    end;
  end;
  
  //**** Определить начальный и конечный подключенные объекты
  DefineCableFirstLastComponsByTrees;

  //**** Определить начальный и конечный подключенные объекты
  {try
    tvWithChange(tvWith, tvWith.Selected);
  finally
    RestoreNodeFrom := GetTreeViewNodeByData(tvFrom, SavedDataFrom, true);
    RestoreNodeTo := GetTreeViewNodeByData(tvTo, SavedDataTo, true);
    if Not Assigned(RestoreNodeFrom) and
       Not Assigned(RestoreNodeTo) then
    begin
      GetTreeViewNodeByData(tvFrom, SavedDataTo, true);
      GetTreeViewNodeByData(tvTo, SavedDataFrom, true);
      if tvFrom.Focused then
        tvTo.SetFocus
      else
      if tvTo.Focused then
        tvFrom.SetFocus;
    end;
  end;    }
  EnableDisableConfiguratorControls;
  RefreshGroupComponsPanels;
end;

procedure TF_MakeEditCrossConnection.AfterSetDataToNode(Sender: TObject);
var
  NodeObject: TObject;
begin
  if Sender is TFlyNode then
    if TObject(TFlyNode(Sender).Data) is TObject then
    begin
      NodeObject := TObject(TFlyNode(Sender).Data);
      if NodeObject is TInterfInfo then
        TInterfInfo(NodeObject).FNode := TFlyNode(Sender);
    end;
end;

function TF_MakeEditCrossConnection.AddComponentToTreeView(
  ASCSComponent: TSCSComponent; AImageIndex: Integer; ATreeView: TFlyTreeViewPro;
  AParentNode: TFlyNode): TFlyNode;
var
  Node: TFlyNode;
  NodeText: String;
begin
  Result := nil;
  Node := nil;
  NodeText := ASCSComponent.GetNameForVisible(false);
  {$IF Not Defined (FINAL_SCS)}
    NodeText := NodeText + '(ID '+IntToStr(ASCSComponent.ID);
    if ASCSComponent.IsLine = biTrue then
      NodeText := NodeText + ', WHOLE_ID '+IntToStr(ASCSComponent.Whole_ID);
    NodeText := NodeText +')';
  {$IFEND}

  if Not Assigned(AParentNode) then
    Node := ATreeView.Items.Add(nil, NodeText)
  else
    Node := ATreeView.Items.AddChild(AParentNode, NodeText);
  Node.Data := ASCSComponent;
  Node.ImageIndex := AImageIndex;
  Node.SelectedIndex := AImageIndex;
  Node.StateIndex := -1;
  Result := Node;
end;

procedure TF_MakeEditCrossConnection.AddCrossInterfacesToNode(ACrossCompon: TSCSComponent; ADestNode: TFlyNode);
var
  Interf, ConnInterf: TSCSinterface;
  Side1List, Side2List: TList;
  InterfAdded: Boolean;
  i, j: integer;
  ptrPortInterfRel: PPortInterfRel;

  procedure AddFromList(AList: TList; ASideNum: Integer);
  var
    i, j: integer;
    Interf: TSCSInterface;
    IsBusy: Integer;
  begin
    for i := 0 to AList.Count - 1 do
    begin
      Interf := TSCSInterface(AList[i]);
      for j := 0 to Interf.Kolvo - 1 do
      begin
        IsBusy := biFalse;
        if CheckNumInPositionList(j+1, Interf.BusyPositions) then
          IsBusy := biTrue
        else
          IsBusy := biFalse;
        AddInterfInfoToTree(Interf, Interf.LoadName+' '+intToStr(j+1)+' '+cMakeEditCrossConnection_Msg26_5+' '+IntToStr(ASideNum), IsBusy, 1, ADestNode, TFlyTreeViewPro(ADestNode.Tree), j+1, j+1);
      end;
    end;
  end;

begin
  Side1List := TList.Create;
  Side2List := TList.Create;
  for i := 0 to ACrossCompon.Interfaces.Count - 1 do
  begin
    Interf := ACrossCompon.Interfaces[i];
    InterfAdded := false;
    if (Interf.PortInterfRels.Count > 0) and (Side2List.IndexOf(Interf) = -1) then
      for j := 0 to Interf.PortInterfRels.Count - 1 do
      begin
        ptrPortInterfRel := Interf.PortInterfRels[j];
        if ptrPortInterfRel.RelType = rtInterfInternalConn then
        begin
          ConnInterf := ACrossCompon.GetInterfaceByID(ptrPortInterfRel.IDInterfRel);
          if (ConnInterf <> nil) and (Side1List.IndexOf(ConnInterf) = -1) then
          begin
            if Not InterfAdded then
            begin
              Side1List.Add(Interf);
              InterfAdded := true;
            end;
            Side2List.Add(ConnInterf);
          end;
        end;
      end;
  end;
  AddFromList(Side1List, 1);
  AddFromList(Side2List, 2);
  Side1List.Free;
  Side2List.Free;
end;

function TF_MakeEditCrossConnection.AddInterfaceToTreeView(AInterface: TSCSInterface; AImageIndex: Integer;
  ATreeView: TFlyTreeViewPro; AParentNode: TFlyNode): TFlyNode;
var
  Node: TFlyNode;
begin
  Result := nil;
  Node := nil;
  if Not Assigned(AParentNode) then
    Node := ATreeView.Items.Add(nil, AInterface.GetNameForVisible)
  else
    Node := ATreeView.Items.AddChild(AParentNode, AInterface.GetNameForVisible);
  Node.Data := AInterface;
  Node.ImageIndex := AImageIndex; 
  Node.SelectedIndex := AImageIndex;
  Node.StateIndex := -1;
  Result := Node;
end;

function TF_MakeEditCrossConnection.AddInterfInfoToTree(AInterf: TSCSInterface; AInterfName: String; AIsBusy, AKolvo: Integer;
      AParentNode: TFlyNode; ATreeView: TFlyTreeViewPro; APosFrom, APosTo: Integer): TFlyNode;
var
  InterfNode: TFlyNode;
  InterfInfo: TInterfInfo;
  ConnectedIDs: String;
  ImageIndex: Integer;
  NodeText: String;
  i: Integer;
begin
  Result := nil;
  InterfNode := nil;

  NodeText := AInterfName;
  {$IF Not Defined (FINAL_SCS)}
    ConnectedIDs := '';
    for i := 0 to AInterf.ConnectedInterfaces.Count - 1 do
    begin
      if ConnectedIDs <> '' then
        ConnectedIDs := ConnectedIDs + ', '
      else
        ConnectedIDs := '->';
      ConnectedIDs := ConnectedIDs + IntToStr(AInterf.ConnectedInterfaces[i].ID);
    end;
    NodeText := NodeText + ' (ID '+IntToStr(AInterf.ID)+ConnectedIDs+';'+IntToStr(APosFrom)+'-'+IntToStr(APosTo)+
        '; Side '+IntToStr(AInterf.Side)+'; ComponID '+IntToStr(AInterf.ComponentOwner.ID)+'; Busy '+BoolToStr(AIsBusy = biTrue)+')';
  {$IFEND}

  ImageIndex := -1;
  if AIsBusy = biTrue then
  begin
    if AInterf.ISPort = BiTrue then
      ImageIndex := 66
    else
      ImageIndex := tciiInterfaceFill
  end
  else
  if AIsBusy = biFalse then
  begin
    if AInterf.ISPort = BiTrue then
      ImageIndex := 65
    else
      ImageIndex := tciiInterfaceNoFill;
  end;
  InterfInfo := TInterfInfo.Create(AInterf);
  InterfInfo.FCaption := AInterfName;
  InterfInfo.IsBusy := AIsBusy;
  InterfInfo.Kolvo := AKolvo;
  InterfInfo.KolvoToConnect := AKolvo;
  InterfInfo.ImageIndex := ImageIndex;
  InterfInfo.PosFrom := APosFrom;
  InterfInfo.PosTo := APosTo;

  //if AParentNode <> nil then
  //  InterfNode := ATreeView.Items.AddChild(AParentNode, AInterfName)
  //else
  //  InterfNode := ATreeView.Items.Add(nil, AInterfName);

  if AParentNode <> nil then
  begin
    InterfNode := ATreeView.Items.AddChildObject(AParentNode, NodeText, InterfInfo);
  end
  else
    InterfNode := ATreeView.Items.AddObject(nil, NodeText, InterfInfo);

  InterfInfo.FNode := InterfNode;
  Result := InterfNode;

  if InterfNode <> nil then
  begin
    InterfNode.ImageIndex := ImageIndex;
    InterfNode.SelectedIndex := InterfNode.ImageIndex;
    InterfNode.StateIndex := -1;
    if FInterfTrees.IndexOf(ATreeView) <> -1 then
    begin
      InterfNode.Cells[ciKolvo] := IntToStr(AKolvo);
      if AIsBusy = biTrue then
        InterfNode.Cells[ciKolvoToConnect] := ''
      else
        InterfNode.Cells[ciKolvoToConnect] := IntToStr(AKolvo); //IntToStr(AInterf.Side);
      //InterfNode.Cells[ciColor] := IntToStr(AInterf.Color);
      if AInterf.Side = 0 then
        InterfNode.Cells[ciSide] := ''
      else
        InterfNode.Cells[ciSide] := IntToStr(AInterf.Side);

      //InterfNode.Data := InterfInfo;
    end;
  end;
end;

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

destructor TF_MakeEditCrossConnection.Destroy;
begin

  inherited;
end;

function TF_MakeEditCrossConnection.Execute(AMakeEdit: TMakeEdit;
  ASCSComponent: TSCSComponent; ACrossConnection: TSCSCrossConnection): Boolean;
begin
  Result := false;
  FFormMode := fmNBCrossConnection;
  FMakeEdit := AMakeEdit;
  if Assigned(ASCSComponent) then
  begin
    PrepareForm;

    FSCSComponent := ASCSComponent;
    if FSCSComponent.ChildComplects.Count = 0 then
      FSCSComponent.LoadChildComplects(true, true, true);
    if FSCSComponent.CrossConnections.Count = 0 then
      FSCSComponent.LoadCrossConnections;

    FCrossConnection := ACrossConnection;

    LoadComponentsWith;

    if ShowModal = mrOK then
    begin
      Result := true;
      with ACrossConnection do
      begin
        ACrossConnection.IDComponFrom := 0;
        ACrossConnection.IDComponTo := 0;
        ACrossConnection.IDComponWith := 0;
        ACrossConnection.IDCompRelFrom := 0;
        ACrossConnection.IDCompRelTo := 0;
        ACrossConnection.IDCompRelWith := 0;
        ACrossConnection.NppFrom := 0;
        ACrossConnection.NppTo := 0;
        ACrossConnection.NppWith := 0;

        //LoadParamsToCrossConnectionRecord(ACrossConnection, nil, 0, 0, 0, '');

        LoadParamsToCrossConnectionRecord(ACrossConnection, tvFrom, IDCompRelFrom, IDComponFrom, NppFrom, NameFrom);
        LoadParamsToCrossConnectionRecord(ACrossConnection, tvTo, IDCompRelTo, IDComponTo, NppTo, NameTo);
        LoadParamsToCrossConnectionRecord(ACrossConnection, tvWith, IDCompRelWith, IDComponWith, NppWith, NameWith);
      end;
    end;

    ClearTrees;
  end;
end;


procedure TF_MakeEditCrossConnection.ShowConnectConfigurator(ACatalog: TSCSCatalog;
  ACrossConnectionMode: TCrossConnectionMode; AConnectConfigeratorMode: TConnectConfigeratorMode;
  ALocateID: Integer = -1);
begin
  FFormMode := ACrossConnectionMode;
  if Assigned(ACatalog) then
  begin
    FCatalog := ACatalog;
    FList := TSCSList(ACatalog);

    if FPointFigureRelations <> nil then
      FreeAndNil(FPointFigureRelations);

    PrepareForm;
    case AConnectConfigeratorMode of
      cmByLine:
        rbSelectByLine.Checked := true;
      cmByPoint:
        rbSelectByPoint.Checked := true;
    end;


    if ALocateID > 0 then
      FindComponInTree(ALocateID, tvWith, true);
    ShowModal;

    if FPointFigureRelations <> nil then
      FreeAndNil(FPointFigureRelations);
    ClearTrees;

    FGroupComponsPanelList.Clear;

    TF_Main(GForm).RefreshNode;
    // Tolik 15/03/2017 --
    if Assigned(GCadForm) then
      RefreshCad(GCadForm.Pcad);
    //
  end;
end;

procedure TF_MakeEditCrossConnection.ShowPointObjectConfigurator(ACatalog: TSCSCatalog);
begin
  FFormMode := fmPointObjectConfigurator;
  if Assigned(ACatalog) then
  begin
    FCatalog := ACatalog;

    PrepareForm;

    if FConnectedLinesToPointObject <> nil then
      FreeAndNil(FConnectedLinesToPointObject);

    //LoadComponentsForPointObjectConfigurator(ACatalog);
    //SetControlsForInterfaces;

    Timer_AfterShowPointObjectConfigurator.Enabled := true;

    ShowModal;

    if FConnectedLinesToPointObject <> nil then
      FreeAndNil(FConnectedLinesToPointObject);
    ClearTrees;

    TF_Main(GForm).RefreshNode;
  end;
end;


function TF_MakeEditCrossConnection.HaveCrossComponConnection(
  ATopComponent, ACrossComponent: TSCSComponent): Boolean;
var
  i: Integer;
  ptrCrossConnection: TSCSCrossConnection;
begin
  Result := false;
  for i := 0 to ATopComponent.CrossConnections.Count - 1 do
  begin
    ptrCrossConnection := TSCSCrossConnection(ATopComponent.CrossConnections[i]);
    if (ptrCrossConnection.ID <> FCrossConnection.ID) or (FCrossConnection.ID = 0) then
      if (ptrCrossConnection.IDComponWith = ACrossComponent.ID) and
         (ptrCrossConnection.NppWith = ACrossComponent.ServCopyIndex) then
        if ACrossComponent.LinkToComlectRec <> nil then
          if ptrCrossConnection.IDCompRelWith = ACrossComponent.LinkToComlectRec.ID then
          begin
            Result := true;
            Break; ///// BREAK /////
          end;
  end;
end;

procedure TF_MakeEditCrossConnection.ChangeConfiguratorFormMode(ANewFormMode: TCrossConnectionMode);
var
  i: Integer;
  ComponentOwner: TSCSCatalog;
  SCSComponent: TSCSComponent;
  CurrWholeComponents: TSCSComponents;
  //16.01.2013 LookedWholeComponents: TSCSComponents;
  LookedWholeID: TIntList; //16.01.2013
  LookedPointObjects: TSCSCatalogs;
  PointObject: TSCSCatalog;
  PointObjectFrom: TSCSCatalog;
  PointObjectTo: TSCSCatalog;
  ImageIndex: Integer;
  ComponentNode: TFlyNode;

  CanAddCableToConfigurator: Boolean;

  PointFigureRelation: TPointFigureRelation;
  PointFiguresFromRelation: TSCSCatalogs;
  PointFigure: TSCSCatalog;

  FirstPoitObjectComponCount: Integer;
  LastPoitObjectComponCount: Integer;

  CrossOwners: TList;
  CrossOwner: TObject;
  OwnerObject: TObject;
  IsGroupCrosses: Boolean;
  OwnerNode: TFlyNode;
  // Tolik 28/08/2019 --
  //OldTick, CurrTick: Cardinal;
  OldTick, CurrTick: DWord;
  //
  //SavedOnChangeFrom: TTVChangedEvent;
  //SavedOnChangeTo: TTVChangedEvent;
  //SavedOnChangeWith: TTVChangedEvent;

  procedure AddPointComponWithObjectToTreeView(ATreeView: TFlyTreeViewPro; AComponent: TSCSComponent; AObject: TSCSCatalog);
  begin
    if LookedPointObjects.IndexOf(AObject) = -1 then
    begin
      LoadComponentsToCableConfigurator(ATreeView, AComponent, AObject, true);
      LookedPointObjects.Add(AObject);
    end;
  end;

begin
  //SavedOnChangeFrom := tvFrom.OnChange;
  //SavedOnChangeTo := tvTo.OnChange;
  //SavedOnChangeWith := tvWith.OnChange;
  //tvFrom.OnChange := nil;
  //tvTo.OnChange := nil;
  //tvWith.OnChange := nil;
  //try
  //  tvFrom.Items.Clear;
  //  tvTo.Items.Clear;
  //  tvWith.Items.Clear;
  //finally
    //tvFrom.OnChange := SavedOnChangeFrom;
    //tvTo.OnChange := SavedOnChangeTo;
    //tvWith.OnChange := SavedOnChangeWith;
  //end;

  FFormMode := ANewFormMode;

  ClearTreeViewFly(tvFrom, false, true);
  ClearTreeViewFly(tvTo, false, true);
  ClearTreeViewFly(tvWith, false, true);

  LoadInterfacesWith(true);
  LoadInterfacesFrom(true);
  LoadInterfacesTo(true);

  Act_AddCable.Visible := (FFormMode = fmCableConfigurator) and rbSelectByPoint.Checked;
  Act_DeleteCable.Visible := (FFormMode = fmCableConfigurator);
  Act_DisconnectAll.Visible := (FFormMode = fmCableConfigurator) or (FFormMode = fmCrossConfigurator);


  if IsThroughConfiguratorMode then
  begin
    case FFormMode of
      fmCableConfigurator:
        begin
          rbSelectByLine.Caption := cMakeEditCrossConnection_Msg1_1;
          rbSelectByPoint.Caption := cMakeEditCrossConnection_Msg1_2;
        end;
      fmCrossConfigurator:
        begin
          rbSelectByLine.Caption := cMakeEditCrossConnection_Msg1_3;
          rbSelectByPoint.Caption := cMakeEditCrossConnection_Msg1_4;
        end;
    end;
    if rbSelectByLine.Checked then
    begin
      gbWith.Caption := cMakeEditCrossConnection_Msg2_1 + cMakeEditCrossConnection_Msg20;
      gbFrom.Caption := cMakeEditCrossConnection_Msg2_2;
      gbTo.Caption := cMakeEditCrossConnection_Msg2_3;
    end
    else
    if rbSelectByPoint.Checked then
    begin
      gbWith.Caption := cMakeEditCrossConnection_Msg2_4 + cMakeEditCrossConnection_Msg20;
      gbFrom.Caption := cMakeEditCrossConnection_Msg2_5;
      gbTo.Caption := cMakeEditCrossConnection_Msg2_6;
    end;
  end;

  BeginProgress;
  try
    tvWith.Items.BeginUpdate;
    tvWith.OnChange := nil;
    tvWith.OnSelectedChanged := nil;
    try
      //*** Определить соединительные компоненты
      LookedPointObjects := nil;
      //16.01.2013 LookedWholeComponents := nil;
      LookedWholeID := nil;

      SetVisibleToGruopComponPanels(false);

      ComponentNode := nil;

      LookedPointObjects := TSCSCatalogs.Create(false);

      if (ANewFormMode = fmCrossConfigurator) or
         ((ANewFormMode = fmCableConfigurator) and rbSelectByLine.Checked) then
      begin
        IsGroupCrosses := false;

        if ANewFormMode = fmCableConfigurator then
          LookedWholeID := TIntList.Create //16.01.2013 LookedWholeComponents := TSCSComponents.Create(false)
        else if ANewFormMode = fmCrossConfigurator then
        begin
          // Определяем группировать ли кроссы
          if rbSelectByLine.Checked then
          begin
            CrossOwners := TList.Create;
            for i := 0 to FCatalog.ComponentReferences.Count - 1 do
            begin
              SCSComponent := FCatalog.ComponentReferences[i];
              if SCSComponent.IsCrossComponent and Assigned(SCSComponent.Parent) and (SCSComponent.Parent is TSCSComponent) then
              begin
                CrossOwner := SCSComponent.GetTopComponent;
                if CrossOwner = SCSComponent then
                  CrossOwner := SCSComponent.GetFirstParentCatalog;
                if (CrossOwner <> nil) and (CrossOwners.IndexOf(CrossOwner) = -1) then
                begin
                  CrossOwners.Add(CrossOwner);
                  if CrossOwners.Count > 1 then
                  begin
                    IsGroupCrosses := true;
                    Break; //// BREAK ////
                  end;
                end;
              end;
            end;
            CrossOwners.Free;
          end;
        end;


        OldTick := GetTickCount;
        for i := 0 to FCatalog.ComponentReferences.Count - 1 do
        begin
          SCSComponent := FCatalog.ComponentReferences[i];
          case ANewFormMode of
            fmCrossConfigurator:
              if SCSComponent.IsCrossComponent then
                if Assigned(SCSComponent.Parent) and (SCSComponent.Parent is TSCSComponent) then
                  if rbSelectByLine.Checked then
                  begin
                    if SCSComponent.IsLine = biFalse then
                    begin
                      OwnerNode := nil;
                      if IsGroupCrosses then
                      begin
                        CrossOwner := SCSComponent.GetTopComponent;
                        if CrossOwner = SCSComponent then
                          CrossOwner := SCSComponent.GetFirstParentCatalog;
                        OwnerNode := GetTreeViewNodeByDataFly(tvWith, CrossOwner, false);
                        if OwnerNode = nil then
                        begin
                          OwnerObject := SCSComponent.GetFirstParentCatalog;
                          if OwnerObject <> nil then
                          begin
                            // Ветка с объектом
                            OwnerNode := GetTreeViewNodeByDataFly(tvWith, OwnerObject, false);
                            if OwnerNode = nil then
                            begin
                              OwnerNode := tvWith.Items.Add(nil, TSCSCatalog(OwnerObject).GetNameForVisible(false));
                              OwnerNode.Data := OwnerObject;
                              OwnerNode.ImageIndex := tciiSCSConNormal;
                              OwnerNode.SelectedIndex := tciiSCSConNormal;
                              OwnerNode.StateIndex := -1;
                            end;
                          end;
                          // Ветка с верхним компонентом
                          if (CrossOwner <> OwnerObject) and (CrossOwner is TSCSComponent) then
                          begin
                            OwnerNode := tvWith.Items.AddChild(OwnerNode, TSCSComponent(CrossOwner).GetNameForVisible(false));
                            OwnerNode.Data := CrossOwner;
                            OwnerNode.ImageIndex := GetComponImageIndexByFilling(TSCSComponent(CrossOwner).IsLine, TSCSComponent(CrossOwner).GetFilling(biNone, itFunctional, false, false));
                            OwnerNode.SelectedIndex := OwnerNode.ImageIndex;
                            OwnerNode.StateIndex := -1;
                          end;
                        end;
                      end;
                      ImageIndex := GetComponImageIndexByFilling(SCSComponent.IsLine, SCSComponent.GetFilling(biNone, itFunctional, false, false));
                      AddCrossInterfacesToNode(SCSComponent, 
                        AddComponentToTreeView(SCSComponent, ImageIndex, tvWith, OwnerNode)
                      );
                      if OwnerNode <> nil then
                        OwnerNode.Expanded := true;
                    end;
                  end
                  else
                  if rbSelectByPoint.Checked then
                    if SCSComponent.JoinedComponents.Count > 0 then
                    begin
                      ComponentOwner := SCSComponent.JoinedComponents[0].GetFirstParentCatalog;
                      if LookedPointObjects.IndexOf(ComponentOwner) = -1 then
                      begin
                        LoadComponentsToCrossConfigurator(tvWith, SCSComponent, nil); //LoadComponentsToCrossConfigurator(tvWith, SCSComponent, SCSComponent.JoinedComponents[0]);
                        LookedPointObjects.Add(ComponentOwner);
                      end;
                    end
                    else
                    begin
                      ComponentOwner := SCSComponent.GetFirstParentCatalog;
                      if LookedPointObjects.IndexOf(ComponentOwner) = -1 then
                      begin
                        LoadComponentsToCrossConfigurator(tvWith, SCSComponent, nil);
                        LookedPointObjects.Add(ComponentOwner);
                      end;
                    end;
            fmCableConfigurator:
              if SCSComponent.IsLine = biTrue then
                //if SCSComponent.ComponentType.SysName <> ctsnCableChannel then
                if FDisabledCompTypesForCableConfigurator.IndexOf(SCSComponent.ComponentType.SysName) = -1 then
                  //16.01.2013 if LookedWholeComponents.IndexOf(SCSComponent) = -1 then
                  if GetValueIndexFromSortedIntList(SCSComponent.Whole_ID, LookedWholeID) = -1 then
                  begin
                    SCSComponent.LoadWholeComponent(false);
                    SCSComponent.DefineFirstLast;

                    CanAddCableToConfigurator := false;
                    if Assigned(SCSComponent.FirstConnectedConnCompon) or
                       Assigned(SCSComponent.LastConnectedConnCompon) then
                      CanAddCableToConfigurator := true
                    else
                    //*** есль ли компоненты в точ. объектах, кот. подкл. к трассе с SCSComponent
                    begin
                      PointObjectFrom := nil;
                      PointObjectTo := nil;
                      DefinePointObjectsForLineCompon(SCSComponent, PointObjectFrom, PointObjectTo);
                      if ((PointObjectFrom <> nil) and (PointObjectFrom.SCSComponents.Count > 0)) or
                         ((PointObjectTo <> nil) and (PointObjectTo.SCSComponents.Count > 0)) then
                        CanAddCableToConfigurator := true;
                    end;
                    if CanAddCableToConfigurator then
                    begin
                      if rbSelectByLine.Checked then
                      begin
                        ImageIndex := GetComponImageIndexByFilling(SCSComponent.IsLine, SCSComponent.GetFilling(biNone, itFunctional, true, false, false));
                        ComponentNode := AddComponentToTreeView(SCSComponent, ImageIndex, tvWith, nil);
                        //LoadConnectedLineComponentsToLine(tvWith, SCSComponent, ComponentNode);
                      end
                      else
                      if rbSelectByPoint.Checked then
                      begin
                        if Assigned(SCSComponent.FirstConnectedConnCompon) and Assigned(SCSComponent.LastConnectedConnCompon) then
                        begin
                          PointObject := SCSComponent.LastConnectedConnCompon.GetFirstParentCatalog;
                          AddPointComponWithObjectToTreeView(tvWith, SCSComponent.LastConnectedConnCompon, PointObject);

                          PointObject := SCSComponent.FirstConnectedConnCompon.GetFirstParentCatalog;
                          AddPointComponWithObjectToTreeView(tvWith, SCSComponent.FirstConnectedConnCompon, PointObject);
                        end
                        else
                        if Assigned(SCSComponent.LastConnectedConnCompon) then
                        begin
                          PointObject := SCSComponent.LastConnectedConnCompon.GetFirstParentCatalog;
                          AddPointComponWithObjectToTreeView(tvWith, SCSComponent.LastConnectedConnCompon, PointObject);
                        end
                        else
                        // если кабель не подключен к точ., но его трасса подключена к точ. объекту в котором имеются компоненты
                        begin
                          if (PointObjectFrom <> nil) and (PointObjectFrom.SCSComponents.Count > 0) then
                            AddPointComponWithObjectToTreeView(tvWith, nil, PointObjectFrom);
                          if (PointObjectTo <> nil) and (PointObjectTo.SCSComponents.Count > 0) then
                            AddPointComponWithObjectToTreeView(tvWith, nil, PointObjectTo);
                        end;
                      end;

                      //*** Занести в список просмотренных
                      //16.01.2013 CurrWholeComponents := FCatalog.GetComponentsByWholeID(SCSComponent.Whole_ID);
                      //16.01.2013 LookedWholeComponents.Assign(CurrWholeComponents, laOr);
                      //16.01.2013 CurrWholeComponents.Clear;
                      //16.01.2013 CurrWholeComponents.Free;
                      InsertValueToSortetIntList(SCSComponent.Whole_ID, LookedWholeID);
                    end;
                  end;
          end;
        end;
        CurrTick := GetTickCount - OldTick;
        CurrTick := GetTickCount - OldTick;

        //*** Загрузить привязанные линейные компоненты
        if (ANewFormMode = fmCableConfigurator) and rbSelectByLine.Checked then
          if ComponentNode <> nil then
          begin
            OldTick := GetTickCount;
            LoadConnectedLineComponentsToLineForSiblingNodes(tvWith, ComponentNode, false);
            CurrTick := GetTickCount - OldTick;
            CurrTick := GetTickCount - OldTick;
          end;

        if ANewFormMode = fmCableConfigurator then
        begin
          tvWith.Items.EndUpdate;
          try
            OldTick := GetTickCount;
            SortTreeViewChildNodesFly(nil, tvWith, tstText);
            CurrTick := GetTickCount - OldTick;
            CurrTick := GetTickCount - OldTick;
          finally
            tvWith.Items.BeginUpdate;
          end;
          OldTick := GetTickCount;
          SortConfiguratorTreeView(tvFrom);
          CurrTick := GetTickCount - OldTick;
          CurrTick := GetTickCount - OldTick;

          OldTick := GetTickCount;
          SortConfiguratorTreeView(tvTo);
          CurrTick := GetTickCount - OldTick;
          CurrTick := GetTickCount - OldTick;
        end;

        if tvWith.Items.Count > 0 then
          SelectNodeFly(tvWith, tvWith.Items[0]);//tvWith.Selected := tvWith.Items[0];

        //16.01.2013 if Assigned(LookedWholeComponents) then
        //16.01.2013   FreeAndNil(LookedWholeComponents);
        if LookedWholeID <> nil then
          FREeAndNil(LookedWholeID);
      end
      else
      //*** Конфигуратор по точечным объектам
      if ((ANewFormMode = fmCableConfigurator) and rbSelectByPoint.Checked) then
      begin
        FCurrIDPointObject := -1;
        FCurrIDPointComponent := -1;

        SetVisibleToGruopComponPanels(True);

        //*** Определить подключенные точ. объекты трассами между собой
        if FPointFigureRelations = nil then
          if FCatalog.ItemType = itList then
          begin
            //FPointFigureRelations := GetPointObjectsRelations(TSCSList(FCatalog).CurrID);
            OldTick := GetTickCount;
            FPointFigureRelations := nil;
            if TSCSList(FCatalog).Setting.SCSType = st_Internal then
              FPointFigureRelations := {GetPointObjectRelationsBetweenList(TSCSList(FCatalog).CurrID) //}GetPointObjectRelationsBetweenListDistr(TSCSList(FCatalog).CurrID)
            else
              FPointFigureRelations := GetPointObjectRelationsBetweenListDistr(TSCSList(FCatalog).CurrID); //GetPointObjectRelationsBetweenList(TSCSList(FCatalog).CurrID);

            CurrTick := GetTickCount - OldTick;
            CurrTick := GetTickCount - OldTick;

            OldTick := GetTickCount;
            DefineObjectsForPointFigureRelations(FPointFigureRelations, TSCSList(FCatalog));

            CurrTick := GetTickCount - OldTick;
            CurrTick := GetTickCount - OldTick;
          end;
        if FPointFigureRelations <> nil then
        begin
          //*** Будет подгружен список точ. соед-х объектов в порядке с МП

          //*** Закинуть все точ-е объекты из связей в общий список
          PointFiguresFromRelation := TSCSCatalogs.Create(false);
          for i := 0 to FPointFigureRelations.Count - 1 do
          begin
            PointFigureRelation := TPointFigureRelation(FPointFigureRelations[i]);
            if PointFiguresFromRelation.IndexOf(PointFigureRelation.FirstPointObject) = -1 then
              PointFiguresFromRelation.Add(PointFigureRelation.FirstPointObject);
            if PointFiguresFromRelation.IndexOf(PointFigureRelation.LastPointObject) = -1 then
              PointFiguresFromRelation.Add(PointFigureRelation.LastPointObject);
          end;

          SortSCSObjectsByPMOrder(PointFiguresFromRelation);
          for i := 0 to PointFiguresFromRelation.Count - 1 do
          begin
            PointFigure := PointFiguresFromRelation[i];
            //*** Загрузить в дерево объекты только текущего листа
            if PointFigure.ListID = TSCSList(FCatalog).SCSID then
              if GetCatalogComponCountWithoutDisabledTypes(PointFigure,
                  FDisabledCompTypesForCableConfigurator, true) > 0 then
                AddPointComponWithObjectToTreeView(tvWith, nil, PointFigure);
          end;
          FreeAndNil(PointFiguresFromRelation);


          {for i := 0 to FPointFigureRelations.Count - 1 do
          begin
            PointFigureRelation := TPointFigureRelation(FPointFigureRelations[i]);

            FirstPoitObjectComponCount := GetCatalogComponCountWithoutDisabledTypes(PointFigureRelation.FirstPointObject,
                FDisabledCompTypesForCableConfigurator, true);
            LastPoitObjectComponCount := GetCatalogComponCountWithoutDisabledTypes(PointFigureRelation.LastPointObject,
                FDisabledCompTypesForCableConfigurator, true);

            if (FirstPoitObjectComponCount > 0) and (LastPoitObjectComponCount > 0) then
            begin
              AddPointComponWithObjectToTreeView(tvWith, nil, PointFigureRelation.FirstPointObject);
              AddPointComponWithObjectToTreeView(tvWith, nil, PointFigureRelation.LastPointObject);
            end;
          end;

          SortConfiguratorTreeView(tvWith, true);}
        end;
      end;
      if Assigned(LookedPointObjects) then
        FreeAndNil(LookedPointObjects);

      SetControlsForInterfaces;
    finally
      tvWith.OnChange := tvWithChange;
      tvWith.OnSelectedChanged := tvWithSelectedChanged;
      tvWith.Items.EndUpdate;
      tvWithChange(tvWith, tvWith.Selected);
      tvWithSelectedChanged(nil, tvWith.Selected);
    end;
  finally
    EndProgress;
  end;
  //if tvWith.Showing then
  //  if Not tvWith.Focused then
  //    tvWith.SetFocus;
end;

function TF_MakeEditCrossConnection.CheckJoinInterfInfos(AInterfInfo1, AInterfInfo2: TInterfInfo): Boolean;
var
  Component1, Component2: TSCSComponent;

  CheckInterfRes: TCheckInterfForUnionResult;
  ConnectKind: TConnectKind;
  InterfCount1, InterfCount2: Integer;

  EmptyPositions1: TSCSInterfPositions;
  EmptyPositions2: TSCSInterfPositions;
begin
  Result := false;
  if Assigned(AInterfInfo1) and Assigned(AInterfInfo2) then
  begin
    Component1 := AInterfInfo1.FInterface.ComponentOwner;
    Component2 := AInterfInfo2.FInterface.ComponentOwner;

    ConnectKind := GetConnectKindByConnectionCompons(Component1, Component2, cntUnion);
    // В проверке пропускаем проверку на подключенность интерфейсов
    CheckInterfRes := CheckInterfForUnion(AInterfInfo1.FInterface, AInterfInfo2.FInterface,
                          GForm, GForm, {ConnectKind, }cntUnion, @InterfCount1, @InterfCount2,
                          [ciueInterfConnected]);
    if CheckInterfRes = chrSuccess then
    begin
      EmptyPositions1 := GetEmptyPositionsFromInterfInfo(AInterfInfo1);
      EmptyPositions2 := GetEmptyPositionsFromInterfInfo(AInterfInfo2);
      if (EmptyPositions1 <> nil) and (EmptyPositions2 <> nil) then
        if (EmptyPositions1.Kolvo > 0) and (EmptyPositions2.Kolvo > 0) then
        begin
          // Если компоненты не подключены, то можем подключить их нах
          //20.10.2011 if Component1.JoinedComponents.IndexOf(Component2) = -1 then
          begin
            Result := true;
          end;
        end;
      if EmptyPositions1 <> nil then
        FreeAndNil(EmptyPositions1);
      if EmptyPositions2 <> nil then
        FreeAndNil(EmptyPositions2);
    end;
  end;
end;


function TF_MakeEditCrossConnection.CheckJoinedComponWithInterfInfo(ACompon: TSCSComponent; AInterfInfo: TInterfInfo): Boolean;
var
  ComponInterf: TSCSInterface;
begin
  Result := false;
  if Assigned(AInterfInfo) and Assigned(AInterfInfo) then
  begin
    // Ищем интерфейс компонента связанный с AInterfInfo
    ComponInterf := AInterfInfo.FInterface.ComponentOwner.GetInterfaceConnectedWithCompon(AInterfInfo.FInterface, ACompon);
    if ComponInterf <> nil then
      Result := CheckJoinedInterfWithInterfInfo(ComponInterf, AInterfInfo);
  end;
end;


function TF_MakeEditCrossConnection.CheckJoinedInterfInfos(AInterfInfo1, AInterfInfo2: TInterfInfo; APtrPosKolvo: PInteger): Boolean;
var
  InterfInfoWithPos: TInterfInfo;
  InterfInfo: TInterfInfo;
  IOfIRel: TSCSIOfIRel;
  InterfPositionList: TObjectList;
  InterfPosition: TSCSInterfPosition;
  i, j: Integer;
begin
  Result := false;
  if (AInterfInfo1 <> nil) and (AInterfInfo2 <> nil) then
    if AInterfInfo1.FInterface.ConnectedInterfaces.IndexOf(AInterfInfo2.FInterface) <> -1 then
      if (AInterfInfo1.IsBusy = biTrue) and (AInterfInfo2.IsBusy = biTrue) then
      begin
        {if (AInterfInfo1.PosFrom = 0) and (AInterfInfo1.PosTo = 0) and (AInterfInfo2.PosFrom = 0) and (AInterfInfo2.PosTo = 0) then
        begin
          Result := true;
          if APtrPosKolvo <> nil then
          begin
            IOfIRel := nil;
            IOfIRel := AInterfInfo1.FInterface.GetIOfIByIDInterfTo(AInterfInfo2.FInterface.ID);
            if IOfIRel = nil then
              IOfIRel := AInterfInfo2.FInterface.GetIOfIByIDInterfTo(AInterfInfo1.FInterface.ID);
            if IOfIRel <> nil then
              APtrPosKolvo^ := GetIOfIRelPosCount(IOfIRel);
          end;
        end
        else
        // Если подключение идет по позициям
        begin
          InterfInfoWithPos := AInterfInfo1;
          InterfInfo := AInterfInfo2;
          if (AInterfInfo1.PosFrom = 0) and (AInterfInfo1.PosTo = 0) and
             (AInterfInfo2.PosFrom <> 0) and (AInterfInfo2.PosTo <> 0) then
            ExchangeObjects(InterfInfoWithPos, InterfInfo);

          for i := 0 to InterfInfo.FInterface.BusyPositions.Count - 1 do
          begin
            InterfPosition := TSCSInterfPosition(InterfInfo.FInterface.BusyPositions[i]);
          end;


          for i := InterfInfoWithPos.PosFrom to InterfInfoWithPos.PosTo do
          begin
            InterfPositionList := GetInterfPositionByNum(i, InterfInfoWithPos.FInterface.BusyPositions);
            for j := 0 to InterfPositionList.Count - 1 do
            begin
              InterfPosition := TSCSInterfPosition(InterfPositionList[j]);
              IOfIRel := nil;
              if InterfPosition <> nil then
              begin
                if InterfPosition.InterfPosConnectionOwner <> nil then
                  IOfIRel := InterfPosition.InterfPosConnectionOwner.Owner;
              end;
              if IOfIRel <> nil then
                if ((IOfIRel.InterfaceOwner = InterfInfoWithPos.FInterface) and (IOfIRel.InterfaceTo = InterfInfo.FInterface)) or
                   ((IOfIRel.InterfaceOwner = InterfInfo.FInterface) and (IOfIRel.InterfaceTo = InterfInfoWithPos.FInterface)) then
                begin
                  Result := true;
                  if APtrPosKolvo <> nil then
                    APtrPosKolvo^ := GetIOfIRelPosCount(IOfIRel);

                  Break; //// BREAK ////
                end;
            end;
            FreeAndNil(InterfPositionList);
          end;
        end;}
        Result := CheckJoinedInterfByPos(AInterfInfo1.FInterface, AInterfInfo2.FInterface, AInterfInfo1.PosFrom, AInterfInfo1.PosTo, AInterfInfo2.PosFrom, AInterfInfo2.PosTo, APtrPosKolvo);
      end;
end;

function TF_MakeEditCrossConnection.CheckJoinedInterfInfoWithNode(ANode: TFlyNode; AInterfInfo: TInterfInfo; ASkipInterfInfo: TInterfInfo=nil): Boolean;
var
    NodeInterfInfo: TInterfInfo;
begin
  Result := false;
  if TObject(ANode.Data) is TInterfInfo then
  begin
    NodeInterfInfo := TInterfInfo(ANode.Data);
    if (NodeInterfInfo <> ASkipInterfInfo) and (AInterfInfo.IsBusy = NodeInterfInfo.IsBusy) then
      if (AInterfInfo.IsBusy = biFalse) or CheckJoinedInterfInfos(NodeInterfInfo, AInterfInfo) then
        Result := true;
  end;
end;

function TF_MakeEditCrossConnection.CheckJoinedInterfWithInterfInfo(AInterf: TSCSInterface; AInterfInfo: TInterfInfo): Boolean;
begin
  Result := CheckJoinedInterfByPos(AInterfInfo.FInterface, AInterf,
                  AInterfInfo.PosFrom, AInterfInfo.PosTo, 1, AInterf.Kolvo);
end;

procedure TF_MakeEditCrossConnection.ClearTrees;
begin
  ClearTreeViewFly(tvFrom, false, true);
  ClearTreeViewFly(tvTo, false, true);
  ClearTreeViewFly(tvWith, false, true);

  LoadInterfacesWith(true);
  LoadInterfacesFrom(true);
  LoadInterfacesTo(true);
end;

procedure TF_MakeEditCrossConnection.LoadComponentsFrom;
var
  i: Integer;
  ChildComponent: TSCSComponent;
  ListItem: TListItem;
begin
  for i := 0 to FSCSComponent.ChildComplects.Count - 1 do
  begin
    ChildComponent := FSCSComponent.ChildComplects[i];
    if Assigned(ChildComponent) then
      AddComponentToTreeView(ChildComponent, tciiComponCon, tvFrom, nil);
  end;
end;

procedure TF_MakeEditCrossConnection.LoadComponentsTo;
var
  i: Integer;
  ChildComponent: TSCSComponent;
  ListItem: TListItem;
begin
  for i := 0 to FSCSComponent.ChildComplects.Count - 1 do
  begin
    ChildComponent := FSCSComponent.ChildComplects[i];
    if Assigned(ChildComponent) then
      AddComponentToTreeView(ChildComponent, tciiComponCon, tvTo, nil);
  end;
end;

//##### Кросовые компоненты ##### 
procedure TF_MakeEditCrossConnection.LoadComponentsWith;
var
  i: Integer;
  ChildComponent: TSCSComponent;
  ListItem: TListItem;
  NodeToSelect: TFlyNode;

  SavedSelectedChanged: TTreeSelChangedEvent;
begin
  NodeToSelect := nil;
  for i := 0 to FSCSComponent.ChildComplects.Count - 1 do
  begin
    ChildComponent := FSCSComponent.ChildComplects[i];
    if Assigned(ChildComponent) then
      if ChildComponent.IsCrossComponent then
        if (ChildComponent.LinkToComlectRec.ID = FCrossConnection.IDCompRelWith) or
           (Not HaveCrossComponConnection(FSCSComponent, ChildComponent)) then
        begin
          AddComponentToTreeView(ChildComponent, tciiComponCon, tvWith, nil);
          if ChildComponent.LinkToComlectRec <> nil then
            if (ChildComponent.ID = FCrossConnection.IDComponWith) and
               (ChildComponent.LinkToComlectRec.ID = FCrossConnection.IDCompRelWith) then
              //tvWith.Selected := tvWith.Items[tvWith.Items.Count - 1];
              NodeToSelect := tvWith.Items[tvWith.Items.Count - 1];
        end;
  end;

  if NodeToSelect = nil then
    if tvWith.Items.Count > 0 then
      NodeToSelect := tvWith.Items[0];
  if NodeToSelect <> nil then
  begin
    SavedSelectedChanged := tvWith.OnSelectedChanged;
    tvWith.OnSelectedChanged := nil;
    try
      SelectNodeFly(tvWith, NodeToSelect);
    finally
      tvWith.OnSelectedChanged := SavedSelectedChanged;
    end;
    tvWith.OnSelectedChanged(nil, tvWith.Selected);
  end;
end;

procedure TF_MakeEditCrossConnection.LoadComponentsForPointObjectConfigurator(APointObject: TSCSCatalog);
var
  ConnectedLineIDs: TIntList;
  LineObject: TSCSCatalog;
  i: Integer;
  SavedOnChange: TFTVChangedEvent;
  SavedOnSelectedChanged: TTreeSelChangedEvent;
begin
  ClearTreeViewFly(tvFrom, false, true);
  ClearTreeViewFly(tvTo, false, true);
  ClearTreeViewFly(tvWith, false, true);

  ConnectedLineIDs := nil;
  if APointObject.ItemType = itSCSConnector then
    ConnectedLineIDs := GetAllConnectedTracesID(APointObject.ListID, APointObject.SCSID);
  if ConnectedLineIDs <> nil then
  begin
    FConnectedLinesToPointObject := GetCatalogListBySCSIDList(APointObject.GetTopParentCatalog, ConnectedLineIDs);
    if FConnectedLinesToPointObject <> nil then
    begin
      SavedOnChange := tvWith.OnChange;
      tvWith.OnChange := nil;
      SavedOnSelectedChanged := tvWith.OnSelectedChanged;
      tvWith.OnSelectedChanged := nil;
      try
        LoadComponentsToCableConfigurator(tvWith, nil, APointObject, false);
        for i := 0 to FConnectedLinesToPointObject.Count - 1 do
        begin
          LineObject := FConnectedLinesToPointObject[i];
          LoadComponentsToCableConfigurator(tvWith, nil, LineObject, false);
        end;
      finally
        tvWith.OnChange := SavedOnChange;
        tvWith.OnSelectedChanged := SavedOnSelectedChanged;
      end;
      SelectNodeFly(tvWith, tvWith.Items[0]); //tvWith.Selected := tvWith.Items[0];
      tvWithChange(tvWith, tvWith.Selected);
      tvWithSelectedChanged(nil, tvWith.Selected);
    end;
    FreeAndNil(ConnectedLineIDs);
  end;
end;

procedure TF_MakeEditCrossConnection.loadComponentsToCrossConnect(ADestTreeView: TFlyTreeViewPro;
  ACrossComponent: TSCSComponent; AExistingIDCompRel, AExistingNpp: Integer);
var
  i: Integer;
  ChildComponent: TSCSComponent;
  Node: TFlyNode;

  ImageIndex: Integer;
  CanAddItem: Boolean;
  CanSelect: Boolean;
  SelectNode: TFlyNode;
begin
  ADestTreeView.Items.BeginUpdate;
  try
    ADestTreeView.Items.Clear;
    //ClearTreeView(ADestTreeView, false, true);
    SelectNode := nil;
    for i := 0 to FSCSComponent.ChildComplects.Count - 1 do
    begin
      ChildComponent := FSCSComponent.ChildComplects[i];
      ImageIndex := tciiComponCon;

      CanAddItem := false;
      CanSelect := false;
      if Assigned(ChildComponent) then
        if Not(ChildComponent.IsCrossComponent) then
        begin
          CanAddItem := true;
          //if ComponentConnectedWithCross(ChildComponent, ACrossComponent) or
          //   Not(ComponentConnectedWithAnyCross(ChildComponent)) then
          //  if ChildComponent.CheckJoinToComponOrChilds(ACrossComponent, -1, -1).CanConnect then
          //  begin
          //    ImageIndex := tciiComponConFill;
          //    if (ChildComponent.LinkToComlectRec.ID = AExistingIDCompRel) and ((ChildComponent.ServCopyIndex = AExistingNpp)) then
          //      CanSelect := true;
          //  end;

          //*** Если компоненты подключены
          if (ChildComponent.LinkToComlectRec.ID = AExistingIDCompRel) and ((ChildComponent.ServCopyIndex = AExistingNpp)) then
            CanSelect := true;
          //*** если компоненты могут быть подключены, то выделить ее из общей толпы
          if ChildComponent.CheckJoinToComponOrChilds(ACrossComponent, -1, -1).CanConnect then
            ImageIndex := tciiComponConFill;
        end;

      if CanAddItem then
      begin
        AddComponentToTreeView(ChildComponent, ImageIndex, ADestTreeView, nil);
        if CanSelect then
          if Not Assigned(SelectNode) then
            SelectNode := ADestTreeView.Items[ADestTreeView.Items.Count - 1];
      end;
    end;

    if Assigned(SelectNode) then
      SelectNodeFly(ADestTreeView, SelectNode); //ADestTreeView.Selected := SelectNode;
  finally
    ADestTreeView.Items.EndUpdate;
  end;
end;

procedure TF_MakeEditCrossConnection.LoadComponentsToCrossConfigurator(ADestTreeView: TFlyTreeViewPro;
  ACrossComponent: TSCSComponent; AJoinedPortToCross: TSCSInterface; AInterfInfoFromCross: TInterfInfo=nil);
var
  ObjectNode: TFlyNode;
  ObjectOwner: TSCSCatalog;
  i: Integer;
  ComponImageIndex: Integer;
  TopComponent: TSCSComponent;
  TopComponNode: TFlyNode;
  SCSComponent: TSCSComponent;
  JoinedComponToCross: TSCSComponent;
  ComponNode: TFlyNode;

  NodeToSelect: TFlyNode;
  ReservNodeToSelect: TFlyNode;

  {//13.10.2011
  procedure LoadComponPortsToTreeView(AComponent: TSCSComponent; AComponNode: TFlyNode; ARecursive: Boolean);
  var
    Ports: TSCSInterfaces;
    Port: TSCSInterface;
    i, j: Integer;
    IsComponToSelect: Boolean;
    PortNode: TFlyNode;
  begin
    IsComponToSelect := false;
    if (SCSComponent = JoinedComponToCross) or
       (ARecursive and (SCSComponent.ChildReferences.IndexOf(JoinedComponToCross) <> -1)) then
      IsComponToSelect := true;

    Ports := AComponent.GetInterfacesByIsPort(biTrue, ARecursive);
    try
      for i := 0 to Ports.Count - 1 do
      begin
        Port := Ports[i];
        PortNode := AddInterfaceToTreeView(Port, GetInterfaceImageIndesByIsBusy(Port.IsBusy), ADestTreeView, AComponNode);
        //*** Найти подсоединенный порт к Кросс компоненте
        if IsComponToSelect then
        begin
          for j := 0 to Port.ConnectedInterfaces.Count - 1 do
            if (Port = AJoinedPortToCross) and
               (Port.ConnectedInterfaces[j].ComponentOwner = ACrossComponent) then
            begin
              NodeToSelect := PortNode;
              Break; ///// BREAK /////
            end;
        end;
      end;
    finally
      FreeAndNil(Ports);
    end;
  end;}

  procedure LoadComponPortsToTreeView(AComponent: TSCSComponent; AComponNode: TFlyNode; ARecursive: Boolean);
  var
    Ports: TSCSInterfaces;
    Port: TSCSInterface;
    i, j, k: Integer;
    IsComponToSelect: Boolean;
    PortNode: TFlyNode;
    PortInterfInfo: TInterfInfo;
    PortNum, PortIsBusy: Integer;
    ConnInterf: TSCSinterface;
    PortExtCaption: String;
  begin
    IsComponToSelect := false;
    if (SCSComponent = JoinedComponToCross) or
       (ARecursive and (SCSComponent.ChildReferences.IndexOf(JoinedComponToCross) <> -1)) then
      IsComponToSelect := true;

    Ports := AComponent.GetInterfacesByIsPort(biTrue, ARecursive);
    try
      for i := 0 to Ports.Count - 1 do
      begin
        Port := Ports[i];
        for j := 0 to Port.Kolvo - 1 do
        begin
          PortNum := Port.NppPort + j;
          PortIsBusy := biFalse;
          if CheckNumInPositionList(j+1, Port.BusyPositions) then
            PortIsBusy := biTrue
          else
            PortIsBusy := biFalse;

          PortExtCaption := '';
          if Port.ComponentOwner <> AComponent then
            PortExtCaption := ' ('+Port.ComponentOwner.GetNameForVisible +')';
          // Добавить порт в дерево
          PortNode := AddInterfInfoToTree(Port, GetPortCaption(Port, PortNum) + PortExtCaption, PortIsBusy, 1, AComponNode, ADestTreeView, j+1, j+1);
          //13.10.2011 PortNode := AddInterfaceToTreeView(Port, GetInterfaceImageIndesByIsBusy(Port.IsBusy), ADestTreeView, AComponNode);
          //*** Найти подсоединенный порт к Кросс компоненте
          if IsComponToSelect and (NodeToSelect = nil) then
          begin
            PortInterfInfo := TInterfInfo(PortNode.Data);
            if (AInterfInfoFromCross <> nil) then
            begin
              if CheckJoinedInterfInfos(PortInterfInfo, AInterfInfoFromCross) then
              begin
                NodeToSelect := PortNode;
                //Break; ///// BREAK /////
              end;
            end
            else
            begin
            //if NodeToSelect = nil then
              for k := 0 to Port.ConnectedInterfaces.Count - 1 do
              begin
                ConnInterf := Port.ConnectedInterfaces[k];
                if ConnInterf.ComponentOwner = ACrossComponent then
                begin
                  if (Port = AJoinedPortToCross) then
                    if CheckJoinedInterfWithInterfInfo(ConnInterf, PortInterfInfo) then
                    begin
                      NodeToSelect := PortNode;
                      Break; ///// BREAK /////
                    end;
                end;
              end;
            end;
          end;
        end;
      end;

      if IsComponToSelect and (ReservNodeToSelect = nil) then
        ReservNodeToSelect := AComponNode;
    finally
      FreeAndNil(Ports);
    end;
  end;

begin
  NodeToSelect := nil;
  ReservNodeToSelect := nil;

  ADestTreeView.Items.BeginUpdate;
  Screen.Cursor := crHourGlass;
  try
    //ADestTreeView.Items.Clear;
    JoinedComponToCross := nil;
    if AJoinedPortToCross <> nil then
      JoinedComponToCross := AJoinedPortToCross.ComponentOwner;


    ObjectOwner := ACrossComponent.GetFirstParentCatalog;
    ObjectNode := nil;
    if Assigned(ObjectOwner) then
    begin
      //*** Загрузить объект
      ObjectNode := ADestTreeView.Items.Add(nil, ObjectOwner.GetNameForVisible(false));
      ObjectNode.Data := ObjectOwner;
      ObjectNode.ImageIndex := tciiSCSConNormal;
      ObjectNode.SelectedIndex := tciiSCSConNormal;
      ObjectNode.StateIndex := -1;

      TopComponent := ACrossComponent.GetTopComponent;
      if Assigned(TopComponent) then
      begin
        ComponImageIndex := GetComponImageIndexByFilling(TopComponent.IsLine, TopComponent.GetFilling(biTrue, itFunctional, false, true));
        TopComponNode := AddComponentToTreeView(TopComponent, ComponImageIndex, ADestTreeView, ObjectNode);
        //*** Загрузить компоненты и порты
        for i := 0 to TopComponent.ChildComplects.Count - 1 do
        begin
          SCSComponent := TopComponent.ChildComplects[i];
          if Assigned(SCSComponent) then
            if Not (SCSComponent.IsCrossComponent) then
            begin
              ComponImageIndex := GetComponImageIndexByFilling(SCSComponent.IsLine, SCSComponent.GetFilling(biTrue, itFunctional, false, true));
              ComponNode := AddComponentToTreeView(SCSComponent, ComponImageIndex, ADestTreeView, TopComponNode);

              //*** Засыпать порты компоненты и всех комлектующих
              LoadComponPortsToTreeView(SCSComponent, ComponNode, true);
            end;
        end;
        TopComponNode.Expanded := true;

        //*** Засыпать порты только верхней компоненты
        LoadComponPortsToTreeView(TopComponent, TopComponNode, false);
      end;
    end;
    if ObjectNode <> nil then
      ObjectNode.Expanded := true;

    //*** Загрузить наименования портов
    DefineInterfaceNodesText(ADestTreeView);

    if (NodeToSelect = nil) and (ReservNodeToSelect <> nil) then
      NodeToSelect := ReservNodeToSelect;
    if Assigned(NodeToSelect) then
    begin
      SelectNodeFly(ADestTreeView, NodeToSelect);  //ADestTreeView.Selected := NodeToSelect
      if NodeToSelect = ReservNodeToSelect then
        NodeToSelect.Expanded := true;
    end
    else
      if ADestTreeView.Items.Count > 0 then
        SelectNodeFly(ADestTreeView, ADestTreeView.Items[0]);  //ADestTreeView.Selected := ADestTreeView.Items[0];
  finally
    ADestTreeView.Items.EndUpdate;
    Screen.Cursor := crDefault;
  end;
end;

procedure TF_MakeEditCrossConnection.LoadComponentsToCableConfigurator(ADestTreeView: TFlyTreeViewPro;
  AJoinedToCable: TSCSComponent; AJoinedObject: TSCSCatalog; ANotExpandCompons: Boolean;
  ASkipComponToSelect: TSCSComponent=nil);
var
  ListNode: TFlyNode;
  RoomNode: TFlyNode;
  ObjectNode: TFlyNode;
  TargetNode: TFlyNode;
  PoinComponentNode: TFlyNode;
  //ObjectOwner: TSCSCatalog;
  i: Integer;
  SCSComponent: TSCSComponent;
  NodeToSelect: TFlyNode;
  ObjectList: TSCSList;
  ObjectRoom: TSCSCatalog;

  function GetPortsCaption(aCompon: TSCSComponent): String;
  var
    Port: TSCSInterface;
    i, MinNpp, MaxNpp: Integer;
  begin
    Result := '';
    MinNpp := 0;
    MaxNpp := 0;
    for i := 0 to aCompon.Interfaces.Count - 1 do
    begin
      Port := aCompon.Interfaces[i];
      if Port.IsPort = biTrue then
      begin
        if (Port.NppPort + Port.Kolvo-1) > MaxNpp then
          MaxNpp := Port.NppPort + Port.Kolvo-1;
        if (Port.NppPort < MinNpp) or (MinNpp = 0) then
          MinNpp := Port.NppPort;
      end;
    end;
    if (MinNpp <> 0) and (MaxNpp <> 0) then
    begin
      if MinNpp = MaxNpp then
        Result := Result +' ('+cNamePort+' '+IntToStr(MinNpp)+')'
      else
        Result := Result +' ('+cNamePort+' '+IntToStr(MinNpp)+'-'+IntToStr(MaxNpp)+')';
    end;
  end;

  function AddPointComponentToTreeView(AComponent: TSCSComponent; AParentNode: TFlyNode): TFlyNode;
  var
    ComponNode: TFlyNode;
    ImageIndex: Integer;
    i: Integer;
    ChildComponent: TSCSComponent;
    IsJoinedComponent: Boolean;
    PortCaption: String;
  begin
    Result := nil;
    if Not (AComponent.IsCrossComponent) and
      // нах элементы какб. каналов
      ((FFormMode <> fmCableConfigurator) or
       (FDisabledCompTypesForCableConfigurator.IndexOf(AComponent.ComponentType.SysName) = -1)) then
    begin
      IsJoinedComponent := checkJoinedComponents(AComponent, AJoinedToCable, true);

      ImageIndex := GetComponImageIndexByFilling(AComponent.IsLine,
                        AComponent.GetFilling(biFalse, itFunctional, FFormMode <> fmPointObjectConfigurator, true), IsJoinedComponent);
      ComponNode := AddComponentToTreeView(AComponent, ImageIndex, ADestTreeView, AParentNode);

      //04.02.2013 Добавить в название нода номер порта, если точечній и крайний
      if (AComponent.IsLine = BiFalse) and (AComponent.ChildComplects.Count = 0) then
      begin
        PortCaption := GetPortsCaption(AComponent);
        if PortCaption <> '' then
          ComponNode.Caption := ComponNode.Caption + PortCaption;
      end;

      for i := 0 to AComponent.ChildComplects.Count - 1 do
      begin
        ChildComponent := AComponent.ChildComplects[i];
        AddPointComponentToTreeView(ChildComponent, ComponNode);
      end;
      if IsJoinedComponent then  //if AComponent = AJoinedToCable then
        if AComponent <> ASkipComponToSelect then
        begin
          NodeToSelect := ComponNode;
          if NodeToSelect.Parent <> nil then
            NodeToSelect.Parent.Expanded := true;
        end;
      Result := ComponNode;
    end;
  end;

begin
  NodeToSelect := nil;
  //ObjectOwner := nil;
  SCSComponent := nil;
  ObjectList := nil;

  ADestTreeView.Items.BeginUpdate;
  Screen.Cursor := crHourGlass;
  try
    //ADestTreeView.Items.Clear;
    //ClearTreeView(ADestTreeView, false, true);

    //if Assigned(AJoinedToCable) then
    //  ObjectOwner := AJoinedToCable.GetFirstParentCatalog;
    ObjectNode := nil;
    TargetNode := nil;
    if Assigned(AJoinedObject) then
    begin
      // Найти Лист
      ListNode := nil;
      RoomNode := nil;
      if FFormMode = fmCableConfigurator then
      begin
        ObjectList := AJoinedObject.GetListOwner;
        if ObjectList <> nil then
        begin
          ListNode := FindNodeByObjectInTree(ADestTreeView, ObjectList);
          if ListNode = nil then
          begin
            ListNode := ADestTreeView.Items.Add(nil, ObjectList.GetNameForVisible);
            ListNode.Data := ObjectList;
            ListNode.ImageIndex := tciiList;
            ListNode.SelectedIndex := tciiList;
            ListNode.StateIndex := -1;
            if ObjectList.CurrID = FList.CurrID then
              ListNode.Text := ListNode.Text + ' '+cMakeEditCrossConnection_Msg2_7;
          end;
          TargetNode := ListNode;
        end;

        //*** Определить комнату объекта
        ObjectRoom := AJoinedObject.GetParentCatalogByItemType(itRoom);
        if ObjectRoom <> nil then
        begin
          RoomNode := FindNodeByObjectInTree(ADestTreeView, ObjectRoom);
          if (RoomNode = nil) and (ListNode <> nil) then
          begin
            RoomNode := ADestTreeView.Items.AddChild(ListNode, ObjectRoom.GetNameForVisible);
            RoomNode.Data := ObjectRoom;
            RoomNode.ImageIndex := tciiRoom;
            RoomNode.SelectedIndex := tciiRoom;
            RoomNode.StateIndex := -1;
          end;
          TargetNode := RoomNode;
        end;
      end;

      //*** Загрузить объект
      ObjectNode := nil;
      if TargetNode = nil then
        ObjectNode := ADestTreeView.Items.Add(nil, AJoinedObject.GetNameForVisible(false))
      else
        ObjectNode := ADestTreeView.Items.AddChild(TargetNode, AJoinedObject.GetNameForVisible(false));
      ObjectNode.Data := AJoinedObject;
      ObjectNode.ImageIndex := tciiSCSConNormal;
      ObjectNode.SelectedIndex := tciiSCSConNormal;
      ObjectNode.StateIndex := -1;

      for i := 0 to AJoinedObject.SCSComponents.Count - 1 do
      begin
        SCSComponent := AJoinedObject.SCSComponents[i];
        PoinComponentNode := AddPointComponentToTreeView(SCSComponent, ObjectNode);
        if ANotExpandCompons then
          if PoinComponentNode <> nil then
            PoinComponentNode.Expanded := false;
      end;

      //*** Раскрыть текущий лист
      if (ObjectList <> nil) and (ObjectList = FList) then
        if ListNode <> nil then
          ListNode.Expanded := true;

      if RoomNode <> nil then
        RoomNode.Expanded := true; 
    end;
    if ObjectNode <> nil then
      ObjectNode.Expanded := true;

    //*** Загрузить наименования портов
    DefineInterfaceNodesText(ADestTreeView);

    if Assigned(NodeToSelect) and Not ANotExpandCompons then
      SelectNodeFly(ADestTreeView, NodeToSelect) //ADestTreeView.Selected := NodeToSelect
    else
      if (ADestTreeView.Items.Count > 0) and (ADestTreeView.Selected = nil) then
        SelectNodeFly(ADestTreeView, ADestTreeView.Items[0]); //ADestTreeView.Selected := ADestTreeView.Items[0];
    ShowSelectedNodeFly(ADestTreeView);
  finally
    ADestTreeView.Items.EndUpdate;
    Screen.Cursor := crDefault;
  end;
end;

procedure TF_MakeEditCrossConnection.LoadConnectedLineComponentsToLine(ADestTreeView: TFlyTreeViewPro;
  ALineComponent: TSCSComponent; ALineComponNode: TFlyNode; AParantNodes: TObjectList; ACheckExisted: Boolean);
var
  EndLinePartCompons: TSCSComponents;
  EndPartComponent: TSCSComponent;
  JoinedLines: TSCSComponents;
  JoinedLine: TSCSComponent;
  ComponentNode: TFlyNode;

  NewNodeImageIndex: Integer;
  i, j: Integer;
begin
  EndLinePartCompons := TSCSComponents.Create(false);

  //if ALineComponent.ID <> ALineComponent.FirstIDCompon then
  begin
    EndPartComponent := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(ALineComponent.FirstIDCompon);
    if EndPartComponent <> nil then
      EndLinePartCompons.Add(EndPartComponent);
  end;
  //if ALineComponent.ID <> ALineComponent.LastIDCompon then
  if ALineComponent.LastIDCompon <> ALineComponent.FirstIDCompon then
  begin
    EndPartComponent := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(ALineComponent.LastIDCompon);
    if EndPartComponent <> nil then
      EndLinePartCompons.Add(EndPartComponent);
  end;
  for i := 0 to EndLinePartCompons.Count - 1 do
  begin
    EndPartComponent := EndLinePartCompons[i];
    JoinedLines := GetJoinedComponentsThroughPoint(EndPartComponent);
    for j := 0 to JoinedLines.Count - 1 do
    begin
      JoinedLine := JoinedLines[j];
      if JoinedLine.Whole_ID <> ALineComponent.Whole_ID then
      begin
        if ACheckExisted then
          ComponentNode := GetComponentNodeFromTreeViewByWholeID(ADestTreeView, JoinedLine.Whole_ID);

        if (ACheckExisted = false) or (ComponentNode = nil) then
          if GetComponentNodeFromNodeListByWholeID(AParantNodes, JoinedLine.Whole_ID) = nil then
          begin
            JoinedLine.LoadWholeComponent(false);
            JoinedLine.DefineFirstLast;

            NewNodeImageIndex := GetComponImageIndexByFilling(JoinedLine.IsLine, JoinedLine.GetFilling(biNone, itFunctional, true, false), true);
            AddComponentToTreeView(JoinedLine, NewNodeImageIndex, ADestTreeView, ALineComponNode);
          end;
      end;
    end;
    FreeAndNil(JoinedLines);
  end;
  FreeAndNil(EndLinePartCompons);
end;

procedure TF_MakeEditCrossConnection.LoadConnectedLineComponentsToLineForSiblingNodes(ADestTreeView: TFlyTreeViewPro;
  ANode: TFlyNode; ACheckExisted: Boolean);
var
  FirstNode: TFlyNode;
  CurrNode: TFlyNode;
  ComponentFromNode: TSCSComponent;
  ParentNodes: TObjectList;
begin
  if ANode <> nil then
  begin 
    FirstNode := GetTreeViewFirstSiblingNodeFly(ANode);
    if FirstNode <> nil then
    begin
      // Заполнить список всех парентов
      ParentNodes := TObjectList.Create(false);
      CurrNode := FirstNode;
      while CurrNode <> nil do
      begin
        ParentNodes.Add(CurrNode);
        CurrNode := CurrNode.Parent;
      end;

      CurrNode := FirstNode;
      while CurrNode <> nil do
      begin
        if (CurrNode.Count = 0) and (CurrNode.Data <> nil) then
          if TObject(CurrNode.Data) is TSCSComponent then
          begin
            ComponentFromNode := TSCSComponent(CurrNode.Data);
            if ComponentFromNode.IsLine = biTrue then
              LoadConnectedLineComponentsToLine(ADestTreeView, ComponentFromNode, CurrNode, ParentNodes, ACheckExisted);
          end;
        CurrNode := CurrNode.getNextSibling;
      end;
      FreeAndNil(ParentNodes);
    end;
  end;
end;


procedure TF_MakeEditCrossConnection.LoadInterfacesWith(AOnlyClear: Boolean);
var
  SCSComponent: TSCSComponent;
  SideAtFromComponent: Integer;
  SideAtToComponent: Integer;
  LineComponOwner: TSCSCatalog;
  TempSide: Integer;
begin
  try
    FLoadedInterfacesWith := false;

    FInterfWithSideAtTree1 := -1;
    FInterfWithSideAtTree2 := -1;
    FInterfFromSideAtTree1 := -1;
    FInterfFromSideAtTree2 := -1;

    if FFormMode <> fmNBCrossConnection then
    begin
      ClearTreeViewFly(tvInterfWithSide1, true, true, true);
      ClearTreeViewFly(tvInterfWithSide2, true, true, true);
    end;

    if Not AOnlyClear then
      if spInterfWith.LowerRight.Visible then
      begin
        SCSComponent := GetComponentFromTreeView(tvWith);
        if SCSComponent <> nil then
        begin
          if SCSComponent.IsLine = biFalse then
          begin
            LoadComponInterfacesToTreeView(SCSComponent, nil, 0, -1, tvInterfWithSide1, nil);
            FLoadedInterfacesWith := true;
            FInterfWithSideAtTree1 := 0;
            FInterfWithSideAtTree2 := -1;
          end
          else
          begin
            SideAtFromComponent := -1;
            SideAtToComponent := -1;
            if (FLineComponFromSide <> nil) and (FLineComponToSide <> nil) then
            begin
              // Если начальный и конечный кабель разные компоненты
              if FLineComponFromSide <> FLineComponToSide then
              begin
                SideAtFromComponent := GetEndComponSideAtEnding(FLineComponFromSide);
                SideAtToComponent := GetEndComponSideAtEnding(FLineComponToSide);

                LoadComponInterfacesToTreeView(FLineComponFromSide, FLineComponToSide, SideAtFromComponent, SideAtToComponent, tvInterfWithSide1, tvInterfWithSide2);
                FLoadedInterfacesWith := true;
              end
              else
              begin
                SideAtFromComponent := 1;
                SideAtToComponent := 2;
                LineComponOwner := FLineComponFromSide.GetFirstParentCatalog;

                if (FPointObjectFrom <> nil) and (FPointObjecttTo <> nil) then
                begin
                  //23.03.2009 LineComponOwner := FLineComponFromSide.GetFirstParentCatalog;
                  if LineComponOwner <> nil then
                  begin
                    GetSidesByConnectedFigures(LineComponOwner.ListID, FPointObjectFrom.ListID,
                      LineComponOwner.SCSID, FPointObjectFrom.SCSID, SideAtFromComponent, TempSide);
                    GetSidesByConnectedFigures(LineComponOwner.ListID, FPointObjecttTo.ListID,
                      LineComponOwner.SCSID, FPointObjecttTo.SCSID, SideAtToComponent, TempSide);
                    if (SideAtFromComponent <> -1) and (SideAtToComponent <> -1) then
                    begin
                      LoadComponInterfacesToTreeView(FLineComponFromSide, FLineComponToSide, SideAtFromComponent, SideAtToComponent, tvInterfWithSide1, tvInterfWithSide2);
                      FLoadedInterfacesWith := true;
                    end;
                  end;
                end
                else
                if FPointObjectFrom <> nil then
                begin
                  if LineComponOwner <> nil then
                  begin
                    GetSidesByConnectedFigures(LineComponOwner.ListID, FPointObjectFrom.ListID,
                      LineComponOwner.SCSID, FPointObjectFrom.SCSID, SideAtFromComponent, TempSide);
                    SideAtToComponent := GetParallelSide(SideAtFromComponent);

                    if (SideAtFromComponent <> -1) and (SideAtToComponent <> -1) then
                    begin
                      LoadComponInterfacesToTreeView(FLineComponFromSide, FLineComponToSide, SideAtFromComponent, SideAtToComponent, tvInterfWithSide1, tvInterfWithSide2);
                      FLoadedInterfacesWith := true;
                    end;
                  end;
                end
                else
                if FPointObjecttTo <> nil then
                begin
                  if LineComponOwner <> nil then
                  begin
                    GetSidesByConnectedFigures(LineComponOwner.ListID, FPointObjecttTo.ListID,
                      LineComponOwner.SCSID, FPointObjecttTo.SCSID, SideAtToComponent, TempSide);
                    SideAtFromComponent := GetParallelSide(SideAtToComponent);

                    if (SideAtFromComponent <> -1) and (SideAtToComponent <> -1) then
                    begin
                      LoadComponInterfacesToTreeView(FLineComponFromSide, FLineComponToSide, SideAtFromComponent, SideAtToComponent, tvInterfWithSide1, tvInterfWithSide2);
                      FLoadedInterfacesWith := true;
                    end;
                  end;
                end
                else
                begin
                  LoadComponInterfacesToTreeView(FLineComponFromSide, FLineComponToSide, SideAtFromComponent, SideAtToComponent, tvInterfWithSide1, tvInterfWithSide2);
                  FLoadedInterfacesWith := true;
                end;
              end;
            end;
            FInterfWithSideAtTree1 := SideAtFromComponent;
            FInterfWithSideAtTree2 := SideAtToComponent;
          end;
          if IsThroughConfiguratorMode then
            SetControlsForInterfacesByCompon(SCSComponent, spInterfWithSide2)
          else
          if FFormMode = fmPointObjectConfigurator then
          begin
            //pnInterfWithSide2.Visible := false;
            //spInterfWithSide2.Visible := false;
            spInterfWithSide2.LowerRight.Visible := false;
          end;
        end;
      end;
  except
    on E: Exception do AddExceptionToLogEx('TF_MakeEditCrossConnection.LoadInterfacesWith', E.Message);
  end;
end;

procedure TF_MakeEditCrossConnection.LoadInterfacesFrom(AOnlyClear: Boolean);
var
  SCSComponent: TSCSComponent;
  PointComponFrom: TSCSComponent;
  PointComponTo: TSCSComponent;
  ComponAtWith: TSCSComponent;
  ComponJoinedToLineAtFromSide: TSCSComponent;
  ComponJoinedToLineAtToSide: TSCSComponent;

  SideAtFromComponent: Integer;
  SideAtToComponent: Integer;
  LineComponOwner: TSCSCatalog;
  LineJoinedToLineAtFromSide: Boolean;
  TempSide: Integer;

  ObjectFrom: TSCSCatalog;
  ObjectWith: TSCSCatalog;
  SideAtWithComponent: Integer;
begin
  try
    FLoadedInterfacesFrom := false;
    FInterfFromSideAtTree1 := -1;
    FInterfFromSideAtTree2 := -1;

    if FFormMode <> fmNBCrossConnection then
    begin
      ClearTreeViewFly(tvInterfFromSide1, true, true, true);
      ClearTreeViewFly(tvInterfFromSide2, true, true, true);
    end;

    if Not AOnlyClear then
      if spInterfFrom.LowerRight.Visible then
      begin
        SCSComponent := GetComponentFromTreeView(tvFrom);
        if SCSComponent <> nil then
        begin
          ObjectFrom := SCSComponent.GetFirstParentCatalog;

          if SCSComponent.IsLine = biFalse then
          begin
            LoadComponInterfacesToTreeView(SCSComponent, nil, 0, -1, tvInterfFromSide1, nil);
            FLoadedInterfacesFrom := true;
            FInterfFromSideAtTree1 := 0;
            FInterfFromSideAtTree2 := -1;
          end
          else
          begin
            SideAtFromComponent := -1;
            SideAtToComponent := -1;
            if IsThroughConfiguratorMode and (FLineComponFromSide <> nil) and (FLineComponToSide <> nil) then
            begin
              LineJoinedToLineAtFromSide := false;
              PointComponFrom := GetComponentFromTreeView(tvWith);
              PointComponTo := GetComponentFromTreeView(tvTo);

              ComponJoinedToLineAtFromSide := nil;
              ComponJoinedToLineAtToSide := nil;
              if FLineComponFromSide.JoinedComponents.IndexOf(PointComponFrom) <> -1 then
                ComponJoinedToLineAtFromSide := PointComponFrom
              else
              begin
                ComponJoinedToLineAtFromSide := GetComponentFromNode(tvFrom.Selected.Parent);
                if ComponJoinedToLineAtFromSide <> nil then
                  LineJoinedToLineAtFromSide := true;
              end;
              if FLineComponToSide.JoinedComponents.IndexOf(PointComponTo) <> -1 then
                ComponJoinedToLineAtToSide := PointComponTo;


              // Если начальный и конечный кабель разные компоненты
              if FLineComponFromSide <> FLineComponToSide then
              begin
                SideAtFromComponent := GetEndComponSideAtEnding(FLineComponFromSide);
                SideAtToComponent := GetEndComponSideAtEnding(FLineComponToSide);

                if Not LineJoinedToLineAtFromSide then
                  LoadComponInterfacesToTreeView(FLineComponFromSide, FLineComponToSide, SideAtFromComponent, SideAtToComponent, tvInterfFromSide1, tvInterfFromSide2)
                else
                  LoadComponInterfacesToTreeView(nil, FLineComponToSide, -1, SideAtToComponent, nil, tvInterfFromSide2);
                FLoadedInterfacesFrom := true;
              end
              else
              begin
                SideAtFromComponent := 1;
                SideAtToComponent := 2;

                if ComponJoinedToLineAtFromSide <> nil then
                begin
                  SideAtFromComponent := GetComponSideJoinedToCompon(FLineComponFromSide, ComponJoinedToLineAtFromSide);
                  if SideAtFromComponent <> -1 then
                  begin
                    if SideAtFromComponent = 1 then
                      SideAtToComponent := 2
                    else
                    if SideAtToComponent = 2 then
                      SideAtToComponent := 1;
                  end;
                end
                else
                // Если подключения с одной стороны не нашлось, смотрим с другой стороны
                if ComponJoinedToLineAtToSide <> nil then
                begin
                  SideAtToComponent := GetComponSideJoinedToCompon(FLineComponToSide, ComponJoinedToLineAtToSide);
                  if SideAtToComponent <> -1 then
                  begin
                    if SideAtToComponent = 1 then
                      SideAtFromComponent := 2
                    else
                    if SideAtToComponent = 2 then
                      SideAtFromComponent := 1;
                  end;
                end;

                if Not LineJoinedToLineAtFromSide then
                  LoadComponInterfacesToTreeView(FLineComponFromSide, FLineComponToSide, SideAtFromComponent, SideAtToComponent, tvInterfFromSide1, tvInterfFromSide2)
                else
                  LoadComponInterfacesToTreeView(nil, FLineComponToSide, -1, SideAtToComponent, nil, tvInterfFromSide2);
                FLoadedInterfacesFrom := true;
              end;
            end
            else
            begin
              ComponAtWith := GetComponentFromTreeView(tvWith);
              if ComponAtWith <> nil then
              begin
                ObjectWith := ComponAtWith.GetFirstParentCatalog;
                if ObjectWith <> nil then
                  if CheckConnectedObjectsInCAD(ObjectFrom, ObjectWith) then
                  begin
                    GetSidesByConnectedFigures(ObjectFrom.ListID, ObjectWith.ListID,
                    ObjectFrom.SCSID, ObjectWith.SCSID, SideAtWithComponent, TempSide);

                    LoadComponInterfacesToTreeView(SCSComponent, nil, SideAtWithComponent, -1, tvInterfFromSide1, nil);
                    //LoadComponInterfacesToTreeView(nil, SCSComponent, -1, TempSide, nil, tvInterfFromSide2);

                    FLoadedInterfacesFrom := true;
                    FInterfFromSideAtTree1 := SideAtWithComponent;
                    FInterfFromSideAtTree2 := -1;
                  end;
              end;
            end;
            FInterfFromSideAtTree1 := SideAtFromComponent;
            FInterfFromSideAtTree2 := SideAtToComponent;
          end;

          if IsThroughConfiguratorMode then
            SetControlsForInterfacesByCompon(SCSComponent, spInterfFromSide2)
          else
          if FFormMode = fmPointObjectConfigurator then
          begin
            //pnInterfFromSide2.Visible := false;
            //spInterfFromSide2.Visible := false;
            spInterfFromSide2.LowerRight.Visible := false;
          end;
        end;
        ExchangeInterfWithInTreeSidesIfCan;
      end;
  except
    on E: Exception do AddExceptionToLogEx('TF_MakeEditCrossConnection.LoadInterfacesFrom', E.Message);
  end;
end;

procedure TF_MakeEditCrossConnection.LoadInterfacesTo(AOnlyClear: Boolean);
var
  SCSComponent: TSCSComponent;
begin
  try
    FLoadedInterfacesTo := false;
    if FFormMode <> fmNBCrossConnection then
      ClearTreeViewFly(tvInterfTo, true, true, true);

    if Not AOnlyClear then
      if spInterfTo.LowerRight.Visible then
      begin
        SCSComponent := GetComponentFromTreeView(tvTo);
        if SCSComponent <> nil then
        begin
          if SCSComponent.IsLine = biFalse then
          begin
            LoadComponInterfacesToTreeView(SCSComponent, nil, 0, -1, tvInterfTo, nil);
            FLoadedInterfacesTo := true;
          end;
        end;
        ExchangeInterfWithInTreeSidesIfCan;
      end;
  except
    on E: Exception do AddExceptionToLogEx('TF_MakeEditCrossConnection.LoadInterfacesTo', E.Message);
  end;
end;

procedure TF_MakeEditCrossConnection.LockTrees(ALock: Boolean);
begin
  if ALock then
  begin
    if FLockCount = 0 then
    begin
      tvWith.Items.BeginUpdate;
      tvFrom.Items.BeginUpdate;
      tvTo.Items.BeginUpdate;
    end;
    Inc(FLockCount);
  end
  else
  begin
    Dec(FLockCount);
    if FLockCount = 0 then
    begin
      tvWith.Items.EndUpdate;
      tvFrom.Items.EndUpdate;
      tvTo.Items.EndUpdate;
    end;
  end;
end;

procedure TF_MakeEditCrossConnection.OnCloseGroupComponsPanel(Sender: TObject);
var
  SavedOwnsObjects: Boolean;
begin
  SavedOwnsObjects := FGroupComponsPanelList.OwnsObjects;
  FGroupComponsPanelList.OwnsObjects := false;
  try
    FGroupComponsPanelList.Remove(Sender);
  finally
    FGroupComponsPanelList.OwnsObjects := SavedOwnsObjects;
  end;
  EnableDisableConfiguratorControls;
end;

procedure TF_MakeEditCrossConnection.OnpmiInterfPathClick(Sender: TObject);
var
  InterfInfo: TInterfInfo;
begin
  InterfInfo := GetInterfInfoFromTree(GetFocusedTreeView);
  if InterfInfo <> nil then
    ShowPathByInterfPosition(TObject(TWinControl(Sender).Tag){, InterfInfo.FInterface, TSCSInterfPosition(TWinControl(Sender).Tag)});
end;

procedure TF_MakeEditCrossConnection.PrepareForm;
var
  ShowThroughConfiguratorChoicer: Boolean;
  ShowConfiguratorControls: Boolean;
  ShowPointObjectConfigurator: Boolean;
begin
  //tvFrom.Items.Clear;
  //tvTo.Items.Clear;
  //tvWith.Items.Clear;

  ClearTreeViewFly(tvFrom, false, true);
  ClearTreeViewFly(tvTo, false, true);
  ClearTreeViewFly(tvWith, false, true);

  LoadInterfacesWith(true);
  LoadInterfacesFrom(true);
  LoadInterfacesTo(true);

  Caption := '';
  ShowThroughConfiguratorChoicer := false;
  ShowConfiguratorControls := false;
  ShowPointObjectConfigurator := false;
  if FFormMode = fmNBCrossConnection then
  begin
    pnLegend.Visible := false;
    case FMakeEdit of
      meMake:
        Caption := cMakeEditCrossConnection_Msg3_1;
      meEdit:
        Caption := cMakeEditCrossConnection_Msg3_2;
    end;
    ShowThroughConfiguratorChoicer := false;
  end
  else
  if IsThroughConfiguratorMode then
  begin
    Caption := cMakeEditCrossConnection_Msg3_3;

    pnLegend.Visible := true;
    rbCross.Checked := false;
    rbCable.Checked := false;
    try
      case FFormMode of
        fmCrossConfigurator:
          rbCross.Checked := true;
        fmCableConfigurator:
          rbCable.Checked := true;
      end;
    except
    end;
    ShowThroughConfiguratorChoicer := true;
    ShowConfiguratorControls := true;
  end
  else
  if FFormMode = fmPointObjectConfigurator then
  begin
    Caption := cMakeEditCrossConnection_Msg3_4;

    pnLegend.Visible := true;

    gbWith.Caption := cMakeEditCrossConnection_Msg4;
    gbFrom.Caption := cMakeEditCrossConnection_Msg5;

    Act_AddCable.Visible := false;
    Act_DeleteCable.Visible := false;
    Act_DisconnectAll.Visible := false;

    ShowPointObjectConfigurator := true;
    ShowConfiguratorControls := true;
  end;

  if pnLegend.Visible then
  begin
    SetControlsForLegend;
    if lbLegend.Tag = biNone then
    begin
      lbLegend.Tag := biTrue;
      lbLegendClick(lbLegend);
    end;
  end;

  //gbTo.Visible := Not ShowPointObjectConfigurator;
  //spTo.Visible := Not ShowPointObjectConfigurator;
  spTo.LowerRight.Visible := Not ShowPointObjectConfigurator;

  tbConfigurator.Visible := ShowConfiguratorControls;
  tbSelectObjectsInPM.Visible := ShowConfiguratorControls;

  pnConfiguratorKind.Visible := ShowThroughConfiguratorChoicer;
  gbConfiguratorNotice.Visible := ShowConfiguratorControls; //ShowThroughConfiguratorChoicer;
  pnNBCrossConnLegend.Visible := Not ShowConfiguratorControls;
  btOK.Visible := Not ShowConfiguratorControls;
  btCancel.Visible := Not ShowConfiguratorControls;
  btClose.Visible := ShowConfiguratorControls;
end;

procedure TF_MakeEditCrossConnection.RefreshGroupComponsPanels;
var
  i: integer;
begin
  for i := 0 to FGroupComponsPanelList.Count - 1 do
    TGroupComponsPanel(FGroupComponsPanelList[i]).RefreshImageIndexes;
end;

procedure TF_MakeEditCrossConnection.ReloadInterfaces(ATreeView1, ATreeView2: TFlyTreeViewPro; AIsBusyToSelect: Integer; AProcToLoadInterf: TLoadInterfacesToTree);
var
  TreeInfo1: TRapList;
  TreeInfo2: TRapList;

  LoadInterfacesToTree: TLoadInterfacesToTree;

  SavedOnEnter1: TNotifyEvent;
  SavedOnEnter2: TNotifyEvent;
  SavedOnSelected1: TTreeSelChangedEvent;
  SavedOnSelected2: TTreeSelChangedEvent;

  procedure SaveTreeNodeInfoToList(ATree: TFlyTreeViewPro; AList: TRapList);
  var
    Node: TflyNode;
    NodeInfo: TInterfInfo;
  begin
    if ATree <> nil then
    begin
      Node := GetFirstNodeFromFlyTree(ATree);
      while Node <> nil do
      begin
        NodeInfo := TInterfInfo.Create(TInterfInfo(Node.Data).FInterface);
        NodeInfo.Assign(TInterfInfo(Node.Data));
        NodeInfo.Selected := Node.Selected;
        NodeInfo.Expanded := Node.Expanded;

        AList.Add(NodeInfo);

        Node := Node.GetNext;
      end;
    end;
  end;

  procedure RestoreTreeFromInfoList(ATree: TFlyTreeViewPro; AList: TRapList);
  var
    Node: TFlyNode;
    NodeInterfInfo: TInterfinfo;

    i: Integer;
    InterfInfoFromList: TInterfInfo;
    FindedInterfInfo: Boolean;
    NodesToSelect: TRapList;
    AddedToSel: Boolean;

    ReservedSelection: TFlyNode;
  begin
    if ATree <> nil then
    begin
      NodesToSelect := TRapList.Create;
      ReservedSelection := nil;

      Node := GetFirstNodeFromFlyTree(ATree);
      while Node <> nil do
      begin
        NodeInterfInfo := TInterfInfo(Node.Data);
        for i := 0 to Alist.Count - 1 do
        begin
          InterfinfoFromList := TInterfInfo(Alist.List^[i]);

          FindedInterfInfo := false;
          if InterfInfoFromList.FInterface = NodeInterfInfo.FInterface then
          begin
            if (NodeInterfInfo.PosFrom = 0) and (NodeInterfInfo.PosTo = 0) and
               (InterfInfoFromList.PosFrom = 0) and (InterfInfoFromList.PosTo = 0) then
              FindedInterfInfo := true
            else
            if ((NodeInterfInfo.PosFrom >= InterfInfoFromList.PosFrom) and (NodeInterfInfo.PosTo <= InterfInfoFromList.PosTo)) or
               ((InterfInfoFromList.PosFrom >= NodeInterfInfo.PosFrom) and (InterfInfoFromList.PosTo <= NodeInterfInfo.PosTo)) then
              FindedInterfInfo := true
            else
            if InterfInfoFromList.Selected and
              ((NodeInterfInfo.PosFrom = InterfInfoFromList.PosTo) or (InterfInfoFromList.PosFrom = NodeInterfInfo.PosTo)) then
              FindedInterfInfo := true;

            if FindedInterfInfo then
            begin
              AddedToSel := false;
              Node.Expanded := InterfInfoFromList.Expanded;
              if NodeInterfInfo.IsBusy = AIsBusyToSelect then
              begin
                Node.Selected := InterfInfoFromList.Selected;
                if InterfInfoFromList.Selected then
                begin
                  NodesToSelect.Add(Node);
                  AddedToSel := true;
                end;
                if ReservedSelection = nil then
                  ReservedSelection := Node;
              end
              else
                Node.Selected := false;

              if AddedToSel then
                Break; //// BREAK ////
            end;
          end;
        end;
        Node := Node.GetNext;
      end;

      if NodesToSelect.Count > 0 then
      begin
        for i := 0 to NodesToSelect.Count - 1 do
        begin
          Node := TFlyNode(NodesToSelect[i]);
          Node.Selected := true;
          if i = 0 then
            ATree.Selected := Node
        end;
      end
      else
      begin
        if (ATree.Selected = nil) or (ATree.Selected.Selected = false) then
        begin
          if ReservedSelection <> nil then
            ATree.Selected := ReservedSelection;
          if ATree.Selected <> nil then
            if Not ATree.Selected.Selected then
              ATree.Selected.Selected := true;
        end;
      end;
      ATree.Repaint;

      FreeAndNil(NodesToSelect);
    end;
  end;

begin
  TreeInfo1 := TRapList.Create;
  TreeInfo2 := TRapList.Create;

  SavedOnEnter1 := nil;
  SavedOnEnter2 := nil;
  SavedOnSelected1 := nil;
  SavedOnSelected2 := nil;
  if ATreeView1 <> nil then
  begin
    SavedOnEnter1 := ATreeView1.OnEnter;
    ATreeView1.OnEnter := nil;
    SavedOnSelected1 := ATreeView1.OnSelectedChanged;
    ATreeView1.OnSelectedChanged := nil;
  end;
  if ATreeView2 <> nil then
  begin
    SavedOnEnter2 := ATreeView2.OnEnter;
    ATreeView2.OnEnter := nil;
    SavedOnSelected2 := ATreeView2.OnSelectedChanged;
    ATreeView2.OnSelectedChanged := nil;
  end;
  try
    SaveTreeNodeInfoToList(ATreeView1, TreeInfo1);
    SaveTreeNodeInfoToList(ATreeView2, TreeInfo2);

    LoadInterfacesToTree := AProcToLoadInterf;
    LoadInterfacesToTree(false);

    RestoreTreeFromInfoList(ATreeView1, TreeInfo1);
    RestoreTreeFromInfoList(ATreeView2, TreeInfo2);
  finally
    if ATreeView1 <> nil then
    begin
      ATreeView1.OnEnter := SavedOnEnter1;
      ATreeView1.OnSelectedChanged := SavedOnSelected1;
    end;
    if ATreeView2 <> nil then
    begin
      ATreeView2.OnEnter := SavedOnEnter2;
      ATreeView2.OnSelectedChanged := SavedOnSelected2;
    end;
  end;
  FreeAndNil(TreeInfo1);
  FreeAndNil(TreeInfo2);
end;

procedure TF_MakeEditCrossConnection.RefreshInterfInfoRelatedOwners(ATreeView: TFlyTreeViewPro);
var
  Node: TFlyNode;
  NodeObject: TObject;
begin
  Node := GetFirstNodeFromFlyTree(ATreeView);
  while Node <> nil do
  begin
    NodeObject := TObject(Node.Data);
    if NodeObject is TInterfInfo then
      TInterfInfo(NodeObject).FNode := Node;
    Node := Node.GetNext;
  end;
end;

procedure TF_MakeEditCrossConnection.RemoveItemsFromInterfInfoListByOtherIsBusy(AList: TRapList; AIsBusy: Integer);
var
  InterfInfo: TInterfInfo;
  i: Integer;
begin 
  for i := AList.Count - 1 downto 0 do
  begin
    InterfInfo := TInterfInfo(AList[i]);
    if InterfInfo.IsBusy <> AIsBusy then
      AList.Delete(i);
  end;
end;

procedure TF_MakeEditCrossConnection.SaveExpandedInfo(ATree: TFlyTreeViewPro; AList: TObjectList);
var
  Node: TFlyNode;
  NodeInfo: TNodeInfo;
begin
  if AList <> nil then
  begin
    AList.Clear;
    Node := nil;
    if ATree.Items.Count > 0 then
      Node := ATree.Items[0];
    while Node <> nil do
    begin
      if Node.Expanded then
        if TObject(Node.Data) is TObject then
        begin
          NodeInfo := TNodeInfo.Create;
          AList.Add(NodeInfo);
          NodeInfo.LoadFromNodeFly(Node);
        end;
      Node := Node.GetNextVisible;
    end;
  end;
end;

procedure TF_MakeEditCrossConnection.SelectNodeByJoinedComponImageIndex(ATreeView: TFlyTreeViewPro);
var
  Node: TFlyNode;
begin
  if (ATreeView.Selected = nil) or (Not IsImageIndexShowConnectCompon(ATreeView.Selected.ImageIndex)) then
  begin
    Node := GetFirstNodeFromFlyTree(ATreeView);
    while Node <> nil do
    begin
      if IsImageIndexShowConnectCompon(Node.ImageIndex) then
      begin
        SelectNodeFly(ATreeView, Node);
        Break; //// BREAK ////
      end;
      Node := Node.GetNext;
    end;
  end;
end;

procedure TF_MakeEditCrossConnection.SelectNodeByJoinedInterfImageIndex(ATreeView: TFlyTreeViewPro);
var
  Node: TFlyNode;
begin
  if (ATreeView.Selected = nil) or (ATreeView.Selected.ImageIndex <> tciiConnectedInterface) then
  begin
    Node := GetFirstNodeFromFlyTree(ATreeView);
    while Node <> nil do
    begin
      if Node.ImageIndex = tciiConnectedInterface then
      begin
        SelectNodeFly(ATreeView, Node);
        Break; //// BREAK ////
      end;
      Node := Node.GetNext;
    end;
  end;
end;

procedure TF_MakeEditCrossConnection.SelectJoinedInterfInfoNode(ASrcInterfTree, ASrcInterfTreeSecond, ATrgComponTree, ATrgInterfTree: TFlyTreeViewPro);
var
  InterfInfo: TInterfInfo;
  Compon: TSCSComponent;
  Node: TFlyNode;
  TrgComponNode: TFlyNode;
begin
  if ASrcInterfTree.Selected <> nil then
  begin
    TrgComponNode := nil;
    InterfInfo := TInterfInfo(GetObjectFromNode(ASrcInterfTree.Selected, TInterfInfo.ClassName));
    if InterfInfo <> nil then
    begin
      Node := GetFirstNodeFromFlyTree(ATrgComponTree);
      while Node <> nil do
      begin
        Compon := TSCSComponent(GetObjectFromNode(Node, TSCSComponent.ClassName));
        if (Compon <> nil) and (InterfInfo.FInterface.ComponentOwner.JoinedComponents.IndexOf(Compon) <> -1) then
          if CheckJoinedComponWithInterfInfo(Compon, InterfInfo) then
          begin
            // Выделяем компонент с подгрузкой интерфейсов
            SelectNodeFly(ATrgComponTree, Node);
            SelectNodeByJoinedInterfImageIndex(ATrgInterfTree);
            DefineInterfTreeViewImageIndex(ATrgInterfTree, GetInterfInfoListFromTree(ASrcInterfTree), GetInterfInfoListFromTree(ASrcInterfTreeSecond), true);
            Break; //// BREAK ////
          end;
        Node := Node.GetNext;
      end;
    end;
  end;
end;

procedure TF_MakeEditCrossConnection.SelectJoinedToChildAtFromTree(ANode: TFlyNode);
var
  Node: TFlyNode;
  BreakNode: TFlyNode;

  NodeObject: TObject;
  SCSComponent: TSCSComponent;
  JoinedLine: TSCSComponent;

  Project: TSCSProject;
  i, j: integer;
  ComponsInfo: TConnectedComponsInfo;
  ConnectedComponsInfo: TConnectedComponsInfo;

  FindedJoined: Boolean;

begin
  if (FFormMode = fmCableConfigurator) and (rbSelectByPoint.Checked) then
  begin
    Project := FCatalog.GetProject;
    if Project <> nil then
    begin
      Node := ANode;
      BreakNode := Node.GetNextSibling;
      FindedJoined := false;
      while (Node <> nil) and (Node <> BreakNode) do
      begin
        NodeObject := TObject(Node.Data);
        if NodeObject is TSCSComponent then
        begin
          SCSComponent := TSCSComponent(NodeObject);
          for i := 0 to Project.ConnectedComponsList.Count - 1 do
          begin
            ComponsInfo := Project.ConnectedComponsList[i];
            if ComponsInfo.IDConnectCompon = SCSComponent.ID then
              if ComponsInfo.ComponWholeID <> 0 then
                for j := 0 to Project.ConnectedComponsList.Count - 1 do
                begin
                  ConnectedComponsInfo := Project.ConnectedComponsList[j];
                  if ConnectedComponsInfo.ComponWholeID = ComponsInfo.ComponWholeID then
                    if ConnectedComponsInfo.IDConnectCompon <> ComponsInfo.IDConnectCompon then
                    begin
                      SelectNodeFly(tvWith, Node);

                      FindedJoined := true;
                      Break; //// BREAK ////
                    end;
                end;
            if FindedJoined then
              Break; //// BREAK ////
          end;
        end;
        if FindedJoined then
          Break; //// BREAK ////
        Node := Node.GetNext;

        if (BreakNode = nil) and (Node <> nil) then
          if Node.Level <= ANode.Level then
            Break; //// BREAK ////
      end;
    end;
  end;
end;


procedure TF_MakeEditCrossConnection.SelectObjectInPMFromTreeView(ATreeView: TFlyTreeViewPro);
begin
  if Not TimerSelectObjInPM.Enabled then
    if (FIsHandlingtvWith = false) or (ATreeView = tvWith) then
    begin
      FTreeViewSelInPM := ATreeView;
      TimerSelectObjInPM.Enabled := true;
    end;
end;

procedure TF_MakeEditCrossConnection.SortConfiguratorTreeView(ATreeView: TFlyTreeViewPro; ASelectCurrList: Boolean = false);
var
  SCSProject: TSCSProject;
  Node: TFlyNode;
  NodeToSelect: TFlyNode;
begin
  NodeToSelect := nil;
  ATreeView.Items.BeginUpdate;
  try
    SCSProject := TSCSProject(FList.GetTopParentCatalog);
    if SCSProject = nil then
    // Tolik 18/05/2018 --
    ATreeView.Items.EndUpdate;
    //
      Exit; ///// EXIT ///// 

    //*** Сортонуть листы по SortID реверсивно
    SortTreeViewChildNodesFly(nil, ATreeView, tstSortID, SCSProject.Setting.ListsInReverseOrder);
    //*** Сортонуть объекты по нэйму
    Node := nil;
    if ATreeView.Items.Count > 0 then
      Node := ATreeView.Items[0];
    if Node <> nil then
      Node := GetTreeViewFirstTopNodeFly(Node);
    while Node <> nil do
    begin
      if TObject(Node.Data) is TSCSList then
      begin
        SortTreeViewChildNodesFly(Node, ATreeView, tstText);
        Node.Expanded := TObject(Node.Data) = FList;
        if (TObject(Node.Data) = FList) and (ASelectCurrList) then
          NodeToSelect := Node;
        ExpandChildNodesFly(Node);
      end;
      Node := Node.getNextSibling;
    end;
    if NodeToSelect <> nil then
      SelectNodeFly(ATreeView, NodeToSelect); //ATreeView.Selected := NodeToSelect;
  finally
    ATreeView.Items.EndUpdate;
  end;
end;

procedure TF_MakeEditCrossConnection.SetAnchorNodeToTree(ATreeView: TFlyTreeViewPro; ANode: TFlyNode);
var
  TreeIndex: Integer;
begin
  TreeIndex := FTreeList.IndexOf(ATreeView);
  if TreeIndex <> -1 then
    FTreeAnchorNodeList[TreeIndex] := ANode;
end;

procedure TF_MakeEditCrossConnection.SetControlsForInterfaces;
var
  IsVisibleInterfWith: Boolean;
  IsVisibleInterfWithSide2: Boolean;
  IsVisibleInterfFrom: Boolean;
  IsVisibleInterfFromSide2: Boolean;
  IsVisibleInterfTo: Boolean;
begin
  try
    IsVisibleInterfWith := false;
    IsVisibleInterfWithSide2 := false;
    IsVisibleInterfFrom := false;
    IsVisibleInterfFromSide2 := false;
    IsVisibleInterfTo := false;

    if btExtendedMode.Down then
      if FFormMode = fmCableConfigurator then
      begin
        IsVisibleInterfWith := true;
        IsVisibleInterfFrom := true;
        IsVisibleInterfTo := true;

        if rbSelectByLine.Checked then
        begin
          IsVisibleInterfWithSide2 := true;
        end
        else
        if rbSelectByPoint.Checked then
        begin
          IsVisibleInterfFromSide2 := true;
        end;
      end
      else
      if FFormMode = fmPointObjectConfigurator then
      begin
        IsVisibleInterfWith := true;
        IsVisibleInterfFrom := true;
      end;

    btExtendedMode.Enabled := ((FFormMode = fmCableConfigurator) or (FFormMode = fmPointObjectConfigurator));
    btExtendedMode.Visible := GUseVisibleInterfaces; 

    //pnInterfWith.Visible := IsVisibleInterfWith;
    //spInterfWith.Visible := IsVisibleInterfWith;
    //pnInterfWithSide2.Visible := IsVisibleInterfWithSide2;
    //spInterfWithSide2.Visible := IsVisibleInterfWithSide2;
    spInterfWith.LowerRight.Visible := IsVisibleInterfWith;
    spInterfWithSide2.LowerRight.Visible := IsVisibleInterfWithSide2;

    //pnInterfFrom.Visible := IsVisibleInterfFrom;
    //spInterfFrom.Visible := IsVisibleInterfFrom;
    //pnInterfFromSide2.Visible := IsVisibleInterfFromSide2;
    //spInterfFromSide2.Visible := IsVisibleInterfFromSide2;

    spInterfFrom.LowerRight.Visible := IsVisibleInterfFrom;
    spInterfFromSide2.LowerRight.Visible := IsVisibleInterfFromSide2;

    //pnInterfTo.Visible := IsVisibleInterfTo;
    //spInterfTo.Visible := IsVisibleInterfTo;
    spInterfTo.LowerRight.Visible := IsVisibleInterfTo;
  except
    on E: Exception do AddExceptionToLogEx('TF_MakeEditCrossConnection.SetControlsForInterfaces', E.Message);
  end;
end;

procedure TF_MakeEditCrossConnection.SetControlsForInterfacesByCompon(AComponment: TSCSComponent; ASplirter: TRzSplitter);
var
  CanShowControls: Boolean;
begin
  CanShowControls := true;
  if AComponment <> nil then
    if AComponment.IsLine = biFalse then
      CanShowControls := false;
  //ATreePanelSide2.Visible := CanShowControls;
  //ASplirter.Visible := CanShowControls;
  ASplirter.LowerRight.Visible := CanShowControls;
end;

procedure TF_MakeEditCrossConnection.SetControlsForLegend;
begin
  {if grLegend.Opened then
    pnLegend.Height := 120
  else
    pnLegend.Height := grLegend.Height + 15;}

  
  {splitLegend.Visible := btLegend.Down;
  if splitLegend.Visible then
  begin
    splitLegend.Align := alNone;
    splitLegend.Align := alBottom;
  end;}

  pnLegend.Visible := btLegend.Down;
  if pnLegend.Visible then
  begin
    gbConfiguratorNotice.Align := alNone;
    gbConfiguratorNotice.Align := alBottom;
  end;
end;

procedure TF_MakeEditCrossConnection.SetVisibleToGruopComponPanels(AVisible: Boolean);
var
  i: Integer;
begin
  for i := 0 to FGroupComponsPanelList.Count - 1 do
    TGroupComponsPanel(FGroupComponsPanelList[i]).Visible := AVisible;
end;


procedure TF_MakeEditCrossConnection.btOKClick(Sender: TObject);
var
  strMessg: String;
  CrossComponent: TSCSComponent;
  ComponentFrom: TSCSComponent;
  ComponentTo: TSCSComponent;
  ComponentsFrom: TSCSComponents;
  ComponentsTo: TSCSComponents;

  ComponFrom: TSCSComponent;
  ComponTo: TSCSComponent;
  CanConnect: Boolean;

  NodeFrom: TFlyNode;
  NodeTo: TFlyNode;

  i, j: Integer;
  CaptCheckInterfPort: string;
begin
  strMessg := '';
  CrossComponent := nil;
  ComponentFrom := nil;
  ComponentTo := nil;

  if Not Assigned(tvFrom.Selected) then
    strMessg := '-'+cMakeEditCrossConnection_Msg6+#10+#13;
  if Not Assigned(tvTo.Selected) then
    strMessg := strMessg + '-'+cMakeEditCrossConnection_Msg7+#10+#13;
  if Not Assigned(tvWith.Selected) then
    strMessg := strMessg + '-'+cMakeEditCrossConnection_Msg8+#10+#13;

  if strMessg <> '' then
  begin
    ModalResult := mrNone;

    strMessg := cMakeEditCrossConnection_Msg9+':'+ #10+#13 + strMessg;
    ShowMessageByType(Self.Handle, smtDisplay, strMessg, Application.Title, MB_ICONINFORMATION or MB_OK);
    Exit; ///// EXIT /////
  end;

  ComponentFrom := GetComponentFromTreeView(tvFrom);
  ComponentTo := GetComponentFromTreeView(tvTo);
  CrossComponent := GetComponentFromTreeView(tvWith);

  NodeFrom := tvFrom.Selected;
  NodeTo := tvTo.Selected;
  if NodeFrom.ImageIndex = tciiComponCon then
  begin
    ModalResult := mrNone;
    ShowMessageByType(Self.Handle, smtDisplay, cMakeEditCrossConnection_Msg10_1+' "'+CrossComponent.Name+'" '+cMakeEditCrossConnection_Msg10_2+' "'+ComponentFrom.Name+'".',
        Application.Title, MB_ICONINFORMATION or MB_OK);
    Exit; ///// EXIT /////
  end;
  if NodeTo.ImageIndex = tciiComponCon then
  begin
    ModalResult := mrNone;
    ShowMessageByType(Self.Handle, smtDisplay, cMakeEditCrossConnection_Msg10_1+' "'+CrossComponent.Name+'" '+cMakeEditCrossConnection_Msg10_2+' "'+ComponentTo.Name+'".',
        Application.Title, MB_ICONINFORMATION or MB_OK);
    Exit; ///// EXIT /////
  end;

  CanConnect := false;
  if Assigned(ComponentFrom) and Assigned(ComponentTo) and Assigned(CrossComponent) then
  begin
    ComponentsFrom := TSCSComponents.Create(false);
    ComponentsTo := TSCSComponents.Create(false);

    ComponentsFrom.Add(ComponentFrom);
    ComponentsFrom.Assign(ComponentFrom.ChildReferences, laOr);
    ComponentsTo.Add(ComponentTo);
    ComponentsTo.Assign(ComponentTo.ChildReferences, laOr);
    try
      for i := 0 to ComponentsFrom.count - 1 do
      begin
        ComponFrom := ComponentsFrom[i];
        if CrossComponent.CheckJoinToSeveralCompons(ComponFrom, nil).CanConnect then
        //if CrossComponent.EmConnectTo(ComponFrom) then
          for j := 0 to ComponentsTo.count - 1 do
          begin
            ComponTo := ComponentsTo[j];
            if CrossComponent.CheckJoinToSeveralCompons(ComponFrom, ComponTo).CanConnect then
            //if CrossComponent.EmConnectTo(ComponTo) then
            begin
              CanConnect := true;
              //CrossComponent.EmDisconnect(ComponFrom);
              //CrossComponent.EmDisconnect(ComponTo);
              Break; ///// BREAK /////
            end;
            //CrossComponent.EmDisconnect(ComponTo);
          end;
        //CrossComponent.EmDisconnect(ComponFrom);
        if CanConnect then
          Break; ///// BREAK /////
      end;
    finally
      ComponentsFrom.Free;
      ComponentsTo.Free;
    end;
  end;

  if Not CanConnect then
  begin
    ModalResult := mrNone;

    CaptCheckInterfPort := cMakeEditCrossConnection_Msg12;
    if Not GUseVisibleInterfaces then
      CaptCheckInterfPort := cMakeEditCrossConnection_Msg12_1;

    ShowMessageByType(Self.Handle, smtDisplay, cMakeEditCrossConnection_Msg11_1+' "'+CrossComponent.Name+'" '+
      cMakeEditCrossConnection_Msg11_2+' "'+ComponentFrom.Name+'" '+
      cMakeEditCrossConnection_Msg11_3+' "'+ComponentTo.Name+'".'+
      CaptCheckInterfPort,
      Application.Title, MB_ICONINFORMATION or MB_OK);
  end;

end;

function TF_MakeEditCrossConnection.ComponentConnectedWithAnyCross(AComponent: TSCSComponent): Boolean;
var
  i: Integer;
  ptrCrossConnection: TSCSCrossConnection;
begin
  Result := false;
  for i := 0 to FSCSComponent.CrossConnections.Count - 1 do
  begin
    ptrCrossConnection := TSCSCrossConnection(FSCSComponent.CrossConnections[i]);
    if ((ptrCrossConnection.IDComponFrom = AComponent.ID) and (ptrCrossConnection.NppFrom = AComponent.ServCopyIndex)) or
       ((ptrCrossConnection.IDComponTo = AComponent.ID) and (ptrCrossConnection.NppTo = AComponent.ServCopyIndex)) then
      if AComponent.LinkToComlectRec <> nil then
        if (ptrCrossConnection.IDCompRelFrom = AComponent.LinkToComlectRec.ID) or
           (ptrCrossConnection.IDCompRelTo = AComponent.LinkToComlectRec.ID) then
        begin
          Result := true;
          Break; ///// BREAK /////
        end;
  end;
end;

function TF_MakeEditCrossConnection.ComponentConnectedWithCross(AComponent, ACross: TSCSComponent): Boolean;
var
  i: Integer;
  ptrCrossConnection: TSCSCrossConnection;
begin
  Result := false;
  for i := 0 to FSCSComponent.CrossConnections.Count - 1 do
  begin
    ptrCrossConnection := TSCSCrossConnection(FSCSComponent.CrossConnections[i]);
    if (ptrCrossConnection.IDComponWith = ACross.ID) and (ptrCrossConnection.NppWith = ACross.ServCopyIndex) then
      if ((ptrCrossConnection.IDComponFrom = AComponent.ID) and (ptrCrossConnection.NppFrom = AComponent.ServCopyIndex)) or
         ((ptrCrossConnection.IDComponTo = AComponent.ID) and (ptrCrossConnection.NppTo = AComponent.ServCopyIndex)) then

        if AComponent.LinkToComlectRec <> nil then
          if (AComponent.LinkToComlectRec.ID = ptrCrossConnection.IDCompRelFrom) or
             (AComponent.LinkToComlectRec.ID = ptrCrossConnection.IDCompRelTo) then

            if ACross.LinkToComlectRec <> nil then
              if ACross.LinkToComlectRec.ID = ptrCrossConnection.IDCompRelWith then
              begin
                Result := true;
                Break; ///// BREAK /////
              end;
  end;
end;

function TF_MakeEditCrossConnection.ComponentConnectedWithOtherCross(
  AComponent: TSCSComponent): Boolean;
var
  i: Integer;
  ptrCrossConnection: TSCSCrossConnection;
begin
  Result := false;
  for i := 0 to FSCSComponent.CrossConnections.Count - 1 do
  begin
    ptrCrossConnection := TSCSCrossConnection(FSCSComponent.CrossConnections[i]);
    if ptrCrossConnection.ID <> FCrossConnection.ID then
      if ((ptrCrossConnection.IDComponFrom = AComponent.ID) and (ptrCrossConnection.NppFrom = AComponent.ServCopyIndex)) or
         ((ptrCrossConnection.IDComponTo = AComponent.ID) and (ptrCrossConnection.NppTo = AComponent.ServCopyIndex)) then
      begin
        Result := true;
        Break; ///// BREAK /////
      end;
  end;
end;

procedure TF_MakeEditCrossConnection.ConnectInterfaces(AInterfInfoList1, AInterfInfoList2: TRapList);
var
  i: Integer;
  InterfCount: Integer;
  InterfList1: TSCSInterfaces;
  InterfList2: TSCSInterfaces;

  InterfInfo1: TInterfInfo;
  InterfInfo2: TInterfInfo;

  {Component1, Component2: TSCSComponent;

  CheckInterfRes: TCheckInterfForUnionResult;
  ConnectKind: TConnectKind;
  InterfCount1, InterfCount2: Integer;

  EmptyPositions1: TSCSInterfPositions;
  EmptyPositions2: TSCSInterfPositions;

  ptrConnection: PComplect;
  
  TempInterfaces1: TSCSInterfaces;
  TempInterfaces2: TSCSInterfaces;
  }
  WasConnect: Boolean;


  {//17.10.2011 - Вынесена
  function GetEmptyPositionsFromInterfInfo(AInterfInfo: TInterfInfo): TSCSInterfPositions;
  var
    PosTo: Integer;
    KolvoFromPos: Integer;
  begin
    Result := nil;
    if (AInterfInfo.PosFrom = 0) and (AInterfInfo.PosTo = 0) then
      Result := AInterfInfo.FInterface.GetEmptyPositions(AInterfInfo.KolvoToConnect)
    else
    if (AInterfInfo.PosFrom > 0) and (AInterfInfo.PosTo > 0) then
    begin
      Result := AInterfInfo.FInterface.GetEmptyPositions;
      PosTo := AInterfInfo.PosTo;
      KolvoFromPos := AInterfInfo.PosTo - (AInterfInfo.PosFrom-1);
      if AInterfInfo.KolvoToConnect < KolvoFromPos then
        PosTo := (AInterfInfo.PosFrom-1) + AInterfInfo.KolvoToConnect;
      PrepareInterfPositionsByRegion(Result, AInterfInfo.PosFrom, PosTo);
    end;
  end;}

begin
  InterfCount := 0;
  try
    if AInterfInfoList1.Count = AInterfInfoList2.Count then
      InterfCount := AInterfInfoList1.Count
    else
    if AInterfInfoList1.Count > AInterfInfoList2.Count then
      InterfCount := AInterfInfoList2.Count
    else
    if AInterfInfoList1.Count < AInterfInfoList2.Count then
      InterfCount := AInterfInfoList1.Count;
    if InterfCount > 0 then
    begin
      InterfList1 := GetInterfacesFromInterfInfoList(AInterfInfoList1, true);
      InterfList2 := GetInterfacesFromInterfInfoList(AInterfInfoList2, true);

      WasConnect := false;

      for i := 0 to InterfCount - 1 do
      begin
        InterfInfo1 := TInterfInfo(AInterfInfoList1[i]);
        InterfInfo2 := TInterfInfo(AInterfInfoList2[i]);

        if JoinInterfInfos(InterfInfo1, InterfInfo2, InterfList1, InterfList2) then
          WasConnect := true;
          
        (*//17.10.2011 - Перенесено в JoinInterfInfos
        // if InterfInfo1.FInterface.ConnectedInterfaces.IndexOf(InterfInfo2.FInterface) = -1 then
        // Иногда несколько позиций одного интерфейса поключаются к позициям другого по разным портам
        begin
          Component1 := InterfInfo1.FInterface.ComponentOwner;
          Component2 := InterfInfo2.FInterface.ComponentOwner;

          ConnectKind := GetConnectKindByConnectionCompons(Component1, Component2, cntUnion);
          // В проверке пропускаем проверку на подключенность интерфейсов
          CheckInterfRes := CheckInterfForUnion(InterfInfo1.FInterface, InterfInfo2.FInterface,
                                GForm, GForm, {ConnectKind, }cntUnion, @InterfCount1, @InterfCount2,
                                [ciueInterfConnected]);
          if CheckInterfRes = chrSuccess then
          begin
            EmptyPositions1 := GetEmptyPositionsFromInterfInfo(InterfInfo1);
            EmptyPositions2 := GetEmptyPositionsFromInterfInfo(InterfInfo2);

            if (EmptyPositions1 <> nil) and (EmptyPositions2 <> nil) then
              if (EmptyPositions1.Kolvo > 0) and (EmptyPositions2.Kolvo > 0) then
              begin
                // Если компоненті не подключені, то подключить их нах
                if Component1.JoinedComponents.IndexOf(Component2) = -1 then
                begin
                  TempInterfaces1 := TSCSInterfaces.Create(false);
                  TempInterfaces2 := TSCSInterfaces.Create(false);
                  if TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(Component1, Component2, false, TempInterfaces1, TempInterfaces2, true).CanConnect then
                    WasConnect := true;

                  FreeAndNil(TempInterfaces1);
                  FreeAndNil(TempInterfaces2);
                end;

                if Component1.JoinedComponents.IndexOf(Component2) <> -1 then
                begin
                  ptrConnection := Component1.GetConnectionByConnected(Component2);
                  if ptrConnection <> nil then
                  begin
                    TF_Main(GForm).ConnectInterfacesWithAccordance(InterfInfo1.FInterface, InterfInfo2.FInterface,
                        InterfCount1, InterfCount2, ptrConnection.ID, cntUnion,
                        EmptyPositions1, EmptyPositions2, true, InterfList1, InterfList2);

                    TF_Main(GForm).F_ChoiceConnectSide.OnAfterJoinCompons(Component1, Component2, -1, -1);

                    WasConnect := true;
                  end;
                end;
              end;

            if EmptyPositions1 <> nil then
              FreeAndNil(EmptyPositions1);
            if EmptyPositions2 <> nil then
              FreeAndNil(EmptyPositions2);
          end;
        end;*)
      end;

      if WasConnect then
        AfterConnectDiconnect;

      FreeAndNil(InterfList1);
      FreeAndNil(InterfList2);
    end;
  except
    on E: Exception do AddExceptionToLogEx('TF_MakeEditCrossConnection.ConnectInterfaces', E.Message);
  end;
end;

procedure TF_MakeEditCrossConnection.DefineCableFirstLastComponsByTrees;
var
  CableCompon: TSCSComponent;
  ComponFrom: TSCSComponent;
  ComponTo: TSCSComponent;
  NodeFrom: TFlyNode;
  NodeTo: TFlyNode;

  ctvWith: TFlyTreeViewPro;
  ctvFrom: TFlyTreeViewPro;
  ctvTo: TFlyTreeViewPro;
begin
  ctvWith := tvWith;
  ctvFrom := tvFrom;
  ctvTo := tvTo;
  if rbSelectByPoint.Checked then
  begin
    ctvWith := tvFrom;
    ctvFrom := tvWith;
  end;

  CableCompon := GetComponentFromTreeView(ctvWith);
  ComponFrom := nil;
  ComponTo := nil;

  NodeFrom := nil;
  NodeTo  := nil;

  if Assigned(CableCompon) then
  begin
    ComponFrom := CableCompon.FirstConnectedConnCompon;
    ComponTo := CableCompon.LastConnectedConnCompon;

    if Assigned(ComponFrom) or Assigned(ComponTo) then
    begin
      NodeFrom := GetTreeViewNodeByDataFly(ctvFrom, ComponFrom, false);
      NodeTo := GetTreeViewNodeByDataFly(ctvTo, ComponTo, false);
      if Not Assigned(NodeFrom) and
         Not Assigned(NodeTo) then
      begin
        NodeFrom := GetTreeViewNodeByDataFly(ctvFrom, ComponTo, false);
        NodeTo := GetTreeViewNodeByDataFly(ctvTo, ComponFrom, false);
        if Assigned(NodeFrom) or Assigned(NodeTo) then
        begin
          ExchangeObjects(CableCompon.FirstConnectedConnCompon, CableCompon.LastConnectedConnCompon);
          ExchangeIntegers(CableCompon.FirstIDConnectedConnCompon, CableCompon.LastIDConnectedConnCompon);
          ExchangeIntegers(CableCompon.FirstIDCompon, CableCompon.LastIDCompon);
        end;
      end;
    end;
  end;
end;

procedure TF_MakeEditCrossConnection.DefineCableWhoseTracesConnectedToObject(ATreeViewWithCables: TFlyTreeViewPro; AObject: TObject);
var
  i: Integer;
  Node: TFlyNode;
  SCSCatalogFromParam: TSCSCatalog;
  SCSCatalogFromNode: TSCSCatalog;
  SCSComponentFromNode: TSCSComponent;
  EndComponent: TSCSComponent;
  LineComponNodeState: Integer;
begin
  SCSCatalogFromParam := nil;
  if AObject is TSCSCatalog then
    SCSCatalogFromParam := TSCSCatalog(AObject)
  else
  if AObject is TSCSComponent then
    SCSCatalogFromParam := TSCSComponent(AObject).GetFirstParentCatalog;

  ATreeViewWithCables.Items.BeginUpdate;
  try
    Node := nil;
    if ATreeViewWithCables.Items.Count > 0 then
      Node := ATreeViewWithCables.Items[0];

    //for i := 0 to ATreeViewWithCables.Items.Count - 1 do
    while Node <> nil do
    begin
      //Node := ATreeViewWithCables.Items[i];
      LineComponNodeState := GetImageStateIndex(nsiEmpty);

      SCSCatalogFromNode := nil;
      SCSComponentFromNode := GetComponentFromNode(Node);
      if (SCSComponentFromNode <> nil) and (SCSComponentFromNode.IsLine = biTrue) then
      begin
        //*** Подклюен ли объект к трассе конечного кабеля
        SCSCatalogFromNode := nil;
        EndComponent := FList.ProjectOwner.GetComponentFromReferences(SCSComponentFromNode.LastIDCompon);
        if EndComponent <> nil then
          SCSCatalogFromNode := EndComponent.GetFirstParentCatalog;
        if CheckConnectedObjectsInCAD(SCSCatalogFromNode, SCSCatalogFromParam) then
          LineComponNodeState := GetImageStateIndex(nsiAttention)
        else
        begin
          SCSCatalogFromNode := nil;
          EndComponent := FList.ProjectOwner.GetComponentFromReferences(SCSComponentFromNode.FirstIDCompon);
          if EndComponent <> nil then
            SCSCatalogFromNode := EndComponent.GetFirstParentCatalog;
          if CheckConnectedObjectsInCAD(SCSCatalogFromNode, SCSCatalogFromParam) then
            LineComponNodeState := GetImageStateIndex(nsiAttention);
        end;
      end;
      Node.StateIndex := LineComponNodeState;

      Node := Node.GetNext;
    end;
  finally
    ATreeViewWithCables.Items.EndUpdate;
  end;
end;

procedure TF_MakeEditCrossConnection.DefineInterfaceNodesText(ATreeView: TFlyTreeViewPro);
var
  LookedInterfaces: TSCSInterfaces;
  Node: TFlyNode;
  i: Integer;
  NodeObject: TObject;
  NodeInterf: TSCSInterface;

  function GetInterfNameFromLooked(AIDInterfase: Integer): String;
  var
    LookInterf: TSCSInterface;
    i: Integer;
  begin
    Result := '';
    for i := 0 to LookedInterfaces.Count - 1 do
    begin
      LookInterf := LookedInterfaces[i];
      if LookInterf.ID_Interface = AIDInterfase then
      begin
        Result := LookInterf.Name;
        Break; ///// BREAK ///// 
      end;
    end;
  end;

begin
  LookedInterfaces := TSCSInterfaces.Create(false);
  try
    Node := GetFirstNodeFromFlyTree(ATreeView);
    //for i := 0 to ATreeView.Items.Count - 1 do
    while Node <> nil do
    begin
      //Node := ATreeView.Items[i];
      NodeObject := TObject(Node.Data);
      if NodeObject is TSCSInterface then
      begin
        NodeInterf := TSCSInterface(NodeObject);
        NodeInterf.Name := '';
        NodeInterf.Name := GetInterfNameFromLooked(NodeInterf.ID_Interface);
        if NodeInterf.Name = '' then
          NodeInterf.LoadName;
        Node.Text := NodeInterf.GetNameForVisible;
        LookedInterfaces.Add(NodeInterf);
      end;
      Node := Node.GetNext;
    end;
  finally
    LookedInterfaces.Free;
  end;
end;

procedure TF_MakeEditCrossConnection.DefineInterfTreeViewImageIndex(ATreeView: TFlyTreeViewPro; AJoinedInterfInfoList1, AJoinedInterfInfoList2: TRapList; ACanSelectJoined: Boolean);
var
  InterfInfo: TInterfInfo;
  Node: TFlyNode;
  NodeImageIndex: Integer;

  NodeToSelect: TFlyNode;
  SelectedCount: Integer;
  PosCountInConnect: Integer;

  function CheckJoinedInteracesByInterfInfo(AInterfInfo: TInterfInfo; AInterfInfoList: TRapList; APtrPosCountInConnect: PInteger): Boolean;
  var
    InterfInfo: TInterfInfo;
    i: integer;
  begin
    Result := false;
    if (AInterfInfo <> nil) and (AInterfInfoList <> nil) then
      for i := 0 to AInterfInfoList.Count - 1 do
      begin
        InterfInfo := TInterfInfo(AInterfInfoList[i]);
        if CheckJoinedInterfInfos(AInterfInfo, InterfInfo, APtrPosCountInConnect) then
        begin
          Result := true;
          Break; //// BREAK ////
        end;
        //if AInterfInfo.FInterface.ConnectedInterfaces.IndexOf(InterfInfo.FInterface) <> -1 then
        //  if (AInterfInfo.IsBusy = biTrue) and (InterfInfo.IsBusy = biTrue) then
        //  begin
        //    Result := true;
        //    Break; //// BREAK ////
        //  end;
      end;
  end;

begin
  try
    Node := GetFirstNodeFromFlyTree(ATreeView);
    NodeToSelect := nil;
    SelectedCount := 0;
    while Node <> nil do
    begin
      if Node.Data <> nil then
      begin
        InterfInfo := TInterfInfo(Node.Data);
        NodeImageIndex := InterfInfo.ImageIndex;
        PosCountInConnect := 0;
        if CheckJoinedInteracesByInterfInfo(InterfInfo, AJoinedInterfInfoList1, @PosCountInConnect) then
        begin
          NodeImageIndex := tciiConnectedInterface;
          NodeToSelect := Node;
        end
        else
        if CheckJoinedInteracesByInterfInfo(InterfInfo, AJoinedInterfInfoList2, @PosCountInConnect) then
        begin
          NodeImageIndex := tciiConnectedInterface;
          NodeToSelect := Node;
        end;

        Node.ImageIndex := NodeImageIndex;
        Node.SelectedIndex := Node.ImageIndex;
        if Node = NodeToSelect then
        begin
          if ACanSelectJoined then
          begin
            if SelectedCount = 0 then
              ATreeView.Selected := NodeToSelect
            else
              NodeToSelect.Selected := true;
            Inc(SelectedCount);
          end;
        end;
        if InterfInfo.IsBusy = biTrue then
          if PosCountInConnect > 0 then
            Node.Cells[ciKolvoToConnect] := IntToStr(PosCountInConnect)
          else
            Node.Cells[ciKolvoToConnect] := '';
      end;
      Node := Node.GetNext;
    end;

    if ACanSelectJoined then
      if NodeToSelect <> nil then
        ATreeView.Repaint; //ATreeView.Selected := NodeToSelect;

    if AJoinedInterfInfoList1 <> nil then
      FreeAndNil(AJoinedInterfInfoList1);
    if AJoinedInterfInfoList2 <> nil then
      FreeAndNil(AJoinedInterfInfoList2);
  except
    on E: Exception do AddExceptionToLogEx('TF_MakeEditCrossConnection.DefineInterfTreeViewImageIndex', E.Message);
  end;
end;

procedure TF_MakeEditCrossConnection.DefineTreeViewImageIndex(ATreeView: TFlyTreeViewPro;
  AJoinedComponent: TSCSComponent; AShowJoined: Boolean);
var
  CurrNode: TFlyNode;
  i: Integer;

  procedure DefineImage(ACurrNode: TFlyNode);
  var
    ParentNode: TFlyNode;
    NodeObject: TObject;
    NodeParentObject: TObject;

    InterfInfo: TInterfInfo;
    Interf: TSCSInterface;
    Compon: TSCSComponent;
    ByIsPort: Integer;
    ImageIndex: Integer;
    IsJoinedComponent: Boolean;
  begin
    NodeObject := TObject(ACurrNode.Data);
    NodeParentObject := nil;
    ParentNode := ACurrNode.Parent;
    if ParentNode <> nil then
      NodeParentObject := TObject(ParentNode.Data);

    Interf := nil;
    Compon := nil;
    ImageIndex := ACurrNode.ImageIndex;
    if Assigned(NodeObject) then
    begin
      if NodeObject is TInterfInfo then
      begin
        InterfInfo := TInterfInfo(NodeObject);
        InterfInfo.IsBusy := BoolToInt(CheckNumInPositionList(InterfInfo.PosFrom, InterfInfo.FInterface.BusyPositions));
        ImageIndex := GetInterfaceImageIndesByIsBusy(InterfInfo.IsBusy);
      end
      else if NodeObject is TSCSInterface then
      begin
        Interf := TSCSInterface(NodeObject);
        ImageIndex := GetInterfaceImageIndesByIsBusy(Interf.IsBusy);
      end
      else if NodeObject is TSCSComponent then
      begin
        Compon := TSCSComponent(NodeObject);
        ByIsPort := biNone;
        case FFormMode of
          fmCrossConfigurator:
            if Not(Compon.IsCrossComponent) then //#Temp
              ByIsPort := biTrue;
          fmCableConfigurator:
            ByIsPort := biFalse;
        end;
        //*** Определится, подключенные ли индексы
        IsJoinedComponent := false;
        if (Compon.IsLine = biTrue) and (NodeParentObject is TSCSComponent) and
           (TSCSComponent(NodeParentObject).IsLine = biTrue) then
          IsJoinedComponent := true;
        if Not IsJoinedComponent then
          IsJoinedComponent := checkJoinedComponents(Compon, AJoinedComponent, true);

        ImageIndex := GetComponImageIndexByFilling(Compon.IsLine,
                        Compon.GetFilling(ByIsPort, itFunctional, FFormMode <> fmPointObjectConfigurator, true), IsJoinedComponent);
        if AShowJoined and IsJoinedComponent then
          ShowNodeFly(ATreeView, ACurrNode);

        ACurrNode.Text := Compon.GetNameForVisible(false);
      end;
    end;
    ACurrNode.ImageIndex := ImageIndex;
    ACurrNode.SelectedIndex := ImageIndex;
  end;

begin
  if Assigned(ATreeView) then
  begin
    CurrNode := GetFirstNodeFromFlyTree(ATreeView);
    //for i := 0 to ATreeView.Items.Count - 1 do
    while CurrNode <> nil do
    begin
      //CurrNode := ATreeView.Items[i];
      DefineImage(CurrNode);
      CurrNode := CurrNode.GetNext;
    end;
  end;
end;

procedure TF_MakeEditCrossConnection.DefineTrunkNodeImageIndex(ASelectedTrunkNode, ATrunkNodeToDefine: TFlyNode;
  AJoinedLineComponToDestTrunk: TSCSComponent; ARefrechTree: Boolean);
var
  DisablTreeView: TFlyTreeViewPro;
  SelectedTrunkComponent: TSCSComponent;
  TrunkComponentToDisable: TSCSComponent;
  ChildTrunkNodeToDisable: TFlyNode;
  ChildTrunkComponToDisable: TSCSComponent;

  PosSelectedTrunkComponent: Integer;
  PosTrunkComponentToDisable: Integer;
  SimpleComponImageIndex: Integer;
  NodesToDefine: TObjectList;
  i: Integer;

  procedure SetImageIndexToNodeAndChilds(ANode: TFlyNode; AImageIndex: Integer; AWithChilds: Boolean);
  var
    ChildNode: TFlyNode;
  begin
    ANode.ImageIndex := AImageIndex;
    ANode.SelectedIndex := AImageIndex;
    if AWithChilds then
    begin
      ChildNode := ANode.getFirstChild;
      while ChildNode <> nil do
      begin
        SetImageIndexToNodeAndChilds(ChildNode, AImageIndex, AWithChilds);
        ChildNode := ChildNode.getNextSibling;
      end;
    end;
  end;

begin
  SelectedTrunkComponent := GetComponentFromNode(ASelectedTrunkNode);
  TrunkComponentToDisable := GetComponentFromNode(ATrunkNodeToDefine);
  PosSelectedTrunkComponent := -1;
  PosTrunkComponentToDisable := -1;

  if Assigned(SelectedTrunkComponent) and Assigned(TrunkComponentToDisable) then
  begin
    //DisablTreeView := TFlyTreeViewPro(ATrunkNodeToDefine.Owner);
    DisablTreeView := TFlyTreeViewPro(ATrunkNodeToDefine.Tree);
    DisablTreeView.Items.BeginUpdate;
    try
      //*** Иконы в нормальное состаяние
      if ARefrechTree then
        DefineTreeViewImageIndex(DisablTreeView, AJoinedLineComponToDestTrunk, true);

      //*** Выделенный компонент является магистральным и комплектующей верхнего уровня
      PosSelectedTrunkComponent := GetComponIdentificatorInComplex(SelectedTrunkComponent);
      if PosSelectedTrunkComponent <> -1 then
        //if TrunkComponentToDisable.IsTop then
        begin
          //*** Определить 1-й Чилд
          ChildTrunkNodeToDisable := GetTopComponNode(ATrunkNodeToDefine);
          {if ChildTrunkNodeToDisable <> nil then
            ChildTrunkNodeToDisable := ChildTrunkNodeToDisable.GetFirstChild;

          while ChildTrunkNodeToDisable <> nil do
          begin
            ChildTrunkComponToDisable := GetComponentFromNode(ChildTrunkNodeToDisable);
            if ChildTrunkComponToDisable <> nil then
            begin
              if GetPointFigureRelationByPointObjects(FPointFigureRelations,
                  SelectedTrunkComponent, ChildTrunkComponToDisable) = nil then
              begin
                SetImageIndexToNodeAndChilds(ChildTrunkNodeToDisable,
                    GetComponImageIndexByFilling(SelectedTrunkComponent.IsLine, foNone, false), true);
              end;
            end;
            ChildTrunkNodeToDisable := ChildTrunkNodeToDisable.getNextSibling;
          end; }

          NodesToDefine := GetAllChildNodesFly(ChildTrunkNodeToDisable);
          NodesToDefine.Insert(0, ChildTrunkNodeToDisable);
          for i := 0 to NodesToDefine.Count - 1 do
          begin
            ChildTrunkNodeToDisable := TFlyNode(NodesToDefine[i]);

            ChildTrunkComponToDisable := GetComponentFromNode(ChildTrunkNodeToDisable);
            if ChildTrunkComponToDisable <> nil then
            begin
              if (GetPointFigureRelationByPointObjects(FPointFigureRelations,
                    SelectedTrunkComponent, ChildTrunkComponToDisable) = nil)
                 //and (SelectedTrunkComponent.GetTopComponent <> ChildTrunkComponToDisable.GetTopComponent) //28.01.2011 если это разные верхние объекты
                  then
              begin
                SetImageIndexToNodeAndChilds(ChildTrunkNodeToDisable,
                    GetComponImageIndexByFilling(SelectedTrunkComponent.IsLine, foNone, false), false);
              end;
            end;
          end;
          FreeAndNil(NodesToDefine); 
        end;
    finally
      DisablTreeView.Items.EndUpdate;
    end;
  end;
end;

procedure TF_MakeEditCrossConnection.DefineTVImageIndexWithTrunkNodes(ASelectedTrunkNode: TFlyNode; ADestTreeView: TFlyTreeViewPro;
  AJoinedLineComponToDestTrunk: TSCSComponent);
var
  i: Integer;
  Node: TFlyNode;
  NodeComponent: TSCSComponent;
  WasRefreshTreeView: Boolean;
begin
  WasRefreshTreeView := false;
  Node := GetFirstNodeFromFlyTree(ADestTreeView);
  //for i := 0 to ADestTreeView.Items.Count - 1 do
  while Node <> nil do
  begin
    //Node := ADestTreeView.Items[i];
    NodeComponent := nil;
    if Node.IsVisible then
      NodeComponent := GetComponentFromNode(Node);
    if (NodeComponent <> nil) and NodeComponent.IsTop then
    begin
      if Not WasRefreshTreeView then
      begin
        DefineTreeViewImageIndex(ADestTreeView, AJoinedLineComponToDestTrunk, true);
        WasRefreshTreeView := true;
      end;
      DefineTrunkNodeImageIndex(ASelectedTrunkNode, Node, AJoinedLineComponToDestTrunk, false);
    end;
    Node := Node.GetNext;
  end;
end;

procedure TF_MakeEditCrossConnection.DelComponentFromTreeView(ATreeView: TFlyTreeViewPro; AComponent: TSCSComponent);
var
  Node: TFlyNode;
  NextNode: TFlyNode;
  ///i: Integer;
begin
  ATreeView.Items.BeginUpdate;
  try
    //i := 0;
    Node := GetFirstNodeFromFlyTree(ATreeView);
    //while i <= ATreeView.Items.Count - 1 do
    while Node <> nil do
    begin
      //Node := ATreeView.Items[i];
      //if Node.Data = AComponent then
//        Node.Delete
//      else
//        Inc(i);
      if Node.Data = AComponent then
      begin
        NextNode := Node.GetNextSibling;
        Node.Delete;
        Node := NextNode;
      end
      else
        Node := Node.GetNext;
    end;
  finally
    ATreeView.Items.EndUpdate;
  end;
end;

procedure TF_MakeEditCrossConnection.EnableDisableConfiguratorControls;
var
  CanConnect: Boolean;
  CanDisconnect: Boolean;
  CanAddCable: Boolean;
  CanDeleteCable: Boolean;

  CheckedPair1: Boolean;
  CheckedPair2: Boolean;

  WithObj: TObject;
  WithNode: TFlyNode;
  WithComponent: TSCSComponent;
  WithFromComponent: TSCSComponent; // Конци кабеля
  WithToComponent: TSCSComponent;   //
  FromComponent: TSCSComponent;
  ToComponent: TSCSComponent;
  FromInterface: TSCSInterface;
  ToInterface: TSCSInterface;

  FromInterfInfo: TInterfInfo;
  ToInterfInfo: TInterfInfo;
  WithInterfInfoAtFrom: TInterfInfo;
  WithInterfInfoAtTo: TInterfInfo;

  Pair1Interfaces: TRapList;
  Pair2Interfaces: TRapList;
  JoinedPair1, JoinedPair2: Boolean;
  CheckJoinPair1, CheckJoinPair2: Boolean;

  WithName: String;
  FromName: String;
  ToName: String;

  Notice: String;
  ctvWith: TFlyTreeViewPro;
  ctvFrom: TFlyTreeViewPro;
  ctvTo: TFlyTreeViewPro;
  ActiveTree: TFlyTreeViewPro;
  ObjectsInGroupPanel: TList;

  ctvInterfWithSide1: TFlyTreeViewPro;
  ctvInterfWithSide2: TFlyTreeViewPro;
  ctvInterfFrom: TFlyTreeViewPro;
  ctvInterfTo: TFlyTreeViewPro;

  SelectedObject: TObject;

  CheckInterfRes: TCheckInterfForUnionResult;
  ConnectKind: TConnectKind;
  InterfCount1, InterfCount2: Integer;
  NodeList: TObjectList;
  CurrNode: TFlyNode;
  i: integer;

begin
  CanConnect := false;
  CanDisconnect := false;
  CanAddCable := false;
  CanDeleteCable := false;

  CheckedPair1 := false;
  CheckedPair2 := false;

  WithComponent := nil;
  WithFromComponent := nil;
  WithToComponent := nil;
  FromComponent := nil;
  ToComponent := nil;
  FromInterface := nil;
  ToInterface := nil;

  FTreeViewFrom := nil;
  FTreeViewTo := nil;
  FTreeViewInterf1 := nil;
  FTreeViewInterf2 := nil;

  FCanConnect := false;
  FCanDisconnect := false;
  FIsInterfAction := false;
  FPair1Compon1 := nil;
  FPair1Compon2 := nil;
  FPair2Compon1 := nil;
  FPair2Compon2 := nil;

  FPair1Compon1Port := nil;
  FPair1Compon2Port := nil;
  FPair2Compon1Port := nil;
  FPair2Compon2Port := nil;

  FPair1Compon1PortInfo := nil;
  FPair1Compon2PortInfo := nil;
  FPair2Compon1PortInfo := nil;
  FPair2Compon2PortInfo := nil;

  FPair1Interfaces.Clear;
  FPair2Interfaces.Clear;
  Pair1Interfaces := TRapList.Create;
  Pair2Interfaces := TRapList.Create;


  WithName := '';
  FromName := '';
  ToName := '';
  Notice := '';

  ctvWith := nil;
  ctvFrom := nil;
  ctvTo := nil;
  ctvInterfWithSide1 := nil;
  ctvInterfWithSide2 := nil;
  ctvInterfFrom := nil;
  ctvInterfTo := nil;

  try
    ctvWith := tvWith;
    ctvFrom := tvFrom;
    ctvTo := tvTo;
    ctvInterfWithSide1 := tvInterfWithSide1;
    ctvInterfWithSide2 := tvInterfWithSide2;
    ctvInterfFrom := tvInterfFromSide1;
    ctvInterfTo := tvInterfTo;
    if (FFormMode = fmCrossConfigurator) or (FFormMode = fmCableConfigurator) then
    begin
      if IsThroughConfiguratorMode then
        if rbSelectByPoint.Checked then
        begin
          ctvWith := tvFrom;
          ctvFrom := tvWith;

          ctvInterfWithSide1 := tvInterfFromSide1;
          ctvInterfWithSide2 := tvInterfFromSide2;
          ctvInterfFrom := tvInterfWithSide1;
        end;

      FTreeViewFrom := ctvFrom;
      FTreeViewTo := ctvTo;

      //*** Определить соединительный компонент (должен быть линейным)
      //17.10.2011 WithComponent := TSCSComponent(GetObjectFromTreeView(ctvWith, cnTSCSComponent));
      WithObj := nil;
      WithNode := ctvWith.Selected;
      if (WithNode <> nil) and (WithNode.Data <> nil) then
        WithObj := TObject(WithNode.Data);
      if WithObj is TSCSComponent then
        WithComponent := TSCSComponent(WithObj)
      else
      if WithObj is TInterfInfo then
        WithComponent := TSCSComponent(GetObjectFromNode(ctvWith.Selected.Parent, cnTSCSComponent));

      if Assigned(WithComponent) then
      begin
        case FFormMode of
          fmCrossConfigurator:
            begin
              WithFromComponent := WithComponent;
              WithToComponent := WithComponent;
            end;
          fmCableConfigurator:
            with TF_Main(GForm).GSCSBase.CurrProject do
            begin
              if WithComponent.FirstIDCompon <> 0 then
                WithFromComponent := GetComponentFromReferences(WithComponent.FirstIDCompon)
              else
                WithFromComponent := WithComponent;
              if WithComponent.LastIDCompon <> 0 then
                WithToComponent := GetComponentFromReferences(WithComponent.LastIDCompon)
              else
                WithToComponent := WithComponent;
            end;
        end;

        if Assigned(WithFromComponent) or Assigned(WithToComponent) then
        begin
          WithName := WithComponent.GetNameForVisible(false);
          //*** Определить подсоединенные/неподсоединенные точечные компоненты
          case FFormMode of
            fmCrossConfigurator:
              begin
                {//13.10.2011
                //*** Сначала определить порты, на основании кот. будут определятся компоненты
                FromInterface := TSCSInterface(GetObjectFromTreeView(ctvFrom, cnTSCSInterface));
                ToInterface := TSCSInterface(GetObjectFromTreeView(ctvTo, cnTSCSInterface));
                if Assigned(FromInterface) then
                begin
                  FromComponent := FromInterface.ComponentOwner;
                  FromName := FromInterface.GetNameForVisible;
                end;
                if Assigned(ToInterface) then
                begin
                  ToComponent := ToInterface.ComponentOwner;
                  ToName := ToInterface.GetNameForVisible;
                end;}

                //*** Сначала определить порты, на основании кот. будут определятся компоненты
                FromInterfInfo := TInterfInfo(GetObjectFromTreeView(ctvFrom, TInterfInfo.ClassName));
                ToInterfInfo := TInterfInfo(GetObjectFromTreeView(ctvTo, TInterfInfo.ClassName));
                WithInterfInfoAtFrom := nil;
                WithInterfInfoAtTo := nil;
                if Assigned(FromInterfInfo) then
                begin
                  FromComponent := FromInterfInfo.FInterface.ComponentOwner;
                  FromName := FromInterfInfo.FCaption; //16.10.2013 FromInterfInfo.FInterface.GetNameForVisible;
                  FromInterface := FromInterfInfo.FInterface;
                  if (WithObj = WithComponent) then
                    WithInterfInfoAtFrom := GetJoinedInterfInfoFromParentNode(WithNode, FromInterfInfo, nil)
                  else
                  if GetJoinedInterfInfoFromParentNode(WithNode, FromInterfInfo, nil) = WithObj then
                    WithInterfInfoAtFrom := TInterfInfo(WithObj);
                end;
                if Assigned(ToInterfInfo) then
                begin
                  ToComponent := ToInterfInfo.FInterface.ComponentOwner;
                  ToName := ToInterfInfo.FCaption; //16.10.2013 ToInterfInfo.FInterface.GetNameForVisible;
                  ToInterface := ToInterfInfo.FInterface;
                  if (WithObj = WithComponent) then
                    WithInterfInfoAtTo := GetJoinedInterfInfoFromParentNode(WithNode, ToInterfInfo, WithInterfInfoAtFrom)
                  else
                  if GetJoinedInterfInfoFromParentNode(WithNode, ToInterfInfo, WithInterfInfoAtFrom) = WithObj then
                    WithInterfInfoAtTo := TInterfInfo(WithObj);
                end;

                // Если находимся на кроссе а не на порту/интерфейсу, и с одной стороны подключение есть. а с другой нету,
                // то для не подключенной стороны определяем интерфейс, который связан с подключенным
                if WithObj = WithComponent then
                begin
                  if Assigned(WithInterfInfoAtFrom) and (WithInterfInfoAtFrom.IsBusy = biTrue) and
                     Assigned(ToInterfInfo) and (ToInterfInfo.IsBusy = biFalse) then
                    WithInterfInfoAtTo := GetInterfInfoFromOtherSide(WithNode, WithInterfInfoAtFrom, biFalse)
                  else
                  if Assigned(WithInterfInfoAtTo) and (WithInterfInfoAtTo.IsBusy = biTrue) and
                    Assigned(FromInterfInfo) and (FromInterfInfo.IsBusy = biFalse) then
                    WithInterfInfoAtFrom := GetInterfInfoFromOtherSide(WithNode, WithInterfInfoAtTo, biFalse);
                end;
              end;
            fmCableConfigurator:
              begin
                FromComponent := TSCSComponent(GetObjectFromTreeView(ctvFrom, cnTSCSComponent));
                if Assigned(FromComponent) then
                begin
                  FromName := FromComponent.GetNameForVisible(false);
                  if Not TF_Main(GForm).F_ChoiceConnectSide.CanJoinComponsByCAD(WithFromComponent, FromComponent) then
                    if TF_Main(GForm).F_ChoiceConnectSide.CanJoinComponsByCAD(WithToComponent, FromComponent) then
                      ExchangeObjects(WithFromComponent, WithToComponent);
                end;
                ToComponent := TSCSComponent(GetObjectFromTreeView(ctvTo, cnTSCSComponent));
                if Assigned(ToComponent) then
                begin
                  ToName := ToComponent.GetNameForVisible(false);
                  if Not TF_Main(GForm).F_ChoiceConnectSide.CanJoinComponsByCAD(WithToComponent, ToComponent) then
                    if TF_Main(GForm).F_ChoiceConnectSide.CanJoinComponsByCAD(WithFromComponent, ToComponent) then
                      ExchangeObjects(WithToComponent, WithFromComponent);
                end;
              end;
          end;

          case FFormMode of
            fmCrossConfigurator:
              begin
                (*
                //*** Если фокус на соединяемой компоненте, то нужны From и To
                if ctvWith.Focused then
                  if Assigned(FromComponent) and Assigned(ToComponent) and (FromInterface <> ToInterface) then
                    if Assigned(WithFromComponent) and Assigned(WithToComponent) then
                    begin
                      //*** Если они соединены, то их можно разъединить
                      if WithFromComponent.CheckConnectedToInterface(FromInterface) and
                         WithToComponent.CheckConnectedToInterface(ToInterface) then
                      begin
                        CanDisconnect := true;
                        FPair1Compon1 := WithFromComponent;
                        FPair1Compon2 := FromComponent;
                        FPair2Compon1 := WithToComponent;
                        FPair2Compon2 := ToComponent;

                        FPair1Compon2Port := FromInterface;
                        FPair2Compon2Port := ToInterface;

                        Notice := cMakeEditCrossConnection_Msg14+' "'+WithName+'" '+cMakeEditCrossConnection_Msg15+' "'+FromName+'" '+cMakeEditCrossConnection_Msg16+' "'+ToName+'".';
                      end
                      else  //*** Если они не соединены, то их можно соединить
                      if Not(WithFromComponent.CheckConnectedToInterface(FromInterface)) and
                         Not(WithToComponent.CheckConnectedToInterface(ToInterface)) then
                        //if {TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(WithFromComponent, FromComponent, true).CanConnect then //if} WithFromComponent.EmConnectTo(FromComponent) then
                        begin
                          if ((WithFromComponent = WithToComponent) and
                              WithFromComponent.CheckJoinToSeveralCompons(FromComponent, ToComponent).CanConnect) or
                             ((WithFromComponent <> WithToComponent) and
                              WithFromComponent.CheckJoinToSeveralCompons(FromComponent, nil).CanConnect and
                              WithToComponent.CheckJoinToSeveralCompons(ToComponent, nil).CanConnect) then
                          //if {TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(WithFromComponent, ToComponent, true).CanConnect then //if} WithToComponent.EmConnectTo(ToComponent) then
                          begin
                            CanConnect := true;
                            FPair1Compon1 := WithFromComponent;
                            FPair1Compon2 := FromComponent;
                            FPair2Compon1 := WithToComponent;
                            FPair2Compon2 := ToComponent;

                            FPair1Compon2Port := FromInterface;
                            FPair2Compon2Port := ToInterface;

                            Notice := cMakeEditCrossConnection_Msg17+' "'+WithName+'" '+cMakeEditCrossConnection_Msg18+' "'+FromName+'" '+cMakeEditCrossConnection_Msg16+' "'+ToName+'".';
                            //WithToComponent.EmDisconnect(ToComponent);
                          end;
                          //WithFromComponent.EmDisconnect(FromComponent);
                        end;
                    end;
                if ctvFrom.Focused then
                  if Assigned(FromComponent) and Assigned(WithFromComponent) then
                  begin
                    //*** Если они соединены, то их можно разъединить
                    if WithFromComponent.CheckConnectedToInterface(FromInterface) then
                    begin
                      CanDisconnect := true;
                      FPair1Compon1 := WithFromComponent;
                      FPair1Compon2 := FromComponent;

                      FPair1Compon2Port := FromInterface;

                      Notice := cMakeEditCrossConnection_Msg14+' "'+WithName+'" '+cMakeEditCrossConnection_Msg15+' "'+FromName+'".';
                    end
                    else  //*** Если они не соединены, то их можно соединить
                    if //(WithComponent.JoinedComponents.Count < 2) and
                        Not(WithFromComponent.CheckConnectedToInterface(FromInterface)) then
                      if TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(WithFromComponent, FromComponent, true).CanConnect then
                      //if WithFromComponent.CheckJoinTo(FromComponent, -1, -1).CanConnect then
                      begin
                        CanConnect := true;
                        FPair1Compon1 := WithFromComponent;
                        FPair1Compon2 := FromComponent;

                        FPair1Compon2Port := FromInterface;

                        Notice := cMakeEditCrossConnection_Msg17+' "'+WithName+'" '+cMakeEditCrossConnection_Msg18+' "'+FromName+'".';
                      end;
                  end;
                if ctvTo.Focused then
                  if Assigned(ToComponent) and Assigned(WithToComponent) then
                  begin
                    //*** Если они соединены, то их можно разъединить
                    if WithToComponent.CheckConnectedToInterface(ToInterface) then
                    begin
                      CanDisconnect := true;
                      FPair1Compon1 := WithToComponent;
                      FPair1Compon2 := ToComponent;

                      FPair1Compon2Port := ToInterface;

                      Notice := cMakeEditCrossConnection_Msg14+' "'+WithName+'" '+cMakeEditCrossConnection_Msg15+' "'+ToName+'".';
                    end
                    else  //*** Если они не соединены, то их можно соединить
                    if //(WithComponent.JoinedComponents.Count < 2) and
                       Not(WithToComponent.CheckConnectedToInterface(ToInterface)) then
                      if TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(WithToComponent, ToComponent, true).CanConnect then
                      //if WithToComponent.CheckJoinTo(ToComponent, -1, -1).CanConnect then
                      begin
                        CanConnect := true;
                        FPair1Compon1 := WithToComponent;
                        FPair1Compon2 := ToComponent;

                        FPair1Compon2Port := ToInterface;

                        Notice := cMakeEditCrossConnection_Msg17+' "'+WithName+'" '+cMakeEditCrossConnection_Msg18+' "'+ToName+'".';
                      end;
                  end;*)
                  
                //*** Если фокус на соединяемой компоненте, то нужны From и To
                if ctvWith.Focused then
                    //if Assigned(WithFromComponent) and Assigned(WithToComponent) then
                    begin
                      FPair1Compon1 := WithFromComponent;
                      FPair1Compon2 := FromComponent;
                      FPair2Compon1 := WithToComponent;
                      FPair2Compon2 := ToComponent;

                      FPair1Compon2Port := FromInterface;
                      FPair2Compon2Port := ToInterface;

                      FPair1Compon1PortInfo := WithInterfInfoAtFrom;
                      FPair1Compon2PortInfo := FromInterfInfo;
                      FPair2Compon1PortInfo := WithInterfInfoAtTo;
                      FPair2Compon2PortInfo := ToInterfInfo;

                      // Смотрим что подключено
                      JoinedPair1 := CheckJoinedInterfInfos(FPair1Compon1PortInfo, FPair1Compon2PortInfo);
                      JoinedPair2 := CheckJoinedInterfInfos(FPair2Compon1PortInfo, FPair2Compon2PortInfo);
                      if JoinedPair1 and JoinedPair2 then
                      begin
                        CanDisconnect := true;
                        Notice := cMakeEditCrossConnection_Msg14+' "'+WithName+'" '+cMakeEditCrossConnection_Msg15+' "'+FromName+'" '+cMakeEditCrossConnection_Msg16+' "'+ToName+'".'
                      end
                      else
                      begin
                        //Смотрим что можно подключить/отключить
                        CheckJoinPair1 := Not JoinedPair1 and
                                          CheckJoinInterfInfos(FPair1Compon1PortInfo, FPair1Compon2PortInfo) and
                                          FPair1Compon1PortInfo.FInterface.ComponentOwner.CheckJoinToSeveralCompons(FPair1Compon2PortInfo.FInterface.ComponentOwner, nil).CanConnect;
                        CheckJoinPair2 := Not JoinedPair2 and
                                          CheckJoinInterfInfos(FPair2Compon1PortInfo, FPair2Compon2PortInfo) and
                                          FPair2Compon1PortInfo.FInterface.ComponentOwner.CheckJoinToSeveralCompons(FPair2Compon2PortInfo.FInterface.ComponentOwner, nil).CanConnect;
                        if Not JoinedPair1 and Not JoinedPair2 and
                          CheckJoinPair1 and CheckJoinPair2 then
                        begin
                          CanConnect := true;
                          Notice := cMakeEditCrossConnection_Msg17+' "'+WithName+'" '+cMakeEditCrossConnection_Msg18+' "'+FromName+'" '+cMakeEditCrossConnection_Msg16+' "'+ToName+'".'
                        end
                        else
                        begin
                          if JoinedPair1 then
                          begin
                            CanDisconnect := true;
                            Notice := cMakeEditCrossConnection_Msg14+' "'+WithName+'" '+cMakeEditCrossConnection_Msg15+' "'+FromName+'"'
                          end
                          else if CheckJoinPair1 then
                          begin
                            CanConnect := true;
                            Notice := cMakeEditCrossConnection_Msg17+' "'+WithName+'" '+cMakeEditCrossConnection_Msg18+' "'+FromName+'"'
                          end;
                          if JoinedPair2 then
                          begin
                            CanDisconnect := true;
                            Notice := cMakeEditCrossConnection_Msg14+' "'+WithName+'" '+cMakeEditCrossConnection_Msg15+' "'+ToName+'"';
                          end
                          else if CheckJoinPair2 then
                          begin
                            CanConnect := true;
                            Notice := cMakeEditCrossConnection_Msg17+' "'+WithName+'" '+cMakeEditCrossConnection_Msg18+' "'+ToName+'"'
                          end;
                        end;
                      end;

                      (*//*** Если они соединены, то их можно разъединить
                      //17.10.2011 if CheckJoinedComponWithInterfInfo(WithFromComponent, FromInterfInfo) or {//17.10.2011 and}
                      //17.10.2011    CheckJoinedComponWithInterfInfo(WithToComponent, ToInterfInfo) then
                      if CheckJoinedInterfInfos(WithInterfInfoAtFrom, FromInterfInfo) or {//17.10.2011 and}
                         CheckJoinedInterfInfos(WithInterfInfoAtTo, ToInterfInfo) then
                      begin
                        CanDisconnect := true;
                        FPair1Compon1 := WithFromComponent;
                        FPair1Compon2 := FromComponent;
                        FPair2Compon1 := WithToComponent;
                        FPair2Compon2 := ToComponent;

                        FPair1Compon2Port := FromInterface;
                        FPair2Compon2Port := ToInterface;

                        FPair1Compon1PortInfo := WithInterfInfoAtFrom;
                        FPair1Compon2PortInfo := FromInterfInfo;
                        FPair2Compon1PortInfo := WithInterfInfoAtTo;
                        FPair2Compon2PortInfo := ToInterfInfo;

                        if Assigned(WithInterfInfoAtFrom) and Assigned(WithInterfInfoAtTo) then
                          Notice := cMakeEditCrossConnection_Msg14+' "'+WithName+'" '+cMakeEditCrossConnection_Msg15+' "'+FromName+'" '+cMakeEditCrossConnection_Msg16+' "'+ToName+'".'
                        else if Assigned(WithInterfInfoAtFrom) then
                          Notice := cMakeEditCrossConnection_Msg14+' "'+WithName+'" '+cMakeEditCrossConnection_Msg15+' "'+FromName+'"'
                        else if Assigned(WithInterfInfoAtTo) then
                          Notice := cMakeEditCrossConnection_Msg14+' "'+WithName+'" '+cMakeEditCrossConnection_Msg15+' "'+ToName+'"';
                      end
                      else  //*** Если они не соединены, то их можно соединить
                      //17.10.2011 if Not CheckJoinedComponWithInterfInfo(WithFromComponent, FromInterfInfo) and
                      //17.10.2011    Not CheckJoinedComponWithInterfInfo(WithToComponent, ToInterfInfo) then
                      if Not CheckJoinedInterfInfos(WithInterfInfoAtFrom, FromInterfInfo) or
                         Not CheckJoinedInterfInfos(WithInterfInfoAtTo, ToInterfInfo) then
                        //if {TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(WithFromComponent, FromComponent, true).CanConnect then //if} WithFromComponent.EmConnectTo(FromComponent) then
                        begin
                          //19.10.2011
                          //if ((WithFromComponent = WithToComponent) and WithFromComponent.CheckJoinToSeveralCompons(FromComponent, ToComponent).CanConnect) or
                          //   ((WithFromComponent <> WithToComponent) and
                          //    WithFromComponent.CheckJoinToSeveralCompons(FromComponent, nil).CanConnect and
                          //    WithToComponent.CheckJoinToSeveralCompons(ToComponent, nil).CanConnect)
                          //then
                          ////if {TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(WithFromComponent, ToComponent, true).CanConnect then //if} WithToComponent.EmConnectTo(ToComponent) then
                          //then
                          begin
                            CanConnect := true;
                            FPair1Compon1 := WithFromComponent;
                            FPair1Compon2 := FromComponent;
                            FPair2Compon1 := WithToComponent;
                            FPair2Compon2 := ToComponent;

                            FPair1Compon2Port := FromInterface;
                            FPair2Compon2Port := ToInterface;

                            FPair1Compon1PortInfo := WithInterfInfoAtFrom;
                            FPair1Compon2PortInfo := FromInterfInfo;
                            FPair2Compon1PortInfo := WithInterfInfoAtTo;
                            FPair2Compon2PortInfo := ToInterfInfo;

                            if Assigned(WithInterfInfoAtFrom) and Assigned(WithInterfInfoAtTo) then
                              Notice := cMakeEditCrossConnection_Msg17+' "'+WithName+'" '+cMakeEditCrossConnection_Msg18+' "'+FromName+'" '+cMakeEditCrossConnection_Msg16+' "'+ToName+'".'
                            else if Assigned(WithInterfInfoAtFrom) then
                              Notice := cMakeEditCrossConnection_Msg17+' "'+WithName+'" '+cMakeEditCrossConnection_Msg18+' "'+FromName+'"'
                            else if Assigned(WithInterfInfoAtTo) then
                              Notice := cMakeEditCrossConnection_Msg17+' "'+WithName+'" '+cMakeEditCrossConnection_Msg18+' "'+ToName+'"'
                            //WithToComponent.EmDisconnect(ToComponent);
                          end;
                          //WithFromComponent.EmDisconnect(FromComponent);
                        end;
                      *)
                    end;
                if ctvFrom.Focused then
                  if Assigned(FromComponent) and Assigned(WithFromComponent) then
                  begin
                    //*** Если они соединены, то их можно разъединить
                    //17.10.2011 if CheckJoinedComponWithInterfInfo(WithFromComponent, FromInterfInfo) then
                    if CheckJoinedInterfInfos(WithInterfInfoAtFrom, FromInterfInfo) then
                    begin
                      CanDisconnect := true;
                      FPair1Compon1 := WithFromComponent;
                      FPair1Compon2 := FromComponent;

                      FPair1Compon2Port := FromInterface;
                      FPair1Compon1PortInfo := WithInterfInfoAtFrom;
                      FPair1Compon2PortInfo := FromInterfInfo;

                      if Assigned(FPair1Compon1PortInfo) and Assigned(FPair1Compon2PortInfo) then
                        Notice := cMakeEditCrossConnection_Msg14+' "'+WithName+'" '+cMakeEditCrossConnection_Msg15+' "'+FromName+'".';
                    end
                    else if FromInterfInfo.IsBusy = biTrue then //02.02.2013
                    begin
                      WithInterfInfoAtFrom := GetJoinedInterfInfoFromObjectTreeFirst(FromInterfInfo, ctvWith);
                      if WithInterfInfoAtFrom <> nil then
                      begin
                        ///FromInterface := WithInterfInfoAtFrom.FInterface;
                        //FromComponent := FromInterface.ComponentOwner;
                        WithFromComponent := WithInterfInfoAtFrom.FInterface.ComponentOwner;

                        CanDisconnect := true;
                        FPair1Compon1 := WithFromComponent;
                        FPair1Compon2 := FromComponent;

                        FPair1Compon2Port := FromInterface;
                        FPair1Compon1PortInfo := WithInterfInfoAtFrom;
                        FPair1Compon2PortInfo := FromInterfInfo;

                        if Assigned(FPair1Compon1PortInfo) and Assigned(FPair1Compon2PortInfo) then
                          Notice := cMakeEditCrossConnection_Msg14+' "'+WithFromComponent.GetNameForVisible+'" '+cMakeEditCrossConnection_Msg15+' "'+FromName+'".';
                      end;
                    end
                    else  //*** Если они не соединены, то их можно соединить
                    if //(WithComponent.JoinedComponents.Count < 2) and
                      //17.10.2011   Not CheckJoinedComponWithInterfInfo(WithFromComponent, FromInterfInfo) then
                        Not CheckJoinedInterfInfos(WithInterfInfoAtFrom, FromInterfInfo) and
                        CheckJoinInterfInfos(WithInterfInfoAtFrom, FromInterfInfo) then
                      if TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(WithFromComponent, FromComponent, true).CanConnect or
                         //01.08.2012 - или если интерфейсы уже подключены
                         (WithInterfInfoAtFrom.Finterface.ConnectedInterfaces.IndexOf(FromInterfInfo.FInterface) <> -1) then
                      //if WithFromComponent.CheckJoinTo(FromComponent, -1, -1).CanConnect then
                      begin
                        CanConnect := true;
                        FPair1Compon1 := WithFromComponent;
                        FPair1Compon2 := FromComponent;

                        FPair1Compon2Port := FromInterface;
                        FPair1Compon1PortInfo := WithInterfInfoAtFrom;
                        FPair1Compon2PortInfo := FromInterfInfo;

                        if Assigned(FPair1Compon1PortInfo) and Assigned(FPair1Compon2PortInfo) then
                          Notice := cMakeEditCrossConnection_Msg17+' "'+WithName+'" '+cMakeEditCrossConnection_Msg18+' "'+FromName+'".';
                      end;
                  end;
                if ctvTo.Focused then
                  if Assigned(ToComponent) and Assigned(WithToComponent) then
                  begin
                    //*** Если они соединены, то их можно разъединить
                    //17.10.2011 if CheckJoinedComponWithInterfInfo(WithToComponent, ToInterfInfo) then
                    if CheckJoinedInterfInfos(WithInterfInfoAtTo, ToInterfInfo) then
                    begin
                      CanDisconnect := true;
                      FPair1Compon1 := WithToComponent;
                      FPair1Compon2 := ToComponent;

                      FPair1Compon2Port := ToInterface;
                      FPair1Compon1PortInfo := WithInterfInfoAtTo;
                      FPair1Compon2PortInfo := ToInterfInfo;

                      if Assigned(FPair1Compon1PortInfo) and Assigned(FPair1Compon2PortInfo) then
                        Notice := cMakeEditCrossConnection_Msg14+' "'+WithName+'" '+cMakeEditCrossConnection_Msg15+' "'+ToName+'".';
                    end
                    else if ToInterfInfo.IsBusy = biTrue then //02.02.2013
                    begin
                      WithInterfInfoAtTo := GetJoinedInterfInfoFromObjectTreeFirst(ToInterfInfo, ctvWith);
                      if WithInterfInfoAtTo <> nil then
                      begin
                        //ToInterface := WithInterfInfoAtTo.FInterface;
                        //ToComponent := ToInterface.ComponentOwner;
                        WithToComponent := WithInterfInfoAtTo.FInterface.ComponentOwner;

                        CanDisconnect := true;
                        FPair1Compon1 := WithToComponent;
                        FPair1Compon2 := ToComponent;

                        FPair1Compon2Port := ToInterface;
                        FPair1Compon1PortInfo := WithInterfInfoAtTo;
                        FPair1Compon2PortInfo := ToInterfInfo;

                        if Assigned(FPair1Compon1PortInfo) and Assigned(FPair1Compon2PortInfo) then
                          Notice := cMakeEditCrossConnection_Msg14+' "'+WithToComponent.GetNameForVisible+'" '+cMakeEditCrossConnection_Msg15+' "'+ToName+'".';
                      end
                      else //16.10.2013 - Если порт из панели Куда не подключен к выделенному из панели Откуда
                      begin
                        CanDisconnect := true;
                        FPair1Compon1 := nil; //WithToComponent;
                        FPair1Compon2 := ToComponent;

                        FPair1Compon2Port := ToInterface;
                        FPair1Compon1PortInfo := nil;
                        FPair1Compon2PortInfo := ToInterfInfo;

                        if Assigned(FPair1Compon2PortInfo) then
                          Notice := cMakeEditCrossConnection_Msg14+' "'+ToName+'".';
                      end;
                    end
                    else  //*** Если они не соединены, то их можно соединить
                    if //(WithComponent.JoinedComponents.Count < 2) and
                       //17.10.2011 Not CheckJoinedComponWithInterfInfo(WithToComponent, ToInterfInfo) then
                       Not CheckJoinedInterfInfos(WithInterfInfoAtTo, ToInterfInfo) and
                       CheckJoinInterfInfos(WithInterfInfoAtTo, ToInterfInfo) then
                      if TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(WithToComponent, ToComponent, true).CanConnect or
                        //01.08.2012 - или если интерфейсы уже подключены
                        (WithInterfInfoAtTo.Finterface.ConnectedInterfaces.IndexOf(ToInterfInfo.FInterface) <> -1) then
                      //if WithToComponent.CheckJoinTo(ToComponent, -1, -1).CanConnect then
                      begin
                        CanConnect := true;
                        FPair1Compon1 := WithToComponent;
                        FPair1Compon2 := ToComponent;

                        FPair1Compon2Port := ToInterface;
                        FPair1Compon1PortInfo := WithInterfInfoAtTo;
                        FPair1Compon2PortInfo := ToInterfInfo;

                        if Assigned(FPair1Compon1PortInfo) and Assigned(FPair1Compon2PortInfo) then
                          Notice := cMakeEditCrossConnection_Msg17+' "'+WithName+'" '+cMakeEditCrossConnection_Msg18+' "'+ToName+'".';
                      end;
                  end;
              end;
            fmCableConfigurator:
              begin
                //*** Если фокус на соединяемой компоненте, то нужны From и To
                if ctvWith.Focused then
                  if Assigned(FromComponent) and Assigned(ToComponent) and (FromComponent <> ToComponent) then
                    if Assigned(WithFromComponent) and Assigned(WithToComponent) then
                    begin
                      //*** Если они соединены, то их можно разъединить
                      if WithFromComponent.Ping(FromComponent, ToComponent) and
                         WithToComponent.Ping(ToComponent, FromComponent) then
                      begin
                        if CheckConnectedComponObjectsInCAD(WithFromComponent, FromComponent) then
                        begin
                          FPair1Compon1 := WithFromComponent;
                          FPair1Compon2 := FromComponent;
                          CheckedPair1 := true;
                        end;
                        if CheckConnectedComponObjectsInCAD(WithToComponent, ToComponent) then
                        begin
                          FPair2Compon1 := WithToComponent;
                          FPair2Compon2 := ToComponent;
                          CheckedPair2 := true;
                        end;
                        if CheckedPair1 and CheckedPair2 then
                          Notice := cMakeEditCrossConnection_Msg14+' "'+WithName+'" '+cMakeEditCrossConnection_Msg15+' "'+FromName+'" '+cMakeEditCrossConnection_Msg16+' "'+ToName+'".'
                        else
                        if CheckedPair1 then
                          Notice := cMakeEditCrossConnection_Msg14+' "'+WithName+'" '+cMakeEditCrossConnection_Msg15+' "'+FromName+'".'
                        else
                        if CheckedPair2 then
                          Notice := cMakeEditCrossConnection_Msg14+' "'+WithName+'" '+cMakeEditCrossConnection_Msg15+' "'+ToName+'".';

                        if CheckedPair1 or CheckedPair2 then
                          CanDisconnect := true;
                      end
                      else  //*** Если они не соединены, то их можно соединить
                      if Not(WithFromComponent.Ping(FromComponent, ToComponent)) and
                         Not(WithToComponent.Ping(ToComponent, FromComponent)) then
                        //if {TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(WithFromComponent, FromComponent, true).CanConnect then //if} WithFromComponent.EmConnectTo(FromComponent) then
                        begin
                          if ((WithFromComponent = WithToComponent) and
                              //09.08.2012 WithFromComponent.CheckJoinToSeveralCompons(FromComponent, ToComponent).CanConnect) or
                              TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(WithFromComponent, FromComponent, true).CanConnect and
                              TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(WithFromComponent, ToComponent, true).CanConnect) or
                             ((WithFromComponent <> WithToComponent) and
                              WithFromComponent.CheckJoinToSeveralCompons(FromComponent, nil).CanConnect and
                              WithToComponent.CheckJoinToSeveralCompons(ToComponent, nil).CanConnect) then
                          //if {TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(WithFromComponent, ToComponent, true).CanConnect then //if} WithToComponent.EmConnectTo(ToComponent) then
                          begin
                            if CheckConnectedComponObjectsInCAD(WithFromComponent, FromComponent) then
                            begin
                              FPair1Compon1 := WithFromComponent;
                              FPair1Compon2 := FromComponent;
                              CheckedPair1 := true;
                            end;
                            if CheckConnectedComponObjectsInCAD(WithToComponent, ToComponent) then
                            begin
                              FPair2Compon1 := WithToComponent;
                              FPair2Compon2 := ToComponent;
                              CheckedPair2 := true;
                            end;
                            if CheckedPair1 and CheckedPair2 then
                              Notice := cMakeEditCrossConnection_Msg17+' "'+WithName+'" '+cMakeEditCrossConnection_Msg18+' "'+FromName+'" '+cMakeEditCrossConnection_Msg16+' "'+ToName+'".'
                            else
                            if CheckedPair1 then
                              Notice := cMakeEditCrossConnection_Msg17+' "'+WithName+'" '+cMakeEditCrossConnection_Msg18+' "'+FromName+'".'
                            else
                            if CheckedPair2 then
                              Notice := cMakeEditCrossConnection_Msg17+' "'+WithName+'" '+cMakeEditCrossConnection_Msg18+' "'+ToName+'".';

                            if CheckedPair1 or CheckedPair2 then
                              CanConnect := true;
                            //WithToComponent.EmDisconnect(ToComponent);
                          end;
                          //WithFromComponent.EmDisconnect(FromComponent);
                        end;
                    end;
                if ctvFrom.Focused then
                  if Assigned(FromComponent) and Assigned(WithFromComponent) then
                  begin
                    //*** Если они соединены, то их можно разъединить
                    if WithFromComponent.Ping(FromComponent, ToComponent) and
                       CheckConnectedComponObjectsInCAD(WithFromComponent, FromComponent) then
                    begin
                      CanDisconnect := true;
                      FPair1Compon1 := WithFromComponent;
                      FPair1Compon2 := FromComponent;

                      Notice := cMakeEditCrossConnection_Msg14+' "'+WithName+'" '+cMakeEditCrossConnection_Msg15+' "'+FromName+'".';
                    end
                    else  //*** Если они не соединены, то их можно соединить
                    if //(WithComponent.JoinedComponents.Count < 2) and
                        Not(WithFromComponent.Ping(FromComponent, ToComponent)) then
                      if TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(WithFromComponent, FromComponent, true).CanConnect then
                      //if WithFromComponent.CheckJoinTo(FromComponent, -1, -1).CanConnect then
                      begin
                        CanConnect := true;
                        FPair1Compon1 := WithFromComponent;
                        FPair1Compon2 := FromComponent;

                        Notice := cMakeEditCrossConnection_Msg17+' "'+WithName+'" '+cMakeEditCrossConnection_Msg18+' "'+FromName+'".';
                      end;
                  end;
                if ctvTo.Focused then
                  if Assigned(ToComponent) and Assigned(WithToComponent) then
                  begin
                    //*** Если они соединены, то их можно разъединить
                    if WithToComponent.Ping(ToComponent, FromComponent) and
                       CheckConnectedComponObjectsInCAD(WithToComponent, ToComponent) then
                    begin
                      CanDisconnect := true;
                      FPair1Compon1 := WithToComponent;
                      FPair1Compon2 := ToComponent;

                      Notice := cMakeEditCrossConnection_Msg14+' "'+WithName+'" '+cMakeEditCrossConnection_Msg15+' "'+ToName+'".';
                    end
                    else  //*** Если они не соединены, то их можно соединить
                    if //(WithComponent.JoinedComponents.Count < 2) and
                       Not(WithToComponent.Ping(ToComponent, FromComponent)) then
                      if TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(WithToComponent, ToComponent, true).CanConnect then
                      //if WithToComponent.CheckJoinTo(ToComponent, -1, -1).CanConnect then
                      begin
                        CanConnect := true;
                        FPair1Compon1 := WithToComponent;
                        FPair1Compon2 := ToComponent;

                        Notice := cMakeEditCrossConnection_Msg17+' "'+WithName+'" '+cMakeEditCrossConnection_Msg18+' "'+ToName+'".';
                      end;
                  end;


              end;
          end;
        end;
      end
      else // Определить точечные компоненты, если небыл найден линейный
      begin
        FromComponent := TSCSComponent(GetObjectFromTreeView(ctvFrom, cnTSCSComponent));
        ToComponent := TSCSComponent(GetObjectFromTreeView(ctvTo, cnTSCSComponent));
      end;

      if FFormMode = fmCableConfigurator then
      begin
        CanAddCable := (rbSelectByPoint.Checked) and Assigned(FromComponent) and Assigned(ToComponent);
        CanDeleteCable := Assigned(WithComponent);
      end;
    end
    else
    if FFormMode = fmPointObjectConfigurator then
    begin
      ctvFrom := tvFrom;
      ctvWith := tvWith;

      ToComponent := TSCSComponent(GetObjectFromTreeView(tvWith, cnTSCSComponent));
      FromComponent := TSCSComponent(GetObjectFromTreeView(tvFrom, cnTSCSComponent));
      if Assigned(ToComponent) and Assigned(FromComponent) then
      begin
        // Если компоненты подключены, и их можно отключить
        if ToComponent.JoinedComponents.IndexOf(FromComponent) <> -1 then
        begin
          CanDisconnect := true;
          FPair1Compon1 := ToComponent;
          FPair1Compon2 := FromComponent;
          Notice := cMakeEditCrossConnection_Msg14+' "'+ToComponent.GetNameForVisible+'" '+cMakeEditCrossConnection_Msg15+' "'+FromComponent.GetNameForVisible+'".';
        end
        else  // Если компоненты не подключены, но их можно подключить
        if TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(ToComponent, FromComponent, true).CanConnect then
        begin
          CanConnect := true;
          FPair1Compon1 := ToComponent;
          FPair1Compon2 := FromComponent;
          Notice := cMakeEditCrossConnection_Msg17+' "'+ToComponent.GetNameForVisible+'" '+cMakeEditCrossConnection_Msg18+' "'+FromComponent.GetNameForVisible+'".';
        end;
      end;
    end;

    // Игтерфейсы
    if IsConfiguratorMode then
    begin
      if ctvInterfWithSide1.Focused then
      begin
        Pair1Interfaces := GetInterfInfoListFromTree(ctvInterfWithSide1);
        Pair2Interfaces := GetInterfInfoListFromTree(ctvInterfFrom);
        FTreeViewInterf1 := ctvInterfWithSide1;
        FTreeViewInterf2 := ctvInterfFrom;
      end
      else
      if ctvInterfFrom.Focused then
      begin
        Pair1Interfaces := GetInterfInfoListFromTree(ctvInterfFrom);
        Pair2Interfaces := GetInterfInfoListFromTree(ctvInterfWithSide1);
        FTreeViewInterf1 := ctvInterfFrom;
        FTreeViewInterf2 := ctvInterfWithSide1;
      end
      else
      if ctvInterfWithSide2.Focused then
      begin
        Pair1Interfaces := GetInterfInfoListFromTree(ctvInterfWithSide2);
        Pair2Interfaces := GetInterfInfoListFromTree(ctvInterfTo);
        FTreeViewInterf1 := ctvInterfWithSide2;
        FTreeViewInterf2 := ctvInterfTo;
      end
      else
      if ctvInterfTo.Focused then
      begin
        Pair1Interfaces := GetInterfInfoListFromTree(ctvInterfTo);
        Pair2Interfaces := GetInterfInfoListFromTree(ctvInterfWithSide2);
        FTreeViewInterf1 := ctvInterfTo;
        FTreeViewInterf2 := ctvInterfWithSide2;
      end;
      // Рассмотрим вариант подключения/отключения
      if (Pair1Interfaces <> nil) and (Pair2Interfaces <> nil) then
      begin
        // вариант подключения
        if (Pair1Interfaces.Count > 0) and (Pair2Interfaces.Count > 0) {and (TInterfInfo(Pair1Interfaces[0]).IsBusy = biFalse)} then
        begin
          //if TInterfInfo(Pair1Interfaces[0]).IsBusy = TInterfInfo(Pair2Interfaces[0]).IsBusy then //20.03.2009
          begin
            if TInterfInfo(Pair1Interfaces[0]).FInterface.Multiple = biFalse then
              RemoveItemsFromInterfInfoListByOtherIsBusy(Pair1Interfaces, TInterfInfo(Pair1Interfaces[0]).IsBusy);
            if TInterfInfo(Pair2Interfaces[0]).FInterface.Multiple = biFalse then
              RemoveItemsFromInterfInfoListByOtherIsBusy(Pair2Interfaces, TInterfInfo(Pair2Interfaces[0]).IsBusy);

            if (Pair1Interfaces.Count > 0) and (Pair2Interfaces.Count > 0) then
            begin
              // вариант подключения
              //if TInterfInfo(Pair1Interfaces[0]).IsBusy = biFalse then //20.03.2009
              if ((TInterfInfo(Pair1Interfaces[0]).IsBusy = biFalse) or               //20.03.2009
                  (TInterfInfo(Pair1Interfaces[0]).FInterface.Multiple = biTrue)) and //20.03.2009
                 ((TInterfInfo(Pair2Interfaces[0]).IsBusy = biFalse) or               //20.03.2009
                  (TInterfInfo(Pair2Interfaces[0]).FInterface.Multiple = biTrue)) then //20.03.2009
              begin
                FromComponent := TInterfInfo(Pair1Interfaces[0]).FInterface.ComponentOwner;
                ToComponent := TInterfInfo(Pair2Interfaces[0]).FInterface.ComponentOwner;

                // Если компоненты уже подключены
                if (FromComponent.JoinedComponents.IndexOf(ToComponent) <> -1) or
                   TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(FromComponent, ToComponent,
                     true).CanConnect then
                begin
                  //ConnectKind := GetConnectKindByConnectionCompons(FromComponent, ToComponent, cntUnion);

                  // В проверке пропускаем проверку на подключенность интерфейсов 
                  CheckInterfRes := CheckInterfForUnion(TInterfInfo(Pair1Interfaces[0]).FInterface, TInterfInfo(Pair2Interfaces[0]).FInterface,
                                        GForm, GForm, {ConnectKind, }cntUnion, @InterfCount1, @InterfCount2,
                                        [ciueInterfConnected]);
                  if CheckInterfRes = chrSuccess then
                    FIsInterfAction := true;
                end;

                if FIsInterfAction then
                begin
                  Notice := cMakeEditCrossConnection_Msg17+' "'+TInterfInfo(Pair1Interfaces[0]).FInterface.LoadName+'" '+
                            cMakeEditCrossConnection_Msg18+' "'+TInterfInfo(Pair2Interfaces[0]).FInterface.LoadName+'".';
                  Canconnect := true;
                end;
              end;

              //else
              //// вариант отключения
              //if TInterfInfo(Pair1Interfaces[0]).IsBusy = biTrue then
              //begin
              //  CanDisconnect := true;
              //  FIsInterfAction := true;
              //end
            end;
          end;
        end;
        //else
        // Рассмотрим вариант отключения
        if Pair1Interfaces.Count > 0 then
          if TInterfInfo(Pair1Interfaces[0]).IsBusy = biTrue then
            begin
              RemoveItemsFromInterfInfoListByOtherIsBusy(Pair1Interfaces, TInterfInfo(Pair1Interfaces[0]).IsBusy);
              if Pair1Interfaces.Count > 0 then
              begin
                if Notice <> '' then
                  Notice := Notice + ' ';
                Notice := Notice + cMakeEditCrossConnection_Msg14+' "'+TInterfInfo(Pair1Interfaces[0]).FInterface.LoadName+'" ';
                CanDisconnect := true;
                FIsInterfAction := true;
              end;
            end;

        if FIsInterfAction then
        begin
          FPair1Interfaces.AddList(Pair1Interfaces);
          FPair2Interfaces.AddList(Pair2Interfaces);
        end;
      end;
    end;

    if Notice = '' then
      Notice := cMakeEditCrossConnection_Msg13;

    if CanConnect or CanDisconnect then
    begin
      FCanConnect := CanConnect;
      FCanDisconnect := CanDisconnect;
    end;

    //*** переход на компонент в основном дереве в режиме точ объектов
    Act_SelectInMainTree.Visible := false;
    Act_SelectInMainTree.Enabled := false;
    Act_FindConnected.Visible := false;
    Act_FindConnected.Enabled := false;
    Act_AddToGroup.Visible := false;
    Act_AddToGroup.Enabled := false;
    Act_FindInGroup.Visible := false;
    pmiInterfPath.Visible := FIsInterfAction and CanDisconnect;
    if (FFormMode = fmCableConfigurator ) and rbSelectByPoint.Checked then
    begin
      if tvTo.Focused then
      begin
        Act_SelectInMainTree.Visible := true;
        SelectedObject := GetObjectFromTreeView(tvTo, '');
        if (SelectedObject <> nil) and (GetTreeViewNodeByDataFly(tvWith, SelectedObject, false) <> nil) then
          Act_SelectInMainTree.Enabled := true;
      end;

      Act_AddToGroup.Visible := true;
      if ctvFrom.Focused or ctvTo.Focused then
      begin
        //SelectedObject := GetObjectFromFocusedTreeView;
        //if SelectedObject <> nil then
        //GetComponCountToJoinFromNode
        //  Act_AddToGroup.Enabled := true;
        ActiveTree := GetFocusedTreeView;
        if ActiveTree <> nil then
        begin
          ObjectsInGroupPanel := nil; //ObjectsInGroupPanel := GetDataListFromGroupComponsPanelByTree(ActiveTree);  
          if GetComponCountToJoinFromNode(ActiveTree.Selected, ObjectsInGroupPanel) > 0 then
            Act_AddToGroup.Enabled := true;
          if ObjectsInGroupPanel <> nil then
            FreeAndNil(ObjectsInGroupPanel);

          if GetGroupComponsPanelByTree(ActiveTree, false) <> nil then
            Act_FindInGroup.Visible := true;

          if FGroupComponsPanelList.Count > 0 then
            CanAddCable := true;
        end;
      end;
    end;
    if IsConfiguratorMode then
      if tvWith.Focused or tvFrom.Focused or
        tvInterfWithSide1.Focused or tvInterfWithSide2.Focused or
        tvInterfFromSide1.Focused or tvInterfFromSide2.Focused then
      begin
        Act_FindConnected.Visible := true;
        if ActiveControl is TFlyTreeViewPro then
          if TFlyTreeViewPro(ActiveControl).Selected <> nil then
            Act_FindConnected.Enabled := true;
      end;

    cbCanJoinFewCablesToCompon.Visible := (GetGroupComponsPanelByTree(tvWith, false) <> nil) or (GetGroupComponsPanelByTree(tvTo, false) <> nil);
  finally
    FreeAndNil(Pair1Interfaces);
    FreeAndNil(Pair2Interfaces);

    Act_Connect.Enabled := CanConnect;
    Act_Disconnect.Enabled := CanDisconnect;
    Act_AddCable.Enabled := CanAddCable;
    Act_DeleteCable.Enabled := CanDeleteCable;
    //Act_DisconnectAll.Enabled := (Assigned(ctvFrom) and ctvFrom.Focused and (ctvFrom.Selected <> nil)) or
    //                             (Assigned(ctvTo) and ctvTo.Focused and (ctvTo.Selected <> nil));
    ActiveTree := GetFocusedTreeView;
    Act_DisconnectAll.Enabled := Assigned(ActiveTree) and (ActiveTree.Selected <> nil);
    try
      if Assigned(ActiveTree) and (ActiveTree.Selected <> nil) then
      begin
        NodeList := GetAllChildNodesFly(ActiveTree.Selected);
        NodeList.Insert(0, ActiveTree.Selected);
        for i := 0 to NodeList.Count - 1 do
        begin
          CurrNode := TFlyNode(NodeList[i]);
          if TObject(CurrNode.Data) is TSCSComponent then
          begin
            if TSCSComponent(CurrNode.Data).IsLine = 1 then
            begin
              Act_DisconnectAll.Enabled := False;
              break;
            end;
          end;
        end;
        FreeAndNil(NodeList);
      end;  
    except
    end;
    mConfNotice.Lines.Text := ' '+ Notice;
  end;
end;

procedure TF_MakeEditCrossConnection.ExchangeInterfWithInTreeSidesIfCan;
var
  //SideAtFromComponent: Integer;
  //SideAtToComponent: Integer;
  SideAtLineComponent: Integer;
  InterfWithSideAtPointComponent: Integer;
  TempSide: Integer;

  ComponFrom: TSCSComponent;
  ComponTo: TSCSComponent;
  ConnCompon: TSCSComponent;
  LineComponSide: TSCSComponent;

  //LineObjFrom: TSCSCatalog;
  //LineObjTo: TSCSCatalog;
  LineObj: TSCSCatalog;

  //PointObjFrom: TSCSCatalog;
  //PointObjTo: TSCSCatalog;
  PointObj: TSCSCatalog;

  ObjFrom: TSCSCatalog;
  ObjWith: TSCSCatalog;
  SideInFromComponent: Integer;
  SideInWithComponent: Integer;
begin
  if (FFormMode = fmCableConfigurator) and rbSelectByLine.Checked then
  begin
    // Если линейный компонент не подключен к точечнsv компонентам
    if (FPointObjectFrom <> nil) and (FPointObjecttTo <> nil) then
      if (FInterfWithSideAtTree1 <> -1) and (FInterfWithSideAtTree2 <> -1) then
        if Not CheckJoinedComponToComponFromObject(FLineComponFromSide, FPointObjectFrom) and
           Not CheckJoinedComponToComponFromObject(FLineComponToSide, FPointObjecttTo) then
        begin
          ComponFrom := GetComponentFromTreeView(tvFrom);
          ComponTo := GetComponentFromTreeView(tvTo);
          ConnCompon := nil;
          LineComponSide := nil;
          InterfWithSideAtPointComponent := -1;
          if ComponFrom <> nil then
          begin
            ConnCompon := ComponFrom;
            LineComponSide := FLineComponFromSide;
            InterfWithSideAtPointComponent := FInterfWithSideAtTree1;
          end
          else
          if ComponTo <> nil then
          begin
            ConnCompon := ComponTo;
            LineComponSide := FLineComponToSide;
            InterfWithSideAtPointComponent := FInterfWithSideAtTree2;
          end;

          if ConnCompon <> nil then
          begin
            PointObj := ConnCompon.GetFirstParentCatalog;
            LineObj := LineComponSide.GetFirstParentCatalog;

            if (PointObj <> nil) and (LineObj <> nil) then
            begin
              GetSidesByConnectedFigures(LineObj.ListID, PointObj.ListID,
                LineObj.SCSID, PointObj.SCSID, SideAtLineComponent, TempSide);

              if (SideAtLineComponent <> -1) then
                if (InterfWithSideAtPointComponent <> SideAtLineComponent) then
                begin
                  ExchangeIntegers(FInterfWithSideAtTree1, FInterfWithSideAtTree2);
                  ExchangeTreesNodesFly(tvInterfWithSide1, tvInterfWithSide2, AfterSetDataToNode);
                end;
            end;
          end;
        end;

    {
    // Если линейный компонент не подключен к точечнsv компонентам
    if (FPointObjectFrom <> nil) and (FPointObjecttTo <> nil) then
      if (FInterfWithSideAtFromComponent <> -1) and (FInterfWithSideAtToComponent <> -1) then
        if Not CheckJoinedComponToComponFromObject(FLineComponFromSide, FPointObjectFrom) and
           Not CheckJoinedComponToComponFromObject(FLineComponToSide, FPointObjecttTo) then
        begin
          ComponFrom := GetComponentFromTreeView(tvFrom);
          ComponTo := GetComponentFromTreeView(tvTo);
          if (ComponFrom <> nil) and (ComponTo <> nil) then
          begin
            PointObjFrom := ComponFrom.GetFirstParentCatalog;
            PointObjTo := ComponTo.GetFirstParentCatalog;

            LineObjFrom := FLineComponFromSide.GetFirstParentCatalog;
            LineObjTo := FLineComponToSide.GetFirstParentCatalog;

            if (PointObjFrom <> nil) and (PointObjTo <> nil) and (LineObjFrom <> nil) and (LineObjTo <> nil) then
            begin
              GetSidesByConnectedFigures(LineObjFrom.ListID, PointObjFrom.ListID,
                LineObjFrom.SCSID, PointObjFrom.SCSID, SideAtFromComponent, TempSide);
              GetSidesByConnectedFigures(LineObjTo.ListID, PointObjTo.ListID,
                LineObjTo.SCSID, PointObjTo.SCSID, SideAtToComponent, TempSide);

              if (SideAtFromComponent <> -1) and (SideAtToComponent <> -1) then
              begin
                if (FInterfWithSideAtFromComponent <> SideAtFromComponent) and (FInterfWithSideAtToComponent <> SideAtToComponent) then
                begin
                  FInterfWithSideAtFromComponent := SideAtFromComponent;
                  FInterfWithSideAtToComponent := SideAtToComponent;
                  ExchangeTreesNodesFly(tvInterfWithSide1, tvInterfWithSide2);
                end;
              end;
            end;
          end;
        end; }
  end
  else
  if (FFormMode = fmPointObjectConfigurator) then
    if FInterfWithSideAtTree1 <> -1 then
    begin
      ObjFrom := GetCatalogFromTreeView(tvFrom);
      ObjWith := GetCatalogFromTreeView(tvWith);

      if (ObjFrom <> nil) and (ObjWith <> nil) then
      begin
        GetSidesByConnectedFigures(ObjFrom.ListID, ObjWith.ListID,
          ObjFrom.SCSID, ObjWith.SCSID, SideInFromComponent, SideInWithComponent);

        if FInterfWithSideAtTree1 <> SideInWithComponent then
        begin
          ExchangeIntegers(FInterfWithSideAtTree1, FInterfWithSideAtTree2);
          ExchangeTreesNodesFly(tvInterfWithSide1, tvInterfWithSide2, AfterSetDataToNode);
        end;
      end;
    end;
end;

function TF_MakeEditCrossConnection.FindComponInTree(AIDCompon: Integer; ATreeView: TFlyTreeViewPro; ASelect: Boolean): Boolean;
var
  CurrObj: TObject;
  CurrCompon: TSCSComponent;
  CurrNode: TFlyNode;
  i: Integer;
begin
  Result := false;
  CurrNode := GetFirstNodeFromFlyTree(ATreeView);
  //for i := 0 to ATreeView.Items.Count - 1 do
  while CurrNode <> nil do
  begin
    //CurrNode := ATreeView.Items[i];
    CurrObj := TObject(CurrNode.Data);
    if CurrObj is TSCSComponent then
    begin
      CurrCompon := TSCSComponent(CurrObj);
      if CurrCompon.ID = AIDCompon then
      begin
        Result := true;
        if ASelect then
        begin
          SelectNodeFly(ATreeView, CurrNode); //ATreeView.Selected := CurrNode;
          ShowNodeFly(ATreeView, CurrNode);
        end;
      end;
    end;
    CurrNode := CurrNode.GetNext;
  end;
end;

function TF_MakeEditCrossConnection.FindNodeByObjectInTree(ATreeView: TFlyTreeViewPro; AObject: TObject): TFlyNode;
var
  i: Integer;
  CurrNode: TFlyNode;
begin
  Result := nil;
  CurrNode := GetFirstNodeFromFlyTree(ATreeView);
  //for i := 0 to ATreeView.Items.Count - 1 do
  while CurrNode <> nil do
  begin
    //CurrNode := ATreeView.Items[i];
    if CurrNode.Data = AObject then
    begin
      Result := CurrNode;
      Break; //// BREAK ////
    end;
    CurrNode := CurrNode.GetNext;
  end;
end;

procedure TF_MakeEditCrossConnection.ExpandTreeNodesByInfo(ATree: TFlyTreeViewPro; AInfoList: TObjectList; ASelInfo: TNodeInfo);
var
  i, j: integer;
  NodeInfo: TNodeInfo;
  Nodes: TList;
  Node, NodeToSel: TFlyNode;
begin
  if AInfoList.Count > 0 then
  begin
    ATree.Items.BeginUpdate;
    try
      NodeToSel := nil;
      Nodes := GetTreeViewNodesFly(ATree);
      for i := 0 to AInfoList.Count - 1 do
      begin
        NodeInfo := TNodeInfo(AInfoList[i]);
        // разворачиваем ноуды
        for j := 0 to Nodes.Count - 1 do
        begin
          Node := TFlyNode(Nodes[j]);
          if ASelInfo.CmpNodeFly(Node) then
            NodeToSel := Node;
          if Not Node.Expanded then
            if NodeInfo.CmpNodeFly(Node) then
            begin
              Node.Expanded := true;
              Nodes.Delete(j);
              Break; //// BREAK ////
            end;
        end;
      end;
      FreeAndNil(Nodes);
      if NodeToSel <> nil then
        ShowNodeFly(ATree, NodeToSel); //ATree.Toggle(NodeToSel);  //SelectNodeFly(ATree, NodeToSel);
    finally
      ATree.Items.EndUpdate;
    end;
  end;
end;

function TF_MakeEditCrossConnection.GetAnchorNodeFromTree(ATreeView: TFlyTreeViewPro): TFlyNode;
var
  TreeIndex: Integer;
begin
  Result := nil;
  TreeIndex := FTreeList.IndexOf(ATreeView);
  if TreeIndex <> -1 then
  begin
    Result := TFlyNode(FTreeAnchorNodeList[TreeIndex]);
    try
      if Not Result.Selected then
        Result := nil
      else
      if Result.Tree = nil then
        Result := nil;
    except
      Result := nil;
    end;
  end;
end;

function TF_MakeEditCrossConnection.GetCatalogFromTreeView(ATreeView: TFlyTreeViewPro): TSCSCatalog;
var
  NodeObject: TObject;
  SCSComponent: TSCSComponent;
  SCSCatalog: TSCSCatalog;
begin
  Result := nil;
  NodeObject := nil;
  SCSComponent := nil;
  SCSCatalog := nil;
  if Assigned(ATreeView) then
    if Assigned(ATreeView.Selected) then
      if ATreeView.Selected.Data <> nil then
        NodeObject := TObject(ATreeView.Selected.Data);
  if NodeObject <> nil then
  begin
    if NodeObject is TSCSInterface then
      SCSComponent := TSCSInterface(NodeObject).ComponentOwner
    else
    if NodeObject is TSCSComponent then
      SCSComponent := TSCSComponent(NodeObject)
    else
    if NodeObject is TSCSCatalog then
      SCSCatalog := TSCSCatalog(NodeObject);

    if SCSCatalog = nil then
      if SCSComponent <> nil then
        SCSCatalog := SCSComponent.GetFirstParentCatalog;
    Result := SCSCatalog;
  end;
end;

function TF_MakeEditCrossConnection.GetCatalogNodeFromTreeView(ATreeView: TTreeView; ACatalog: TSCSCatalog): TTreeNode;
var
  i: Integer;
  Node: TTreeNode;
begin
  Result := nil;
  for i := 0 to ATreeView.Items.Count - 1 do
  begin
    Node := ATreeView.Items[i];
    if TObject(Node.Data) is TSCSCatalog then
      if TSCSCatalog(TObject(Node.Data)) = ACatalog then
      begin
        Result := Node;
        Break; //// BREAK ////
      end;
  end;
end;

function TF_MakeEditCrossConnection.GetComponCountToJoinFromNode(ANode: TFlyNode; ALeveFromList: TList): Integer;
var
  BreakNode: TFLyNode;
  Node: TFlyNode;
begin
  Result := 0;

  if ANode <> nil then
  begin
    Node := ANode;
    BreakNode := ANode.GetNextSibling;
    while (Node <> nil) and (Node <> BreakNode) do
    begin
      if (ALeveFromList = nil) or (ALeveFromList.IndexOf(Node.Data) = -1) then
        case GetImageIndexNoConnected(Node.ImageIndex) of
          tciiComponConNoFill,
          tciiComponConPartFill,
          tciiComponLineNoFill,
          tciiComponLinePartFill:
            Result := Result + 1;
        end;
      Node := Node.GetNext;
      if (BreakNode = nil) and (Node <> nil) then
        if Node.Level <= ANode.Level then
          Break; //// BREAK ////
    end;
  end;
end;

function TF_MakeEditCrossConnection.GetComponentFromNode(ATreeNode: TFlyNode): TSCSComponent;
begin
  Result := nil;
  if ATreeNode <> nil then
    if ATreeNode.Data <> nil then
      if TObject(ATreeNode.Data) is TSCSComponent then
        Result := TSCSComponent(ATreeNode.Data);
end;

function TF_MakeEditCrossConnection.GetComponentFromTreeView(ATreeView: TFlyTreeViewPro): TSCSComponent;
begin
  Result := nil;
  if Assigned(ATreeView) then
    if Assigned(ATreeView.Selected) then
      Result := GetComponentFromNode(ATreeView.Selected);
      //if ATreeView.Selected.Data <> nil then
      //  Result := TSCSComponent(ATreeView.Selected.Data);
end;

function TF_MakeEditCrossConnection.GetComponentNodeFromNodeListByWholeID(ANodeList: TObjectList; AWholeID: Integer): TFlyNode;
var
  i: Integer;
  Node: TFlyNode;
begin
  Result := nil;
  for i := 0 to ANodeList.Count - 1 do
  begin
    Node := TFlyNode(ANodeList[i]);
    if TObject(Node.Data) is TSCSComponent then
      if TSCSComponent(TObject(Node.Data)).Whole_ID = AWholeID then
      begin
        Result := Node;
        Break; //// BREAK ////
      end;
  end;
end;

function TF_MakeEditCrossConnection.GetComponentNodeFromTreeView(ATreeView: TFlyTreeViewPro; AComponent: TSCSComponent): TFlyNode;
var
  i: Integer;
  Node: TFlyNode;
begin
  Result := nil;
  Node := GetFirstNodeFromFlyTree(ATreeView);
  //for i := 0 to ATreeView.Items.Count - 1 do
  while Node <> nil do
  begin
    //Node := ATreeView.Items[i];
    if TObject(Node.Data) is TSCSComponent then
      if TSCSComponent(TObject(Node.Data)) = AComponent then
      begin
        Result := Node;
        Break; //// BREAK ////
      end;
    Node := Node.GetNext;
  end;
end;

function TF_MakeEditCrossConnection.GetComponentNodeFromTreeViewByWholeID(ATreeView: TFlyTreeViewPro; AWholeID: Integer): TFlyNode;
var
  i: Integer;
  Node: TFlyNode;
begin
  Result := nil;

  Node := GetFirstNodeFromFlyTree(ATreeView);
  //for i := 0 to ATreeView.Items.Count - 1 do
  while Node <> nil do
  begin
    //Node := ATreeView.Items[i];
    if TObject(Node.Data) is TSCSComponent then
      if TSCSComponent(TObject(Node.Data)).Whole_ID = AWholeID then
      begin
        Result := Node;
        Break; //// BREAK ////
      end;
    Node := Node.GetNext; 
  end;
end;

function TF_MakeEditCrossConnection.GetComponJoinedCount(AComponent: TSCSComponent): Integer;
begin
  Result := 0;
  {case AComponent.IsLine of
    biTrue:
    : ;
  end;}
end;

function TF_MakeEditCrossConnection.GetConnectedObjectsToObjectInPointObjectConfigurator(ASCSObject: TSCSCatalog): TSCSCatalogs;
var
  i: Integer;
  SCSCatalog: TSCSCatalog;
begin
  Result := TSCSCatalogs.Create(false);
  //if ASCSObject.ItemType = itSCSLine then
    Result.Add(FCatalog);

  for i := 0 to FConnectedLinesToPointObject.Count - 1 do
  begin
    SCSCatalog := FConnectedLinesToPointObject[i];
    if (SCSCatalog <> ASCSObject) then
      Result.Add(SCSCatalog);
  end;

  {case ASCSObject.ItemType of
    itSCSLine:
      Result.Add(FCatalog);
    itSCSConnector:
      for i := 0 to FConnectedLinesToPointObject.Count - 1 do
      begin
        SCSCatalog := FConnectedLinesToPointObject[i];
        if SCSCatalog <> ASCSObject then
          Result.Add(SCSCatalog);
      end;
  end;}
end;

function TF_MakeEditCrossConnection.GetDataListFromGroupComponsPanelByTree(ATree: TFlyTreeViewPro): TList;
var
  GroupComponsPanel: TGroupComponsPanel;
begin
  Result := nil;
  GroupComponsPanel := GetGroupComponsPanelByTree(ATree, false);
  if GroupComponsPanel <> nil then
    Result := GetTreeViewDataListFly(GroupComponsPanel.Tree);
end;

function TF_MakeEditCrossConnection.GetEmptyPositionsFromInterfInfo(AInterfInfo: TInterfInfo): TSCSInterfPositions;
var
  PosTo: Integer;
  KolvoFromPos: Integer;
begin
  Result := nil;
  if (AInterfInfo.PosFrom = 0) and (AInterfInfo.PosTo = 0) then
    Result := AInterfInfo.FInterface.GetEmptyPositions(AInterfInfo.KolvoToConnect)
  else
  if (AInterfInfo.PosFrom > 0) and (AInterfInfo.PosTo > 0) then
  begin
    Result := AInterfInfo.FInterface.GetEmptyPositions;
    PosTo := AInterfInfo.PosTo;
    KolvoFromPos := AInterfInfo.PosTo - (AInterfInfo.PosFrom-1);
    if AInterfInfo.KolvoToConnect < KolvoFromPos then
      PosTo := (AInterfInfo.PosFrom-1) + AInterfInfo.KolvoToConnect;
    PrepareInterfPositionsByRegion(Result, AInterfInfo.PosFrom, PosTo);
  end;
end;

function TF_MakeEditCrossConnection.GetImageStateIndex(AIndex: Integer): Integer;
begin
  //Result := FImageCountBeforeState + AIndex;
  Result := -1;
  case AIndex of
    nsiAttention:
      Result := STATE_CHECKED;
    nsiEmpty:
      Result := STATE_UNCHECKED;
  end;
  //if AIndex <> -1 then
  //  Result := FImageCountBeforeState + AIndex;
end;

function TF_MakeEditCrossConnection.GetFocusedTreeView: TFlyTreeViewPro;
begin
  Result := nil;
  if ActiveControl <> nil then
    if ActiveControl is TFlyTreeViewPro then
    begin
      Result := TFlyTreeViewPro(ActiveControl);
    end;
end;

function TF_MakeEditCrossConnection.GetGroupComponsPanelByTree(ATree: TFlyTreeViewPro; AWithCreate: Boolean): TGroupComponsPanel;
var
  GroupComponsPanel: TGroupComponsPanel;
  i: integer;
begin
  Result := nil;
  if ATree <> nil then
  begin
    for i := 0 to FGroupComponsPanelList.Count - 1 do
    begin
      GroupComponsPanel := TGroupComponsPanel(FGroupComponsPanelList[i]);
      if GroupComponsPanel.TreeOwner = ATree then
      begin
        Result := GroupComponsPanel;
        Break; //// BREAK ////
      end;
    end;

    if Result = nil then
      if AWithCreate then
      begin
        Result := TGroupComponsPanel.Create(ATree, Self);
        Result.OnUserClose := OnCloseGroupComponsPanel;
        FGroupComponsPanelList.Add(Result);

        XPMenu.Active := false;
        XPMenu.Active := true;
      end;
  end;
end;

function TF_MakeEditCrossConnection.GetInterfInfoFromNode(ANode: TFlyNode): TInterfInfo;
begin
  Result := nil;
  if ANode <> nil then
    if ANode.Data <> nil then
      if TObject(ANode.Data) is TInterfInfo then
        Result := TInterfInfo(ANode.Data);
end;

function TF_MakeEditCrossConnection.GetInterfInfoFromOtherSide(ACrossNode: TFlyNode; AInterfInfo: TInterfinfo; AIsBusy: Integer=-1): TInterfinfo;
var
  Node: TFlyNode;
  NodeInterfInfo: TInterfinfo;
  PreRes: TInterfinfo;
begin
  Result := nil;
  PreRes := nil; // Результат на тот случай если не найдем пустой интерфейс именно с другой стороны
  Node := ACrossNode.getFirstChild;
  while Node <> nil do
  begin
    if TObject(Node.Data) is TInterfinfo then
    begin
      NodeInterfInfo := TInterfinfo(Node.Data);
      if (AIsBusy = -1) or (NodeInterfInfo.IsBusy = AIsBusy) then
      begin
        if PreRes = nil then
          PreRes := NodeInterfInfo;
        if AInterfInfo.FInterface.InternalConnected.IndexOf(NodeInterfInfo.FInterface) <> -1 then
        begin
          Result := NodeInterfInfo;
          Break; //// BREAK ////
        end;
      end;
    end;
    Node := Node.GetNextSibling;
  end;
  if Result = nil then
    Result := PreRes;
end;

function TF_MakeEditCrossConnection.GetInterfInfoFromTree(ATreeView: TFlyTreeViewPro): TInterfInfo;
begin
  Result := nil;
  if ATreeView.Selected <> nil then
    Result := GetInterfInfoFromNode(ATreeView.Selected);
end;

function TF_MakeEditCrossConnection.GetInterfInfoListFromTree(ATreeView: TFlyTreeViewPro): TRapList;
var
  SelectedNode: TFlyNode;
begin
  Result := TRapList.Create;

  SelectedNode := ATreeView.Items.GetFirstSelectedNode;
  while SelectedNode <> nil do
  begin
    if SelectedNode.Data <> nil then
      Result.Add(SelectedNode.Data);
    SelectedNode := ATreeView.Items.GetNextSelectedNode(SelectedNode);
  end;
end;

function TF_MakeEditCrossConnection.GetInterfacesFromInterfInfoList(AInterfInfoList: TRapList; AAndFromSiblingNodes: Boolean): TSCSInterfaces;
var
  i: Integer;
  Interfinfo: TInterfInfo;
  InterfinfoFromNode: TInterfInfo;
  StartNode: TFlyNode;
  Node: TFlyNode;
begin
  Result := TSCSInterfaces.Create(false);
  for i := 0 to AInterfInfoList.Count - 1 do
  begin
    Interfinfo := TInterfInfo(AInterfInfoList[i]);
    if Result.IndexOf(Interfinfo.FInterface) = -1 then
    begin
      Result.Add(Interfinfo.FInterface);

      if AAndFromSiblingNodes then
        if Interfinfo.FNode <> nil then
        begin
          StartNode := Interfinfo.FNode;
          Node := GetTreeViewFirstSiblingNodeFly(Interfinfo.FNode);

          //*** Пройтись по выделенным ветвям
          while Node <> nil do
          begin
            if Node.Selected then
            begin
              InterfinfoFromNode := TInterfInfo(Node.Data);
              if Result.IndexOf(InterfinfoFromNode.FInterface) = -1 then
                Result.Add(InterfinfoFromNode.FInterface);
            end;
            Node := Node.GetNextSibling;
          end;

          // Пройтись по остальным не выделенным ветвям? рассматривая ветвь StartNode как начальную
          Node := StartNode;
          while Node <> nil do
          begin
            if Not Node.Selected then
            begin
              InterfinfoFromNode := TInterfInfo(Node.Data);
              if Result.IndexOf(InterfinfoFromNode.FInterface) = -1 then
                Result.Add(InterfinfoFromNode.FInterface);
            end;
            Node := Node.GetNextSibling;
            if Node = nil then
              Node := GetTreeViewFirstSiblingNodeFly(StartNode);
            if Node = StartNode then
              Node := nil;
          end;
        end;
    end;
  end;
end;

function TF_MakeEditCrossConnection.GetJoinedInterfInfoFromTree(AInterfInfo: TInterfInfo;
  ATreeView: TFlyTreeViewPro): TRapList;
var
  i: Integer;
  Node: TFlyNode;
  InterfInfo: TInterfInfo;
begin
  Result := TRapList.Create;
  // Просмотреть выделенные
  Node := ATreeView.Items.GetFirstSelectedNode;
  while Node <> nil do
  begin
    InterfInfo := TInterfInfo(Node.Data);
    if InterfInfo.FInterface.ConnectedInterfaces.IndexOf(AInterfInfo.FInterface) <> -1 then
      Result.Add(InterfInfo);
    Node := ATreeView.Items.GetNextSelectedNode(Node);
  end;

  // Если среди выделенного нет ничего, то смотрим что есть
  if Result.Count = 0 then
  begin
    Node := GetFirstNodeFromFlyTree(ATreeView);
    while Node <> nil do
    begin
      InterfInfo := TInterfInfo(Node.Data);
      if InterfInfo.FInterface.ConnectedInterfaces.IndexOf(AInterfInfo.FInterface) <> -1 then
      begin
        Result.Add(InterfInfo);
      end;
      Node := Node.GetNext;
    end;
  end;
end;


function TF_MakeEditCrossConnection.GetJoinedInterfInfoFromObjectTreeFirst(AInterfInfo: TInterfInfo; ATreeView: TFlyTreeViewPro): TInterfInfo;
var
  Node: TFlyNode;
begin
  Result := nil;
  Node := GetFirstNodeFromFlyTree(ATreeView);
  while Node <> nil do
  begin
    if CheckJoinedInterfInfoWithNode(Node, AInterfInfo, nil) then
    begin
      Result := TInterfInfo(Node.Data);
      Break; //// BREAK ////
    end;
    Node := Node.GetNext;
  end;
end;

function TF_MakeEditCrossConnection.GetJoinedInterfInfoFromParentNode(ANode: TFlyNode; AInterfInfo, ASkipInterfInfo: TInterfInfo): TInterfInfo;
var
  Node: TFlyNode;

  //function CheckNode(ANode: TFlyNode): Boolean;
  //var
  //  NodeInterfInfo: TInterfInfo;
  //begin
  //  Result := false;
  //  if TObject(ANode.Data) is TInterfInfo then
  //  begin
  //    NodeInterfInfo := TInterfInfo(ANode.Data);
  //    if (NodeInterfInfo <> ASkipInterfInfo) and (AInterfInfo.IsBusy = NodeInterfInfo.IsBusy) then
  //      if (AInterfInfo.IsBusy = biFalse) or CheckJoinedInterfInfos(NodeInterfInfo, AInterfInfo) then
  //        Result := true;
  //  end;
  //end;

begin
  Result := nil;
  if CheckJoinedInterfInfoWithNode(ANode, AInterfInfo, ASkipInterfInfo) then
    Result := TInterfInfo(ANode.Data)
  else
  begin
    Node := ANode.getFirstChild;
    while Node <> nil do
    begin
      if CheckJoinedInterfInfoWithNode(Node, AInterfInfo, ASkipInterfInfo) then
      begin
        Result := TInterfInfo(Node.Data);
        Break; //// BREAK ////
      end;
      Node := Node.GetNextSibling;
    end;
  end;
end;

function TF_MakeEditCrossConnection.GetObjectFromNode(ANode: TFlyNode; const AWithClassName: String): TObject;
var
  NodeObject: TObject;
begin
  Result := nil;
  if Assigned(ANode) then
  begin
    NodeObject := TObject(ANode.Data);
    if (AWithClassName = '' ) or (NodeObject.ClassName = AWithClassName) then
      Result := NodeObject;
  end;
end;

function TF_MakeEditCrossConnection.GetObjectFromTreeView(ATreeView: TFlyTreeViewPro; const AWithClassName: String): TObject;
var
  NodeObject: TObject;
begin
  Result := nil;
  if Assigned(ATreeView) then
    Result := GetObjectFromNode(ATreeView.Selected, AWithClassName);
end;

function TF_MakeEditCrossConnection.GetObjectFromFocusedTreeView: TObject;
var
  FocusedTree: TFlyTreeViewPro;
begin
  Result := nil;
  FocusedTree := GetFocusedTreeView;
  if FocusedTree <> nil then
    Result := GetObjectFromTreeView(FocusedTree, '');
end;

function TF_MakeEditCrossConnection.GetTopComponNode(ACurrNode: TFlyNode): TFlyNode;
var
  CurrNode: TFlyNode;
begin
  Result := nil;
  CurrNode := ACurrNode;
  while CurrNode <> nil do
  begin
    if GetComponentFromNode(CurrNode) <> nil then
      Result := CurrNode;
    CurrNode := CurrNode.Parent;
  end;
end;

function TF_MakeEditCrossConnection.GetTopObjectFromNodeByClassName(ACurrNode: TFlyNode; AClassName: String): TObject;
var
  CurrNode: TFlyNode;
  ObjectFromNode: TObject;
begin
  Result := nil;
  CurrNode := ACurrNode;
  while CurrNode <> nil do
  begin
    ObjectFromNode := GetObjectFromNode(CurrNode, AClassName);
    if ObjectFromNode <> nil then
    begin
      Result := ObjectFromNode;
      Break; //// BREAK ////
    end;
    CurrNode := CurrNode.Parent;
  end;
end;

function TF_MakeEditCrossConnection.IsThroughConfiguratorMode: Boolean;
begin
  Result := false;
  if FFormMode in [fmCrossConfigurator, fmCableConfigurator] then
    Result := true;
end;

function TF_MakeEditCrossConnection.IsConfiguratorMode: Boolean;
begin
  Result := false;
  if FFormMode in [fmCrossConfigurator, fmCableConfigurator, fmPointObjectConfigurator] then
    Result := true;
end;

function TF_MakeEditCrossConnection.JoinInterfInfos(AInterfInfo1, AInterfInfo2: TInterfInfo;
  AInterfList1, AInterfList2: TSCSInterfaces): Boolean;
var
  InterfList1, InterfList2: TSCSInterfaces;
  Component1, Component2: TSCSComponent;

  CheckInterfRes: TCheckInterfForUnionResult;
  ConnectKind: TConnectKind;
  InterfCount1, InterfCount2: Integer;

  EmptyPositions1: TSCSInterfPositions;
  EmptyPositions2: TSCSInterfPositions;

  TempInterfaces1: TSCSInterfaces;
  TempInterfaces2: TSCSInterfaces;

  ptrConnection: PComplect;
begin
  Result := false;
  if Assigned(AInterfInfo1) and Assigned(AInterfInfo2) then
  begin
    InterfList1 := AInterfList1;
    InterfList2 := AInterfList2;
    if InterfList1 = nil then
    begin
      InterfList1 := TSCSInterfaces.Create(false);
      InterfList1.Add(AInterfInfo1.FInterface);
    end;
    if InterfList2 = nil then
    begin
      InterfList2 := TSCSInterfaces.Create(false);
      InterfList2.Add(AInterfInfo2.FInterface);
    end;

    Component1 := AInterfInfo1.FInterface.ComponentOwner;
    Component2 := AInterfInfo2.FInterface.ComponentOwner;

    ConnectKind := GetConnectKindByConnectionCompons(Component1, Component2, cntUnion);
    // В проверке пропускаем проверку на подключенность интерфейсов
    CheckInterfRes := CheckInterfForUnion(AInterfInfo1.FInterface, AInterfInfo2.FInterface,
                          GForm, GForm, {ConnectKind, }cntUnion, @InterfCount1, @InterfCount2,
                          [ciueInterfConnected]);
    if CheckInterfRes = chrSuccess then
    begin
      EmptyPositions1 := GetEmptyPositionsFromInterfInfo(AInterfInfo1);
      EmptyPositions2 := GetEmptyPositionsFromInterfInfo(AInterfInfo2);

      if (EmptyPositions1 <> nil) and (EmptyPositions2 <> nil) then
        if (EmptyPositions1.Kolvo > 0) and (EmptyPositions2.Kolvo > 0) then
        begin
          // Если компоненті не подключені, то подключить их нах
          if Component1.JoinedComponents.IndexOf(Component2) = -1 then
          begin
            TempInterfaces1 := TSCSInterfaces.Create(false);
            TempInterfaces2 := TSCSInterfaces.Create(false);
            if TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(Component1, Component2, false, TempInterfaces1, TempInterfaces2, true).CanConnect then
              Result := true;

            FreeAndNil(TempInterfaces1);
            FreeAndNil(TempInterfaces2);
          end;

          if Component1.JoinedComponents.IndexOf(Component2) <> -1 then
          begin
            ptrConnection := Component1.GetConnectionByConnected(Component2);
            if ptrConnection <> nil then
            begin
              TF_Main(GForm).ConnectInterfacesWithAccordance(AInterfInfo1.FInterface, AInterfInfo2.FInterface,
                  InterfCount1, InterfCount2, ptrConnection.ID, cntUnion,
                  EmptyPositions1, EmptyPositions2, true, InterfList1, InterfList2);

              TF_Main(GForm).F_ChoiceConnectSide.OnAfterJoinCompons(Component1, Component2, -1, -1);

              Result := true;
            end;
          end;
        end;

      if EmptyPositions1 <> nil then
        FreeAndNil(EmptyPositions1);
      if EmptyPositions2 <> nil then
        FreeAndNil(EmptyPositions2);
    end;

    if AInterfList1 = nil then
      InterfList1.Free;
    if AInterfList2 = nil then
      InterfList2.Free;
  end;
end;

procedure TF_MakeEditCrossConnection.LoadComponInterfacesToTreeView(AComponentSide1, AComponentSide2: TSCSComponent;
  ACompon1InterfSide, ACompon2InterfSide: Integer; ATreeViewSide1, ATreeViewSide2: TFlyTreeViewPro);

  (*function AddInterfInfoToTree(AInterf: TSCSInterface; AInterfName: String; AIsBusy, AKolvo: Integer;
    AParentNode: TFlyNode; ATreeView: TFlyTreeViewPro; APosFrom, APosTo: Integer): TFlyNode;
  var
    InterfNode: TFlyNode;
    InterfInfo: TInterfInfo;
    ConnectedIDs: String;
    ImageIndex: Integer;
    NodeText: String;
    i: Integer;
  begin
    Result := nil;
    InterfNode := nil;

    NodeText := AInterfName;
    {$IF Not Defined (FINAL_SCS)}
      ConnectedIDs := '';
      for i := 0 to AInterf.ConnectedInterfaces.Count - 1 do
      begin
        if ConnectedIDs <> '' then
          ConnectedIDs := ConnectedIDs + ', '
        else
          ConnectedIDs := '->';
        ConnectedIDs := ConnectedIDs + IntToStr(AInterf.ConnectedInterfaces[i].ID);
      end;
      NodeText := NodeText + ' (ID '+IntToStr(AInterf.ID)+ConnectedIDs+';'+IntToStr(APosFrom)+'-'+IntToStr(APosTo)+
          '; Side '+IntToStr(AInterf.Side)+'; ComponID '+IntToStr(AInterf.ComponentOwner.ID)+'; Busy '+BoolToStr(AIsBusy = biTrue)+')';
    {$IFEND}

    ImageIndex := -1;
    if AIsBusy = biTrue then
      ImageIndex := tciiInterfaceFill
    else
    if AIsBusy = biFalse then
      ImageIndex := tciiInterfaceNoFill;

    InterfInfo := TInterfInfo.Create(AInterf);
    InterfInfo.IsBusy := AIsBusy;
    InterfInfo.Kolvo := AKolvo;
    InterfInfo.KolvoToConnect := AKolvo;
    InterfInfo.ImageIndex := ImageIndex;
    InterfInfo.PosFrom := APosFrom;
    InterfInfo.PosTo := APosTo;

    //if AParentNode <> nil then
    //  InterfNode := ATreeView.Items.AddChild(AParentNode, AInterfName)
    //else
    //  InterfNode := ATreeView.Items.Add(nil, AInterfName);

    if AParentNode <> nil then
      InterfNode := ATreeView.Items.AddChildObject(AParentNode, NodeText, InterfInfo)
    else
      InterfNode := ATreeView.Items.AddObject(nil, NodeText, InterfInfo);

    InterfInfo.FNode := InterfNode;
    Result := InterfNode;

    if InterfNode <> nil then
    begin
      InterfNode.ImageIndex := ImageIndex;
      InterfNode.SelectedIndex := InterfNode.ImageIndex;
      InterfNode.StateIndex := -1;
      InterfNode.Cells[ciKolvo] := IntToStr(AKolvo);
      if AIsBusy = biTrue then
        InterfNode.Cells[ciKolvoToConnect] := ''
      else
        InterfNode.Cells[ciKolvoToConnect] := IntToStr(AKolvo); //IntToStr(AInterf.Side);
      //InterfNode.Cells[ciColor] := IntToStr(AInterf.Color);
      if AInterf.Side = 0 then
        InterfNode.Cells[ciSide] := ''
      else
        InterfNode.Cells[ciSide] := IntToStr(AInterf.Side);

      //InterfNode.Data := InterfInfo;
    end;
  end;*)

  procedure AddinterfToTreeByBusyKolvo(AInterf: TSCSInterface; AName: String; ATreeView: TFlyTreeViewPro);
  begin
    if AInterf.KolvoBusy = 0 then
    begin
      AddInterfInfoToTree(AInterf, AName, biFalse, AInterf.Kolvo, nil, ATreeView, 0, 0);
    end
    else
    if AInterf.KolvoBusy >= AInterf.Kolvo then
    begin
      if AInterf.Multiple = biFalse then
        AddInterfInfoToTree(AInterf, AName, biTrue, AInterf.Kolvo, nil, ATreeView, 0, 0)
      else
      //Если многократный интерфейс занят полностю, то отображаем кол-во занятых + один свободен
      begin
        AddInterfInfoToTree(AInterf, AName, biTrue, AInterf.KolvoBusy, nil, ATreeView, 0, 0);
        //AddInterfInfoToTree(AInterf, AName, biFalse, AInterf.Kolvo, nil, ATreeView, 0, 0);
      end;
    end
    else
    if (AInterf.KolvoBusy > 0) and (AInterf.KolvoBusy < AInterf.Kolvo) then
    begin
      AddInterfInfoToTree(AInterf, AName, biFalse, AInterf.Kolvo - AInterf.KolvoBusy, nil, ATreeView, 0, 0);
      AddInterfInfoToTree(AInterf, AName, biTrue, AInterf.KolvoBusy, nil, ATreeView, 0, 0);
    end;
    {else
    // Если многократный интерфейс занят полностю, то отображаем кол-во занятых + один свободен
    if (AInterf.KolvoBusy > 0) and ((AInterf.KolvoBusy >= AInterf.Kolvo) and (AInterf.Multiple = biTrue)) then
    begin
      AddInterfInfoToTree(AInterf, AName, biTrue, AInterf.KolvoBusy, nil, ATreeView, 0, 0);
      AddInterfInfoToTree(AInterf, AName, biFalse, AInterf.Kolvo, nil, ATreeView, 0, 0);
      //AddInterfInfoToTree(AInterf, AName, biFalse, AInterf.Kolvo - AInterf.KolvoBusy, nil, ATreeView, 0, 0);
    end;}
  end;

  procedure AddComponIntrerfToTree(ACompon: TSCSComponent; AComponInterfSide: Integer; ATreeView: TFlyTreeViewPro);
  var
    i, j, k, l: Integer;
    Port, PortI, PortJ: TSCSInterface;
    PortInterfRel: PPortInterfRel;
    Interf: TSCSInterface;

    PortNum: Integer;
    PortIsBusy: Integer;
    PortNode: TFlyNode;

    CurrInterfFrom: Integer;
    CurrInterfTo: Integer;
    InterfIsBusy: Integer;
    PrevInterfIsBusy: Integer;
    SameInterfCount: Integer; // косличество одинаковых интерфейсов

    PortList: TSCSInterfaces;
    LookedPortInterfaces: TSCSInterfaces;
    // Tolik -- 16/07/2016  -- чтобы интерфейсы в конфигураторе отображались согласно порядкового номера
    PortInterfRel1: PPortInterfRel;
    DirectOrder: Boolean; // в каком порядке загружать интерфейсы портов -- напрямую или задом наперед,
                          // а то после каждого сейва в конфигураторе порядок портов меняется задом наперед
    procedure LoadPortInterfaceToTreeByOrder(aIndex: Integer );
    var l : Integer;
    begin
      PortInterfRel := Port.PortInterfRels.List^[aIndex];
      if PortInterfRel.RelType = rtPortInterfRel then
      begin
        if PortInterfRel.Interf = nil then
          PortInterfRel.Interf := ACompon.GetInterfaceByID(PortInterfRel.IDInterfRel);
        if PortInterfRel.Interf <> nil then
        begin
          LookedPortInterfaces.Add(PortInterfRel.Interf);

          //CurrInterfFrom := (j+1) * PortInterfRel.UnitInterfKolvo;
          CurrInterfFrom := (j * PortInterfRel.UnitInterfKolvo) + 1;
          CurrInterfTo := CurrInterfFrom + PortInterfRel.UnitInterfKolvo - 1;

          // Занятые и свободные позиции отдельно
          InterfIsBusy := biNone;
          SameInterfCount := 0;
          for l := CurrInterfFrom to CurrInterfTo do
          begin
            PrevInterfIsBusy := InterfIsBusy;

            InterfIsBusy := BoolToInt(CheckNumInPositionList(l, PortInterfRel.Interf.BusyPositions));
            if PrevInterfIsBusy = biNone then
              SameInterfCount := 1
            else
            if (InterfIsBusy <> PrevInterfIsBusy) and (SameInterfCount > 0) then
            begin
              AddInterfInfoToTree(PortInterfRel.Interf, PortInterfRel.Interf.LoadName, PrevInterfIsBusy, SameInterfCount, PortNode, ATreeView, (l-SameInterfCount), l-1);
              SameInterfCount := 1;
            end
            else
            if InterfIsBusy = PrevInterfIsBusy then
              SameInterfCount := SameInterfCount + 1;
          end;
          if SameInterfCount > 0 then
            AddInterfInfoToTree(PortInterfRel.Interf, PortInterfRel.Interf.LoadName, InterfIsBusy, SameInterfCount, PortNode, ATreeView, (CurrInterfTo-SameInterfCount)+1, CurrInterfTo);

        end;
      end;
    end;
  begin
    ClearTreeViewFly(ATreeView, false, true);

    if ACompon <> nil then
    begin
      LookedPortInterfaces := TSCSInterfaces.Create(false);
      PortList := TSCSInterfaces.Create(false);

      // Составляем список портов
      for i := 0 to ACompon.Interfaces.Count - 1 do
      begin
        Port := ACompon.Interfaces[i];
        if Port.IsPort = biTrue then
          if (Port.Side = 0) or (Port.Side = AComponInterfSide) then
            PortList.Add(Port);
      end;
      // Сортируем порты по номеру порта
      for i := 0 to PortList.Count - 1 do
      begin
        PortI := PortList[i];
        for j := i to PortList.Count - 1 do
        begin
          PortJ := PortList[j];
          if PortJ.NppPort < PortI.NppPort then
          begin
            ExchangeObjects(PortI, PortJ);
            PortList[i] := PortI;
            PortList[j] := PortJ;
          end;
        end;
      end;  
      // Вкидка портов с интерфейсами в дерево
      for i := 0 to PortList.Count - 1 do
      begin
        Port := PortList[i];

        if Port.IsPort = biTrue then
          if (Port.Side = 0) or (Port.Side = AComponInterfSide) then
          begin
            if Port.PortInterfRels.Count = 0 then
            begin
              //if Port.Kolvo = 1 then
              //  AddinterfToTreeByBusyKolvo(Port, Port.Name, ATreeView)
              //else
              //if Port.Kolvo > 1 then
              //  AddinterfToTreeByBusyKolvo(Port, Port.Name + IntToStr(Port.NppPort)+'-'+IntToStr(Port.NppPort+Port.Kolvo-1), ATreeView);
              AddinterfToTreeByBusyKolvo(Port, GetPortCaption(Port), ATreeView)
            end
            else
            // Если на портах есть интерфейсы, то разгруппировать эти порты
            for j := 0 to Port.Kolvo - 1 do
            begin
              PortNum := Port.NppPort + j;
              PortIsBusy := biFalse;
              if CheckNumInPositionList(j+1, Port.BusyPositions) then
                PortIsBusy := biTrue
              else
                PortIsBusy := biFalse;
              // Добавить порт в дерево
              //PortNode := AddInterfInfoToTree(Port, Port.LoadName + IntToStr(PortNum), PortIsBusy, 1, nil, ATreeView, j+1, j+1);
              PortNode := AddInterfInfoToTree(Port, GetPortCaption(Port, PortNum), PortIsBusy, 1, nil, ATreeView, j+1, j+1);
              // Добавить интерфейсы порта в дерево

              // Tolik -- 16/07/2016 --
              DirectOrder := True;
              if Port.PortInterfRels.Count > 1 then
              begin
                PortInterfRel := Port.PortInterfRels.List^[0];
                PortInterfRel1 := Port.PortInterfRels.List^[Port.PortInterfRels.Count - 1];
                if (PortInterfRel.RelType = rtPortInterfRel) and (PortInterfRel1.RelType = rtPortInterfRel) then
                begin
                  if (PortInterfRel.Interf <> nil) and (PortInterfRel1.Interf <> nil) then
                  begin
                    if PortInterfRel.Interf.Npp > PortInterfRel1.Interf.Npp then
                      DirectOrder := False;
                  end;
                end;
              end;

              if DirectOrder then
                for k := 0 to Port.PortInterfRels.Count - 1 do
                  LoadPortInterfaceToTreeByOrder(k)
              else
                if not DirectOrder then
                  for k := (Port.PortInterfRels.Count - 1) downto 0 do
                    LoadPortInterfaceToTreeByOrder(k);
              // -- Tolik -- так было, оставил для истории (на всякий)
              
              {for k := 0 to Port.PortInterfRels.Count - 1 do
              begin
                PortInterfRel := Port.PortInterfRels.List^[k];
                if PortInterfRel.RelType = rtPortInterfRel then
                begin
                  if PortInterfRel.Interf = nil then
                    PortInterfRel.Interf := ACompon.GetInterfaceByID(PortInterfRel.IDInterfRel);
                  if PortInterfRel.Interf <> nil then
                  begin
                    LookedPortInterfaces.Add(PortInterfRel.Interf);

                    //CurrInterfFrom := (j+1) * PortInterfRel.UnitInterfKolvo;
                    CurrInterfFrom := (j * PortInterfRel.UnitInterfKolvo) + 1;
                    CurrInterfTo := CurrInterfFrom + PortInterfRel.UnitInterfKolvo - 1;

                    // Занятые и свободные позиции отдельно
                    InterfIsBusy := biNone;
                    SameInterfCount := 0;
                    for l := CurrInterfFrom to CurrInterfTo do
                    begin
                      PrevInterfIsBusy := InterfIsBusy;

                      InterfIsBusy := BoolToInt(CheckNumInPositionList(l, PortInterfRel.Interf.BusyPositions));
                      if PrevInterfIsBusy = biNone then
                        SameInterfCount := 1
                      else
                      if (InterfIsBusy <> PrevInterfIsBusy) and (SameInterfCount > 0) then
                      begin
                        AddInterfInfoToTree(PortInterfRel.Interf, PortInterfRel.Interf.LoadName, PrevInterfIsBusy, SameInterfCount, PortNode, ATreeView, (l-SameInterfCount), l-1);
                        SameInterfCount := 1;
                      end
                      else
                      if InterfIsBusy = PrevInterfIsBusy then
                        SameInterfCount := SameInterfCount + 1;
                    end;
                    if SameInterfCount > 0 then
                      AddInterfInfoToTree(PortInterfRel.Interf, PortInterfRel.Interf.LoadName, InterfIsBusy, SameInterfCount, PortNode, ATreeView, (CurrInterfTo-SameInterfCount)+1, CurrInterfTo);

                    //Если многократный интерфейс занят полностю, то отображаем + один свободен
                    //if PortInterfRel.Interf.KolvoBusy >= PortInterfRel.Interf.Kolvo then
                    //  if PortInterfRel.Interf.Multiple = biTrue then
                    //    AddInterfInfoToTree(PortInterfRel.Interf, PortInterfRel.Interf.LoadName, biFalse, PortInterfRel.Interf.Kolvo, PortNode, ATreeView, 0, 0);
                  end;
                end;

              end;}
              SetCorrectImage(PortNode);
            end;
          end;
      end;

      // Интерфесы компоннента
      for i := 0 to ACompon.Interfaces.Count - 1 do
      begin
        Interf := ACompon.Interfaces[i];

        if Interf.TypeI = itFunctional then
          if Interf.IsPort = biFalse then
            if LookedPortInterfaces.IndexOf(Interf) = -1 then
              if (Interf.Side = 0) or (Interf.Side = AComponInterfSide) then
              begin
                AddinterfToTreeByBusyKolvo(Interf, Interf.LoadName, ATreeView);
              end;
      end;

      FreeAndNil(PortList);
      FreeAndNil(LookedPortInterfaces);
    end;
  end;


begin
  try
    AddComponIntrerfToTree(AComponentSide1, ACompon1InterfSide, ATreeViewSide1);
    AddComponIntrerfToTree(AComponentSide2, ACompon2InterfSide, ATreeViewSide2);

  except
    on E: Exception do AddExceptionToLogEx('TF_MakeEditCrossConnection.LoadComponInterfacesToTreeView', E.Message);
  end;
end;

procedure TF_MakeEditCrossConnection.LoadParamsToCrossConnectionRecord(ACrossConnection: TSCSCrossConnection;
  ASrcTreeView: TFlyTreeViewPro; var AIDCompRel, AIDCompon,
  AComponIndex: Integer; var AComponName: String);
var
  SCSComponent: TSCSComponent;
  ptrComplect: PComplect;
begin
  SCSComponent := nil;
  AIDCompRel := 0;
  AIDCompon := 0;
  AComponIndex := 0;
  AComponName := '';

  if Assigned(ASrcTreeView.Selected) then
    if ASrcTreeView.Selected.Data <> nil then
      SCSComponent := TSCSComponent(ASrcTreeView.Selected.Data);

  if Assigned(SCSComponent) then
  begin
    AIDCompon := SCSComponent.ID;
    AComponIndex := SCSComponent.ServCopyIndex;
    AComponName := SCSComponent.Name;

    ptrComplect := SCSComponent.LinkToComlectRec; //FSCSComponent.GetComplectByIDChild(SCSComponent.ID);
    if ptrComplect <> nil then
      AIDCompRel := ptrComplect.ID;
  end;
end;

procedure TF_MakeEditCrossConnection.lvFrom_Change(Sender: TObject;
  Item: TListItem; Change: TItemChange);
begin
  //lbFrom.Caption := IntToStr(TSCSComponent(Item.Data).LinkToComlectRec.ID);
end;

procedure TF_MakeEditCrossConnection.pnOkCancelResize(Sender: TObject);
begin
  SetMiddleControlChilds(TControl(Sender), TControl(Self));
end;

procedure TF_MakeEditCrossConnection.tvWith__Change(Sender: TObject;
  Node: TTreeNode);
var
  NodeObject: TObject;
  SCSCatalog: TSCSCatalog; 
  SCSComponent: TSCSComponent;
  SCSCable: TSCSComponent;
  SCSPort: TSCSinterface;
  PortFromPointComponent: TSCSinterface;
  PortFromSecondPointComponent: TSCSinterface;
  CrossInterf: TSCSinterface;
  CrossInterfFrom: TSCSinterface;
  CrossInterfTo: TSCSinterface;
  JoinedComponent: TSCSComponent;
  JoinedInterface: TSCSInterface;
  ComponentsFromTraces: TSCSComponents;
  CrossComponent: TSCSComponent;
  PointComponent: TSCSComponent;
  PointChildComponent: TSCSComponent;
  PointOwnerComponent: TSCSCatalog;
  PointTopComponent: TSCSComponent;
  SecondPointComponent: TSCSComponent;
  SecondPointObject: TSCSCatalog;
  SecontLineSideComponent: TSCSComponent;
  ComponFrom: TSCSComponent;
  ComponTo: TSCSComponent;
  //LineComponFrom: TSCSComponent;
  //LineComponTo: TSCSComponent;
  //IDConnObj1: Integer;
  //IDConnObj2: Integer;
  //IDConnObjTmp1: Integer;
  //IDConnObjTmp2: Integer;
  //IDLineObjFrom: Integer;
  //IDLineObjTo: Integer;
  //ObjLineFrom: TSCSCatalog;
  //ObjLineTo: TSCSCatalog;
  ObjJoinedConnFrom: TSCSCatalog;
  ObjJoinedConnTo: TSCSCatalog;

  //ObjTmp: TSCSCatalog;
  CanExchPoinObjectsByInterfCount: Boolean;
  ConnectedPointObjects: TSCSCatalogs;
  ConnectedPointObject: TSCSCatalog;

  ConnectedObjects: TSCSCatalogs;
  ConnectedObject: TSCSCatalog;

  tvFromPrevItemsCount: Integer;
  tvToNode: TTreeNode;
  tvToPrevNode: TTreeNode;
  tvToNodesToRemove: TObjectList;

  i, j: Integer;
  ImageIndex: Integer;
  CableNode: TTreeNode;
  CrossNode: TTreeNode;

  SCSComponNode: TTreeNode;
  PosOfTrunkComplect: Integer;
  Componentowner: TSCSCatalog;
begin
  //FIsHandlingtvWith := true;
//  FLineComponFromSide := nil;
//  FLineComponToSide := nil;
//  FPointComponentFrom := nil;
//  FPointComponentTo := nil;
//
//  SCSCatalog := nil;
//  SCSComponent := nil;
//  CrossComponent := nil;
//  PointComponent := nil;
//  SecondPointObject := nil;
//  SecondPointComponent := nil;
//  SecontLineSideComponent := nil;
//  SCSPort := nil;
//  CrossInterfFrom := nil;
//  CrossInterfTo := nil;
//
//  tvFrom.Items.BeginUpdate;
//  tvTo.Items.BeginUpdate;
//  try
//    tvFrom.OnChange := nil;
//    try
//      tvFromPrevItemsCount := tvFrom.Items.Count;
//      tvFrom.Items.Clear;
//    finally
//      tvFrom.OnChange := tvFromChange;
//    end;
//
//    if Not((FFormMode = fmCableConfigurator) and (rbSelectByPoint.Checked)) then
//      tvTo.Items.Clear;
//
//    NodeObject := nil;
//    if Assigned(Node) then
//      if Node.Data <> nil then
//      begin
//        NodeObject := TSCSComponent(Node.Data);
//        if NodeObject is TSCSCatalog then
//          SCSCatalog := TSCSCatalog(NodeObject);
//        if NodeObject is TSCSComponent then
//          SCSComponent := TSCSComponent(NodeObject);
//        if NodeObject is TSCSInterface then
//          SCSPort := TSCSInterface(NodeObject);
//      end;
//    //if Assigned(SCSComponent) or Assigned(SCSCatalog) then
//    //begin
//    //  SCSComponent := TSCSComponent(NodeObject);
//      ComponFrom := nil;
//      ComponTo := nil;
//      case FFormMode of
//        fmNBCrossConnection:
//          if Assigned(SCSComponent) then
//          begin
//            tvTo.Items.Clear;
//
//            CrossComponent := SCSComponent;
//            loadComponentsToCrossConnect(tvFrom, CrossComponent, FCrossConnection.IDCompRelFrom, FCrossConnection.NppFrom);
//            loadComponentsToCrossConnect(tvTo, CrossComponent, FCrossConnection.IDCompRelTo, FCrossConnection.NppTo);
//          end;
//        fmCrossConfigurator:
//          begin
//            tvTo.Items.Clear;
//            if rbSelectByLine.Checked and Assigned(SCSComponent) then  // патч-корд слева
//            begin
//              CrossComponent := SCSComponent;
//              if CrossComponent.JoinedComponents.Count > 0 then
//                for i := 0 to CrossComponent.Interfaces.Count - 1 do
//                begin
//                  CrossInterf := CrossComponent.Interfaces[i];
//                  if (CrossInterf.TypeI = itFunctional) and
//                     (CrossInterf.ConnectedInterfaces.Count > 0) then
//                  begin
//                    if CrossInterfFrom = nil then
//                      CrossInterfFrom := CrossInterf.ConnectedInterfaces[0]
//                    else
//                    if CrossInterfTo = nil then
//                      CrossInterfTo :=  CrossInterf.ConnectedInterfaces[0];
//                  end;
//                end;
//              LoadComponentsToCrossConfigurator(tvFrom, CrossComponent, CrossInterfFrom);
//              LoadComponentsToCrossConfigurator(tvTo, CrossComponent, CrossInterfTo);
//
//              {//**** ХУЙНЯ
//              if CrossComponent.JoinedComponents.Count > 0 then
//              begin
//                ComponFrom := CrossComponent.JoinedComponents[0];
//                if CrossComponent.JoinedComponents.Count > 1 then
//                  ComponTo := CrossComponent.JoinedComponents[1];
//              end;
//              LoadComponentsToCrossConfigurator(tvFrom, CrossComponent, ComponFrom);
//              LoadComponentsToCrossConfigurator(tvTo, CrossComponent, ComponTo);}
//            end
//            else
//            if rbSelectByPoint.Checked and Assigned(SCSPort) then
//            begin
//              PortFromPointComponent := SCSPort;
//              PortFromSecondPointComponent := nil;
//
//              PointComponent := SCSPort.ComponentOwner;
//              PointTopComponent := PointComponent.GetTopComponent;
//
//              //*** Найти/загрузить подключенный кросс
//              for i := 0 to SCSPort.ConnectedInterfaces.Count - 1 do
//              begin
//                CrossInterfFrom := SCSPort.ConnectedInterfaces[i];
//                if CrossInterfFrom.ComponentOwner.IsCrossComponent then
//                begin
//                  CrossComponent := CrossInterfFrom.ComponentOwner;
//                  ImageIndex := GetComponImageIndexByFilling(CrossComponent.IsLine, CrossComponent.GetFilling(biNone, itFunctional, false, false));
//                  CrossNode := AddComponentToTreeView(CrossComponent, ImageIndex, tvFrom, nil);
//                  if CrossNode <> nil then
//                    tvFrom.Selected := CrossNode;
//                  Break; ///// BREAK /////
//                end;
//              end;
//
//              //*** Найти второй подключенный порт
//              if CrossComponent <> nil then
//                for i := 0 to CrossComponent.Interfaces.Count - 1 do
//                begin
//                  CrossInterfTo := CrossComponent.Interfaces[i];
//                  if (CrossInterfTo <> CrossInterfFrom) and (CrossInterfTo.TypeI = itFunctional) then
//                    if CrossInterfTo <> PortFromPointComponent then
//                      for j := 0 to CrossInterfTo.ConnectedInterfaces.Count - 1 do
//                        if CrossInterfTo.ConnectedInterfaces[j] <> PortFromPointComponent then
//                        begin
//                          PortFromSecondPointComponent := CrossInterfTo.ConnectedInterfaces[j];
//                          SecondPointComponent := PortFromSecondPointComponent.ComponentOwner;
//                          Break; ///// BREAK /////
//                        end;
//                end;
//              //*** Загрузить кросс в дерево с подключенным портом на второй стороне
//              if SecondPointComponent <> nil then
//                LoadComponentsToCrossConfigurator(tvTo, CrossComponent, PortFromSecondPointComponent)
//              else //*** Загрузить сам шкаф
//                LoadComponentsToCrossConfigurator(tvTo, PointComponent, nil);
//
//
//              //*** Найти/загрузить недоподключенный/неподключенный кросс
//              for i := 0 to PointTopComponent.ChildReferences.Count - 1 do
//              begin
//                PointChildComponent := PointTopComponent.ChildReferences[i];
//                if PointChildComponent.IsCrossComponent then
//                  if PointChildComponent <> CrossComponent then
//                    if PointChildComponent.JoinedComponents.Count < 2 then
//                    begin
//                      ImageIndex := GetComponImageIndexByFilling(PointChildComponent.IsLine, PointChildComponent.GetFilling(biNone, itFunctional, false, false));
//                      AddComponentToTreeView(PointChildComponent, ImageIndex, tvFrom, nil);
//                    end;
//              end;
//            end;
//          end;
//        fmCableConfigurator:
//          if rbSelectByLine.Checked and Assigned(SCSComponent) then  // кабель слева
//          begin
//            tvTo.Items.Clear;
//            CrossComponent := SCSComponent;
//            
//            ObjJoinedConnFrom := nil;
//            ObjJoinedConnTo := nil;
//            //*** Определить точечные подсоединенные объекты ObjFrom и ObjTo
//            //with TF_Main(GForm) do
//            //begin
//              CrossComponent.LoadWholeComponent(false);
//              CrossComponent.DefineFirstLast;
//
//              DefinePointObjectsForLineCompon(CrossComponent, ObjJoinedConnFrom, ObjJoinedConnTo);
//
//              FLineComponFromSide := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(CrossComponent.FirstIDCompon);
//              FLineComponToSide := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(CrossComponent.LastIDCompon);
//
//              SendFirstLastIDsToPartComponent(CrossComponent, FLineComponFromSide);
//              SendFirstLastIDsToPartComponent(CrossComponent, FLineComponToSide);
//
//            //ComponFrom := CrossComponent.FirstConnectedConnCompon;
//            //ComponTo := CrossComponent.LastConnectedConnCompon;
//
//            //LoadComponentsToCableConfigurator(tvFrom, ComponFrom, ObjJoinedConnFrom, false);
//            //LoadComponentsToCableConfigurator(tvTo, ComponTo, ObjJoinedConnTo, false);
//
//            LoadComponentsToCableConfigurator(tvFrom, FLineComponFromSide, ObjJoinedConnFrom, false);
//            LoadComponentsToCableConfigurator(tvTo, FLineComponToSide, ObjJoinedConnTo, false);
//          end
//          else
//          if rbSelectByPoint.Checked and (Assigned(SCSComponent) or Assigned(SCSCatalog)) then
//          begin
//            //FCurrIDPointObject := -1;
//            //FCurrIDPointComponent := -1;
//            //tvToNodesToRemove := TObjectList.Create(false);
//            if Not Assigned(SCSCatalog) and Assigned(SCSComponent) then
//              SCSCatalog := SCSComponent.GetFirstParentCatalog;
//
//            PosOfTrunkComplect := -1;
//            if SCSComponent <> nil then
//              PosOfTrunkComplect := GetComponIdentificatorInComplex(SCSComponent);
//
//            //*** Подгрузить подключенные объекты на другой стороне
//            if Assigned(SCSCatalog) and (SCSCatalog.ID <> FCurrIDPointObject) then
//            begin
//              tvTo.Items.Clear;
//
//              ConnectedPointObjects := GetPointObjectsByConnectedFropmPointRelations(FPointFigureRelations, SCSCatalog);
//              SortSCSObjectsByPMOrder(ConnectedPointObjects);
//              for i := 0 to ConnectedPointObjects.Count - 1 do
//              begin
//                ConnectedPointObject := ConnectedPointObjects[i];
//                LoadComponentsToCableConfigurator(tvTo, nil, ConnectedPointObject, true);
//              end;
//              FreeAndNil(ConnectedPointObjects);
//              //SortConfiguratorTreeView(tvTo, true); Сортирует по имени
//              FCurrIDPointObject := SCSCatalog.ID;
//            end; {
//            else // Убрать ветви, объекты которых пренадлежат другим листам
//            if SCSCatalog.ID = FCurrIDPointObject then
//            begin
//              tvToNode := nil;
//              if tvTo.Items.Count > 0 then
//                tvToNode := GetTreeViewFirstTopNode(tvTo.Items[0]);
//              while tvToNode <> nil do
//              begin
//                tvToPrevNode := tvToNode;
//                tvToNode := tvToNode.getNextSibling;
//                if TObject(tvToPrevNode.Data) is TSCSCatalog then
//                  if TSCSCatalog(TObject(tvToPrevNode.Data)).ListID <> SCSCatalog.ListID then
//                    tvToNodesToRemove.Add(tvToPrevNode); //tvToPrevNode.Delete;
//              end;
//            end; }
//
//            if Assigned(SCSComponent) then
//            begin
//              FPointComponentFrom := SCSComponent;
//
//              PointComponent := SCSComponent;
//              CableNode := nil;
//
//              //*** Добавить подключенные линейные компоненты
//              for i := 0 to PointComponent.JoinedComponents.Count - 1 do
//              begin
//                JoinedComponent := PointComponent.JoinedComponents[i];
//                if JoinedComponent.IsLine = biTrue then
//                begin
//                  ImageIndex := GetComponImageIndexByFilling(JoinedComponent.IsLine, JoinedComponent.GetFilling(biNone, itFunctional, true, false), true);
//                  CableNode := AddComponentToTreeView(JoinedComponent, ImageIndex, tvFrom, nil);
//                  //LoadConnectedLineComponentsToLine(tvFrom, JoinedComponent, CableNode);
//
//                  {if CableNode <> nil then
//                  begin
//                    tvFrom.OnChange := nil;
//                    try
//                      tvFrom.Selected := CableNode;
//                    finally
//                      tvFrom.OnChange := tvFromChange;
//                    end;
//                  end;}
//
//                  JoinedComponent.LoadWholeComponent(false);
//                  JoinedComponent.DefineFirstLast;
//
//                  {//*** Если подключенный компонент находится на другом листе
//                  if (JoinedComponent.FirstConnectedConnCompon <> nil) and
//                     (JoinedComponent.FirstConnectedConnCompon <> PointComponent) then
//                  begin
//                    SecondPointComponent := JoinedComponent.FirstConnectedConnCompon;
//                    SecontLineSideComponent := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(JoinedComponent.FirstIDCompon);
//                  end;
//                  if (JoinedComponent.LastConnectedConnCompon <> nil) and
//                     (JoinedComponent.LastConnectedConnCompon <> PointComponent) then
//                  begin
//                    SecondPointComponent := JoinedComponent.LastConnectedConnCompon;
//                    SecontLineSideComponent := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(JoinedComponent.FirstIDCompon);
//                  end;
//                  if SecondPointComponent <> nil then
//                  begin
//                    SecondPointObject := SecondPointComponent.GetFirstParentCatalog;
//                    if SecondPointObject <> nil then
//                      if SecondPointObject.ListID <> SCSCatalog.ListID then
//                      begin
//                        tvToNode := GetCatalogNodeFromTreeView(tvTo, SecondPointObject);
//                        if tvToNode <> nil then
//                          tvToNodesToRemove.Remove(tvToNode)
//                        else
//                          //LoadComponentsToCableConfigurator(tvTo, SecondPointComponent, SecondPointObject, false);
//                          LoadComponentsToCableConfigurator(tvTo, SecontLineSideComponent, SecondPointObject, false);
//                      end;
//                  end;}
//                end;
//              end;
//              if CableNode <> nil then
//                tvFrom.Selected := CableNode;
//
//              //*** Загрузить остальные линейные компоненты из трасс подсоединенных к объкту с PointComponent
//              PointOwnerComponent := PointComponent.GetFirstParentCatalog;
//              ComponentsFromTraces := nil;
//              if PointOwnerComponent <> nil then
//                ComponentsFromTraces := TSCSComponents(GetLineComponsFromTracesJoinedToPoint(PointOwnerComponent.ListID, PointOwnerComponent.SCSID));
//
//              if ComponentsFromTraces <> nil then
//                for i := 0 to ComponentsFromTraces.Count - 1 do
//                begin
//                  SCSComponent := ComponentsFromTraces[i];
//                  if (SCSComponent.IsLine = biTrue) and
//                     //(SCSComponent.ComponentType.SysName <> ctsnCableChannel) and
//                     (FDisabledCompTypesForCableConfigurator.IndexOf(SCSComponent.ComponentType.SysName) = -1) and
//                     (PointOwnerComponent.GetTheirComponentJoinedTo(SCSComponent) = nil) then
//                  begin
//                    ComponentOwner := SCSComponent.GetFirstParentCatalog;
//                    if (PosOfTrunkComplect = -1) or
//                       (GetComplexIdentificatorByConnectedTrace(ComponentOwner.ListID, ComponentOwner.SCSID) = PosOfTrunkComplect) then
//                    begin
//                      SCSComponent.LoadWholeComponent(false);
//                      SCSComponent.DefineFirstLast;
//
//                      ImageIndex := GetComponImageIndexByFilling(SCSComponent.IsLine, SCSComponent.GetFilling(biNone, itFunctional, true, false));
//                      SCSComponNode := AddComponentToTreeView(SCSComponent, ImageIndex, tvFrom, nil);
//                      //LoadConnectedLineComponentsToLine(tvFrom, SCSComponent, SCSComponNode);
//                    end;
//                  end;
//                end;
//
//              //*** Загрузить подключенные линейные компоненнты
//              if tvFrom.Items.Count > 0 then
//                LoadConnectedLineComponentsToLineForSiblingNodes(tvFrom, tvFrom.Items[0], true);
//
//              FCurrIDPointComponent := SCSComponent.ID;
//            end;
//            //*** Сбросить изображения подключенных компонекомпонент
//            if (tvFromPrevItemsCount > 0) and (tvFrom.Items.Count = 0) then
//              DefineTreeViewImageIndex(tvTo, nil, true);
//                
//            //*** задизейблить лишнее
//            if PosOfTrunkComplect <> -1 then
//              if tvFrom.Selected = nil then
//                DefineTVImageIndexWithTrunkNodes(tvWith.Selected, tvTo, FLineComponToSide);
//
//            if tvTo.Selected <> nil then
//              tvToChange(tvTo, tvTo.Selected);
//
//            //*** Удалить ветви-объекты из других листов
//            //for i := 0 to tvToNodesToRemove.Count - 1 do
//            //  TTreeNode(tvToNodesToRemove[i]).Delete;
//            //FreeAndNil(tvToNodesToRemove);
//
//
//
//            (*
//            PointComponent := SCSComponent;
//            CableNode := nil;
//
//            //*** Добавить подключенные линейные компоненты
//            for i := 0 to PointComponent.JoinedComponents.Count - 1 do
//            begin
//              JoinedComponent := PointComponent.JoinedComponents[i];
//              if JoinedComponent.IsLine = biTrue then
//              begin
//                ImageIndex := GetComponImageIndexByFilling(JoinedComponent.IsLine, JoinedComponent.GetFilling(biNone, itFunctional, false));
//                CableNode := AddComponentToTreeView(JoinedComponent, ImageIndex, tvFrom, nil);
//                {if CableNode <> nil then
//                begin
//                  tvFrom.OnChange := nil;
//                  try
//                    tvFrom.Selected := CableNode;
//                  finally
//                    tvFrom.OnChange := tvFromChange;
//                  end;
//                end;}
//
//                JoinedComponent.LoadWholeComponent(false);
//                JoinedComponent.DefineFirstLast;
//
//                if (JoinedComponent.FirstConnectedConnCompon <> nil) and
//                   (JoinedComponent.FirstConnectedConnCompon <> PointComponent) then
//                  SecondPointComponent := JoinedComponent.FirstConnectedConnCompon;
//                if (JoinedComponent.LastConnectedConnCompon <> nil) and
//                   (JoinedComponent.LastConnectedConnCompon <> PointComponent) then
//                  SecondPointComponent := JoinedComponent.LastConnectedConnCompon;
//                if SecondPointComponent <> nil then
//                  LoadComponentsToCableConfigurator(tvTo, SecondPointComponent, SecondPointComponent.GetFirstParentCatalog, false);
//              end;
//            end;
//            if CableNode <> nil then
//              tvFrom.Selected := CableNode;
//
//            //*** Загрузить остальные линейные компоненты из трасс подсоединенных к объкту с PointComponent
//            PointOwnerComponent := PointComponent.GetFirstParentCatalog;
//            ComponentsFromTraces := nil;
//            if PointOwnerComponent <> nil then
//              ComponentsFromTraces := TSCSComponents(GetLineComponsFromTracesJoinedToPoint(PointOwnerComponent.ListID, PointOwnerComponent.SCSID));
//
//            if ComponentsFromTraces <> nil then
//              for i := 0 to ComponentsFromTraces.Count - 1 do
//              begin
//                SCSComponent := ComponentsFromTraces[i];
//                if (SCSComponent.IsLine = biTrue) and
//                   (SCSComponent.ComponentType.SysName <> ctsnCableChannel) and
//                   (PointOwnerComponent.GetTheirComponentJoinedTo(SCSComponent) = nil) then
//                begin
//                  SCSComponent.LoadWholeComponent(false);
//                  SCSComponent.DefineFirstLast;
//
//                  ImageIndex := GetComponImageIndexByFilling(SCSComponent.IsLine, SCSComponent.GetFilling(biNone, itFunctional, false));
//                  AddComponentToTreeView(SCSComponent, ImageIndex, tvFrom, nil);
//                end;
//              end;*)
//          end;
//        fmPointObjectConfigurator:
//          begin
//            if Not Assigned(SCSCatalog) and Assigned(SCSComponent) then
//              SCSCatalog := SCSComponent.GetFirstParentCatalog;
//            if SCSCatalog <> nil then
//            begin
//              if SCSComponent <> nil then
//              begin
//
//              end;
//              ConnectedObjects := GetConnectedObjectsToObjectInPointObjectConfigurator(SCSCatalog);
//              //*** Определить подключенные компоненты к кабелю
//              for i := 0 to ConnectedObjects.Count - 1 do
//              begin
//                ConnectedObject := ConnectedObjects[i];
//                if ConnectedObject.ItemType = itSCSLine then
//                  for j := 0 to ConnectedObject.ComponentReferences.Count - 1 do
//                  begin
//                    SCSCable := ConnectedObject.ComponentReferences[j];
//                    //if SCSCable.ComponentType.SysName <> ctsnCableChannel then
//                    if FDisabledCompTypesForCableConfigurator.IndexOf(SCSCable.ComponentType.SysName) = -1 then
//                    begin
//                      SCSCable.LoadWholeComponent(false);
//                      SCSCable.DefineFirstLast;
//                    end;
//                  end;
//                LoadComponentsToCableConfigurator(tvFrom, SCSComponent, ConnectedObject, false);
//              end;
//
//              FreeAndNil(ConnectedObjects);
//            end;
//          end;
//      end;
//
//    (*end
//    else
//    if Assigned(SCSPort) then
//      if FFormMode = fmCrossConfigurator then
//        if rbSelectByPoint.Checked then
//        begin
//          PortFromPointComponent := SCSPort;
//          PortFromSecondPointComponent := nil;
//
//          PointComponent := SCSPort.ComponentOwner;
//          PointTopComponent := PointComponent.GetTopComponent;
//
//          //*** Найти/загрузить подключенный кросс
//          for i := 0 to SCSPort.ConnectedInterfaces.Count - 1 do
//          begin
//            CrossInterfFrom := SCSPort.ConnectedInterfaces[i];
//            if CrossInterfFrom.ComponentOwner.IsCrossComponent then
//            begin
//              CrossComponent := CrossInterfFrom.ComponentOwner;
//              ImageIndex := GetComponImageIndexByFilling(CrossComponent.IsLine, CrossComponent.GetFilling(biNone, itFunctional, false));
//              CrossNode := AddComponentToTreeView(CrossComponent, ImageIndex, tvFrom, nil);
//              if CrossNode <> nil then
//                tvFrom.Selected := CrossNode;
//              Break; ///// BREAK /////
//            end;
//          end;
//
//          //*** Найти второй подключенный порт
//          if CrossComponent <> nil then
//            for i := 0 to CrossComponent.Interfaces.Count - 1 do
//            begin
//              CrossInterfTo := CrossComponent.Interfaces[i];
//              if (CrossInterfTo <> CrossInterfFrom) and (CrossInterfTo.TypeI = itFunctional) then
//                if CrossInterfTo <> PortFromPointComponent then
//                  for j := 0 to CrossInterfTo.ConnectedInterfaces.Count - 1 do
//                    if CrossInterfTo.ConnectedInterfaces[j] <> PortFromPointComponent then
//                    begin
//                      PortFromSecondPointComponent := CrossInterfTo.ConnectedInterfaces[j];
//                      SecondPointComponent := PortFromSecondPointComponent.ComponentOwner;
//                      Break; ///// BREAK /////
//                    end;
//            end;
//          //*** Загрузить кросс в дерево с подключенным портом на второй стороне
//          if SecondPointComponent <> nil then
//            LoadComponentsToCrossConfigurator(tvTo, CrossComponent, PortFromSecondPointComponent)
//          else //*** Загрузить сам шкаф
//            LoadComponentsToCrossConfigurator(tvTo, PointComponent, nil);
//
//
//          //*** Найти/загрузить недоподключенный/неподключенный кросс
//          for i := 0 to PointTopComponent.ChildReferences.Count - 1 do
//          begin
//            PointChildComponent := PointTopComponent.ChildReferences[i];
//            if PointChildComponent.IsCrossComponent then
//              if PointChildComponent <> CrossComponent then
//                if PointChildComponent.JoinedComponents.Count < 2 then
//                begin
//                  ImageIndex := GetComponImageIndexByFilling(PointChildComponent.IsLine, PointChildComponent.GetFilling(biNone, itFunctional, false));
//                  AddComponentToTreeView(PointChildComponent, ImageIndex, tvFrom, nil);
//                end;
//          end;
//
//
//
//          {//***************** ХУЙНЯ ****
//
//          PointComponent := SCSPort.ComponentOwner;
//          PointTopComponent := PointComponent.GetTopComponent;
//
//          //*** Найти/загрузить подключенный кросс
//          for i := 0 to PointComponent.JoinedComponents.Count - 1 do
//          begin
//            JoinedComponent := PointComponent.JoinedComponents[i];
//            if JoinedComponent.ID_ComponentType in [ctPatchCord, ctCrossPointObject] then
//            begin
//              CrossComponent := JoinedComponent;
//              ImageIndex := GetComponImageIndexByFilling(JoinedComponent.IsLine, JoinedComponent.GetFilling(biNone, itFunctional, false));
//              CrossNode := AddComponentToTreeView(JoinedComponent, ImageIndex, tvFrom, nil);
//              if CrossNode <> nil then
//                tvFrom.Selected := CrossNode;
//              Break; ///// BREAK /////
//            end;
//          end;
//
//          //*** Найти второй подключенный порт
//          if CrossComponent <> nil then
//            for i := 0 to CrossComponent.JoinedComponents.Count - 1 do
//            begin
//              JoinedComponent := CrossComponent.JoinedComponents[i];
//              if JoinedComponent <> PointComponent then
//              begin
//                SecondPointComponent := JoinedComponent;
//                Break; ///// BREAK /////
//              end;
//            end;
//          //*** Загрузить кросс в дерево с подключенным портом на второй стороне
//          if SecondPointComponent <> nil then
//            LoadComponentsToCrossConfigurator(tvTo, CrossComponent, SecondPointComponent)
//          else //*** Загрузить сам шкаф
//            LoadComponentsToCrossConfigurator(tvTo, PointComponent, nil);
//
//          //*** Найти/загрузить недоподключенный/неподключенный кросс
//          for i := 0 to PointTopComponent.ChildReferences.Count - 1 do
//          begin
//            PointChildComponent := PointTopComponent.ChildReferences[i];
//            if PointChildComponent.ID_ComponentType in [ctPatchCord, ctCrossPointObject] then
//              if PointChildComponent <> CrossComponent then
//                if PointChildComponent.JoinedComponents.Count < 2 then
//                begin
//                  ImageIndex := GetComponImageIndexByFilling(PointChildComponent.IsLine, PointChildComponent.GetFilling(biNone, itFunctional, false));
//                  AddComponentToTreeView(PointChildComponent, ImageIndex, tvFrom, nil);
//                end;
//          end; }
//        end;
//      *)
//  finally
//    tvFrom.Items.EndUpdate;
//    tvTo.Items.EndUpdate;
//    if IsConfiguratorMode then
//      EnableDisableConfiguratorControls;
//    FIsHandlingtvWith := false;
//  end;
//  if FFormMode in [fmCrossConfigurator, fmCableConfigurator, fmPointObjectConfigurator] then
//  begin
//    SelectObjectInPMFromTreeView(TTreeView(Sender));
//  end;
end;

procedure TF_MakeEditCrossConnection.gbConfiguratorKindResize(
  Sender: TObject);
begin
  //SetMiddleControlChilds(TControl(Sender), TControl(Self));
end;

procedure TF_MakeEditCrossConnection.rbCrossClick(Sender: TObject);
begin
  ChangeConfiguratorFormMode(fmCrossConfigurator);
end;

procedure TF_MakeEditCrossConnection.rbCableClick(Sender: TObject);
begin
  ChangeConfiguratorFormMode(fmCableConfigurator);
end;

procedure TF_MakeEditCrossConnection.rbSelectByLineClick(Sender: TObject);
begin
  ChangeConfiguratorFormMode(FFormMode);
end;

procedure TF_MakeEditCrossConnection.rbSelectByPointClick(Sender: TObject);
begin
  ChangeConfiguratorFormMode(FFormMode);
end;


procedure TF_MakeEditCrossConnection.FormCreate(Sender: TObject);
var
  i: Integer;
  Action: TAction;
  TreeViewList: TRapList;
  //13.10.2011 InterfTreeViewList: TRapList;
  CurrTreeView: TFlyTreeViewPro;

  TreeCollection: TTreeCollectionClass;
  TreeCollectionClassName: String;
  NewSectionNode: TFlyNode;


  procedure AddItemToTV(ATV: TTreeView; AText: string; AImageIndex, AStateIndex: Integer);
  var
    TVNode: TTreeNode;
    LegendItem: TRzGroupItem;
  begin
    TVNode := ATV.Items.Add(nil, '');
    TVNode.Text := AText;
    TVNode.ImageIndex := AImageIndex;
    TVNode.SelectedIndex := AImageIndex;
    TVNode.StateIndex := AStateIndex;

    {LegendItem := grLegend.Items.Add;
    LegendItem.Caption := AText;
    LegendItem.ImageIndex := AImageIndex;}
  end;

begin
  for i := 0 to ActionManager.ActionCount - 1 do
  begin
    Action := TAction(ActionManager.Actions[i]);
    Action.Hint := Action.Caption;
  end;

  FDisabledCompTypesForCableConfigurator := TStringList.Create;
  FDisabledCompTypesForCableConfigurator.Add(ctsnCableChannelElement);
  FDisabledCompTypesForCableConfigurator.Add(ctsnCableChannel);
  FDisabledCompTypesForCableConfigurator.Add(ctsnCableChannelAccessory);

  FLockCount := 0;
  FPointFigureRelations := nil;
  FConnectedLinesToPointObject := nil;
  //gbConfiguratorKindResize(gbConfiguratorKind);
  pnOkCancelResize(pnOkCancel);

  FPair1Interfaces := TRapList.Create;
  FPair2Interfaces := TRapList.Create;
  
  FImageCountBeforeState := TF_Main(GForm).DM.ImageList_Dir.Count;

  FTreeList := TRapList.Create;
  FTreeAnchorNodeList := TRapList.Create;

  {FTreeList.Add(tvWith);
  FTreeList.Add(tvFrom);
  FTreeList.Add(tvTo);
  FTreeList.Add(tvInterfWithSide1);
  FTreeList.Add(tvInterfWithSide2);
  FTreeList.Add(tvInterfFromSide1);
  FTreeList.Add(tvInterfFromSide2);
  FTreeList.Add(tvInterfTo);}

  TreeViewList := TRapList.Create;
  TreeViewList.Add(tvWith);
  TreeViewList.Add(tvFrom);
  TreeViewList.Add(tvTo);

  {//13.10.2011
  InterfTreeViewList := TRapList.Create;
  InterfTreeViewList.Add(tvInterfWithSide1);
  InterfTreeViewList.Add(tvInterfWithSide2);
  InterfTreeViewList.Add(tvInterfFromSide1);
  InterfTreeViewList.Add(tvInterfFromSide2);
  InterfTreeViewList.Add(tvInterfTo);}
  FInterfTrees := TRapList.Create; //13.10.2011
  FInterfTrees.Add(tvInterfWithSide1);
  FInterfTrees.Add(tvInterfWithSide2);
  FInterfTrees.Add(tvInterfFromSide1);
  FInterfTrees.Add(tvInterfFromSide2);
  FInterfTrees.Add(tvInterfTo);

  FTreeList.AddList(TreeViewList);
  FTreeList.AddList(FInterfTrees); //13.10.2011 FTreeList.AddList(InterfTreeViewList);

  // Настройки деревьев с компонентами
  for i := 0 to TreeViewList.Count - 1 do
  begin
    CurrTreeView := TFlyTreeViewPro(TreeViewList[i]);

    CurrTreeView.Align := alClient;
    CurrTreeView.FitColumnToClientWidth := true;
    CurrTreeView.Images.Clear;
    CurrTreeView.Images.AddImages(TF_Main(GForm).DM.ImageList_Dir);
    CurrTreeView.Images.AddImages(ltState);

    //CurrTreeView.ButtonSize := 10;
    CurrTreeView.ButtonCheckedIndex := nsiAttention + FImageCountBeforeState;
    CurrTreeView.ButtonUnCheckedIndex := nsiEmpty + FImageCountBeforeState;
    CurrTreeView.ButtonCollapsedIndex := nsiCollapsed + FImageCountBeforeState;
    CurrTreeView.ButtonExpandedIndex := nsiExpanded + FImageCountBeforeState;

    CurrTreeView.FixedRows := 0;
    CurrTreeView.Options := CurrTreeView.Options + [goColSizing] - [goDrawFocusSelected, goHorzLine, goVertLine, goRangeSelect];
    CurrTreeView.ShowLogic := true;
    CurrTreeView.StatesDrawed := false; // уберает тормоза. но требует подгрузки иконок collapse/Expanded
    CurrTreeView.Items.Clear;

    //CurrTreeView.Columns[0].Width := 300;
  end;
  // Настройки деревьев с интерфейсами
  for i := 0 to FInterfTrees.Count - 1 do //13.10.2011 for i := 0 to InterfTreeViewList.Count - 1 do
  begin
    CurrTreeView := TFlyTreeViewPro(FInterfTrees[i]); //13.10.2011 TFlyTreeViewPro(InterfTreeViewList[i]);
    CurrTreeView.Images.Clear;
    CurrTreeView.Images.AddImages(TF_Main(GForm).DM.ImageList_Dir);
    CurrTreeView.Images.AddImages(ltState);

    CurrTreeView.ButtonCollapsedIndex := nsiCollapsed + FImageCountBeforeState;
    CurrTreeView.ButtonExpandedIndex := nsiExpanded + FImageCountBeforeState;

    CurrTreeView.Options := CurrTreeView.Options + [goColSizing, goEditing] - [goDrawFocusSelected];

    //CurrTreeView.FitColumnToClientWidth := true;
    //CurrTreeView.FitToHeight := true;
    CurrTreeView.Indent := 12;
    CurrTreeView.ShowLogic := true;
    CurrTreeView.StatesDrawed := false;
    //CurrTreeView.ShowRoot := false;
    //CurrTreeView.WordWrap := true;


    CurrTreeView.Columns[ciInterface].Caption := cMakeEditCrossConnection_Msg26_1;

    // количество
    TreeCollection := CurrTreeView.Columns.Add(cMakeEditCrossConnection_Msg26_2, TreeCollectionClassName);
    // Количество для подключения
    TreeCollection := CurrTreeView.Columns.Add(cMakeEditCrossConnection_Msg26_3, TreeCollectionClassName);
    // Цвет
    TreeCollection := CurrTreeView.Columns.Add(cMakeEditCrossConnection_Msg26_4, TreeCollectionClassName);
    // Сторона
    TreeCollection := CurrTreeView.Columns.Add(cMakeEditCrossConnection_Msg26_5, TreeCollectionClassName);

    CurrTreeView.Columns[ciInterface].ReadOnly := true;
    CurrTreeView.Columns[ciInterface].Width := 80;
    CurrTreeView.Columns[ciKolvo].EditorStyle.EditorType := tetInteger;
    CurrTreeView.Columns[ciKolvo].ReadOnly := true;
    CurrTreeView.Columns[ciKolvo].Width := 60;
    CurrTreeView.Columns[ciKolvoToConnect].EditorStyle.EditorType := tetInteger;
    CurrTreeView.Columns[ciKolvoToConnect].Width := 60;
    //CurrTreeView.Columns[ciColor].EditorStyle.EditorType := tetColor;
    CurrTreeView.Columns[ciColor].Width := 50;
    CurrTreeView.Columns[ciColor].ReadOnly := true;
    CurrTreeView.Columns[ciSide].Width := 50;
    CurrTreeView.Columns[ciSide].ReadOnly := true;
  end;
  // Общие настройки деревьев
  for i := 0 to FTreeList.Count - 1 do
  begin
    FTreeAnchorNodeList.Add(nil);

    CurrTreeView := TFlyTreeViewPro(FTreeList[i]);

    CurrTreeView.ClickableColumns := false;
    CurrTreeView.DefaultRowHeight := 17;
    //CurrTreeView.FixedColAsButton := true;
    CurrTreeView.Indent := 17;
    CurrTreeView.RightClickSelect := true;
    CurrTreeView.ShowHint := true;
    CurrTreeView.ShowImages := true;
    //CurrTreeView.ToolTips := true;
    //CurrTreeView.TransparentMode := true;
    //CurrTreeView.Options := CurrTreeView.Options + [goRowSelect];
    CurrTreeView.ToolTips := true;

    //CurrTreeView.Items.Clear;
  end;

  //13.10.2011 FreeAndNil(InterfTreeViewList);
  FreeAndNil(TreeViewList);


  lbLegend.Tag := biNone;

  tvLegend.Items.Clear;
  tvLegend.ReadOnly := true;
  tvLegend.RowSelect := true;
  tvLegend.Color := clInfoBk; //clBtnFace;
  btLegendClick(tvLegend);

  //ilLegend.AddImages(TF_Main(GForm).DM.ImageList_Dir);
  //ilLegend.AddImages(ltState);


  if GUseVisibleInterfaces then
  begin
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_1, tciiConnectedComponLineFill, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_2, tciiConnectedComponLinePartFill, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_3, tciiConnectedComponConFill, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_4, tciiConnectedComponConPartFill, -1);
    //AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_5+' '+cMakeEditCrossConnection_Msg2_6, -1{TF_Main(GForm).DM.ImageList_Dir.Count + nsiAttention}, nsiAttention);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_5+' '+cMakeEditCrossConnection_Msg2_6, -1, nsiAttention);

    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_6, tciiComponLineFill, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_7, tciiComponLineNoFill, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_8, tciiComponLinePartFill, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_9, tciiComponLine, -1);

    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_10, tciiComponConFill, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_11, tciiComponConNoFill, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_12, tciiComponConPartFill, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_13, tciiComponCon, -1);

    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_14, tciiConnectedInterface, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_15, tciiInterfaceFill, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_16, tciiInterfaceNoFill, -1);
  end
  else
  begin
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_1_1, tciiConnectedComponLineFill, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_2_1, tciiConnectedComponLinePartFill, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_3_1, tciiConnectedComponConFill, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_4_1, tciiConnectedComponConPartFill, -1);
    //AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_5+' '+cMakeEditCrossConnection_Msg2_6, -1{TF_Main(GForm).DM.ImageList_Dir.Count + nsiAttention}, nsiAttention);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_5+' '+cMakeEditCrossConnection_Msg2_6, -1, nsiAttention);

    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_6_1, tciiComponLineFill, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_7_1, tciiComponLineNoFill, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_8_1, tciiComponLinePartFill, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_9_1, tciiComponLine, -1);

    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_10_1, tciiComponConFill, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_11_1, tciiComponConNoFill, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_12_1, tciiComponConPartFill, -1);
    AddItemToTV(tvLegend, cMakeEditCrossConnection_Msg23_13_1, tciiComponCon, -1);
  end;

  FGroupComponsPanelList := TObjectList.Create(true);

  FTreeFromExpandedInfo := TObjectList.Create(true);
  FTreeToExpandedInfo := TObjectList.Create(true);
  FTreeFromSelInfo := TNodeInfo.Create;
  FTreeToSelInfo := TNodeInfo.Create;
end;

procedure TF_MakeEditCrossConnection.FormDestroy(Sender: TObject);
begin
  FreeAndNil(FGroupComponsPanelList);

  LoadInterfacesWith(true);
  LoadInterfacesFrom(true);
  LoadInterfacesTo(true);

  FreeAndNil(FTreeList);
  FreeAndNil(FTreeAnchorNodeList);
  FreeAndNil(FDisabledCompTypesForCableConfigurator);

  if FPair1Interfaces <> nil then
    FreeAndNil(FPair1Interfaces);
  if FPair2Interfaces <> nil then
    FreeAndNil(FPair2Interfaces);

  FInterfTrees.Free;

  FTreeFromExpandedInfo.Free;
  FTreeToExpandedInfo.Free;
  FTreeFromSelInfo.Free;
  FTreeToSelInfo.Free;
end;


procedure TF_MakeEditCrossConnection.btCloseClick(Sender: TObject);
begin
  Close;
end;

procedure TF_MakeEditCrossConnection.Act_ConnectExecute(Sender: TObject);
var
  Pair1Compon1Interfaces: TSCSInterfaces;
  Pair1Compon2Interfaces: TSCSInterfaces;
  Pair2Compon1Interfaces: TSCSInterfaces;
  Pair2Compon2Interfaces: TSCSInterfaces;
  WasConnect: Boolean;
begin
  if FCanConnect then
  begin
    if Not FIsInterfAction then
    begin
      WasConnect := false;
      if Assigned(FPair1Compon1PortInfo) or
          Assigned(FPair1Compon2PortInfo) or
          Assigned(FPair2Compon1PortInfo) or
          Assigned(FPair2Compon2PortInfo) then
      begin
        if JoinInterfInfos(FPair1Compon1PortInfo, FPair1Compon2PortInfo, nil, nil) then
          WasConnect := true;
        if JoinInterfInfos(FPair2Compon1PortInfo, FPair2Compon2PortInfo, nil, nil) then
          WasConnect := true;
        if WasConnect then
          AfterConnectDiconnect;
      end
      else
      begin
        Pair1Compon1Interfaces := nil;
        Pair1Compon2Interfaces := nil;
        Pair2Compon1Interfaces := nil;
        Pair2Compon2Interfaces := nil;

        //*** Порты для соединения кросом
        if FPair1Compon1Port <> nil then
        begin
          Pair1Compon1Interfaces := TSCSInterfaces.Create(false);
          Pair1Compon1Interfaces.Add(FPair1Compon1Port);
        end;
        if FPair1Compon2Port <> nil then
        begin
          Pair1Compon2Interfaces := TSCSInterfaces.Create(false);
          Pair1Compon2Interfaces.Add(FPair1Compon2Port);
        end;
        if FPair2Compon1Port <> nil then
        begin
          Pair2Compon1Interfaces := TSCSInterfaces.Create(false);
          Pair2Compon1Interfaces.Add(FPair2Compon1Port);
        end;
        if FPair2Compon2Port <> nil then
        begin
          Pair2Compon2Interfaces := TSCSInterfaces.Create(false);
          Pair2Compon2Interfaces.Add(FPair2Compon2Port);
        end;

        Screen.Cursor := crHourGlass;
        LockTrees(true);
        try
          if Assigned(FPair1Compon1) and Assigned(FPair1Compon2) then
          begin
            TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(FPair1Compon1, FPair1Compon2, false, Pair1Compon1Interfaces, Pair1Compon2Interfaces);
            //FPair1Compon1.JoinTo(FPair1Compon2, Side1, Side2);
          end;
          if Assigned(FPair2Compon1) and Assigned(FPair2Compon2) then
          begin
            TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(FPair2Compon1, FPair2Compon2, false, Pair2Compon1Interfaces, Pair2Compon2Interfaces);
            //FPair2Compon1.JoinTo(FPair2Compon2, Side1, Side2);
          end;
          AfterConnectDiconnect;
        finally
          LockTrees(false);
          Screen.Cursor := crDefault;

          if Pair1Compon1Interfaces <> nil then
            FreeAndNil(Pair1Compon1Interfaces);
          if Pair1Compon2Interfaces <> nil then
            FreeAndNil(Pair1Compon2Interfaces);
          if Pair2Compon1Interfaces <> nil then
            FreeAndNil(Pair2Compon1Interfaces);
          if Pair2Compon2Interfaces <> nil then
            FreeAndNil(Pair2Compon2Interfaces);
        end;
      end;
    end
    else
    begin
      ConnectInterfaces(FPair1Interfaces, FPair2Interfaces);
    end;
  end;
end;

procedure TF_MakeEditCrossConnection.Act_DisconnectExecute(
  Sender: TObject);
var
  i, j: Integer;
  InterfInfo: TInterfInfo;
  InterfInfoJoinedList: TRapList;
  InterfInfoJoined: TInterfInfo;

  IOfIRel: TSCSIOfIRel;
  IOfIRelList: TRapList;
  IDCompRel: Integer;
  InterfOwner: TSCSInterface;
  ComponOwner: TSCSComponent;
  ComponTo: TSCSComponent;
  IDCompRelList: TRapList;
  ComponOwnerList: TRapList;
  ComponToList: TRapList;

  WasDisconnect: Boolean;

  function DisjoinByIOfIRelList(AIOfIRelList: TRapList): Boolean;
  var
    i: Integer;
  begin
    Result := false;
    IDCompRelList := TRapList.Create;
    ComponOwnerList := TRapList.Create;
    ComponToList := TRapList.Create;
    // Разъединить интерфейсы по списку связей
    for i := 0 to AIOfIRelList.Count - 1 do
    begin
      IOfIRel := TSCSIOfIRel(AIOfIRelList[i]);
      IDCompRel := IOfIRel.IDCompRel;

      ComponOwner := IOfIRel.InterfaceOwner.ComponentOwner;
      ComponTo := IOfIRel.InterfaceTo.ComponentOwner;
      InterfOwner := IOfIRel.InterfaceOwner;
      InterfOwner.FreeIOfIRel(IOfIRel);

      IDCompRelList.Add(Pointer(IDCompRel));
      ComponOwnerList.Add(ComponOwner);
      ComponToList.Add(ComponTo);

      Result := true; //WasDisconnect := true;
      //*** Проверить, была ли удалина связь компонентов
      //if Not TF_Main(GForm).GSCSBase.CurrProject.CheckUseCompRelAtInterfaces(IDCompRel) then
      //begin
      //  ComponOwner.DisJoinFrom(ComponTo);
      //end;
    end;
    // Разъединить компоненты, если у них не осталось связанных интерфейсов
    for i := 0 to IDCompRelList.Count - 1 do
    begin
      //*** Проверить, была ли удалина связь компонентов
      if Not TF_Main(GForm).GSCSBase.CurrProject.CheckUseCompRelAtInterfaces(Integer(IDCompRelList[i])) then
      begin
        ComponOwner := ComponOwnerList[i];
        ComponTo := ComponToList[i];
        ComponOwner.DisJoinFrom(ComponTo);
      end;
    end;
    FreeAndNil(IDCompRelList);
    FreeAndNil(ComponOwnerList);
    FreeAndNil(ComponToList);
  end;

  function DisjoinInterfFromAll(aInterf: TSCSInterface; aPosFrom, aPosTo: Integer): Boolean;
  var
    IOfIRels: TSCSObjectList;
    IOfIRelsRap: TRapList;
  begin
    IOfIRels := aInterf.GetIOfIRelsByRange(aPosFrom, aPosTo);
    IOfIRelsRap := IOfIRels.ToRapList;
    Result := DisjoinByIOfIRelList(IOfIRelsRap);
    IOfIRelsRap.Free;
    IOfIRels.Free;
  end;

  function DisjoinByInterfInfo(AInterfInfo1, AInterfInfo2: TInterfInfo): Boolean;
  var
    IOfIRelList: TRapList;
    IOfIRel: TSCSIOfIRel;
  begin
    Result := false;
    if Assigned(AInterfInfo1) and Assigned(AInterfInfo2) then
    begin
      IOfIRel := GetIOfIRelThatConnectInterfaces(
                              AInterfInfo1.FInterface, AInterfInfo2.FInterface,
                              AInterfInfo1.PosFrom, AInterfInfo1.PosTo,
                              AInterfInfo2.PosFrom, AInterfInfo2.PosTo);
      if IOfIRel <> nil then
      begin
        IOfIRelList := TRapList.Create;
        IOfIRelList.Add(IOfIRel);
        Result := DisjoinByIOfIRelList(IOfIRelList);
        IOfIRelList.Free;
      end;
    end
    //16.10.2013 - освобождаем каждый интерфейс отельно
    else if Assigned(AInterfInfo1) then
    begin
      Result := DisjoinInterfFromAll(AInterfInfo1.FInterface, AInterfInfo1.PosFrom, AInterfInfo1.PosTo);
    end
    else if Assigned(AInterfInfo2) then
    begin
      Result := DisjoinInterfFromAll(AInterfInfo2.FInterface, AInterfInfo2.PosFrom, AInterfInfo2.PosTo);
    end;
  end;

begin
  if FCanDisconnect then
  begin
    Screen.Cursor := crHourGlass;
    LockTrees(true);
    WasDisconnect := false;
    try
      if Not FIsInterfAction then
      begin
        // Если порты кросса, или панети в кросс-режиме
        if Assigned(FPair1Compon1PortInfo) or
          Assigned(FPair1Compon2PortInfo) or
          Assigned(FPair2Compon1PortInfo) or
          Assigned(FPair2Compon2PortInfo) then
        begin
          if DisjoinByInterfInfo(FPair1Compon1PortInfo, FPair1Compon2PortInfo) then
            WasDisconnect := true;
          if DisjoinByInterfInfo(FPair2Compon1PortInfo, FPair2Compon2PortInfo) then
            WasDisconnect := true;
        end
        else
        // Обычное отключение компонентов
        begin
          if Assigned(FPair1Compon1) and Assigned(FPair1Compon2) then
            FPair1Compon1.DisJoinFrom(FPair1Compon2);
          if Assigned(FPair2Compon1) and Assigned(FPair2Compon2) then
            FPair2Compon1.DisJoinFrom(FPair2Compon2);

          WasDisconnect := true;
          //17.10.2011 AfterConnectDiconnect;
        end;
      end
      else
      begin
        IOfIRelList := TRapList.Create;
        for i := 0 to FPair1Interfaces.Count - 1 do
        begin
          InterfInfo := TInterfInfo(FPair1Interfaces[i]);

          InterfInfoJoinedList := GetJoinedInterfInfoFromTree(InterfInfo, FTreeViewInterf2);
          for j := 0 to InterfInfoJoinedList.Count - 1 do
          begin
            InterfInfoJoined := TInterfinfo(InterfInfoJoinedList[j]);
            if InterfInfoJoined <> nil then
              if CheckJoinedInterfInfos(InterfInfo, InterfInfoJoined) then
              begin
                IOfIRel := GetIOfIRelThatConnectInterfaces(InterfInfo.FInterface, InterfInfoJoined.FInterface,
                            InterfInfo.PosFrom, InterfInfo.PosTo, InterfInfoJoined.PosFrom, InterfInfoJoined.PosTo);
                if IOfIRel <> nil then
                begin
                  if IOfIRelList.IndexOf(IOfIRel) = -1 then
                    IOfIRelList.Add(IOfIRel);
                  LoadPartIOfIRelsToList(InterfInfo.FInterface, IOfIRel, IOfIRelList);
                  LoadPartIOfIRelsToList(InterfInfoJoined.FInterface, IOfIRel, IOfIRelList);
                end;
              end;
          end;
          FreeAndNil(InterfInfoJoinedList);
        end;

        if DisjoinByIOfIRelList(IOfIRelList) then
          WasDisconnect := true;

        {//17.10.2011 - перенесено в DisjoinByIOfIRelList
        IDCompRelList := TRapList.Create;
        ComponOwnerList := TRapList.Create;
        ComponToList := TRapList.Create;
        // Разъединить интерфейсы по списку связей
        for i := 0 to IOfIRelList.Count - 1 do
        begin
          IOfIRel := TSCSIOfIRel(IOfIRelList[i]);
          IDCompRel := IOfIRel.IDCompRel;

          ComponOwner := IOfIRel.InterfaceOwner.ComponentOwner;
          ComponTo := IOfIRel.InterfaceTo.ComponentOwner;
          InterfOwner := IOfIRel.InterfaceOwner;
          InterfOwner.FreeIOfIRel(IOfIRel);

          IDCompRelList.Add(Pointer(IDCompRel));
          ComponOwnerList.Add(ComponOwner);
          ComponToList.Add(ComponTo);

          WasDisconnect := true;
          //*** Проверить, была ли удалина связь компонентов
          //if Not TF_Main(GForm).GSCSBase.CurrProject.CheckUseCompRelAtInterfaces(IDCompRel) then
          //begin
          //  ComponOwner.DisJoinFrom(ComponTo);
          //end;
        end;
        // Разъединить компоненты, если у них не осталось связанных интерфейсов
        for i := 0 to IDCompRelList.Count - 1 do
        begin
          //*** Проверить, была ли удалина связь компонентов
          if Not TF_Main(GForm).GSCSBase.CurrProject.CheckUseCompRelAtInterfaces(Integer(IDCompRelList[i])) then
          begin
            ComponOwner := ComponOwnerList[i];
            ComponTo := ComponToList[i];
            ComponOwner.DisJoinFrom(ComponTo);
          end;
        end;
        FreeAndNil(IDCompRelList);
        FreeAndNil(ComponOwnerList);
        FreeAndNil(ComponToList); }

        FreeAndNil(IOfIRelList);

        {for i := 0 to FPair1Interfaces.Count - 1 do
        begin
          InterfInfo := TInterfInfo(FPair1Interfaces[i]);

          InterfInfoJoinedList := GetJoinedInterfInfoFromTree(InterfInfo, FTreeViewInterf2);
          for j := 0 to InterfInfoJoinedList.Count - 1 do
          begin
            InterfInfoJoined := TInterfinfo(InterfInfoJoinedList[j]);
            if InterfInfoJoined <> nil then
              if CheckJoinedInterfInfos(InterfInfo, InterfInfoJoined) then
              begin
                IOfIRel := GetIOfIRelThatConnectInterfaces(InterfInfo.FInterface, InterfInfoJoined.FInterface);
                if IOfIRel <> nil then
                begin
                  IDCompRel := IOfIRel.IDCompRel;
                  if InterfInfo.FInterface.IOfIRelOut.IndexOf(IOfIRel) <> -1 then
                    InterfInfo.FInterface.FreeIOfIRel(IOfIRel)
                  else
                  if InterfInfoJoined.FInterface.IOfIRelOut.IndexOf(IOfIRel) <> -1 then
                    InterfInfoJoined.FInterface.FreeIOfIRel(IOfIRel);

                  //*** Проверить, была ли удалина связь компонентов
                  if Not TF_Main(GForm).GSCSBase.CurrProject.CheckUseCompRelAtInterfaces(IDCompRel) then
                  begin
                    InterfInfo.FInterface.ComponentOwner.DisJoinFrom(InterfInfoJoined.FInterface.ComponentOwner);
                  end;
                end;
              end;
          end;
          FreeAndNil(InterfInfoJoinedList);
        end;}
        //17.10.2011 if WasDisconnect then
        //17.10.2011   AfterConnectDiconnect;
      end;

      if WasDisconnect then //17.10.2011
        AfterConnectDiconnect;
    finally
      LockTrees(false);
      Screen.Cursor := crDefault;
    end;
  end;
end;

procedure TF_MakeEditCrossConnection.FormShow(Sender: TObject);
begin
  FIsHandlingtvWith := false;
  tvWith.SetFocus;

  SetControlsForInterfaces;
end;

procedure TF_MakeEditCrossConnection.tvFrom__Change(Sender: TObject;
  Node: TTreeNode);
var
  LineComponent: TSCSComponent;

  PointObjectFirstFromTree: TSCSCatalog;
  PointObjectFirst: TSCSCatalog;
  PointObjectLast: TSCSCatalog;

  ResPointComponent: TSCSComponent;
  ResPointObject: TSCSCatalog;
  tvToNode: TTreeNode;
begin (*
  if IsThroughConfiguratorMode then
  begin
    //*** Если в левой панеле выбор идет по точ. компонентам,
    //    то здесь находить подключенные точ. компоненты к тек. выбранному для правой панеле


    if (FFormMode = fmCableConfigurator) and rbSelectByPoint.Checked then
    begin
      tvTo.Items.BeginUpdate;
      try
        //tvTo.Items.Clear;
        FLineComponFromSide := nil;
        FLineComponToSide := nil;

        LineComponent := nil;
        PointObjectFirst := nil;
        PointObjectLast := nil;
        ResPointComponent := nil;
        ResPointObject := nil;
        if (tvFrom.Selected <> nil) and (tvFrom.Selected.Data <> nil) then
          if TObject(tvFrom.Selected.Data) is TSCSComponent then
            LineComponent := TSCSComponent(tvFrom.Selected.Data);
        if LineComponent <> nil then
        begin
          PointObjectFirstFromTree := GetCatalogFromTreeView(tvWith);

          if (LineComponent.FirstIDCompon <> 0) and (LineComponent.LastIDCompon <> 0) then
          begin
            DefinePointObjectsForLineCompon(LineComponent, PointObjectFirst, PointObjectLast);

            FLineComponFromSide := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(LineComponent.FirstIDCompon);
            FLineComponToSide := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(LineComponent.LastIDCompon);
            SendFirstLastIDsToPartComponent(LineComponent, FLineComponFromSide);
            SendFirstLastIDsToPartComponent(LineComponent, FLineComponToSide);

            if (PointObjectFirst <> nil) and (PointObjectFirst <> nil) then
            begin
              if (PointObjectFirst = PointObjectFirstFromTree) and (PointObjectLast <> PointObjectFirstFromTree) then
              begin
                ResPointComponent := LineComponent.LastConnectedConnCompon;
                ResPointObject := PointObjectLast;
              end
              else
              if (PointObjectFirst <> PointObjectFirstFromTree) and (PointObjectLast = PointObjectFirstFromTree) then
              begin
                ResPointComponent := LineComponent.FirstConnectedConnCompon;
                ResPointObject := PointObjectFirst;
                ExchangeObjects(FLineComponFromSide, FLineComponToSide);
              end
              else
              begin
                ResPointComponent := LineComponent.LastConnectedConnCompon;
                ResPointObject := PointObjectLast;
              end;
            end
            else
            if (PointObjectFirst <> nil) and (PointObjectFirst <> PointObjectFirstFromTree) then
            begin
              ResPointComponent := LineComponent.FirstConnectedConnCompon;
              ResPointObject := PointObjectFirst;
              ExchangeObjects(FLineComponFromSide, FLineComponToSide);
            end
            else
            if (PointObjectLast <> nil) and (PointObjectLast <> PointObjectFirstFromTree) then
            begin
              ResPointComponent := LineComponent.LastConnectedConnCompon;
              ResPointObject := PointObjectLast;
            end;
          end;
          if ResPointObject <> nil then
          begin
            FPointComponentTo := ResPointComponent;

            tvToNode := GetComponentNodeFromTreeView(tvTo, ResPointComponent);
            if tvToNode <> nil then
              tvTo.Selected := tvToNode;
            //DefineTreeViewImageIndex(tvTo, ResPointComponent);

            if GetComponIdentificatorInComplex(GetComponentFromNode(tvWith.Selected)) <> -1 then
              DefineTVImageIndexWithTrunkNodes(tvWith.Selected, tvTo, FLineComponToSide) //DefineTrunkNodeImageIndex(tvWith.Selected, tvTo.Selected, FLineComponToSide, true)
            else
              DefineTreeViewImageIndex(tvTo, FLineComponToSide, true);
          end;
        end;
      finally
        tvTo.Items.EndUpdate;
      end;
    end;

    {if (FFormMode = fmCableConfigurator) and rbSelectByPoint.Checked then
    begin
      tvTo.Items.BeginUpdate;
      try
        tvTo.Items.Clear;

        LineComponent := nil;
        PointObjectFirst := nil;
        PointObjectLast := nil;
        ResPointComponent := nil;
        ResPointObject := nil;
        if (tvFrom.Selected <> nil) and (tvFrom.Selected.Data <> nil) then
          if TObject(tvFrom.Selected.Data) is TSCSComponent then
            LineComponent := TSCSComponent(tvFrom.Selected.Data);
        if LineComponent <> nil then
        begin
          PointObjectFirstFromTree := GetCatalogFromTreeView(tvWith);

          if (LineComponent.FirstIDCompon > 0) and (LineComponent.LastIDCompon > 0) then
          begin
            DefinePointObjectsForLineCompon(LineComponent, PointObjectFirst, PointObjectLast);

            if (PointObjectFirst <> nil) and (PointObjectFirst <> nil) then
            begin
              if (PointObjectFirst = PointObjectFirstFromTree) and (PointObjectLast <> PointObjectFirstFromTree) then
              begin
                ResPointComponent := LineComponent.LastConnectedConnCompon;
                ResPointObject := PointObjectLast;
              end
              else
              if (PointObjectFirst <> PointObjectFirstFromTree) and (PointObjectLast = PointObjectFirstFromTree) then
              begin
                ResPointComponent := LineComponent.FirstConnectedConnCompon;
                ResPointObject := PointObjectFirst;
              end;
            end;
          end;
          if ResPointObject <> nil then
            if (GetComponentFromTreeView(tvTo) <> ResPointComponent) or (ResPointComponent = nil) then
              LoadComponentsToCableConfigurator(tvTo, ResPointComponent, ResPointObject, false);
        end;
      finally
        tvTo.Items.EndUpdate;
      end;
    end; }
    //SelectObjectInPMFromTreeView(TTreeView(Sender));
  end;
  if IsConfiguratorMode then
  begin
    EnableDisableConfiguratorControls;
    SelectObjectInPMFromTreeView(TTreeView(Sender));
  end;  *)
end;

(*
procedure TF_MakeEditCrossConnection.tvFromChange(Sender: TObject;
  Node: TTreeNode);
var
  IDPointObjTmp1: Integer;
  IDPointObjTmp2: Integer;

  LineComponent: TSCSComponent;
  LineComponentFirst: TSCSComponent;
  LineComponentLast: TSCSComponent;
  LineObjectFirst: TSCSCatalog;
  LineObjectLast: TSCSCatalog;

  PointComponentFirst: TSCSComponent;
  PointComponentLast: TSCSComponent;
  PointObjectFirstFromTree: TSCSCatalog;
  PointObjectFirst: TSCSCatalog;
  PointObjectLast: TSCSCatalog;

  ResPointComponent: TSCSComponent;
  ResPointObject: TSCSCatalog;
begin
  if IsConfiguratorMode then
  begin
    //*** Если в левой панеле выбор идет по точ. компонентам,
    //    то здесь находить подключенные точ. компоненты к тек. выбранному для правой панеле
    if rbSelectByPoint.Checked then
    begin
      tvTo.Items.Clear;

      LineComponent := nil;
      LineObjectFirst := nil;
      LineObjectLast := nil;
      PointComponentFirst := nil;
      PointComponentLast := nil;
      PointObjectFirst := nil;
      PointObjectLast := nil;
      ResPointComponent := nil;
      ResPointObject := nil;
      if (tvFrom.Selected <> nil) and (tvFrom.Selected.Data <> nil) then
        if TObject(tvFrom.Selected.Data) is TSCSComponent then
          LineComponent := TSCSComponent(tvFrom.Selected.Data);
      if LineComponent <> nil then
      begin
        PointObjectFirstFromTree := GetCatalogFromTreeView(tvWith);

        if (LineComponent.FirstIDCompon > 0) and (LineComponent.LastIDCompon > 0) then
        begin
          LineComponentFirst := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(LineComponent.FirstIDCompon);
          LineComponentLast := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(LineComponent.LastIDCompon);

          LineObjectFirst := LineComponentFirst.GetFirstParentCatalog;
          LineObjectLast := LineComponentLast.GetFirstParentCatalog;

          //*** Для стороны откуда
          //GetConnObjectsByLine(LineObjectFirst.ListID, LineObjectFirst.SCSID, IDConnObjTmp1, IDConnObjTmp2);



          if LineComponent.FirstConnectedConnCompon <> nil then
            PointComponentFirst := LineComponent.FirstConnectedConnCompon;
          if LineComponent.LastConnectedConnCompon <> nil then
            PointComponentLast := LineComponent.LastConnectedConnCompon;

          {if PointComponentFirst <> nil then
            PointObjectFirst := PointComponentFirst.GetFirstParentCatalog;
          if PointComponentLast <> nil then
            PointObjectLast := PointComponentLast.GetFirstParentCatalog;

          if (PointObjectFirst <> nil) and (PointObjectFirst <> nil) then
          begin
            if (PointObjectFirst = PointObjectFirstFromTree) and (PointObjectLast <> PointObjectFirstFromTree) then
            begin
              ResPointComponent := PointComponentLast;
              ResPointObject := PointObjectLast;
            end
            else
            if (PointObjectFirst <> PointObjectFirstFromTree) and (PointObjectLast = PointObjectFirstFromTree) then
            begin
              ResPointComponent := PointComponentFirst;
              ResPointObject := PointObjectFirst;
            end;
          end;}
        end;
        if (ResPointComponent <> nil) and (ResPointObject <> nil) then
          if (GetComponentFromTreeView(tvTo) <> ResPointComponent) then
            LoadComponentsToCableConfigurator(tvTo, ResPointComponent, ResPointObject, false);
      end;
    end;
    EnableDisableConfiguratorControls;
    SelectObjectInPMFromTreeView(TTreeView(Sender));
  end;
end; *)

procedure TF_MakeEditCrossConnection.tvTo__Change(Sender: TObject;
  Node: TTreeNode);
begin
  {if IsThroughConfiguratorMode then
  begin
    //*** Если в левой панеле выбор идет по точ. компонентам
    if (FFormMode = fmCableConfigurator) and rbSelectByPoint.Checked then
    begin
      //*** Определить лин-е компоненты, трасса которых подключена к текщему объекту
      DefineCableWhoseTracesConnectedToObject(tvFrom, GetObjectFromNode(Node, ''));
    end;

    EnableDisableConfiguratorControls;
    SelectObjectInPMFromTreeView(TTreeView(Sender));
  end;}
end;

procedure TF_MakeEditCrossConnection.tvEnter(Sender: TObject);
var
  i: Integer;
  CurrTree: TFlyTreeViewPro;
begin
  if IsThroughConfiguratorMode or (FFormMode = fmPointObjectConfigurator) then
  begin
    TFlyTreeViewPro(Sender).SelectedBackgroundColor := clHighlight;
    for i := 0 to FTreeList.Count - 1 do
    begin
      CurrTree := TFlyTreeViewPro(FTreeList[i]);
      if CurrTree <> Sender then
        CurrTree.SelectedBackgroundColor := clGray;
    end;


    if TFlyTreeViewPro(Sender) = tvWith then
      FIsHandlingtvWith := true;
    try
      EnableDisableConfiguratorControls;
    finally
      if TFlyTreeViewPro(Sender) = tvWith then
        FIsHandlingtvWith := false;
    end;
    SelectObjectInPMFromTreeView(TFlyTreeViewPro(Sender));
  end;
end;

procedure TF_MakeEditCrossConnection.tvWith__MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  Node: TFlyNode;
begin
  if Button = mbRight then
  begin
    Node := TFlyTreeViewPro(Sender).GetNodeAt(X, Y);
    if Node <> nil then
      SelectNodeFly(TFlyTreeViewPro(Sender), Node); //TFlyTreeViewPro(Sender).Selected := Node;
  end;
end;

procedure TF_MakeEditCrossConnection.tvWith__MouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  Node: TFlyNode;
  ScrPoint: TPoint;
  Point: TPoint;
begin
  if Button = mbRight then
    if GetCursorPos(ScrPoint) then
    begin
      Point := TFlyTreeViewPro(Sender).ScreenToClient(ScrPoint);
      Node := TFlyTreeViewPro(Sender).GetNodeAt(Point.X, Point.Y);
      if Node <> nil then
        pmCommon.Popup(ScrPoint.X, ScrPoint.Y);
    end;
end;

procedure TF_MakeEditCrossConnection.tvWith__CustomDrawItem(
  Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState;
  var DefaultDraw: Boolean);
begin
  if (Node.ImageIndex = tciiConnectedComponLineFill) or
     (Node.ImageIndex = tciiConnectedComponLinePartFill) or
     (Node.ImageIndex = tciiConnectedComponConFill) or
     (Node.ImageIndex = tciiConnectedComponConPartFill) then
  begin
    Sender.Canvas.Font.Style := [fsBold];
  end;
end;


procedure TF_MakeEditCrossConnection.Act_AddCableExecute(Sender: TObject);
var
  FromPointComponent: TSCSComponent;
  FromPointObject: TSCSCatalog;
  ToPointComponent: TSCSComponent;
  ToPointObject: TSCSCatalog;

  SCSListIDs: TIntList;
  SCSObjectsforUndo: TSCSCatalogs;

  FromGroupComponsPanel: TGroupComponsPanel;
  ToGroupComponsPanel: TGroupComponsPanel;

  FromPointCompons: TSCSComponents;
  ToPointCompons: TSCSComponents;

  NBCable: TSCSComponent;
  PointFigureRelation: TPointFigureRelation;
  JoinedPoints: TStringList; // Записи с подключенными точ. объектами в виде id+'_'+id

  strNoExistsGroupName: String;

  Log: TStringList;
  CanWhile: Boolean;
  CanLoopJ: Boolean;
  ComponsToJoin: TSCSComponents;
  SavedCanExtendInterfPosInVirtualCompons: Boolean;
  CanJoinFewCablesToCompon: Boolean; // Можно ли подключать несколько кабелей между двумя компонентами
  DisabledToJoin: TRapObjectList;
  // Tolik 16/05/2017
  ListOfPagesToSaveForUndo: TList;
  //

  i, j: Integer;

  function ConnectPointComponsByCable(AFromCompon, AToCompon, ANBCable: TSCSComponent;
    APointFigureRelation: TPointFigureRelation): Boolean;
  var
    FromPointObject: TSCSCatalog;
    ToPointObject: TSCSCatalog;

    PointFigureRelation: TPointFigureRelation;

    NewIDLineComponent: Integer;
    FromLineComponent: TSCSComponent;
    ToLineComponent: TSCSComponent;
    Rotated: Boolean;

    LineObject: TSCSCatalog;
    IDComponByLine: Integer;
    ComponByLine: TSCSComponent;

    i: Integer;
  begin
    Result := false;

    PointFigureRelation := APointFigureRelation;
    if PointFigureRelation = nil then
      PointFigureRelation := GetPointFigureRelationByPointObjects(FPointFigureRelations, AFromCompon, AToCompon);

    if PointFigureRelation <> nil then
    begin
      FromPointObject := AFromCompon.GetFirstParentCatalog;
      ToPointObject := AToCompon.GetFirstParentCatalog;

      FromLineComponent := nil;
      ToLineComponent := nil;

      Rotated := false;
      if (FromPointObject = PointFigureRelation.LastPointObject) and
         (ToPointObject = PointFigureRelation.FirstPointObject) then
      begin
        ExchangeObjects(FromPointObject, ToPointObject);
        ExchangeObjects(AFromCompon, AToCompon);
        Rotated := true;
      end;

      DisableMarking; //15.01.2011 - Отключаем генерацию маркировки для кабеля
      try
        for i := 0 to PointFigureRelation.TracesObjects.Count - 1 do
        begin
          LineObject := PointFigureRelation.TracesObjects[i];
          NewIDLineComponent := CopyComponentToSCSObject(LineObject.SCSID, ANBCable.ID);
          if i = 0 then
            FromLineComponent := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(NewIDLineComponent);
          if i = PointFigureRelation.TracesObjects.Count - 1 then
            ToLineComponent := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(NewIDLineComponent);
        end;
      finally
        EnableMarking; //15.01.2011
      end;
      TF_Main(GForm).F_ChoiceConnectSide.ConnectObjectsByWay(PointFigureRelation.Traces, nil, nil, nil);

      //06.04.2012 - если все подключения в одном ТО, то определить какая трасса к какому внутр. объекту подключена
      // например два подъезда в одном доме подключены трассой
      if FromPointObject = ToPointObject then
        //06.04.2012 if GetParentComponByCompTypeSysName(AFromCompon, ctsnHouse) <> nil then
        begin
          if FromLineComponent <> nil then
          begin
            IDComponByLine := GetIDElementFromComplexObjByTrace(FromPointObject.ListID, FromPointObject.SCSID, FromLineComponent.GetFirstParentCatalog.SCSID);
            ComponByLine := FromPointObject.GetComponentFromReferences(IDComponByLine);
            if ComponByLine <> nil then
            begin
              // Если начальная трасса смотрит на объект в котором не начальный а конечный компонент, то меняем трассы местами 
              if ComponByLine.ChildReferences.IndexOf(AToCompon) <> -1 then
                ExchangeObjects(FromLineComponent, ToLineComponent);
            end;
          end;
        end;

      FLineComponFromSide := nil;
      FLineComponToSide := nil;
      Result := true;
      if FromLineComponent <> nil then
      begin
        if TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(AFromCompon, FromLineComponent, false).CanConnect = false then
          Result := false;

        if Rotated then
          FLineComponFromSide := ToLineComponent
        else
          FLineComponFromSide := FromLineComponent;
      end
      else
        Result := false;
      if ToLineComponent <> nil then
      begin
        if TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(AToCompon, ToLineComponent, false).CanConnect = false then
          Result := false;
        if Rotated then
          FLineComponToSide := FromLineComponent
        else
          FLineComponToSide := ToLineComponent;
      end
      else
        Result := false;
    end;
  end;

  procedure RemovePointComponsFromListThatNoConnectToNBCable(ACompons: TSCSComponents; ANBCable: TSCSComponent);
  var
    i: Integer;
    Compon: TSCSComponent;
  begin
    for i := 0 to ACompons.Count - 1 do
    begin
      Compon := ACompons[i];
      if Not Compon.CheckJoinTo(ANBCable, -1, -1).CanConnect then
        ACompons[i] := nil;
    end;
    ACompons.Pack;
  end;

  procedure AfterConnection;
  begin
    DefineTreeViewImageIndex(tvWith, nil, true);
    DefineTreeViewImageIndex(tvTo, nil, true);

    tvWithChange(tvWith, tvWith.Selected);
    tvWithSelectedChanged(nil, tvWith.Selected);
    tvFromChange(tvFrom, tvFrom.Selected);
    tvFromSelectedChanged(nil, tvFrom.Selected);
    //DefineTreeViewImageIndex(tvTo, FLineComponToSide);
  end;

begin
  try
    CanJoinFewCablesToCompon := cbCanJoinFewCablesToCompon.Checked; //false;
    if FFormMode = fmCableConfigurator then
      if rbSelectByPoint.Checked then
      begin
        // Если подключение идет не по группам
        if FGroupComponsPanelList.Count = 0 then
        begin
          FromPointComponent := GetComponentFromTreeView(tvWith);
          ToPointComponent := GetComponentFromTreeView(tvTo);
          if Assigned(FromPointComponent) and Assigned(ToPointComponent) then
          begin
            PointFigureRelation := nil;
            NBCable := nil;

            //FromPointObject := FromPointComponent.GetFirstParentCatalog;
            //ToPointObject := ToPointComponent.GetFirstParentCatalog;
            //if Assigned(FromPointObject) and Assigned(ToPointObject) then
              //PointFigureRelation := GetPointFigureRelationByPointObjects(FPointFigureRelations, FromPointObject, ToPointObject);

            PointFigureRelation := GetPointFigureRelationByPointObjects(FPointFigureRelations, FromPointComponent, ToPointComponent);

            if PointFigureRelation <> nil then
            begin
              NBCable := TF_Main(GForm).CreateFConnectComplWith.DefineCableForJoinToPoints(FromPointComponent, ToPointComponent, GSCSIni.PM.NBLineComponGUIDForConfigurator);
              if NBCable <> nil then
              begin
                BeginProgress; //14.01.2011
                try
                  // UNDO
                  SCSListIDs := GetVariousListsIDsByObjects(PointFigureRelation.TracesObjects, false);
                  SaveListsToUndoStack(SCSListIDs);
                  FreeAndNil(SCSListIDs);

                  GSCSIni.PM.NBLineComponGUIDForConfigurator := NBCable.GuidNB;

                  ConnectPointComponsByCable(FromPointComponent, ToPointComponent, NBCable, PointFigureRelation);
                  {
                  FromLineComponent := nil;
                  ToLineComponent := nil;

                  Rotated := false;
                  if (FromPointObject = PointFigureRelation.LastPointObject) and
                     (ToPointObject = PointFigureRelation.FirstPointObject) then
                  begin
                    ExchangeObjects(FromPointObject, ToPointObject);
                    ExchangeObjects(FromPointComponent, ToPointComponent);
                    Rotated := true;
                  end;
                  for i := 0 to PointFigureRelation.TracesObjects.Count - 1 do
                  begin
                    LineObject := PointFigureRelation.TracesObjects[i];
                    NewIDLineComponent := CopyComponentToSCSObject(LineObject.SCSID, NBCable.ID);
                    if i = 0 then
                      FromLineComponent := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(NewIDLineComponent);
                    if i = PointFigureRelation.TracesObjects.Count - 1 then
                      ToLineComponent := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(NewIDLineComponent);
                  end;
                  TF_Main(GForm).F_ChoiceConnectSide.ConnectObjectsByWay(PointFigureRelation.Traces);

                  FLineComponFromSide := nil;
                  FLineComponToSide := nil;
                  if FromLineComponent <> nil then
                  begin
                    TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(FromPointComponent, FromLineComponent, false);
                    if Rotated then
                      FLineComponFromSide := ToLineComponent
                    else
                      FLineComponFromSide := FromLineComponent;
                  end;
                  if ToLineComponent <> nil then
                  begin
                    TF_Main(GForm).F_ChoiceConnectSide.JoinWithDefineSides(ToPointComponent, ToLineComponent, false);
                    if Rotated then
                      FLineComponToSide := FromLineComponent
                    else
                      FLineComponToSide := ToLineComponent;
                  end; }

                  AfterConnection;

                  FreeAndNil(NBCable);
                finally
                  EndProgress;
                end;
              end;
            end
            else
              MessageModal(cMakeEditCrossConnection_Msg21, ApplicationName, MB_ICONINFORMATION or MB_OK);
          end;
        end
        else
        begin
          FromGroupComponsPanel := GetGroupComponsPanelByTree(tvWith, false);
          ToGroupComponsPanel := GetGroupComponsPanelByTree(tvTo, false);

          // Если нет одной из групп - выводим сообщение
          if (FromGroupComponsPanel = nil) or (ToGroupComponsPanel = nil) then
          begin
            strNoExistsGroupName := '';

            if FromGroupComponsPanel = nil then
              strNoExistsGroupName := gbWith.Caption
            else
            if ToGroupComponsPanel = nil then
              strNoExistsGroupName := gbTo.Caption;

            if strNoExistsGroupName <> '' then
              MessageModal(cMakeEditCrossConnection_Msg28+' "'+strNoExistsGroupName+'"', ApplicationName, MB_OK or MB_ICONINFORMATION);
          end
          else
          if (FromGroupComponsPanel <> nil) and (ToGroupComponsPanel <> nil) then
          begin
            FromPointCompons := FromGroupComponsPanel.GetComponents;
            ToPointCompons := ToGroupComponsPanel.GetComponents;

            // Если есть группа без отмеченных компонентов - выводим сообщение
            if (FromPointCompons.Count = 0) or (ToPointCompons.Count = 0) then
            begin
              strNoExistsGroupName := '';
              if (FromPointCompons.Count = 0) and (ToPointCompons.Count = 0) then
                strNoExistsGroupName := cMakeEditCrossConnection_Msg29
              else
              if FromPointCompons.Count = 0 then
                strNoExistsGroupName := cMakeEditCrossConnection_Msg30 + ' "'+gbWith.Caption+'"'
              else
              if ToPointCompons.Count = 0 then
                strNoExistsGroupName := cMakeEditCrossConnection_Msg30 + ' "'+gbTo.Caption+'"';

              if strNoExistsGroupName <> '' then
                MessageModal(strNoExistsGroupName, ApplicationName, MB_OK or MB_ICONINFORMATION);
            end
            else
            begin
              NBCable := TF_Main(GForm).CreateFConnectComplWith.DefineCableForJoinToPoints(nil, nil, GSCSIni.PM.NBLineComponGUIDForConfigurator);
              if NBCable <> nil then
              begin
                GSCSIni.PM.NBLineComponGUIDForConfigurator := NBCable.GuidNB;

                // Удаляем из списков точ-е компоненты, которые не могут подключится к кабелю
                BeginProgress;
                try
                  RemovePointComponsFromListThatNoConnectToNBCable(FromPointCompons, NBCable);
                  RemovePointComponsFromListThatNoConnectToNBCable(ToPointCompons, NBCable);

                  // UNDO
                  //
                  // формируем список всех объектов, компоненты которых будут принимать участие в подключении
                  SCSObjectsforUndo := TSCSCatalogs.Create(false);
                  for i := 0 to FromPointCompons.Count - 1 do
                  begin
                    FromPointComponent := FromPointCompons[i];
                    for j := 0 to ToPointCompons.Count - 1 do
                    begin
                      PointFigureRelation := GetPointFigureRelationByPointObjects(FPointFigureRelations, FromPointComponent, ToPointCompons[j]);
                      if PointFigureRelation <> nil then
                      begin
                        if PointFigureRelation.FirstPointObject <> nil then
                          SCSObjectsforUndo.Add(PointFigureRelation.FirstPointObject);
                        if PointFigureRelation.LastPointObject <> nil then
                          SCSObjectsforUndo.Add(PointFigureRelation.LastPointObject);
                        SCSObjectsforUndo.AddItems(PointFigureRelation.TracesObjects);
                      end;
                    end;
                  end;
                  SCSListIDs := GetVariousListsIDsByObjects(SCSObjectsforUndo, false);
                  // Tolik 16/05/2017 -*-
                  ListOfPagesToSaveForUndo := IntCadsToCads(SCSListIDs);
                  {SaveListsToUndoStack(SCSListIDs);}
                  SaveForProjectUndo(ListOfPagesToSaveForUndo, True, False);
                  ListOfPagesToSaveForUndo.Free;
                  //
                  FreeAndNil(SCSListIDs);
                  FreeAndNil(SCSObjectsforUndo);

                finally
                  EndProgress;
                end;

                // Подключаем все нах
                Log := TStringList.Create;
                JoinedPoints := TStringList.Create;
                DisabledToJoin := TRapObjectList.Create;
                ComponsToJoin := TSCSComponents.Create(false);
                BeginProgress('', FromPointCompons.Count);
                try
                  for i := 0 to FromPointCompons.Count - 1 do
                  begin
                    FromPointComponent := FromPointCompons[i];
                    FromPointObject := FromPointComponent.GetFirstParentCatalog;

                    {//10.04.2009
                    for j := 0 to ToPointCompons.Count - 1 do
                    begin
                      ToPointComponent := ToPointCompons[j];
                      ToPointObject := ToPointComponent.GetFirstParentCatalog;
                      if FromPointObject <> ToPointObject then
                      begin
                        if ToPointComponent.CheckJoinTo(NBCable, -1, -1).CanConnect then
                          if ConnectPointComponsByCable(FromPointComponent, ToPointComponent, NBCable, nil) then
                            if FromPointComponent.Ping(ToPointComponent) then
                            begin
                              ToPointCompons.Delete(j);
                              Log.Add('"'+FromPointComponent.GetNameForVisible+'" '+cNameWith+' "'+ToPointComponent.GetNameForVisible+'"');
                              Break; //// BREAK ////
                            end;
                      end;
                    end;}


                    CanLoopJ := true;
                    for j := 0 to ToPointCompons.Count - 1 do
                      if ToPointCompons[j] <> nil then
                      begin
                        ToPointComponent := ToPointCompons[j];
                        ToPointObject := ToPointComponent.GetFirstParentCatalog;
                        if (FromPointObject <> ToPointObject)
                          and (DisabledToJoin.GetObject(FromPointComponent.ID) = nil) //01.02.2011
                          and (DisabledToJoin.GetObject(ToPointComponent.ID) = nil) //01.02.2011
                        then
                        begin
                          ComponsToJoin.Clear;
                          ComponsToJoin.Add(FromPointComponent);
                          ComponsToJoin.Add(ToPointComponent);


                          CanWhile := true;
                          while CanWhile do
                          begin
                            CanWhile := false;

                            SavedCanExtendInterfPosInVirtualCompons := GCanExtendInterfPosInVirtualCompons;
                            try
                              // Если кабель подкл. к двум точ. виртуальным кабинетам,
                              // то отключаем добавление интерфейсов, чтобы небыло зацыкливания
                              if (FromPointComponent.IsTemplate = biTrue) and (ToPointComponent.IsTemplate = biTrue) then
                                GCanExtendInterfPosInVirtualCompons := false;

                              if FromPointComponent.CheckJoinTo(NBCable, -1, -1).CanConnect then
                              //if NBCable.CheckJoinToListCompons(ComponsToJoin).CanConnect then
                              begin
                                if ToPointComponent.CheckJoinTo(NBCable, -1, -1).CanConnect then
                                begin
                                  if ConnectPointComponsByCable(FromPointComponent, ToPointComponent, NBCable, nil) then
                                  begin
                                    // Запоминаем подключение
                                    JoinedPoints.Add(IntToStr(FromPointComponent.ID)+'_'+IntToStr(ToPointComponent.ID));

                                    if FromPointComponent.Ping(ToPointComponent) then
                                    begin
                                      //10.04.2009 ToPointCompons.Delete(j);
                                      Log.Add('"'+FromPointComponent.GetNameForVisible+'" '+cNameWith+' "'+ToPointComponent.GetNameForVisible+'"');
                                      //10.04.2009 Break; //// BREAK ////
                                      CanWhile := true;
                                    end;

                                    // Если подключили два подъезда, то больше их не подключаем, так как это можно делать бесконечно
                                    if (FromPointComponent.ComponentType.SysName = ctsnApproach) and
                                       (ToPointComponent.ComponentType.SysName = ctsnApproach) then
                                      CanWhile := false;

                                    //01.02.2011  Если не включена опция "Подключать несколько кабелей к одному компоненту"
                                    //01.02.2011 то заносим в список DisabledToJoin компоненты которые не в панеле
                                    if Not CanJoinFewCablesToCompon then
                                    begin
                                      CanWhile := false;
                                      if GetParentComponByOneCompTypeSysName(FromPointComponent, GCompTypeSysNamePanels) = nil then
                                        DisabledToJoin.Insert(FromPointComponent, @FromPointComponent.ID);
                                      if GetParentComponByOneCompTypeSysName(ToPointComponent, GCompTypeSysNamePanels) = nil then
                                        DisabledToJoin.Insert(ToPointComponent, @ToPointComponent.ID);
                                    end;
                                  end;
                                end
                                else
                                  ToPointCompons[j] := nil;
                              end
                              else
                              begin
                                //if Not FromPointComponent.CheckJoinTo(NBCable, -1, -1).CanConnect then
                                  CanLoopJ := false;
                              end;
                            finally
                              GCanExtendInterfPosInVirtualCompons := SavedCanExtendInterfPosInVirtualCompons;
                            end;
                          end;
                        end;
                        if Not CanLoopJ then
                          Break; //// BREAK ////
                      end;

                    StepProgress;
                  end;

                  AfterConnection;

                finally
                  EndProgress;
                  FreeAndNil(ComponsToJoin);
                  FreeAndNil(DisabledToJoin);
                  FreeAndNil(JoinedPoints);
                end;


                if Log.Count > 0 then
                begin
                  FromGroupComponsPanel.DoUserClose;
                  ToGroupComponsPanel.DoUserClose;

                  Log.Insert(0, cMakeEditCrossConnection_Msg31);
                  if MessageModal(cMakeEditCrossConnection_Msg32, ApplicationName, MB_ICONQUESTION or MB_YESNO) = IDYES then
                    TF_Main(GForm).F_AnswerToQuast.ShowContextHelp(cMakeEditCrossConnection_Msg33, Log.Text);
                end
                else
                  MessageModal(cMakeEditCrossConnection_Msg34, ApplicationName, MB_OK or MB_ICONQUESTION);
                GLog.AddStrings(Log);

                FreeAndNil(Log);
                FreeAndNil(NBCable);
              end;
            end;

            FreeAndNil(FromPointCompons);
            FreeAndNil(ToPointCompons);
          end;
        end;
      end;
  except
    on E: Exception do AddExceptionToLogEx('TF_MakeEditCrossConnection.Act_AddCableExecute', E.Message);
  end;
end;

procedure TF_MakeEditCrossConnection.Act_DeleteCableExecute(
  Sender: TObject);
var
  ComponList: TSCSComponents;
  LineComponent: TSCSComponent;
  TreeView: TFlyTreeViewPro;
  //WholeComponent
begin
  try
    LineComponent := nil;
    TreeView := nil;
    if FFormMode = fmCableConfigurator then
    begin
      if rbSelectByLine.Checked then
        TreeView := tvWith
      else
      if rbSelectByPoint.Checked then
        TreeView := tvFrom;

      if TreeView <> nil then
      begin
        LineComponent := TSCSComponent(GetObjectFromTreeView(TreeView, cnTSCSComponent));
        if LineComponent <> nil then
          if MessageModal(cMakeEditCrossConnection_Msg19+' "'+LineComponent.GetNameForVisible+'"?', ApplicationName, MB_ICONQUESTION or MB_YESNO) = IDYES then
          begin
            BeginProgress;
            try
              TreeView.Items.BeginUpdate;
              try
                if FLineComponFromSide <> nil then
                  if LineComponent.Whole_ID = FLineComponFromSide.Whole_ID then
                  FLineComponFromSide := nil;
                if FLineComponToSide <> nil then
                  if LineComponent.Whole_ID = FLineComponToSide.Whole_ID then
                    FLineComponToSide := nil;

                //TF_Main(GForm).DM.DelComponent(LineComponent.ID, LineComponent, dmTrace);

                //*** Удалить весь кабель с учетом UNDO
                ComponList := TSCSComponents.Create(false);
                ComponList.Add(LineComponent);
                TF_Main(GForm).DelComponentsFromList(LineComponent.GetListOwner, ComponList, true, biTrue);
                FreeAndNil(ComponList);

                DelComponentFromTreeView(TreeView, LineComponent);
                //TreeView.Selected.Delete;

                if rbSelectByLine.Checked then
                begin
                  tvWithChange(tvWith, tvWith.Selected);
                  tvWithSelectedChanged(nil, tvWith.Selected);
                end
                else
                if rbSelectByPoint.Checked then
                  AfterConnectDiconnect;
              finally
                TreeView.Items.EndUpdate;
              end;
            finally
              EndProgress;
            end;
          end;
      end;
    end;
  except
    on E: Exception do AddExceptionToLogEx('TF_MakeEditCrossConnection.Act_DeleteCableExecute', E.Message);
  end;
end;


procedure TF_MakeEditCrossConnection.tvWith__Expanding(Sender: TObject;
  Node: TTreeNode; var AllowExpansion: Boolean);
begin
  //if (FFormMode = fmCableConfigurator) and rbSelectByLine.Checked then
  //  LoadConnectedLineComponentsToLineForSiblingNodes(TFlyTreeViewPro(Sender), Node.getFirstChild, false);
end;

procedure TF_MakeEditCrossConnection.tvFrom__Expanding(Sender: TObject;
  Node: TTreeNode; var AllowExpansion: Boolean);
begin
  //if (FFormMode = fmCableConfigurator) and rbSelectByPoint.Checked then
  //  LoadConnectedLineComponentsToLineForSiblingNodes(TFlyTreeViewPro(Sender), Node.getFirstChild, false);
end;

procedure TF_MakeEditCrossConnection.tvTo__Expanding(Sender: TObject;
  Node: TTreeNode; var AllowExpansion: Boolean);
begin
  //if (FFormMode = fmCableConfigurator) and rbSelectByPoint.Checked then
  //  DefineTrunkNodeImageIndex(tvWith.Selected, tvTo.Selected, FLineComponToSide, true);
end;

procedure TF_MakeEditCrossConnection.Act_SelectInMainTreeExecute(
  Sender: TObject);
begin
  GetTreeViewNodeByDataFly(tvWith, GetObjectFromTreeView(tvTo, ''), true);
end;

procedure TF_MakeEditCrossConnection.lbLegendClick(Sender: TObject);
begin
  TRzLabel(Sender).Caption := cMakeEditCrossConnection_Msg22 + ' ';
  TRzLabel(Sender).Tag := BoolToInt(Not IntToBool(TRzLabel(Sender).Tag));
  if TRzLabel(Sender).Tag = biTrue then
    TRzLabel(Sender).Caption := TRzLabel(Sender).Caption + '<<<'
  else
    TRzLabel(Sender).Caption := TRzLabel(Sender).Caption + '>>>';

  pnLegend.Visible := TRzLabel(Sender).Tag = biTrue;
  {tvLegend.Visible := TRzLabel(Sender).Tag = biTrue;
  if Not tvLegend.Visible then
  begin
    FSavedLegendHeight := pnLegend.Height;
    pnLegend.Height := pnLegendLabel.Height + 2;
  end
  else
  begin
    pnLegend.Height := FSavedLegendHeight;
  end;}
end;

procedure TF_MakeEditCrossConnection.btLegendClick(Sender: TObject);
begin
  btLegend.Caption := cMakeEditCrossConnection_Msg22 + ' ';
  if btLegend.Down then
    btLegend.Caption := btLegend.Caption + '<<<'
  else
    btLegend.Caption := btLegend.Caption + '>>>';

  SetControlsForLegend;
end;

procedure TF_MakeEditCrossConnection.Act_DisconnectAllExecute(
  Sender: TObject);
var
  //FocusedTree: TTreeView;
  NodeList: TObjectList;
  ComponentstToDisjoin: TSCSComponents;
  InterfacesToDisjoin: TSCSInterfaces;
  SCSComponent: TSCSComponent;
  JoinedComponent: TSCSComponent;
  SCSInterface: TSCSInterface;
  HaveJoindedComponentByCurrMode: Boolean;
  i, j: Integer;

  CurrNode: TFlyNode;
  NodeAfterLast: TFlyNode;

  ListOwner: TSCSList;

  function CanDisJoinComponByFormMode(AComponent: TSCSComponent): Boolean;
  var
    IsCross: Boolean;
  begin
    Result := false;

    IsCross := AComponent.IsCrossComponent;
    if (IsCross and (FFormMode = fmCrossConfigurator)) or
       (Not IsCross and (FFormMode = fmCableConfigurator)) then
      Result := true;
  end;

begin
  try
    //FocusedTree := nil;
    {if FTreeViewFrom <> nil then
      if FTreeViewFrom.Focused then
        if FTreeViewFrom.Selected <> nil then
        begin
          FTreeViewTo := FTreeViewFrom;
        end;
    if FTreeViewTo = nil then
      if FTreeViewTo <> nil then
        if FTreeViewTo.Focused then
          if FTreeViewTo.Selected <> nil then
          begin
            FTreeViewTo := FTreeViewTo;
          end;}
    FTreeViewTo := GetFocusedTreeView;
    if FTreeViewTo <> nil then
    begin
      ComponentstToDisjoin := TSCSComponents.Create(false);
      InterfacesToDisjoin := TSCSInterfaces.Create(false);

      {
      // Определить все компоненты выделеного объекта в дереве
      if TObject(FTreeViewTo.Selected.Data) is TSCSCatalog then
        ComponentstToDisjoin.Assign(TSCSCatalog(FTreeViewTo.Selected.Data).ComponentReferences)
      else
      if TObject(FTreeViewTo.Selected.Data) is TSCSComponent then
      begin
        ComponentstToDisjoin.Assign(TSCSComponent(FTreeViewTo.Selected.Data).ChildReferences);
        ComponentstToDisjoin.Insert(0, TSCSComponent(FTreeViewTo.Selected.Data));
      end;}

      // Получить все подветви выделенной ветви
      NodeList := GetAllChildNodesFly(FTreeViewTo.Selected);
      NodeList.Insert(0, FTreeViewTo.Selected);
      for i := 0 to NodeList.Count - 1 do
      begin
        CurrNode := TFlyNode(NodeList[i]);
        if TObject(CurrNode.Data) is TSCSComponent then
          ComponentstToDisjoin.Add(TSCSComponent(CurrNode.Data))
        else if TObject(CurrNode.Data) is TSCSInterface then
          InterfacesToDisjoin.Add(TSCSInterface(CurrNode.Data))
        else if TObject(CurrNode.Data) is TInterfInfo then
          InterfacesToDisjoin.Add(TInterfInfo(CurrNode.Data).FInterface);

          {if TSCSInterface(CurrNode.Data).ComponentOwner <> nil then
          begin
            // Если встречаем порт, то в список компоненов добавляем подключенные кроссы
            for j := 0 to TSCSInterface(CurrNode.Data).ComponentOwner.JoinedComponents.Count - 1 do
            begin
              JoinedComponent := TSCSInterface(CurrNode.Data).ComponentOwner.JoinedComponents[j];
              //if CanDisJoinComponByFormMode(SCSComponent) then
            end;
            //ComponentstToDisjoin.Add(TSCSInterface(CurrNode.Data).ComponentOwner);
          end;}
      end;


      // Оставить те, котоые могут одключится
      i := ComponentstToDisjoin.Count - 1;
      while i >= 0 do
      begin
        SCSComponent := ComponentstToDisjoin[i];
        HaveJoindedComponentByCurrMode := false;

        if CanDisJoinComponByFormMode(SCSComponent) then
          for j := 0 to SCSComponent.JoinedComponents.Count - 1 do
          begin
            JoinedComponent := SCSComponent.JoinedComponents[j];
            if CanDisJoinComponByFormMode(JoinedComponent) then
            begin
              HaveJoindedComponentByCurrMode := true;
              Break; //// BREAK ////
            end;
          end;

        if Not HaveJoindedComponentByCurrMode then
          ComponentstToDisjoin.Delete(i);
        Dec(i);
      end;



      if (ComponentstToDisjoin.Count > 0) or (InterfacesToDisjoin.Count > 0) then
      begin
        if MessageModal(cMakeEditCrossConnection_Msg24, ApplicationName, MB_ICONQUESTION or MB_YESNO) = IDYES then
        begin
          // UNDO
          ListOwner := TSCSList(GetTopObjectFromNodeByClassName(FTreeViewTo.Selected, cnTSCSList));
          if ListOwner <> nil then
            SaveListToUndoStack(ListOwner.CurrID);

          BeginProgress;
          try
            for i := 0 to ComponentstToDisjoin.Count - 1 do
            begin
              SCSComponent := ComponentstToDisjoin[i];
              j := SCSComponent.JoinedComponents.Count - 1;
              while j >= 0 do
              begin
                JoinedComponent := SCSComponent.JoinedComponents[j];
                if CanDisJoinComponByFormMode(JoinedComponent) then
                  SCSComponent.DisJoinFrom(JoinedComponent);
                Dec(j);
              end;
            end;

            // Отключить интерфейсы
            for i := 0 to InterfacesToDisjoin.Count - 1 do
            begin
              SCSInterface := InterfacesToDisjoin[i];

              j := SCSInterface.ConnectedInterfaces.Count - 1;
              while j >= 0 do
              begin
                if j <= (SCSInterface.ConnectedInterfaces.Count - 1) then
                  SCSInterface.ComponentOwner.DisJoinFrom(SCSInterface.ConnectedInterfaces[j].ComponentOwner);
                Dec(j);
              end;
            end;
          finally
            EndProgress;
          end;
          AfterConnectDiconnect;
        end;
      end
      else
        MessageModal(cMakeEditCrossConnection_Msg25, ApplicationName, MB_ICONINFORMATION or MB_OK);

      FreeAndNil(NodeList);
      FreeAndNil(InterfacesToDisjoin);
      FreeAndNil(ComponentstToDisjoin);
    end;
  except
    on E: Exception do AddExceptionToLogEx('TF_MakeEditCrossConnection.Act_DisconnectAllExecute', E.Message);
  end;
end;


procedure TF_MakeEditCrossConnection.tvWithChange(Sender: TObject;
  Node: TFlyNode);
var
  NodeObject: TObject;
  SCSCatalog: TSCSCatalog;
  SCSComponent: TSCSComponent;
  SCSCable: TSCSComponent;
  SCSPort: TSCSinterface;
  PortFromPointComponent: TSCSinterface;
  PortFromSecondPointComponent: TSCSinterface;
  CrossInterf: TSCSinterface;
  CrossInterfFrom: TSCSinterface;
  CrossInterfTo: TSCSinterface;
  JoinedComponent: TSCSComponent;
  JoinedInterface: TSCSInterface;
  ComponentsFromTraces: TSCSComponents;
  CrossComponent: TSCSComponent;
  PointComponent: TSCSComponent;
  PointChildComponent: TSCSComponent;
  PointOwnerComponent: TSCSCatalog;
  PointTopComponent: TSCSComponent;
  SecondPointComponent: TSCSComponent;
  SecondPointObject: TSCSCatalog;
  SecontLineSideComponent: TSCSComponent;
  ComponFrom: TSCSComponent;
  ComponTo: TSCSComponent;
  //LineComponFrom: TSCSComponent;
  //LineComponTo: TSCSComponent;
  //IDConnObj1: Integer;
  //IDConnObj2: Integer;
  //IDConnObjTmp1: Integer;
  //IDConnObjTmp2: Integer;
  //IDLineObjFrom: Integer;
  //IDLineObjTo: Integer;
  //ObjLineFrom: TSCSCatalog;
  //ObjLineTo: TSCSCatalog;
  ObjJoinedConnFrom: TSCSCatalog;
  ObjJoinedConnTo: TSCSCatalog;

  //ObjTmp: TSCSCatalog;
  CanExchPoinObjectsByInterfCount: Boolean;
  ConnectedPointObjects: TSCSCatalogs;
  ConnectedPointObject: TSCSCatalog;

  ConnectedObjects: TSCSCatalogs;
  ConnectedObject: TSCSCatalog;

  tvFromPrevItemsCount: Integer;
  tvToNode: TFlyNode;
  tvToPrevNode: TFlyNode;
  tvToNodesToRemove: TObjectList;

  i, j: Integer;
  ImageIndex: Integer;
  CableNode: TFlyNode;
  CrossNode: TFlyNode;

  SCSComponNode: TFlyNode;
  PosOfTrunkComplect: Integer;
  Componentowner: TSCSCatalog;
begin
  Exit; ///// EXIT /////
  
  FIsHandlingtvWith := true;
  FLineComponFromSide := nil;
  FLineComponToSide := nil;
  FPointComponentFrom := nil;
  FPointComponentTo := nil;
  FPointObjectFrom := nil;
  FPointObjecttTo := nil;

  SCSCatalog := nil;
  SCSComponent := nil;
  CrossComponent := nil;
  PointComponent := nil;
  SecondPointObject := nil;
  SecondPointComponent := nil;
  SecontLineSideComponent := nil;
  SCSPort := nil;
  CrossInterfFrom := nil;
  CrossInterfTo := nil;

  tvFrom.Items.BeginUpdate;
  tvTo.Items.BeginUpdate;
  try
    tvFrom.OnChange := nil;
    try
      tvFromPrevItemsCount := tvFrom.Items.Count;
      tvFrom.Items.Clear;
    finally
      tvFrom.OnChange := tvFromChange;
    end;

    if Not((FFormMode = fmCableConfigurator) and (rbSelectByPoint.Checked)) then
      tvTo.Items.Clear;

    NodeObject := nil;
    if Assigned(Node) then
      if Node.Data <> nil then
      begin
        NodeObject := TSCSComponent(Node.Data);
        if NodeObject is TSCSCatalog then
          SCSCatalog := TSCSCatalog(NodeObject);
        if NodeObject is TSCSComponent then
          SCSComponent := TSCSComponent(NodeObject);
        if NodeObject is TSCSInterface then
          SCSPort := TSCSInterface(NodeObject);
      end;
    //if Assigned(SCSComponent) or Assigned(SCSCatalog) then
    //begin
    //  SCSComponent := TSCSComponent(NodeObject);
      ComponFrom := nil;
      ComponTo := nil;
      case FFormMode of
        fmNBCrossConnection:
          if Assigned(SCSComponent) then
          begin
            tvTo.Items.Clear;

            CrossComponent := SCSComponent;
            loadComponentsToCrossConnect(tvFrom, CrossComponent, FCrossConnection.IDCompRelFrom, FCrossConnection.NppFrom);
            loadComponentsToCrossConnect(tvTo, CrossComponent, FCrossConnection.IDCompRelTo, FCrossConnection.NppTo);
          end;
        fmCrossConfigurator:
          begin
            tvTo.Items.Clear;
            if rbSelectByLine.Checked and Assigned(SCSComponent) then  // патч-корд слева
            begin
              CrossComponent := SCSComponent;
              if CrossComponent.JoinedComponents.Count > 0 then
                for i := 0 to CrossComponent.Interfaces.Count - 1 do
                begin
                  CrossInterf := CrossComponent.Interfaces[i];
                  if (CrossInterf.TypeI = itFunctional) and
                     (CrossInterf.ConnectedInterfaces.Count > 0) then
                  begin
                    if CrossInterfFrom = nil then
                      CrossInterfFrom := CrossInterf.ConnectedInterfaces[0]
                    else
                    if CrossInterfTo = nil then
                      CrossInterfTo :=  CrossInterf.ConnectedInterfaces[0];
                  end;
                end;
              LoadComponentsToCrossConfigurator(tvFrom, CrossComponent, CrossInterfFrom);
              LoadComponentsToCrossConfigurator(tvTo, CrossComponent, CrossInterfTo);

              {//**** ХУЙНЯ
              if CrossComponent.JoinedComponents.Count > 0 then
              begin
                ComponFrom := CrossComponent.JoinedComponents[0];
                if CrossComponent.JoinedComponents.Count > 1 then
                  ComponTo := CrossComponent.JoinedComponents[1];
              end;
              LoadComponentsToCrossConfigurator(tvFrom, CrossComponent, ComponFrom);
              LoadComponentsToCrossConfigurator(tvTo, CrossComponent, ComponTo);}
            end
            else
            if rbSelectByPoint.Checked and Assigned(SCSPort) then
            begin
              PortFromPointComponent := SCSPort;
              PortFromSecondPointComponent := nil;

              PointComponent := SCSPort.ComponentOwner;
              PointTopComponent := PointComponent.GetTopComponent;

              //*** Найти/загрузить подключенный кросс
              for i := 0 to SCSPort.ConnectedInterfaces.Count - 1 do
              begin
                CrossInterfFrom := SCSPort.ConnectedInterfaces[i];
                if CrossInterfFrom.ComponentOwner.IsCrossComponent then
                begin
                  CrossComponent := CrossInterfFrom.ComponentOwner;
                  ImageIndex := GetComponImageIndexByFilling(CrossComponent.IsLine, CrossComponent.GetFilling(biNone, itFunctional, false, false));
                  CrossNode := AddComponentToTreeView(CrossComponent, ImageIndex, tvFrom, nil);
                  if CrossNode <> nil then
                    SelectNodeFly(tvFrom, CrossNode); //tvFrom.Selected := CrossNode;
                  Break; ///// BREAK /////
                end;
              end;

              //*** Найти второй подключенный порт
              if CrossComponent <> nil then
                for i := 0 to CrossComponent.Interfaces.Count - 1 do
                begin
                  CrossInterfTo := CrossComponent.Interfaces[i];
                  if (CrossInterfTo <> CrossInterfFrom) and (CrossInterfTo.TypeI = itFunctional) then
                    if CrossInterfTo <> PortFromPointComponent then
                      for j := 0 to CrossInterfTo.ConnectedInterfaces.Count - 1 do
                        if CrossInterfTo.ConnectedInterfaces[j] <> PortFromPointComponent then
                        begin
                          PortFromSecondPointComponent := CrossInterfTo.ConnectedInterfaces[j];
                          SecondPointComponent := PortFromSecondPointComponent.ComponentOwner;
                          Break; ///// BREAK /////
                        end;
                end;
              //*** Загрузить кросс в дерево с подключенным портом на второй стороне
              if SecondPointComponent <> nil then
                LoadComponentsToCrossConfigurator(tvTo, CrossComponent, PortFromSecondPointComponent)
              else //*** Загрузить сам шкаф
                LoadComponentsToCrossConfigurator(tvTo, PointComponent, nil);


              //*** Найти/загрузить недоподключенный/неподключенный кросс
              for i := 0 to PointTopComponent.ChildReferences.Count - 1 do
              begin
                PointChildComponent := PointTopComponent.ChildReferences[i];
                if PointChildComponent.IsCrossComponent then
                  if PointChildComponent <> CrossComponent then
                    if PointChildComponent.JoinedComponents.Count < 2 then
                    begin
                      ImageIndex := GetComponImageIndexByFilling(PointChildComponent.IsLine, PointChildComponent.GetFilling(biNone, itFunctional, false, false));
                      AddComponentToTreeView(PointChildComponent, ImageIndex, tvFrom, nil);
                    end;
              end;
            end;
          end;
        fmCableConfigurator:
          if rbSelectByLine.Checked and Assigned(SCSComponent) then  // кабель слева
          begin
            tvTo.Items.Clear;
            CrossComponent := SCSComponent;
            
            ObjJoinedConnFrom := nil;
            ObjJoinedConnTo := nil;
            //*** Определить точечные подсоединенные объекты ObjFrom и ObjTo
            //with TF_Main(GForm) do
            //begin
              CrossComponent.LoadWholeComponent(false);
              CrossComponent.DefineFirstLast;

              DefinePointObjectsForLineCompon(CrossComponent, ObjJoinedConnFrom, ObjJoinedConnTo);

              if CrossComponent.FirstIDCompon <> 0 then
                FLineComponFromSide := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(CrossComponent.FirstIDCompon)
              else
                FLineComponFromSide := CrossComponent;
              if CrossComponent.LastIDCompon <> 0 then
                FLineComponToSide := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(CrossComponent.LastIDCompon)
              else
                FLineComponToSide := CrossComponent;

              SendFirstLastIDsToPartComponent(CrossComponent, FLineComponFromSide);
              SendFirstLastIDsToPartComponent(CrossComponent, FLineComponToSide);

            //ComponFrom := CrossComponent.FirstConnectedConnCompon;
            //ComponTo := CrossComponent.LastConnectedConnCompon;

            //LoadComponentsToCableConfigurator(tvFrom, ComponFrom, ObjJoinedConnFrom, false);
            //LoadComponentsToCableConfigurator(tvTo, ComponTo, ObjJoinedConnTo, false);

            LoadComponentsToCableConfigurator(tvFrom, FLineComponFromSide, ObjJoinedConnFrom, false);
            LoadComponentsToCableConfigurator(tvTo, FLineComponToSide, ObjJoinedConnTo, false, GetComponentFromNode(tvFrom.Selected));
          end
          else
          if rbSelectByPoint.Checked and (Assigned(SCSComponent) or Assigned(SCSCatalog)) then
          begin
            //FCurrIDPointObject := -1;
            //FCurrIDPointComponent := -1;
            //tvToNodesToRemove := TObjectList.Create(false);
            if Not Assigned(SCSCatalog) and Assigned(SCSComponent) then
              SCSCatalog := SCSComponent.GetFirstParentCatalog;

            PosOfTrunkComplect := -1;
            if SCSComponent <> nil then
              PosOfTrunkComplect := GetComponIdentificatorInComplex(SCSComponent);

            //*** Подгрузить подключенные объекты на другой стороне
            if Assigned(SCSCatalog) and (SCSCatalog.ID <> FCurrIDPointObject) then
            begin
              tvTo.Items.Clear;

              ConnectedPointObjects := GetPointObjectsByConnectedFropmPointRelations(FPointFigureRelations, SCSCatalog);
              SortSCSObjectsByPMOrder(ConnectedPointObjects);
              for i := 0 to ConnectedPointObjects.Count - 1 do
              begin
                ConnectedPointObject := ConnectedPointObjects[i];
                LoadComponentsToCableConfigurator(tvTo, nil, ConnectedPointObject, true);
              end;
              FreeAndNil(ConnectedPointObjects);
              //SortConfiguratorTreeView(tvTo, true); Сортирует по имени
              FCurrIDPointObject := SCSCatalog.ID;
            end; {
            else // Убрать ветви, объекты которых пренадлежат другим листам
            if SCSCatalog.ID = FCurrIDPointObject then
            begin
              tvToNode := nil;
              if tvTo.Items.Count > 0 then
                tvToNode := GetTreeViewFirstTopNode(tvTo.Items[0]);
              while tvToNode <> nil do
              begin
                tvToPrevNode := tvToNode;
                tvToNode := tvToNode.getNextSibling;
                if TObject(tvToPrevNode.Data) is TSCSCatalog then
                  if TSCSCatalog(TObject(tvToPrevNode.Data)).ListID <> SCSCatalog.ListID then
                    tvToNodesToRemove.Add(tvToPrevNode); //tvToPrevNode.Delete;
              end;
            end; }

            if Assigned(SCSComponent) then
            begin
              FPointComponentFrom := SCSComponent;

              PointComponent := SCSComponent;
              CableNode := nil;

              //*** Добавить подключенные линейные компоненты
              for i := 0 to PointComponent.JoinedComponents.Count - 1 do
              begin
                JoinedComponent := PointComponent.JoinedComponents[i];
                if JoinedComponent.IsLine = biTrue then
                begin
                  ImageIndex := GetComponImageIndexByFilling(JoinedComponent.IsLine, JoinedComponent.GetFilling(biNone, itFunctional, true, false), true);
                  CableNode := AddComponentToTreeView(JoinedComponent, ImageIndex, tvFrom, nil);
                  //LoadConnectedLineComponentsToLine(tvFrom, JoinedComponent, CableNode);

                  {if CableNode <> nil then
                  begin
                    tvFrom.OnChange := nil;
                    try
                      tvFrom.Selected := CableNode;
                    finally
                      tvFrom.OnChange := tvFromChange;
                    end;
                  end;}

                  JoinedComponent.LoadWholeComponent(false);
                  JoinedComponent.DefineFirstLast;

                  {//*** Если подключенный компонент находится на другом листе
                  if (JoinedComponent.FirstConnectedConnCompon <> nil) and
                     (JoinedComponent.FirstConnectedConnCompon <> PointComponent) then
                  begin
                    SecondPointComponent := JoinedComponent.FirstConnectedConnCompon;
                    SecontLineSideComponent := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(JoinedComponent.FirstIDCompon);
                  end;
                  if (JoinedComponent.LastConnectedConnCompon <> nil) and
                     (JoinedComponent.LastConnectedConnCompon <> PointComponent) then
                  begin
                    SecondPointComponent := JoinedComponent.LastConnectedConnCompon;
                    SecontLineSideComponent := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(JoinedComponent.FirstIDCompon);
                  end;
                  if SecondPointComponent <> nil then
                  begin
                    SecondPointObject := SecondPointComponent.GetFirstParentCatalog;
                    if SecondPointObject <> nil then
                      if SecondPointObject.ListID <> SCSCatalog.ListID then
                      begin
                        tvToNode := GetCatalogNodeFromTreeView(tvTo, SecondPointObject);
                        if tvToNode <> nil then
                          tvToNodesToRemove.Remove(tvToNode)
                        else
                          //LoadComponentsToCableConfigurator(tvTo, SecondPointComponent, SecondPointObject, false);
                          LoadComponentsToCableConfigurator(tvTo, SecontLineSideComponent, SecondPointObject, false);
                      end;
                  end;}
                end;
              end;
              Application.ProcessMessages;
              if CableNode <> nil then
                SelectNodeFly(tvFrom, CableNode); //tvFrom.Selected := CableNode;

              //*** Загрузить остальные линейные компоненты из трасс подсоединенных к объкту с PointComponent
              PointOwnerComponent := PointComponent.GetFirstParentCatalog;
              ComponentsFromTraces := nil;
              if PointOwnerComponent <> nil then
                ComponentsFromTraces := TSCSComponents(GetLineComponsFromTracesJoinedToPoint(PointOwnerComponent.ListID, PointOwnerComponent.SCSID));

              if ComponentsFromTraces <> nil then
                for i := 0 to ComponentsFromTraces.Count - 1 do
                begin
                  SCSComponent := ComponentsFromTraces[i];
                  if (SCSComponent.IsLine = biTrue) and
                     //(SCSComponent.ComponentType.SysName <> ctsnCableChannel) and
                     (FDisabledCompTypesForCableConfigurator.IndexOf(SCSComponent.ComponentType.SysName) = -1) and
                     (PointOwnerComponent.GetTheirComponentJoinedTo(SCSComponent) = nil) then
                  begin
                    ComponentOwner := SCSComponent.GetFirstParentCatalog;
                    if (PosOfTrunkComplect = -1) or
                       (GetComplexIdentificatorByConnectedTrace(PointComponent, SCSCatalog, ComponentOwner) = PosOfTrunkComplect) then
                    begin
                      SCSComponent.LoadWholeComponent(false);
                      SCSComponent.DefineFirstLast;

                      ImageIndex := GetComponImageIndexByFilling(SCSComponent.IsLine, SCSComponent.GetFilling(biNone, itFunctional, true, false));
                      SCSComponNode := AddComponentToTreeView(SCSComponent, ImageIndex, tvFrom, nil);
                      //LoadConnectedLineComponentsToLine(tvFrom, SCSComponent, SCSComponNode);
                    end;
                  end;
                end;

              //*** Загрузить подключенные линейные компоненнты
              if tvFrom.Items.Count > 0 then
                LoadConnectedLineComponentsToLineForSiblingNodes(tvFrom, tvFrom.Items[0], true);

              FCurrIDPointComponent := SCSComponent.ID;
            end;
            //*** Сбросить изображения подключенных компонекомпонент
            if (tvFromPrevItemsCount > 0) and (tvFrom.Items.Count = 0) then
              DefineTreeViewImageIndex(tvTo, nil, true);
                
            //*** задизейблить лишнее
            if PosOfTrunkComplect <> -1 then
              if tvFrom.Selected = nil then
                DefineTVImageIndexWithTrunkNodes(tvWith.Selected, tvTo, FLineComponToSide);

            if tvTo.Selected <> nil then
              tvToChange(tvTo, tvTo.Selected);

            //*** Удалить ветви-объекты из других листов
            //for i := 0 to tvToNodesToRemove.Count - 1 do
            //  TTreeNode(tvToNodesToRemove[i]).Delete;
            //FreeAndNil(tvToNodesToRemove);



            (*
            PointComponent := SCSComponent;
            CableNode := nil;

            //*** Добавить подключенные линейные компоненты
            for i := 0 to PointComponent.JoinedComponents.Count - 1 do
            begin
              JoinedComponent := PointComponent.JoinedComponents[i];
              if JoinedComponent.IsLine = biTrue then
              begin
                ImageIndex := GetComponImageIndexByFilling(JoinedComponent.IsLine, JoinedComponent.GetFilling(biNone, itFunctional, false));
                CableNode := AddComponentToTreeView(JoinedComponent, ImageIndex, tvFrom, nil);
                {if CableNode <> nil then
                begin
                  tvFrom.OnChange := nil;
                  try
                    tvFrom.Selected := CableNode;
                  finally
                    tvFrom.OnChange := tvFromChange;
                  end;
                end;}

                JoinedComponent.LoadWholeComponent(false);
                JoinedComponent.DefineFirstLast;

                if (JoinedComponent.FirstConnectedConnCompon <> nil) and
                   (JoinedComponent.FirstConnectedConnCompon <> PointComponent) then
                  SecondPointComponent := JoinedComponent.FirstConnectedConnCompon;
                if (JoinedComponent.LastConnectedConnCompon <> nil) and
                   (JoinedComponent.LastConnectedConnCompon <> PointComponent) then
                  SecondPointComponent := JoinedComponent.LastConnectedConnCompon;
                if SecondPointComponent <> nil then
                  LoadComponentsToCableConfigurator(tvTo, SecondPointComponent, SecondPointComponent.GetFirstParentCatalog, false);
              end;
            end;
            if CableNode <> nil then
              tvFrom.Selected := CableNode;

            //*** Загрузить остальные линейные компоненты из трасс подсоединенных к объкту с PointComponent
            PointOwnerComponent := PointComponent.GetFirstParentCatalog;
            ComponentsFromTraces := nil;
            if PointOwnerComponent <> nil then
              ComponentsFromTraces := TSCSComponents(GetLineComponsFromTracesJoinedToPoint(PointOwnerComponent.ListID, PointOwnerComponent.SCSID));

            if ComponentsFromTraces <> nil then
              for i := 0 to ComponentsFromTraces.Count - 1 do
              begin
                SCSComponent := ComponentsFromTraces[i];
                if (SCSComponent.IsLine = biTrue) and
                   (SCSComponent.ComponentType.SysName <> ctsnCableChannel) and
                   (PointOwnerComponent.GetTheirComponentJoinedTo(SCSComponent) = nil) then
                begin
                  SCSComponent.LoadWholeComponent(false);
                  SCSComponent.DefineFirstLast;

                  ImageIndex := GetComponImageIndexByFilling(SCSComponent.IsLine, SCSComponent.GetFilling(biNone, itFunctional, false));
                  AddComponentToTreeView(SCSComponent, ImageIndex, tvFrom, nil);
                end;
              end;*)
          end;
        fmPointObjectConfigurator:
          begin
            if Not Assigned(SCSCatalog) and Assigned(SCSComponent) then
              SCSCatalog := SCSComponent.GetFirstParentCatalog;
            if SCSCatalog <> nil then
            begin
              if SCSComponent <> nil then
              begin

              end;
              ConnectedObjects := GetConnectedObjectsToObjectInPointObjectConfigurator(SCSCatalog);
              //*** Определить подключенные компоненты к кабелю
              for i := 0 to ConnectedObjects.Count - 1 do
              begin
                ConnectedObject := ConnectedObjects[i];
                if ConnectedObject.ItemType = itSCSLine then
                  for j := 0 to ConnectedObject.ComponentReferences.Count - 1 do
                  begin
                    SCSCable := ConnectedObject.ComponentReferences[j];
                    //if SCSCable.ComponentType.SysName <> ctsnCableChannel then
                    if FDisabledCompTypesForCableConfigurator.IndexOf(SCSCable.ComponentType.SysName) = -1 then
                    begin
                      SCSCable.LoadWholeComponent(false);
                      SCSCable.DefineFirstLast;
                    end;
                  end;
                LoadComponentsToCableConfigurator(tvFrom, SCSComponent, ConnectedObject, false);
              end;

              FreeAndNil(ConnectedObjects);
            end;
          end;
      end;

    (*end
    else
    if Assigned(SCSPort) then
      if FFormMode = fmCrossConfigurator then
        if rbSelectByPoint.Checked then
        begin
          PortFromPointComponent := SCSPort;
          PortFromSecondPointComponent := nil;

          PointComponent := SCSPort.ComponentOwner;
          PointTopComponent := PointComponent.GetTopComponent;

          //*** Найти/загрузить подключенный кросс
          for i := 0 to SCSPort.ConnectedInterfaces.Count - 1 do
          begin
            CrossInterfFrom := SCSPort.ConnectedInterfaces[i];
            if CrossInterfFrom.ComponentOwner.IsCrossComponent then
            begin
              CrossComponent := CrossInterfFrom.ComponentOwner;
              ImageIndex := GetComponImageIndexByFilling(CrossComponent.IsLine, CrossComponent.GetFilling(biNone, itFunctional, false));
              CrossNode := AddComponentToTreeView(CrossComponent, ImageIndex, tvFrom, nil);
              if CrossNode <> nil then
                tvFrom.Selected := CrossNode;
              Break; ///// BREAK /////
            end;
          end;

          //*** Найти второй подключенный порт
          if CrossComponent <> nil then
            for i := 0 to CrossComponent.Interfaces.Count - 1 do
            begin
              CrossInterfTo := CrossComponent.Interfaces[i];
              if (CrossInterfTo <> CrossInterfFrom) and (CrossInterfTo.TypeI = itFunctional) then
                if CrossInterfTo <> PortFromPointComponent then
                  for j := 0 to CrossInterfTo.ConnectedInterfaces.Count - 1 do
                    if CrossInterfTo.ConnectedInterfaces[j] <> PortFromPointComponent then
                    begin
                      PortFromSecondPointComponent := CrossInterfTo.ConnectedInterfaces[j];
                      SecondPointComponent := PortFromSecondPointComponent.ComponentOwner;
                      Break; ///// BREAK /////
                    end;
            end;
          //*** Загрузить кросс в дерево с подключенным портом на второй стороне
          if SecondPointComponent <> nil then
            LoadComponentsToCrossConfigurator(tvTo, CrossComponent, PortFromSecondPointComponent)
          else //*** Загрузить сам шкаф
            LoadComponentsToCrossConfigurator(tvTo, PointComponent, nil);


          //*** Найти/загрузить недоподключенный/неподключенный кросс
          for i := 0 to PointTopComponent.ChildReferences.Count - 1 do
          begin
            PointChildComponent := PointTopComponent.ChildReferences[i];
            if PointChildComponent.IsCrossComponent then
              if PointChildComponent <> CrossComponent then
                if PointChildComponent.JoinedComponents.Count < 2 then
                begin
                  ImageIndex := GetComponImageIndexByFilling(PointChildComponent.IsLine, PointChildComponent.GetFilling(biNone, itFunctional, false));
                  AddComponentToTreeView(PointChildComponent, ImageIndex, tvFrom, nil);
                end;
          end;



          {//***************** ХУЙНЯ ****

          PointComponent := SCSPort.ComponentOwner;
          PointTopComponent := PointComponent.GetTopComponent;

          //*** Найти/загрузить подключенный кросс
          for i := 0 to PointComponent.JoinedComponents.Count - 1 do
          begin
            JoinedComponent := PointComponent.JoinedComponents[i];
            if JoinedComponent.ID_ComponentType in [ctPatchCord, ctCrossPointObject] then
            begin
              CrossComponent := JoinedComponent;
              ImageIndex := GetComponImageIndexByFilling(JoinedComponent.IsLine, JoinedComponent.GetFilling(biNone, itFunctional, false));
              CrossNode := AddComponentToTreeView(JoinedComponent, ImageIndex, tvFrom, nil);
              if CrossNode <> nil then
                tvFrom.Selected := CrossNode;
              Break; ///// BREAK /////
            end;
          end;

          //*** Найти второй подключенный порт
          if CrossComponent <> nil then
            for i := 0 to CrossComponent.JoinedComponents.Count - 1 do
            begin
              JoinedComponent := CrossComponent.JoinedComponents[i];
              if JoinedComponent <> PointComponent then
              begin
                SecondPointComponent := JoinedComponent;
                Break; ///// BREAK /////
              end;
            end;
          //*** Загрузить кросс в дерево с подключенным портом на второй стороне
          if SecondPointComponent <> nil then
            LoadComponentsToCrossConfigurator(tvTo, CrossComponent, SecondPointComponent)
          else //*** Загрузить сам шкаф
            LoadComponentsToCrossConfigurator(tvTo, PointComponent, nil);

          //*** Найти/загрузить недоподключенный/неподключенный кросс
          for i := 0 to PointTopComponent.ChildReferences.Count - 1 do
          begin
            PointChildComponent := PointTopComponent.ChildReferences[i];
            if PointChildComponent.ID_ComponentType in [ctPatchCord, ctCrossPointObject] then
              if PointChildComponent <> CrossComponent then
                if PointChildComponent.JoinedComponents.Count < 2 then
                begin
                  ImageIndex := GetComponImageIndexByFilling(PointChildComponent.IsLine, PointChildComponent.GetFilling(biNone, itFunctional, false));
                  AddComponentToTreeView(PointChildComponent, ImageIndex, tvFrom, nil);
                end;
          end; }
        end;
      *)
  finally
    tvFrom.Items.EndUpdate;
    tvTo.Items.EndUpdate;
    if IsConfiguratorMode then
      EnableDisableConfiguratorControls;
    FIsHandlingtvWith := false;
  end;
  if FFormMode in [fmCrossConfigurator, fmCableConfigurator, fmPointObjectConfigurator] then
  begin
    SelectObjectInPMFromTreeView(TFlyTreeViewPro(Sender));
  end;
end;

procedure TF_MakeEditCrossConnection.tvWithDrawCell(Sender: TObject;
  aCanvas: TCanvas; ACol, ARow: Integer; Rect: TRect;
  State: TExGridDrawState);
var
  Node: TFlyNode;
begin
  {Node := TFlyTreeViewPro(Sender).GetNodeAtRow(ARow);
  if Node <> nil then
    if (Node.ImageIndex = tciiConnectedComponLineFill) or
       (Node.ImageIndex = tciiConnectedComponLinePartFill) or
       (Node.ImageIndex = tciiConnectedComponConFill) or
       (Node.ImageIndex = tciiConnectedComponConPartFill) then
    begin
      aCanvas.Font.Style := [fsBold];
      aCanvas.FillRect(Rect);
      aCanvas.TextRect(Rect, Rect.Left + 1, Rect.Top + 1, Node.Text);
    end;}
end;

procedure TF_MakeEditCrossConnection.tvWithGetNodeAttributes(
  Node: TFlyNode; Column: Integer; aFont: TFont; var BackColor: TColor;
  var Alignment: TAlignment);
begin
  if (Node.ImageIndex = tciiConnectedComponLineFill) or
     (Node.ImageIndex = tciiConnectedComponLinePartFill) or
     (Node.ImageIndex = tciiConnectedComponConFill) or
     (Node.ImageIndex = tciiConnectedComponConPartFill) then
  begin
    aFont.Style := [fsBold];
  end;
end;


procedure TF_MakeEditCrossConnection.tvWithExpanding(Sender: TObject;
  Node: TFlyNode; var AllowExpansion: Boolean);
begin
  if (FFormMode = fmCableConfigurator) and rbSelectByLine.Checked then
    LoadConnectedLineComponentsToLineForSiblingNodes(TFlyTreeViewPro(Sender), Node.getFirstChild, false);
end;


procedure TF_MakeEditCrossConnection.tvFromChange(Sender: TObject;
  Node: TFlyNode);
var
  LineComponent: TSCSComponent;

  PointObjectFirstFromTree: TSCSCatalog;
  PointObjectFirst: TSCSCatalog;
  PointObjectLast: TSCSCatalog;

  ResPointComponent: TSCSComponent;
  ResPointObject: TSCSCatalog;
  tvToNode: TFlyNode;
begin
  Exit; ///// EXIT /////

  if IsThroughConfiguratorMode then
  begin
    //*** Если в левой панеле выбор идет по точ. компонентам,
    //    то здесь находить подключенные точ. компоненты к тек. выбранному для правой панеле


    if (FFormMode = fmCableConfigurator) and rbSelectByPoint.Checked then
    begin
      tvTo.Items.BeginUpdate;
      try
        //tvTo.Items.Clear;
        FLineComponFromSide := nil;
        FLineComponToSide := nil;

        LineComponent := nil;
        PointObjectFirst := nil;
        PointObjectLast := nil;
        ResPointComponent := nil;
        ResPointObject := nil;
        if (tvFrom.Selected <> nil) and (tvFrom.Selected.Data <> nil) then
          if TObject(tvFrom.Selected.Data) is TSCSComponent then
            LineComponent := TSCSComponent(tvFrom.Selected.Data);
        if LineComponent <> nil then
        begin
          PointObjectFirstFromTree := GetCatalogFromTreeView(tvWith);

          if (LineComponent.FirstIDCompon <> 0) and (LineComponent.LastIDCompon <> 0) then
          begin
            DefinePointObjectsForLineCompon(LineComponent, PointObjectFirst, PointObjectLast);

            FLineComponFromSide := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(LineComponent.FirstIDCompon);
            FLineComponToSide := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(LineComponent.LastIDCompon);
            SendFirstLastIDsToPartComponent(LineComponent, FLineComponFromSide);
            SendFirstLastIDsToPartComponent(LineComponent, FLineComponToSide);

            if (PointObjectFirst <> nil) and (PointObjectFirst <> nil) then
            begin
              if (PointObjectFirst = PointObjectFirstFromTree) and (PointObjectLast <> PointObjectFirstFromTree) then
              begin
                ResPointComponent := LineComponent.LastConnectedConnCompon;
                ResPointObject := PointObjectLast;
              end
              else
              if (PointObjectFirst <> PointObjectFirstFromTree) and (PointObjectLast = PointObjectFirstFromTree) then
              begin
                ResPointComponent := LineComponent.FirstConnectedConnCompon;
                ResPointObject := PointObjectFirst;
                ExchangeObjects(FLineComponFromSide, FLineComponToSide);
              end
              else
              begin
                ResPointComponent := LineComponent.LastConnectedConnCompon;
                ResPointObject := PointObjectLast;
              end;
            end
            else
            if (PointObjectFirst <> nil) and (PointObjectFirst <> PointObjectFirstFromTree) then
            begin
              ResPointComponent := LineComponent.FirstConnectedConnCompon;
              ResPointObject := PointObjectFirst;
              ExchangeObjects(FLineComponFromSide, FLineComponToSide);
            end
            else
            if (PointObjectLast <> nil) and (PointObjectLast <> PointObjectFirstFromTree) then
            begin
              ResPointComponent := LineComponent.LastConnectedConnCompon;
              ResPointObject := PointObjectLast;
            end;
          end;
          if ResPointObject <> nil then
          begin
            FPointComponentTo := ResPointComponent;

            tvToNode := GetComponentNodeFromTreeView(tvTo, ResPointComponent);
            if tvToNode <> nil then
              SelectNodeFly(tvTo, tvToNode); //tvTo.Selected := tvToNode;
            //DefineTreeViewImageIndex(tvTo, ResPointComponent);

            if GetComponIdentificatorInComplex(GetComponentFromNode(tvWith.Selected)) <> -1 then
              DefineTVImageIndexWithTrunkNodes(tvWith.Selected, tvTo, FLineComponToSide) //DefineTrunkNodeImageIndex(tvWith.Selected, tvTo.Selected, FLineComponToSide, true)
            else
              DefineTreeViewImageIndex(tvTo, FLineComponToSide, true);
          end;
        end;
      finally
        tvTo.Items.EndUpdate;
      end;
    end;

    {if (FFormMode = fmCableConfigurator) and rbSelectByPoint.Checked then
    begin
      tvTo.Items.BeginUpdate;
      try
        tvTo.Items.Clear;

        LineComponent := nil;
        PointObjectFirst := nil;
        PointObjectLast := nil;
        ResPointComponent := nil;
        ResPointObject := nil;
        if (tvFrom.Selected <> nil) and (tvFrom.Selected.Data <> nil) then
          if TObject(tvFrom.Selected.Data) is TSCSComponent then
            LineComponent := TSCSComponent(tvFrom.Selected.Data);
        if LineComponent <> nil then
        begin
          PointObjectFirstFromTree := GetCatalogFromTreeView(tvWith);

          if (LineComponent.FirstIDCompon > 0) and (LineComponent.LastIDCompon > 0) then
          begin
            DefinePointObjectsForLineCompon(LineComponent, PointObjectFirst, PointObjectLast);

            if (PointObjectFirst <> nil) and (PointObjectFirst <> nil) then
            begin
              if (PointObjectFirst = PointObjectFirstFromTree) and (PointObjectLast <> PointObjectFirstFromTree) then
              begin
                ResPointComponent := LineComponent.LastConnectedConnCompon;
                ResPointObject := PointObjectLast;
              end
              else
              if (PointObjectFirst <> PointObjectFirstFromTree) and (PointObjectLast = PointObjectFirstFromTree) then
              begin
                ResPointComponent := LineComponent.FirstConnectedConnCompon;
                ResPointObject := PointObjectFirst;
              end;
            end;
          end;
          if ResPointObject <> nil then
            if (GetComponentFromTreeView(tvTo) <> ResPointComponent) or (ResPointComponent = nil) then
              LoadComponentsToCableConfigurator(tvTo, ResPointComponent, ResPointObject, false);
        end;
      finally
        tvTo.Items.EndUpdate;
      end;
    end; }
    //SelectObjectInPMFromTreeView(TTreeView(Sender));
  end;
  if IsConfiguratorMode then
  begin
    EnableDisableConfiguratorControls;
    SelectObjectInPMFromTreeView(TFlyTreeViewPro(Sender));
  end;
end;

procedure TF_MakeEditCrossConnection.tvFromExpanding(Sender: TObject;
  Node: TFlyNode; var AllowExpansion: Boolean);
begin
  if (FFormMode = fmCableConfigurator) and rbSelectByPoint.Checked then
    LoadConnectedLineComponentsToLineForSiblingNodes(TFlyTreeViewPro(Sender), Node.getFirstChild, false);
end;


procedure TF_MakeEditCrossConnection.tvToChange(Sender: TObject;
  Node: TFlyNode);
begin
  Exit; ///// EXIT /////
  if IsThroughConfiguratorMode then
  begin
    //*** Если в левой панеле выбор идет по точ. компонентам
    if (FFormMode = fmCableConfigurator) and rbSelectByPoint.Checked then
    begin
      //*** Определить лин-е компоненты, трасса которых подключена к текщему объекту
      DefineCableWhoseTracesConnectedToObject(tvFrom, GetObjectFromNode(Node, ''));
    end;

    EnableDisableConfiguratorControls;
    SelectObjectInPMFromTreeView(TFlyTreeViewPro(Sender));
  end;
end;

procedure TF_MakeEditCrossConnection.tvToExpanding(Sender: TObject;
  Node: TFlyNode; var AllowExpansion: Boolean);
begin
  if (FFormMode = fmCableConfigurator) and rbSelectByPoint.Checked then
    DefineTrunkNodeImageIndex(tvWith.Selected, tvTo.Selected, FLineComponToSide, true);
end;



procedure TF_MakeEditCrossConnection.Button1Click(Sender: TObject);
var
  CurrNode: TFlyNode;
  Node: TFlyNode;
  Num: Integer;
  SelNodes: TList;
  i: Integer;

  pn: TGroupComponsPanel;
begin
  AddExceptionToLogEx('test', 'test');

  Exit; ///// EXIT /////
  pn := TGroupComponsPanel.Create(tvWith, Self);
  pn.AddNodeFrom(tvWith.Selected, true);


  Exit; ///// EXIT /////
  SelNodes := TList.Create;
  tvInterfWithSide1.FillSelectedList(SelNodes);
  for i := 0 to SelNodes.Count - 1 do
  begin
    if tvInterfWithSide1.Selected <> SelNodes[i] then
    TFlyNode(SelNodes[i]).Selected := false;
  end;
  tvInterfWithSide1.Repaint;
  SelNodes.Free;


  Exit; ///// EXIT /////
  tvInterfWithSide2.Visible := true;
  tvInterfWithSide2.Visible := false;

  Exit; ///// EXIT /////
  ExchangeTreesNodesFly(tvInterfWithSide1, tvInterfWithSide2, AfterSetDataToNode);
  ExchangeIntegers(FInterfWithSideAtTree1, FInterfWithSideAtTree2);

  Exit; ///// EXIT /////
  Node := nil;

  CurrNode := GetFirstNodeFromFlyTree(tvFrom);
  Num := -1;
  while CurrNode <> nil do
  begin
    Inc(Num);
    if Num = 0 then
    begin
      Node := CurrNode;
      Break; //// BREAK ////
    end;
    CurrNode := CurrNode.GetNext;
  end;
  //if Node <> nil then
  begin
    tvFrom.Items.BeginUpdate;
    try
      //tvFrom.OnChange := nil;
      tvFrom.Items.Clear;
      CurrNode := tvFrom.Items.Add(nil, '111');
      CurrNode := tvFrom.Items.Add(nil, '111');
      //tvFrom.Items.EndUpdate;
      SelectNodeFly(tvFrom, CurrNode);
      //tvFrom.Items.BeginUpdate;
    finally
      tvFrom.Items.EndUpdate;
    end;
  end;
end;

procedure TF_MakeEditCrossConnection.Timer_TVFromSelectTimer(
  Sender: TObject);
var
  Node: TFlyNode;
begin

end;

procedure TF_MakeEditCrossConnection.tvWithDblClick(Sender: TObject);
begin
  if (FFormMode = fmCableConfigurator) and (rbSelectByPoint.Checked) then
    SelectJoinedToChildAtFromTree(tvWith.Selected);

  if IsConfiguratorMode then
  begin
    SelectNodeByJoinedComponImageIndex(tvFrom);
    SelectNodeByJoinedComponImageIndex(tvTo);
  end;
end;


procedure TF_MakeEditCrossConnection.tvWithSelectedChanged(OldNode,
  NewNode: TFlyNode);
var
  NodeObject: TObject;
  SCSCatalog: TSCSCatalog;
  SCSComponent: TSCSComponent;
  SCSCable: TSCSComponent;
  SCSPort: TSCSinterface;
  InterfInfo, CrossInterfInfo, SecondInterfInfo: TinterfInfo;
  PortFromPointComponent: TSCSinterface;
  PortFromSecondPointComponent: TSCSinterface;
  CrossInterf: TSCSinterface;
  CrossInterfFrom: TSCSinterface;
  CrossInterfTo: TSCSinterface;
  JoinedComponent: TSCSComponent;
  JoinedInterface: TSCSInterface;
  ComponentsFromTraces: TSCSComponents;
  CrossComponent: TSCSComponent;
  PointComponent: TSCSComponent;
  PointChildComponent: TSCSComponent;
  PointOwnerComponent: TSCSCatalog;
  PointTopComponent: TSCSComponent;
  SecondPointComponent: TSCSComponent;
  SecondPointObject: TSCSCatalog;
  SecontLineSideComponent: TSCSComponent;
  ComponFrom: TSCSComponent;
  ComponTo: TSCSComponent;
  //LineComponFrom: TSCSComponent;
  //LineComponTo: TSCSComponent;
  //IDConnObj1: Integer;
  //IDConnObj2: Integer;
  //IDConnObjTmp1: Integer;
  //IDConnObjTmp2: Integer;
  //IDLineObjFrom: Integer;
  //IDLineObjTo: Integer;
  //ObjLineFrom: TSCSCatalog;
  //ObjLineTo: TSCSCatalog;
  ObjJoinedConnFrom: TSCSCatalog;
  ObjJoinedConnTo: TSCSCatalog;

  //ObjTmp: TSCSCatalog;
  CanExchPoinObjectsByInterfCount: Boolean;
  ConnectedPointObjects: TSCSCatalogs;
  ConnectedPointObject: TSCSCatalog;

  ConnectedObjects: TSCSCatalogs;
  ConnectedObject: TSCSCatalog;

  tvFromPrevItemsCount: Integer;
  tvToNode: TFlyNode;
  tvToPrevNode: TFlyNode;
  tvToNodesToRemove: TObjectList;

  i, j: Integer;
  ImageIndex: Integer;
  CableNode: TFlyNode;
  CrossNode: TFlyNode;
  InterfNode: TFlyNode;

  SCSComponNode: TFlyNode;
  PosOfTrunkComplect: Integer;
  Componentowner: TSCSCatalog;

  SideObj1, SideObj2: Integer;
  LineObjectsToFindSide: TSCSCatalogs;
  LineObjectsSides: TIntList;
  LineObjIndex: Integer;
  LineObjSide: Integer;
  
  //tvFromOldNode: TFlyNode;
  tvFromSavedOnSelectedChanged: TTreeSelChangedEvent;

  procedure PrepareSelectedLineComponent(AComponent: TSCSComponent);
  begin
    ObjJoinedConnFrom := nil;
    ObjJoinedConnTo := nil;

    AComponent.LoadWholeComponent(false);
    AComponent.DefineFirstLast;

    DefinePointObjectsForLineCompon(AComponent, ObjJoinedConnFrom, ObjJoinedConnTo);
    FPointObjectFrom := ObjJoinedConnFrom;
    FPointObjecttTo := ObjJoinedConnTo;

    FLineComponFromSide := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(AComponent.FirstIDCompon);
    FLineComponToSide := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(AComponent.LastIDCompon);

    SendFirstLastIDsToPartComponent(AComponent, FLineComponFromSide);
    SendFirstLastIDsToPartComponent(AComponent, FLineComponToSide);
  end;

begin
  if (OldNode = NewNode) and (NewNode <> nil) then
    Exit; ///// EXIT /////

  FIsHandlingtvWith := true;
  try
    FLineComponFromSide := nil;
    FLineComponToSide := nil;
    FPointComponentFrom := nil;
    FPointComponentTo := nil;
    FPointObjectFrom := nil;
    FPointObjecttTo := nil;

    SCSCatalog := nil;
    SCSComponent := nil;
    CrossComponent := nil;
    PointComponent := nil;
    SecondPointObject := nil;
    SecondPointComponent := nil;
    SecontLineSideComponent := nil;
    SCSPort := nil;
    InterfInfo := nil;
    CrossInterfFrom := nil;
    CrossInterfTo := nil;

    LoadInterfacesWith(true);
    LoadInterfacesFrom(true);
    LoadInterfacesTo(true);

    // Запоминаем виды
    SaveExpandedInfo(tvFrom, FTreeFromExpandedInfo);
    SaveExpandedInfo(tvTo, FTreeToExpandedInfo);
    if (tvFrom <> nil) and (FTreeFromSelInfo <> nil) then
      FTreeFromSelInfo.LoadFromNodeFly(tvFrom.Selected);
    if (tvTo <> nil) and (FTreeToSelInfo <> nil) then
      FTreeToSelInfo.LoadFromNodeFly(tvTo.Selected);

    tvFrom.Items.BeginUpdate;
    tvTo.Items.BeginUpdate;
    tvFromSavedOnSelectedChanged := tvFrom.OnSelectedChanged;
    tvFrom.OnSelectedChanged := nil;
    try
      tvFrom.OnChange := nil;
      try
        tvFromPrevItemsCount := tvFrom.Items.Count;
        //tvFrom.Items.Clear;
        ClearTreeViewFly(tvFrom, false, true);
      finally
        tvFrom.OnChange := tvFromChange;
      end;

      if Not((FFormMode = fmCableConfigurator) and (rbSelectByPoint.Checked)) then
        ClearTreeViewFly(tvTo, false, true);

      NodeObject := nil;
      if Assigned(NewNode) then
        if NewNode.Data <> nil then
        begin
          NodeObject := TSCSComponent(NewNode.Data);
          if NodeObject is TSCSCatalog then
            SCSCatalog := TSCSCatalog(NodeObject);
          if NodeObject is TSCSComponent then
            SCSComponent := TSCSComponent(NodeObject);
          if NodeObject is TSCSInterface then
            SCSPort := TSCSInterface(NodeObject);
          if NodeObject is TInterfInfo then
            InterfInfo := TInterfInfo(NodeObject);
        end;
      //if Assigned(SCSComponent) or Assigned(SCSCatalog) then
      //begin
      //  SCSComponent := TSCSComponent(NodeObject);
        ComponFrom := nil;
        ComponTo := nil;
        case FFormMode of
          fmNBCrossConnection:
            if Assigned(SCSComponent) then
            begin
              tvTo.Items.Clear;

              CrossComponent := SCSComponent;
              loadComponentsToCrossConnect(tvFrom, CrossComponent, FCrossConnection.IDCompRelFrom, FCrossConnection.NppFrom);
              loadComponentsToCrossConnect(tvTo, CrossComponent, FCrossConnection.IDCompRelTo, FCrossConnection.NppTo);
            end;
          fmCrossConfigurator:
            begin
              tvTo.Items.Clear;
              if rbSelectByLine.Checked then  // патч-корд слева
              begin
                if (SCSComponent = nil) and (InterfInfo <> nil) then
                  SCSComponent := InterfInfo.FInterface.ComponentOwner;
                if Assigned(SCSComponent) then
                begin
                  CrossComponent := SCSComponent;
                  if CrossComponent.JoinedComponents.Count > 0 then
                    for i := 0 to CrossComponent.Interfaces.Count - 1 do
                    begin
                      CrossInterf := CrossComponent.Interfaces[i];
                      if (CrossInterf.TypeI = itFunctional) and
                         (CrossInterf.ConnectedInterfaces.Count > 0) then
                      begin
                        if CrossInterfFrom = nil then
                          CrossInterfFrom := CrossInterf.ConnectedInterfaces[0]
                        else
                        if CrossInterfTo = nil then
                          CrossInterfTo :=  CrossInterf.ConnectedInterfaces[0];
                      end;
                    end;
                  SecondInterfInfo := nil;
                  if (InterfInfo <> nil) then
                  begin
                    SecondInterfInfo := GetInterfInfoFromOtherSide(NewNode.Parent, InterfInfo);
                    if SecondInterfInfo <> nil then
                    begin
                      if (InterfInfo.Finterface.ConnectedInterfaces.IndexOf(CrossInterfFrom) = -1) and
                         (InterfInfo.Finterface.ConnectedInterfaces.IndexOf(CrossInterfTo) <> -1) then
                        ExchangeObjects(CrossInterfFrom, CrossInterfTo); //21.10.2011 }ExchangeObjects(InterfInfo, SecondInterfInfo);
                    end;
                  end;
                  LoadComponentsToCrossConfigurator(tvFrom, CrossComponent, CrossInterfFrom, InterfInfo);
                  LoadComponentsToCrossConfigurator(tvTo, CrossComponent, CrossInterfTo, SecondInterfInfo);

                  if tvFrom.Selected = tvFrom.GetFirstVisibleNode then
                    ExpandTreeNodesByInfo(tvFrom, FTreeFromExpandedInfo, FTreeFromSelInfo);
                  if tvTo.Selected = tvTo.GetFirstVisibleNode then
                    ExpandTreeNodesByInfo(tvTo, FTreeToExpandedInfo, FTreeToSelInfo);

                  {//**** ХУЙНЯ
                  if CrossComponent.JoinedComponents.Count > 0 then
                  begin
                    ComponFrom := CrossComponent.JoinedComponents[0];
                    if CrossComponent.JoinedComponents.Count > 1 then
                      ComponTo := CrossComponent.JoinedComponents[1];
                  end;
                  LoadComponentsToCrossConfigurator(tvFrom, CrossComponent, ComponFrom);
                  LoadComponentsToCrossConfigurator(tvTo, CrossComponent, ComponTo);}
                end;
              end
              else
              if rbSelectByPoint.Checked then
              begin
                if InterfInfo <> nil then
                  SCSPort := InterfInfo.FInterface;
                if Assigned(SCSPort) then
                begin
                  PortFromPointComponent := SCSPort;
                  PortFromSecondPointComponent := nil;

                  PointComponent := SCSPort.ComponentOwner;
                  PointTopComponent := PointComponent.GetTopComponent;

                  CrossInterfInfo := nil; //18.10.2011
                  SecondInterfInfo := nil; //18.10.2011
                  //*** Найти/загрузить подключенный кросс
                  for i := 0 to SCSPort.ConnectedInterfaces.Count - 1 do
                  begin
                    CrossInterfFrom := SCSPort.ConnectedInterfaces[i];
                    if CrossInterfFrom.ComponentOwner.IsCrossComponent then
                    begin
                      if (InterfInfo = nil) or (CheckJoinedInterfWithInterfInfo(CrossInterfFrom, InterfInfo)) then
                      begin
                        CrossComponent := CrossInterfFrom.ComponentOwner;
                        ImageIndex := GetComponImageIndexByFilling(CrossComponent.IsLine, CrossComponent.GetFilling(biNone, itFunctional, false, false));
                        CrossNode := AddComponentToTreeView(CrossComponent, ImageIndex, tvFrom, nil);
                        if CrossNode <> nil then
                        begin
                          AddCrossInterfacesToNode(CrossComponent, CrossNode);
                          if InterfInfo = nil then
                          begin
                            SelectNodeFly(tvFrom, CrossNode); //tvFrom.Selected := CrossNode;
                          end
                          else
                          begin
                            CrossInterfInfo := GetJoinedInterfInfoFromParentNode(CrossNode, InterfInfo, nil);
                            if CrossInterfInfo <> nil then
                              SelectNodeFly(tvFrom, CrossInterfInfo.FNode);
                          end;
                        end;
                        Break; ///// BREAK /////
                      end;
                    end;
                  end;

                  //*** Найти второй подключенный порт
                  if CrossComponent <> nil then
                    for i := 0 to CrossComponent.Interfaces.Count - 1 do
                    begin
                      CrossInterfTo := CrossComponent.Interfaces[i];
                      if (CrossInterfTo <> CrossInterfFrom) and (CrossInterfTo.TypeI = itFunctional) then
                        if CrossInterfTo <> PortFromPointComponent then
                          for j := 0 to CrossInterfTo.ConnectedInterfaces.Count - 1 do
                            if CrossInterfTo.ConnectedInterfaces[j] <> PortFromPointComponent then
                            begin
                              if (InterfInfo <> nil) then
                                SecondInterfInfo := GetInterfInfoFromOtherSide(CrossNode, CrossInterfInfo, biTrue); // Находим занятый интерфейс с другой стороны
                              if (InterfInfo = nil) or (SecondInterfInfo <> nil) then
                              begin
                                PortFromSecondPointComponent := CrossInterfTo.ConnectedInterfaces[j];
                                SecondPointComponent := PortFromSecondPointComponent.ComponentOwner;
                                Break; ///// BREAK /////
                              end;
                            end;
                      if SecondPointComponent <> nil then
                        Break; //// BREAK ////
                    end;
                  //*** Загрузить кросс в дерево с подключенным портом на второй стороне
                  if SecondPointComponent <> nil then
                    LoadComponentsToCrossConfigurator(tvTo, CrossComponent, PortFromSecondPointComponent, SecondInterfInfo)
                  else //*** Загрузить сам шкаф
                    LoadComponentsToCrossConfigurator(tvTo, PointComponent, nil);


                  //*** Найти/загрузить недоподключенный/неподключенный кросс
                  for i := 0 to PointTopComponent.ChildReferences.Count - 1 do
                  begin
                    PointChildComponent := PointTopComponent.ChildReferences[i];
                    if PointChildComponent.IsCrossComponent then
                      if PointChildComponent <> CrossComponent then
                        if PointChildComponent.JoinedComponents.Count < 2 then
                        begin
                          ImageIndex := GetComponImageIndexByFilling(PointChildComponent.IsLine, PointChildComponent.GetFilling(biNone, itFunctional, false, false));
                          AddCrossInterfacesToNode(PointChildComponent,
                            AddComponentToTreeView(PointChildComponent, ImageIndex, tvFrom, nil)
                          );
                        end;
                  end;

                end;
              end;
            end;
          fmCableConfigurator:
            if rbSelectByLine.Checked and Assigned(SCSComponent) then  // кабель слева
            begin
              tvTo.Items.Clear;
              CrossComponent := SCSComponent;

              PrepareSelectedLineComponent(CrossComponent);

              //ComponFrom := CrossComponent.FirstConnectedConnCompon;
              //ComponTo := CrossComponent.LastConnectedConnCompon;

              //LoadComponentsToCableConfigurator(tvFrom, ComponFrom, ObjJoinedConnFrom, false);
              //LoadComponentsToCableConfigurator(tvTo, ComponTo, ObjJoinedConnTo, false);

              LoadComponentsToCableConfigurator(tvFrom, FLineComponFromSide, ObjJoinedConnFrom, false);
              LoadComponentsToCableConfigurator(tvTo, FLineComponToSide, ObjJoinedConnTo, false, GetComponentFromNode(tvFrom.Selected));
            end
            else
            if rbSelectByPoint.Checked and (Assigned(SCSComponent) or Assigned(SCSCatalog)) then
            begin
              //FCurrIDPointObject := -1;
              //FCurrIDPointComponent := -1;
              //tvToNodesToRemove := TObjectList.Create(false);
              if Not Assigned(SCSCatalog) and Assigned(SCSComponent) then
                SCSCatalog := SCSComponent.GetFirstParentCatalog;

              PosOfTrunkComplect := -1;
              if SCSComponent <> nil then
                PosOfTrunkComplect := GetComponIdentificatorInComplex(SCSComponent);

              //*** Подгрузить подключенные объекты на другой стороне
              if Assigned(SCSCatalog) and (SCSCatalog.ID <> FCurrIDPointObject) then
              begin
                tvTo.Items.Clear;

                ConnectedPointObjects := GetPointObjectsByConnectedFropmPointRelations(FPointFigureRelations, SCSCatalog);
                SortSCSObjectsByPMOrder(ConnectedPointObjects);
                for i := 0 to ConnectedPointObjects.Count - 1 do
                begin
                  ConnectedPointObject := ConnectedPointObjects[i];
                  LoadComponentsToCableConfigurator(tvTo, nil, ConnectedPointObject, true);
                end;
                FreeAndNil(ConnectedPointObjects);
                //SortConfiguratorTreeView(tvTo, true); Сортирует по имени
                FCurrIDPointObject := SCSCatalog.ID;
              end; {
              else // Убрать ветви, объекты которых пренадлежат другим листам
              if SCSCatalog.ID = FCurrIDPointObject then
              begin
                tvToNode := nil;
                if tvTo.Items.Count > 0 then
                  tvToNode := GetTreeViewFirstTopNode(tvTo.Items[0]);
                while tvToNode <> nil do
                begin
                  tvToPrevNode := tvToNode;
                  tvToNode := tvToNode.getNextSibling;
                  if TObject(tvToPrevNode.Data) is TSCSCatalog then
                    if TSCSCatalog(TObject(tvToPrevNode.Data)).ListID <> SCSCatalog.ListID then
                      tvToNodesToRemove.Add(tvToPrevNode); //tvToPrevNode.Delete;
                end;
              end; }

              if Assigned(SCSComponent) then
              begin
                FPointComponentFrom := SCSComponent;

                PointComponent := SCSComponent;
                CableNode := nil;

                //*** Добавить подключенные линейные компоненты
                for i := 0 to PointComponent.JoinedComponents.Count - 1 do
                begin
                  JoinedComponent := PointComponent.JoinedComponents[i];
                  if JoinedComponent.IsLine = biTrue then
                  begin
                    ImageIndex := GetComponImageIndexByFilling(JoinedComponent.IsLine, JoinedComponent.GetFilling(biNone, itFunctional, true, false), true);
                    CableNode := AddComponentToTreeView(JoinedComponent, ImageIndex, tvFrom, nil);
                    //LoadConnectedLineComponentsToLine(tvFrom, JoinedComponent, CableNode);

                    {if CableNode <> nil then
                    begin
                      tvFrom.OnChange := nil;
                      try
                        tvFrom.Selected := CableNode;
                      finally
                        tvFrom.OnChange := tvFromChange;
                      end;
                    end;}

                    JoinedComponent.LoadWholeComponent(false);
                    JoinedComponent.DefineFirstLast;

                    {//*** Если подключенный компонент находится на другом листе
                    if (JoinedComponent.FirstConnectedConnCompon <> nil) and
                       (JoinedComponent.FirstConnectedConnCompon <> PointComponent) then
                    begin
                      SecondPointComponent := JoinedComponent.FirstConnectedConnCompon;
                      SecontLineSideComponent := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(JoinedComponent.FirstIDCompon);
                    end;
                    if (JoinedComponent.LastConnectedConnCompon <> nil) and
                       (JoinedComponent.LastConnectedConnCompon <> PointComponent) then
                    begin
                      SecondPointComponent := JoinedComponent.LastConnectedConnCompon;
                      SecontLineSideComponent := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(JoinedComponent.FirstIDCompon);
                    end;
                    if SecondPointComponent <> nil then
                    begin
                      SecondPointObject := SecondPointComponent.GetFirstParentCatalog;
                      if SecondPointObject <> nil then
                        if SecondPointObject.ListID <> SCSCatalog.ListID then
                        begin
                          tvToNode := GetCatalogNodeFromTreeView(tvTo, SecondPointObject);
                          if tvToNode <> nil then
                            tvToNodesToRemove.Remove(tvToNode)
                          else
                            //LoadComponentsToCableConfigurator(tvTo, SecondPointComponent, SecondPointObject, false);
                            LoadComponentsToCableConfigurator(tvTo, SecontLineSideComponent, SecondPointObject, false);
                        end;
                    end;}
                  end;
                end;
                Application.ProcessMessages;
                if CableNode <> nil then
                begin
                  SelectNodeFly(tvFrom, CableNode); //tvFrom.Selected := CableNode;
                  tvFromSelectedChanged(nil, tvFrom.Selected);
                end;

                //*** Загрузить остальные линейные компоненты из трасс подсоединенных к объкту с PointComponent
                PointOwnerComponent := PointComponent.GetFirstParentCatalog;
                ComponentsFromTraces := nil;
                if PointOwnerComponent <> nil then
                  ComponentsFromTraces := TSCSComponents(GetLineComponsFromTracesJoinedToPoint(PointOwnerComponent.ListID, PointOwnerComponent.SCSID));

                if ComponentsFromTraces <> nil then
                  if ComponentsFromTraces.Count > 0 then
                  begin
                    LineObjectsToFindSide := TSCSCatalogs.Create(false);
                    LineObjectsSides := TIntList.Create;
                    for i := 0 to ComponentsFromTraces.Count - 1 do
                    begin
                      SCSComponent := ComponentsFromTraces[i];
                      if (SCSComponent.IsLine = biTrue) and
                         //(SCSComponent.ComponentType.SysName <> ctsnCableChannel) and
                         (FDisabledCompTypesForCableConfigurator.IndexOf(SCSComponent.ComponentType.SysName) = -1) {and
                         (PointOwnerComponent.GetTheirComponentJoinedTo(SCSComponent) = nil)} then
                        if PointComponent.JoinedComponents.IndexOf(SCSComponent) = -1 then
                        begin
                          ComponentOwner := SCSComponent.GetFirstParentCatalog;
                          // находим номер стороны трассы и если на этой стороне есть свобод. фйнкц. интерфейсы, то показываем кабель
                          LineObjSide := -1;
                          LineObjIndex := LineObjectsToFindSide.IndexOf(ComponentOwner);
                          if LineObjIndex = -1 then
                          begin
                            GetSidesByConnectedFigures(SCSCatalog.ListID, ComponentOwner.ListID, SCSCatalog.SCSID, ComponentOwner.SCSID, SideObj1, SideObj2);
                            LineObjSide := SideObj2;
                            LineObjectsToFindSide.Add(ComponentOwner);
                            LineObjectsSides.Add(LineObjSide);
                          end
                          else
                            LineObjSide := LineObjectsSides[LineObjIndex];

                          if LineObjSide <> -1 then
                            if SCSComponent.GetInterfaceCountToConnectBySide(LineObjSide) > 0 then
                              if (PosOfTrunkComplect = -1) or
                                 (GetComplexIdentificatorByConnectedTrace(PointComponent, SCSCatalog, ComponentOwner) = PosOfTrunkComplect) then
                              begin
                                SCSComponent.LoadWholeComponent(false);
                                SCSComponent.DefineFirstLast;

                                ImageIndex := GetComponImageIndexByFilling(SCSComponent.IsLine, SCSComponent.GetFilling(biNone, itFunctional, true, false));
                                SCSComponNode := AddComponentToTreeView(SCSComponent, ImageIndex, tvFrom, nil);
                                //LoadConnectedLineComponentsToLine(tvFrom, SCSComponent, SCSComponNode);
                              end;
                        end;
                    end;
                    FreeAndNil(LineObjectsSides);
                    FreeAndNil(LineObjectsToFindSide);
                  end;

                //*** Загрузить подключенные линейные компоненнты
                if tvFrom.Items.Count > 0 then
                  LoadConnectedLineComponentsToLineForSiblingNodes(tvFrom, tvFrom.Items[0], true);

                FCurrIDPointComponent := SCSComponent.ID;
              end;
              //*** Сбросить изображения подключенных компонекомпонент
              if (tvFromPrevItemsCount > 0) and (tvFrom.Items.Count = 0) then
                DefineTreeViewImageIndex(tvTo, nil, true);

              //*** задизейблить лишнее
              if PosOfTrunkComplect <> -1 then
                if tvFrom.Selected = nil then
                  DefineTVImageIndexWithTrunkNodes(tvWith.Selected, tvTo, FLineComponToSide);

              if tvTo.Selected <> nil then
                tvToChange(tvTo, tvTo.Selected);

              //*** Удалить ветви-объекты из других листов
              //for i := 0 to tvToNodesToRemove.Count - 1 do
              //  TTreeNode(tvToNodesToRemove[i]).Delete;
              //FreeAndNil(tvToNodesToRemove);



              (*
              PointComponent := SCSComponent;
              CableNode := nil;

              //*** Добавить подключенные линейные компоненты
              for i := 0 to PointComponent.JoinedComponents.Count - 1 do
              begin
                JoinedComponent := PointComponent.JoinedComponents[i];
                if JoinedComponent.IsLine = biTrue then
                begin
                  ImageIndex := GetComponImageIndexByFilling(JoinedComponent.IsLine, JoinedComponent.GetFilling(biNone, itFunctional, false));
                  CableNode := AddComponentToTreeView(JoinedComponent, ImageIndex, tvFrom, nil);
                  {if CableNode <> nil then
                  begin
                    tvFrom.OnChange := nil;
                    try
                      tvFrom.Selected := CableNode;
                    finally
                      tvFrom.OnChange := tvFromChange;
                    end;
                  end;}

                  JoinedComponent.LoadWholeComponent(false);
                  JoinedComponent.DefineFirstLast;

                  if (JoinedComponent.FirstConnectedConnCompon <> nil) and
                     (JoinedComponent.FirstConnectedConnCompon <> PointComponent) then
                    SecondPointComponent := JoinedComponent.FirstConnectedConnCompon;
                  if (JoinedComponent.LastConnectedConnCompon <> nil) and
                     (JoinedComponent.LastConnectedConnCompon <> PointComponent) then
                    SecondPointComponent := JoinedComponent.LastConnectedConnCompon;
                  if SecondPointComponent <> nil then
                    LoadComponentsToCableConfigurator(tvTo, SecondPointComponent, SecondPointComponent.GetFirstParentCatalog, false);
                end;
              end;
              if CableNode <> nil then
                tvFrom.Selected := CableNode;

              //*** Загрузить остальные линейные компоненты из трасс подсоединенных к объкту с PointComponent
              PointOwnerComponent := PointComponent.GetFirstParentCatalog;
              ComponentsFromTraces := nil;
              if PointOwnerComponent <> nil then
                ComponentsFromTraces := TSCSComponents(GetLineComponsFromTracesJoinedToPoint(PointOwnerComponent.ListID, PointOwnerComponent.SCSID));

              if ComponentsFromTraces <> nil then
                for i := 0 to ComponentsFromTraces.Count - 1 do
                begin
                  SCSComponent := ComponentsFromTraces[i];
                  if (SCSComponent.IsLine = biTrue) and
                     (SCSComponent.ComponentType.SysName <> ctsnCableChannel) and
                     (PointOwnerComponent.GetTheirComponentJoinedTo(SCSComponent) = nil) then
                  begin
                    SCSComponent.LoadWholeComponent(false);
                    SCSComponent.DefineFirstLast;

                    ImageIndex := GetComponImageIndexByFilling(SCSComponent.IsLine, SCSComponent.GetFilling(biNone, itFunctional, false));
                    AddComponentToTreeView(SCSComponent, ImageIndex, tvFrom, nil);
                  end;
                end;*)
            end;
          fmPointObjectConfigurator:
            begin
              if Not Assigned(SCSCatalog) and Assigned(SCSComponent) then
                SCSCatalog := SCSComponent.GetFirstParentCatalog;
              if SCSCatalog <> nil then
              begin
                ConnectedObjects := GetConnectedObjectsToObjectInPointObjectConfigurator(SCSCatalog);
                //*** Определить подключенные компоненты к кабелю
                for i := 0 to ConnectedObjects.Count - 1 do
                begin
                  ConnectedObject := ConnectedObjects[i];
                  if ConnectedObject.ItemType = itSCSLine then
                    for j := 0 to ConnectedObject.ComponentReferences.Count - 1 do
                    begin
                      SCSCable := ConnectedObject.ComponentReferences[j];
                      //if SCSCable.ComponentType.SysName <> ctsnCableChannel then
                      if FDisabledCompTypesForCableConfigurator.IndexOf(SCSCable.ComponentType.SysName) = -1 then
                      begin
                        SCSCable.LoadWholeComponent(false);
                        SCSCable.DefineFirstLast;
                      end;
                    end;
                  LoadComponentsToCableConfigurator(tvFrom, SCSComponent, ConnectedObject, false);
                end;
                FreeAndNil(ConnectedObjects);
              end;

              if SCSComponent <> nil then
                if SCSComponent.IsLine = biTrue then
                begin
                  //PrepareSelectedLineComponent(SCSComponent);
                  FLineComponFromSide := SCSComponent;
                  FLineComponToSide := SCSComponent;
                end;
            end;
        end;

      (*end
      else
      if Assigned(SCSPort) then
        if FFormMode = fmCrossConfigurator then
          if rbSelectByPoint.Checked then
          begin
            PortFromPointComponent := SCSPort;
            PortFromSecondPointComponent := nil;

            PointComponent := SCSPort.ComponentOwner;
            PointTopComponent := PointComponent.GetTopComponent;

            //*** Найти/загрузить подключенный кросс
            for i := 0 to SCSPort.ConnectedInterfaces.Count - 1 do
            begin
              CrossInterfFrom := SCSPort.ConnectedInterfaces[i];
              if CrossInterfFrom.ComponentOwner.IsCrossComponent then
              begin
                CrossComponent := CrossInterfFrom.ComponentOwner;
                ImageIndex := GetComponImageIndexByFilling(CrossComponent.IsLine, CrossComponent.GetFilling(biNone, itFunctional, false));
                CrossNode := AddComponentToTreeView(CrossComponent, ImageIndex, tvFrom, nil);
                if CrossNode <> nil then
                  tvFrom.Selected := CrossNode;
                Break; ///// BREAK /////
              end;
            end;

            //*** Найти второй подключенный порт
            if CrossComponent <> nil then
              for i := 0 to CrossComponent.Interfaces.Count - 1 do
              begin
                CrossInterfTo := CrossComponent.Interfaces[i];
                if (CrossInterfTo <> CrossInterfFrom) and (CrossInterfTo.TypeI = itFunctional) then
                  if CrossInterfTo <> PortFromPointComponent then
                    for j := 0 to CrossInterfTo.ConnectedInterfaces.Count - 1 do
                      if CrossInterfTo.ConnectedInterfaces[j] <> PortFromPointComponent then
                      begin
                        PortFromSecondPointComponent := CrossInterfTo.ConnectedInterfaces[j];
                        SecondPointComponent := PortFromSecondPointComponent.ComponentOwner;
                        Break; ///// BREAK /////
                      end;
              end;
            //*** Загрузить кросс в дерево с подключенным портом на второй стороне
            if SecondPointComponent <> nil then
              LoadComponentsToCrossConfigurator(tvTo, CrossComponent, PortFromSecondPointComponent)
            else //*** Загрузить сам шкаф
              LoadComponentsToCrossConfigurator(tvTo, PointComponent, nil);


            //*** Найти/загрузить недоподключенный/неподключенный кросс
            for i := 0 to PointTopComponent.ChildReferences.Count - 1 do
            begin
              PointChildComponent := PointTopComponent.ChildReferences[i];
              if PointChildComponent.IsCrossComponent then
                if PointChildComponent <> CrossComponent then
                  if PointChildComponent.JoinedComponents.Count < 2 then
                  begin
                    ImageIndex := GetComponImageIndexByFilling(PointChildComponent.IsLine, PointChildComponent.GetFilling(biNone, itFunctional, false));
                    AddComponentToTreeView(PointChildComponent, ImageIndex, tvFrom, nil);
                  end;
            end;



            {//***************** ХУЙНЯ ****

            PointComponent := SCSPort.ComponentOwner;
            PointTopComponent := PointComponent.GetTopComponent;

            //*** Найти/загрузить подключенный кросс
            for i := 0 to PointComponent.JoinedComponents.Count - 1 do
            begin
              JoinedComponent := PointComponent.JoinedComponents[i];
              if JoinedComponent.ID_ComponentType in [ctPatchCord, ctCrossPointObject] then
              begin
                CrossComponent := JoinedComponent;
                ImageIndex := GetComponImageIndexByFilling(JoinedComponent.IsLine, JoinedComponent.GetFilling(biNone, itFunctional, false));
                CrossNode := AddComponentToTreeView(JoinedComponent, ImageIndex, tvFrom, nil);
                if CrossNode <> nil then
                  tvFrom.Selected := CrossNode;
                Break; ///// BREAK /////
              end;
            end;

            //*** Найти второй подключенный порт
            if CrossComponent <> nil then
              for i := 0 to CrossComponent.JoinedComponents.Count - 1 do
              begin
                JoinedComponent := CrossComponent.JoinedComponents[i];
                if JoinedComponent <> PointComponent then
                begin
                  SecondPointComponent := JoinedComponent;
                  Break; ///// BREAK /////
                end;
              end;
            //*** Загрузить кросс в дерево с подключенным портом на второй стороне
            if SecondPointComponent <> nil then
              LoadComponentsToCrossConfigurator(tvTo, CrossComponent, SecondPointComponent)
            else //*** Загрузить сам шкаф
              LoadComponentsToCrossConfigurator(tvTo, PointComponent, nil);

            //*** Найти/загрузить недоподключенный/неподключенный кросс
            for i := 0 to PointTopComponent.ChildReferences.Count - 1 do
            begin
              PointChildComponent := PointTopComponent.ChildReferences[i];
              if PointChildComponent.ID_ComponentType in [ctPatchCord, ctCrossPointObject] then
                if PointChildComponent <> CrossComponent then
                  if PointChildComponent.JoinedComponents.Count < 2 then
                  begin
                    ImageIndex := GetComponImageIndexByFilling(PointChildComponent.IsLine, PointChildComponent.GetFilling(biNone, itFunctional, false));
                    AddComponentToTreeView(PointChildComponent, ImageIndex, tvFrom, nil);
                  end;
            end; }
          end;
        *)
    finally
      tvFrom.OnSelectedChanged := tvFromSavedOnSelectedChanged;
      tvFrom.Items.EndUpdate;
      tvTo.Items.EndUpdate;
      if IsConfiguratorMode then
        EnableDisableConfiguratorControls;
    end;
    LoadInterfacesWith(false);

    if FFormMode in [fmCrossConfigurator, fmCableConfigurator, fmPointObjectConfigurator] then //20.12.2011
    begin
      SelectObjectInPMFromTreeView(tvWith);
      //23.12.2011 tvInterfWithSide1SelectedChanged(nil, tvInterfWithSide1.Selected);
      //23.12.2011 tvInterfWithSide2SelectedChanged(nil, tvInterfWithSide2.Selected);
    end;

    if tvFrom.Selected <> nil then
      if Assigned(tvFrom.OnSelectedChanged) then
      begin
        tvFrom.OnSelectedChanged(nil, tvFrom.Selected);
      end;

    //23.12.2011 - интерфейсы выделяем уже после того как насыпался tvFrom 
    if FFormMode in [fmCrossConfigurator, fmCableConfigurator, fmPointObjectConfigurator] then
    begin
      tvInterfWithSide1SelectedChanged(nil, tvInterfWithSide1.Selected);
      tvInterfWithSide2SelectedChanged(nil, tvInterfWithSide2.Selected);
    end;
  finally
    FIsHandlingtvWith := false;
  end;
  //20.12.2011
  //if FFormMode in [fmCrossConfigurator, fmCableConfigurator, fmPointObjectConfigurator] then
  //begin
  //  SelectObjectInPMFromTreeView(tvWith);
  //  tvInterfWithSide1SelectedChanged(nil, tvInterfWithSide1.Selected);
  //  tvInterfWithSide2SelectedChanged(nil, tvInterfWithSide2.Selected);
  //end;
end;

procedure TF_MakeEditCrossConnection.tvFromDblClick(Sender: TObject);
begin
  if (FFormMode = fmCableConfigurator) and (rbSelectByPoint.Checked) then
    SelectNodeByJoinedComponImageIndex(tvTo);
end;


procedure TF_MakeEditCrossConnection.tvFromSelectedChanged(OldNode,
  NewNode: TFlyNode);
var
  LineComponent: TSCSComponent;

  PointObjectFirstFromTree: TSCSCatalog;
  PointObjectFirst: TSCSCatalog;
  PointObjectLast: TSCSCatalog;

  ResPointComponent: TSCSComponent;
  ResPointObject: TSCSCatalog;
  tvToNode: TFlyNode;
  ComponAtFromTree: TSCSComponent;

  ObjJoinedConnFrom: TSCSCatalog;
  ObjJoinedConnTo: TSCSCatalog;

  tvToSavedOnSelectedChanged: TTreeSelChangedEvent;
begin
  if (OldNode = NewNode) and (NewNode <> nil) then
    Exit; ///// EXIT /////


  if IsThroughConfiguratorMode then
  begin
    //*** Если в левой панеле выбор идет по точ. компонентам,
    //    то здесь находить подключенные точ. компоненты к тек. выбранному для правой панеле
    if (FFormMode = fmCableConfigurator) and rbSelectByPoint.Checked then
    begin
      tvTo.Items.BeginUpdate;
      try
        FLineComponFromSide := nil;
        FLineComponToSide := nil;

        LineComponent := nil;
        PointObjectFirst := nil;
        PointObjectLast := nil;
        ResPointComponent := nil;
        ResPointObject := nil;

        if (tvFrom.Selected <> nil) and (tvFrom.Selected.Data <> nil) then
          if TObject(tvFrom.Selected.Data) is TSCSComponent then
            LineComponent := TSCSComponent(tvFrom.Selected.Data);

        //tvTo.Items.Clear;
        if LineComponent <> nil then
        begin
          PointObjectFirstFromTree := GetCatalogFromTreeView(tvWith);
          ComponAtFromTree := GetComponentFromNode(tvWith.Selected);

          if (LineComponent.FirstIDCompon = 0) or (LineComponent.LastIDCompon = 0) then
          begin
            LineComponent.LoadWholeComponent(false);
            LineComponent.DefineFirstLast;
            DefinePointObjectsForLineCompon(LineComponent, ObjJoinedConnFrom, ObjJoinedConnTo);
          end;

          if (LineComponent.FirstIDCompon <> 0) and (LineComponent.LastIDCompon <> 0) then
          begin
            DefinePointObjectsForLineCompon(LineComponent, PointObjectFirst, PointObjectLast);

            FLineComponFromSide := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(LineComponent.FirstIDCompon);
            FLineComponToSide := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(LineComponent.LastIDCompon);
            SendFirstLastIDsToPartComponent(LineComponent, FLineComponFromSide);
            SendFirstLastIDsToPartComponent(LineComponent, FLineComponToSide);

            if (PointObjectFirst <> nil) and (PointObjectLast <> nil) then
            //28.01.2011 if (PointObjectFirst <> nil) and (PointObjectFirst <> nil) then
            begin
              if (PointObjectFirst = PointObjectFirstFromTree) and (PointObjectLast <> PointObjectFirstFromTree) then
              begin
                ResPointComponent := LineComponent.LastConnectedConnCompon;
                ResPointObject := PointObjectLast;
              end
              else
              if (PointObjectFirst <> PointObjectFirstFromTree) and (PointObjectLast = PointObjectFirstFromTree) then
              begin
                ResPointComponent := LineComponent.FirstConnectedConnCompon;
                ResPointObject := PointObjectFirst;
                ExchangeObjects(FLineComponFromSide, FLineComponToSide);
              end
              else
              begin
                //28.01.2011 На случай если LineComponent.LastConnectedConnCompon и LineComponent.FirstConnectedConnCompon
                //28.01.2011 в одном одном объекте, то выделить нужно тот который не в панеле слева
                if ComponAtFromTree <> LineComponent.LastConnectedConnCompon then
                begin
                  ResPointComponent := LineComponent.LastConnectedConnCompon;
                  ResPointObject := PointObjectLast;
                end
                else
                begin
                  ResPointComponent := LineComponent.FirstConnectedConnCompon;
                  ResPointObject := PointObjectFirst;
                end;
              end;
            end
            else
            if (PointObjectFirst <> nil) and (PointObjectFirst <> PointObjectFirstFromTree) then
            begin
              ResPointComponent := LineComponent.FirstConnectedConnCompon;
              ResPointObject := PointObjectFirst;
              ExchangeObjects(FLineComponFromSide, FLineComponToSide);
            end
            else
            if (PointObjectLast <> nil) and (PointObjectLast <> PointObjectFirstFromTree) then
            begin
              ResPointComponent := LineComponent.LastConnectedConnCompon;
              ResPointObject := PointObjectLast;
            end;
          end;
          if ResPointObject <> nil then
          begin
            FPointComponentTo := ResPointComponent;

            tvToNode := GetComponentNodeFromTreeView(tvTo, ResPointComponent);
            if tvToNode <> nil then
            begin
              tvToSavedOnSelectedChanged := tvTo.OnSelectedChanged;
              tvTo.OnSelectedChanged := nil;
              try
                SelectNodeFly(tvTo, tvToNode); //tvTo.Selected := tvToNode;
              finally
                tvTo.OnSelectedChanged := tvToSavedOnSelectedChanged;
                if Assigned(tvTo.OnSelectedChanged) then
                  tvTo.OnSelectedChanged(nil, tvTo.Selected);
              end;
            end;
            //DefineTreeViewImageIndex(tvTo, ResPointComponent);

            if GetComponIdentificatorInComplex(GetComponentFromNode(tvWith.Selected)) <> -1 then
              DefineTVImageIndexWithTrunkNodes(tvWith.Selected, tvTo, FLineComponToSide) //DefineTrunkNodeImageIndex(tvWith.Selected, tvTo.Selected, FLineComponToSide, true)
            else
              DefineTreeViewImageIndex(tvTo, FLineComponToSide, true);
          end;
        end;
      finally
        tvTo.Items.EndUpdate;
      end;
    end;

    {if (FFormMode = fmCableConfigurator) and rbSelectByPoint.Checked then
    begin
      tvTo.Items.BeginUpdate;
      try
        tvTo.Items.Clear;

        LineComponent := nil;
        PointObjectFirst := nil;
        PointObjectLast := nil;
        ResPointComponent := nil;
        ResPointObject := nil;
        if (tvFrom.Selected <> nil) and (tvFrom.Selected.Data <> nil) then
          if TObject(tvFrom.Selected.Data) is TSCSComponent then
            LineComponent := TSCSComponent(tvFrom.Selected.Data);
        if LineComponent <> nil then
        begin
          PointObjectFirstFromTree := GetCatalogFromTreeView(tvWith);

          if (LineComponent.FirstIDCompon > 0) and (LineComponent.LastIDCompon > 0) then
          begin
            DefinePointObjectsForLineCompon(LineComponent, PointObjectFirst, PointObjectLast);

            if (PointObjectFirst <> nil) and (PointObjectFirst <> nil) then
            begin
              if (PointObjectFirst = PointObjectFirstFromTree) and (PointObjectLast <> PointObjectFirstFromTree) then
              begin
                ResPointComponent := LineComponent.LastConnectedConnCompon;
                ResPointObject := PointObjectLast;
              end
              else
              if (PointObjectFirst <> PointObjectFirstFromTree) and (PointObjectLast = PointObjectFirstFromTree) then
              begin
                ResPointComponent := LineComponent.FirstConnectedConnCompon;
                ResPointObject := PointObjectFirst;
              end;
            end;
          end;
          if ResPointObject <> nil then
            if (GetComponentFromTreeView(tvTo) <> ResPointComponent) or (ResPointComponent = nil) then
              LoadComponentsToCableConfigurator(tvTo, ResPointComponent, ResPointObject, false);
        end;
      finally
        tvTo.Items.EndUpdate;
      end;
    end; }
    //SelectObjectInPMFromTreeView(TTreeView(Sender));
  end;
  LoadInterfacesFrom(false);
  //ExchangeInterfWithInTreeSidesIfCan;

  tvInterfFromSide1SelectedChanged(nil, tvInterfFromSide1.Selected);
  tvInterfFromSide2SelectedChanged(nil, tvInterfFromSide2.Selected);
  if IsThroughConfiguratorMode then
    if rbSelectByPoint.Checked then
      DefineInterfTreeViewImageIndex(tvInterfTo, GetInterfInfoListFromTree(tvInterfFromSide1), GetInterfInfoListFromTree(tvInterfFromSide2), true);

  if (FFormMode = fmPointObjectConfigurator) or ((FFormMode = fmCableConfigurator) and rbSelectByPoint.Checked) then
  begin
    // Определить иконки подключенных компонентов, на тот случай, если в этом дереве несколько подкюченных компонентов к tvWith
    DefineInterfTreeViewImageIndex(tvInterfFromSide1, GetInterfInfoListFromTree(tvInterfWithSide1), GetInterfInfoListFromTree(tvInterfWithSide2), true);
    DefineInterfTreeViewImageIndex(tvInterfFromSide2, GetInterfInfoListFromTree(tvInterfWithSide1), GetInterfInfoListFromTree(tvInterfWithSide2), true);
  end;

  if IsConfiguratorMode then
  begin
    EnableDisableConfiguratorControls;
    SelectObjectInPMFromTreeView(tvFrom);
  end;
end;

procedure TF_MakeEditCrossConnection.tvToSelectedChanged(OldNode,
  NewNode: TFlyNode);
begin
  if (OldNode = NewNode) and (NewNode <> nil) then
    Exit; ///// EXIT /////

  if IsThroughConfiguratorMode then
  begin
    //*** Если в левой панеле выбор идет 9по точ. компонентам
    if (FFormMode = fmCableConfigurator) and rbSelectByPoint.Checked then
    begin
      //*** Определить лин-е компоненты, трасса которых подключена к текщему объекту
      DefineCableWhoseTracesConnectedToObject(tvFrom, GetObjectFromNode(NewNode, ''));
    end;

    EnableDisableConfiguratorControls;
    SelectObjectInPMFromTreeView(tvTo);
  end;
  LoadInterfacesTo(false);
  //ExchangeInterfWithInTreeSidesIfCan;
end;

procedure TF_MakeEditCrossConnection.pnInterfResize(Sender: TObject);
var
  Panels: TList;
  Panel: TControl;
  i: integer;
begin
  {Panels := TList.Create;
  Panels.Add(pnInterfWith);
  Panels.Add(pnInterfFrom);
  Panels.Add(pnInterfTo);
  for i := 0 to Panels.Count - 1 do
  begin
    Panel := TControl(Panels[i]);
    if Panel <> Sender then
      Panel.Height := TControl(Sender).Height;
  end;
  Panels.Free;}
end;

procedure TF_MakeEditCrossConnection.btExtendedModeClick(Sender: TObject);
begin
  SetControlsForInterfaces;

  if btExtendedMode.Down then
  begin
    if Not FLoadedInterfacesWith then
      LoadInterfacesWith(false);
    if Not FLoadedInterfacesFrom then
      LoadInterfacesFrom(false);
    if Not FLoadedInterfacesTo then
    begin
      LoadInterfacesTo(false);

      tvInterfWithSide1SelectedChanged(nil, tvInterfWithSide1.Selected);
      tvInterfWithSide2SelectedChanged(nil, tvInterfWithSide2.Selected);

      tvInterfFromSide1SelectedChanged(nil, tvInterfFromSide1.Selected);
      tvInterfFromSide2SelectedChanged(nil, tvInterfFromSide2.Selected);
    end;
  end;
end;

procedure TF_MakeEditCrossConnection.Splitter1CanResize(Sender: TObject;
  var NewSize: Integer; var Accept: Boolean);
begin
  //
end;


procedure TF_MakeEditCrossConnection.tvInterfWithSide1SelectedChanged(
  OldNode, NewNode: TFlyNode);
begin
  if OldNode = NewNode then
    Exit; ///// EXIT /////

  {$IF NOT Defined (FINAL_SCS)}
    GetInterfInfoFromTree(tvInterfWithSide1);
  {$IFEND}

  DefineInterfTreeViewImageIndex(tvInterfFromSide1, GetInterfInfoListFromTree(tvInterfWithSide1), GetInterfInfoListFromTree(tvInterfWithSide2), true);
  if spInterfWithSide2.LowerRight.Visible then
    DefineInterfTreeViewImageIndex(tvInterfTo, GetInterfInfoListFromTree(tvInterfWithSide1), GetInterfInfoListFromTree(tvInterfWithSide2), true);

  if (FFormMode = fmPointObjectConfigurator) then
    DefineInterfTreeViewImageIndex(tvInterfFromSide2, GetInterfInfoListFromTree(tvInterfWithSide1), GetInterfInfoListFromTree(tvInterfWithSide2), true);

  EnableDisableConfiguratorControls; 
end;

procedure TF_MakeEditCrossConnection.tvInterfWithSide2DblClick(
  Sender: TObject);
begin
  //23.12.2011 SelectNodeByJoinedComponImageIndex(tvTo);
  //23.12.2011 SelectNodeByJoinedInterfImageIndex(tvInterfTo);
  //23.12.2011 DefineInterfTreeViewImageIndex(tvInterfTo, GetInterfInfoListFromTree(tvInterfWithSide2), GetInterfInfoListFromTree(tvInterfWithSide1), true);
  SelectJoinedInterfInfoNode(tvInterfWithSide2, tvInterfWithSide1, tvTo, tvInterfTo);
end;


procedure TF_MakeEditCrossConnection.tvInterfWithSide2SelectedChanged(
  OldNode, NewNode: TFlyNode);
begin
  if OldNode = NewNode then              //
    Exit; ///// EXIT /////

  DefineInterfTreeViewImageIndex(tvInterfTo, GetInterfInfoListFromTree(tvInterfWithSide2), GetInterfInfoListFromTree(tvInterfWithSide1), true);

  if (FFormMode = fmPointObjectConfigurator) then
    DefineInterfTreeViewImageIndex(tvInterfFromSide2, GetInterfInfoListFromTree(tvInterfWithSide1), GetInterfInfoListFromTree(tvInterfWithSide2), true);

  EnableDisableConfiguratorControls;
end;

procedure TF_MakeEditCrossConnection.tvInterfFromSide1SelectedChanged(
  OldNode, NewNode: TFlyNode);
begin
  if OldNode = NewNode then
    Exit; ///// EXIT /////

  EnableDisableConfiguratorControls;
end;

procedure TF_MakeEditCrossConnection.tvInterfFromSide2DblClick(
  Sender: TObject);
begin
  //23.12.2011 SelectNodeByJoinedComponImageIndex(tvTo);
  //23.12.2011 SelectNodeByJoinedInterfImageIndex(tvInterfTo);
  //23.12.2011 DefineInterfTreeViewImageIndex(tvInterfTo, GetInterfInfoListFromTree(tvInterfFromSide1), GetInterfInfoListFromTree(tvInterfFromSide2), true);

  SelectJoinedInterfInfoNode(tvInterfFromSide2, tvInterfFromSide1, tvTo, tvInterfTo);
end;


procedure TF_MakeEditCrossConnection.tvInterfFromSide2SelectedChanged(
  OldNode, NewNode: TFlyNode);
begin
  if OldNode = NewNode then
    Exit; ///// EXIT /////
  if spInterfFromSide2.LowerRight.Visible then
    DefineInterfTreeViewImageIndex(tvInterfTo, GetInterfInfoListFromTree(tvInterfFromSide1), GetInterfInfoListFromTree(tvInterfFromSide2), true);

  EnableDisableConfiguratorControls;
end;

procedure TF_MakeEditCrossConnection.tvInterfToSelectedChanged(OldNode,
  NewNode: TFlyNode);
begin
  if OldNode = NewNode then
    Exit; ///// EXIT /////
    
  EnableDisableConfiguratorControls;
end;

procedure TF_MakeEditCrossConnection.Timer_AfterShowPointObjectConfiguratorTimer(
  Sender: TObject);
begin
  TTimer(Sender).Enabled := false;

  LoadComponentsForPointObjectConfigurator(FCatalog);
end;

procedure TF_MakeEditCrossConnection.spInterfFromSide2Change(
  Sender: TObject);
var
  Splitters: TList;
  Splitter: TRzSplitter;
  i: integer;
  SavedOnChange: TNotifyEvent;
begin
  Exit; ///// EXIT /////
  Splitters := TList.Create;
  Splitters.Add(spInterfWith);
  Splitters.Add(spInterfFrom);
  Splitters.Add(spInterfTo);
  for i := 0 to Splitters.Count - 1 do
  begin
    Splitter := TRzSplitter(Splitters[i]);
    if Splitter <> Sender then
    begin
      SavedOnChange := Splitter.OnResize;
      Splitter.OnResize := nil;
      try
        Splitter.Position := TRzSplitter(Sender).Position;
      finally
        Splitter.OnResize := SavedOnChange;
      end;
    end;
  end;
  Splitters.Free;
end;

procedure TF_MakeEditCrossConnection.spInterfChange(Sender: TObject);
begin
  Timer_spInterfMouseUp.Tag := Integer(Sender);
  Timer_spInterfMouseUpTimer(Timer_spInterfMouseUp);
end;

procedure TF_MakeEditCrossConnection.spInterfWithDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  // Включаем обработку Resize
  TRzSplitter(Sender).OnChange := spInterfChange;
end;


procedure TF_MakeEditCrossConnection.spInterfMouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  //Timer_spInterfMouseUp.Enabled := true;
  //Timer_spInterfMouseUp.Tag := Integer(Sender);

  // Отключаем обработку Resize
  TRzSplitter(Sender).OnChange := nil;
end;

procedure TF_MakeEditCrossConnection.Timer_spInterfMouseUpTimer(
  Sender: TObject);
var
  Splitters: TList;
  Splitter: TRzSplitter;
  i: integer;
  SavedOnChange: TNotifyEvent;
  SavedOnResize: TNotifyEvent;
begin
  TTimer(Sender).Enabled := false;

  Splitters := TList.Create;
  Splitters.Add(spInterfWith);
  Splitters.Add(spInterfFrom);
  Splitters.Add(spInterfTo);
  for i := 0 to Splitters.Count - 1 do
  begin
    Splitter := TRzSplitter(Splitters[i]);
    if Splitter <> TObject(TTimer(Sender).Tag) then
    begin
      SavedOnChange := Splitter.OnChange;
      Splitter.OnChange := nil;
      SavedOnResize := Splitter.OnResize;
      Splitter.OnResize := nil;
      try
        Splitter.Position := TRzSplitter(TTimer(Sender).Tag).Position;
      finally
        Splitter.OnChange := SavedOnChange;
        Splitter.OnResize := SavedOnResize;
      end;
    end;
  end;
  Splitters.Free;
end;

procedure TF_MakeEditCrossConnection.spInterfWithResize(Sender: TObject);
begin
  //Timer_spInterfMouseUp.Enabled := true;
  Timer_spInterfMouseUp.Tag := Integer(spInterfWith);

  Timer_spInterfMouseUpTimer(Timer_spInterfMouseUp);
end;

procedure TF_MakeEditCrossConnection.tvInterfWithSide1DblClick(
  Sender: TObject);
begin
  //23.12.2011 SelectNodeByJoinedComponImageIndex(tvFrom);
  //23.12.2011 SelectNodeByJoinedInterfImageIndex(tvInterfFromSide1);
  //23.12.2011 DefineInterfTreeViewImageIndex(tvInterfFromSide1, GetInterfInfoListFromTree(tvInterfWithSide1), GetInterfInfoListFromTree(tvInterfWithSide2), true);
  SelectJoinedInterfInfoNode(tvInterfWithSide1, tvInterfWithSide2, tvFrom, tvInterfFromSide1);
end;


procedure TF_MakeEditCrossConnection.tvInterfSelectCell(
  Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
var
  //EarlierSelectedNode: TFlyNode;
  //EarlierInterfInfo: TInterfInfo;

  SelectedNodes: TList;
  NodeToSelect: TFlyNode;
  //InterfInfoToSelect: TInterfInfo;
begin
  if ACol = TFlyTreeViewPro(Sender).StructureCol then
  begin
    NodeToSelect := TFlyTreeViewPro(Sender).GetNodeAtRow(ARow);

    // Если при выделении не нажаты CTRL или SHIFT, то запомнить выделенную ветвь как якорь
    if ((GetKeyState(VK_SHIFT) AND $80) = 0) and ((GetKeyState(VK_CONTROL) AND $80) = 0) then
    begin
      SelectedNodes := TList.Create;
      TFlyTreeViewPro(Sender).FillSelectedList(SelectedNodes);

      if SelectedNodes.Count = 1 then
        SetAnchorNodeToTree(TFlyTreeViewPro(Sender), NodeToSelect);
      SelectedNodes.Free;
    end
    else
    // иначе если нажат CTRL или SHIFTто после выделения сбросить не подходящие выделения
    if ((GetKeyState(VK_SHIFT) AND $80) = $80) or ((GetKeyState(VK_CONTROL) AND $80) = $80) then
    begin
      Timer_SetAnchorNode.Tag := Integer(Sender);
      Timer_SetAnchorNode.Enabled := true;
    end;

    {
    InterfInfoToSelect := nil;
    if NodeToSelect <> nil then
      InterfInfoToSelect := TInterfInfo(NodeToSelect.Data);

    if InterfInfoToSelect <> nil then
    begin

      EarlierSelectedNode := TFlyTreeViewPro(Sender).Items.GetFirstSelectedNode;
      while EarlierSelectedNode <> nil do
      begin
        EarlierInterfInfo := TInterfInfo(EarlierSelectedNode.Data);
        if (NodeToSelect.Parent = EarlierSelectedNode) or
           (EarlierSelectedNode.Parent = NodeToSelect) or
           (EarlierInterfInfo.IsBusy <> InterfInfoToSelect.IsBusy) then
        begin
          CanSelect := false;
          Break; //// BREAK ////
        end;
        EarlierSelectedNode := TFlyTreeViewPro(Sender).Items.GetNextSelectedNode(EarlierSelectedNode);
      end;
    end;}
  end;

  Timer_AfterSelectedInterfNode.Tag := Integer(Sender);
  Timer_AfterSelectedInterfNode.Enabled := true;
end;

procedure TF_MakeEditCrossConnection.Timer_SetAnchorNodeTimer(
  Sender: TObject);
var
  InterfTreeView: TFlyTreeViewPro;
  AnchorNode: TFlyNode;
  AnchorInterfInfo: TInterfInfo;

  SelectedNodes: TList;
  EarlierSelectedNode: TFlyNode;
  EarlierInterfInfo: TInterfInfo;
  i: Integer;
begin
  TTImer(Sender).Enabled := false;

  try
    InterfTreeView := TFlyTreeViewPro(TTImer(Sender).Tag);
    if InterfTreeView <> nil then
    begin
      AnchorNode := GetAnchorNodeFromTree(InterfTreeView);
      if AnchorNode <> nil then
      begin
        AnchorInterfInfo := TInterfInfo(AnchorNode.Data);

        SelectedNodes := TList.Create;
        InterfTreeView.FillSelectedList(SelectedNodes);
        if SelectedNodes.Count > 1 then
        begin
          for i := 0 to SelectedNodes.Count - 1 do
          begin
            EarlierSelectedNode := TFlyNode(SelectedNodes[i]);
            if EarlierSelectedNode <> AnchorNode then
            begin
              EarlierInterfInfo := TInterfInfo(EarlierSelectedNode.Data);
              if (AnchorNode.Parent = EarlierSelectedNode) or
                 (EarlierSelectedNode.Parent = AnchorNode) or
                 (EarlierInterfInfo.IsBusy <> AnchorInterfInfo.IsBusy) then
              begin
                EarlierSelectedNode.Selected := false;
              end;
            end;
          end;
          InterfTreeView.Repaint;
        end;
        FreeAndNil(SelectedNodes);
      end;
    end;
    TTImer(Sender).Tag := 0;
  except
    on E: Exception do AddExceptionToLogEx('TF_MakeEditCrossConnection.Timer_AfterSelectedInterfNodeTimer', E.Message);
  end;
end;

procedure TF_MakeEditCrossConnection.Timer_AfterSelectedInterfNodeTimer(
  Sender: TObject);
var
  Interfinfo: TInterfinfo;
  TreeView: TFlyTreeViewPro;
begin
  TTimer(Sender).Enabled := false;

  try
    TreeView := TFlyTreeViewPro(TTimer(Sender).Tag);
    if TreeView <> nil then
      if TreeView.Selected <> nil then
        if TreeView.Selected.Data <> nil then
      begin
        Interfinfo := TInterfinfo(TreeView.Selected.Data);
        TreeView.Columns[ciKolvoToConnect].ReadOnly := IntToBool(Interfinfo.IsBusy);

        SelectObjectInPMFromTreeView(TreeView); //20.12.2011
      end;
  except
    on E: Exception do AddExceptionToLogEx('TF_MakeEditCrossConnection.Timer_AfterSelectedInterfNodeTimer', E.Message);
  end;
end;


procedure TF_MakeEditCrossConnection.tvInterfEdited(
  Sender: TObject; Node: TFlyNode; var S: String);
var
  InterfInfo: TinterfInfo;
  NewKolvoToConnect: Integer;
begin
  if (TFlyTreeViewPro(Sender).Col = ciKolvoToConnect) and (Node <> nil) then
  begin
    InterfInfo := TInterfInfo(Node.Data);

    if InterfInfo.IsBusy = biFalse then
    begin
      NewKolvoToConnect := InterfInfo.KolvoToConnect;
      try
        NewKolvoToConnect := StrToInt(S);
      except
      end;

      if NewKolvoToConnect > InterfInfo.KolvoToConnect then
        S := IntToStr(InterfInfo.KolvoToConnect)
      else
        InterfInfo.KolvoToConnect := NewKolvoToConnect;
    end
    else
    begin
      S := '';
    end;
  end;
end;

procedure TF_MakeEditCrossConnection.tvInterfWithSide1DrawCell(
  Sender: TObject; aCanvas: TCanvas; ACol, ARow: Integer; Rect: TRect;
  State: TExGridDrawState);
var
  Node: TFlyNode;
  Interfinfo: TInterfinfo;
  ActualColumn: Integer;
begin
  Exit; ///// EXIT /////
  ActualColumn := TFlyTreeViewPro(Sender).Columns.VisibleColumn[ACol].Index;
  if ActualColumn = ciKolvoToConnect then
  begin
    Node := TFlyTreeViewPro(Sender).GetNodeAtRow(ARow);
    Interfinfo := nil;
    if Node <> nil then
      Interfinfo := TInterfinfo(Node.Data);
    if Interfinfo <> nil then
      if Interfinfo.IsBusy = biTrue then
      begin
        aCanvas.Brush.Color := $F4F4F4; //$F3F3F3; //clSkyBlue;
        aCanvas.FillRect(Rect);
        aCanvas.TextRect(Rect, Rect.Left + 1, Rect.Top + 1, Node.Cells[ActualColumn]);
      end;
  end;
end;

procedure TF_MakeEditCrossConnection.tvInterfGetNodeAttributes(
  Node: TFlyNode; Column: Integer; aFont: TFont; var BackColor: TColor;
  var Alignment: TAlignment);
var
  Interfinfo: TInterfinfo;
  ActualColumn: Integer;
begin
  if Column = ciInterface then
  begin
    if Node <> nil then
      if Node.ImageIndex = tciiConnectedInterface then
        aFont.Style := aFont.Style + [fsBold];
  end
  else
  begin
    Interfinfo := nil;
    if Node <> nil then
      Interfinfo := TInterfinfo(Node.Data);
    if Interfinfo <> nil then
      if Column = ciKolvoToConnect then
      begin
        if Interfinfo.IsBusy = biTrue then
        begin
          // Если эта ветвь не выделена
          if (Node.Tree.Row <> Node.GetRow) and (Node.Tree.Col <> Column) then
            BackColor := clDisabledCell;
        end;
      end
      else
      if Column = ciColor then
      begin
        if Interfinfo.FInterface <> nil then
          BackColor := Interfinfo.FInterface.Color;
      end;
  end;
end;


procedure TF_MakeEditCrossConnection.Act_FindConnectedExecute(
  Sender: TObject);
begin
  if ActiveControl is TFlyTreeViewPro then
  begin
    if Assigned(TFlyTreeViewPro(ActiveControl).OnDblClick) then
      TFlyTreeViewPro(ActiveControl).OnDblClick(ActiveControl);
  end;
end;

procedure TF_MakeEditCrossConnection.Act_AddToGroupExecute(
  Sender: TObject);
var
  GroupComponsPanel: TGroupComponsPanel;
  ActiveTree: TFlyTreeViewPro;

  FindedNode: TFlyNode;
begin
  ActiveTree := GetFocusedTreeView;

  if (ActiveTree = tvWith) or (ActiveTree = tvTo) then
    if ActiveTree.Selected <> nil then
    begin
      GroupComponsPanel := GetGroupComponsPanelByTree(ActiveTree, true);
      if GroupComponsPanel <> nil then
      begin
        FindedNode := GetTreeViewNodeByDataFly(GroupComponsPanel.Tree, ActiveTree.Selected.Data, true);

        if FindedNode = nil then
          GroupComponsPanel.AddNodeFrom(ActiveTree.Selected, true);

        EnableDisableConfiguratorControls;
      end;
    end;
end;


procedure TF_MakeEditCrossConnection.Act_FindInGroupExecute(
  Sender: TObject);
var
  ActiveTree: TFlyTreeViewPro;
  GoupComponsPanel: TGroupComponsPanel;

  FindedNode: TFlyNode;
begin
  ActiveTree := GetFocusedTreeView;
  if ActiveTree <> nil then
    if ActiveTree.Selected <> nil then
  begin
    GoupComponsPanel := GetGroupComponsPanelByTree(ActiveTree, false);
    if GoupComponsPanel <> nil then
    begin
      FindedNode := GetTreeViewNodeByDataFly(GoupComponsPanel.Tree, ActiveTree.Selected.Data, false);
      if FindedNode <> nil then
        GoupComponsPanel.Tree.Selected := FindedNode
      else
        MessageModal(cMakeEditCrossConnection_Msg35, ApplicationName, MB_OK or MB_ICONINFORMATION);
    end;
  end;
end;

procedure TF_MakeEditCrossConnection.pmCommonPopup(Sender: TObject);
var
  FocusedTree: TFlyTreeViewPro;
  pmiInterfPathVisible: Boolean;
  MenuItem: TMenuItem;
  InterfInfo: TInterfInfo;
  i, j: integer;
  InterfPosition: TSCSInterfPosition;
  InterfPosConnection: TSCSInterfPosConnection;
begin
  if pmiInterfPath.Visible then
  begin
    pmiInterfPathVisible := false;
    FocusedTree := GetFocusedTreeView;
    if (FocusedTree = tvInterfWithSide1) or
       (FocusedTree = tvInterfWithSide2) or
       (FocusedTree = tvInterfFromSide1) or
       (FocusedTree = tvInterfFromSide2) or
       (FocusedTree = tvInterfTo) then
    if FInterfTrees.IndexOf(FocusedTree) <> -1 then
    begin
      InterfInfo := GetInterfInfoFromTree(FocusedTree);
      {if (InterfInfo <> nil) and (InterfInfo.FInterface.ComponentOwner.IsLine = biTrue) and
         (InterfInfo.IsBusy = biTrue) then
      begin
        pmiInterfPathVisible := true;
        // Чистим подпункты
        for i := pmiInterfPath.Count - 1 downto 0 do
        begin
          MenuItem := pmiInterfPath.Items[i];
          pmiInterfPath.Remove(MenuItem);
          MenuItem.Free;
        end;

        for i := 0 to InterfInfo.FInterface.BusyPositions.Count - 1 do
        begin
          InterfPosition := TSCSInterfPosition(InterfInfo.FInterface.BusyPositions[i]);
          MenuItem := TMenuItem.Create(Self);
          MenuItem.Caption := IntToStr(InterfPosition.FromPos)+' - '+IntToStr(InterfPosition.ToPos);
          MenuItem.Tag := Integer(InterfPosition);
          pmiInterfPath.Add(MenuItem);
        end;
      end;}

      if (InterfInfo <> nil) and (InterfInfo.IsBusy = biTrue) and
         CheckSysNameIsCable(InterfInfo.FInterface.ComponentOwner.ComponentType.SysName) then
        if LoadInterfPositionsToMenuItem(pmiInterfPath, InterfInfo.FInterface, OnpmiInterfPathClick) then
          pmiInterfPathVisible := true;
    end;
    pmiInterfPath.Visible := pmiInterfPathVisible;
  end;
end;


procedure TF_MakeEditCrossConnection.TimerSelectObjInPMTimer(
  Sender: TObject);
var
  NodeObject: TObject;
  SCSCatalog: TSCSCatalog;
  SCSComponent: TSCSComponent;
  SCSInterface: TSCSInterface;
  GridIndex: Integer;
  MT: TkbmMemTable;
begin
  TTimer(Sender).Enabled := false;

  //TimerSelectObjInPM
  if FTreeViewSelInPM.Selected <> nil then
    if FTreeViewSelInPM.Selected.Data <> nil then
      if cbSelectObjectsInPM.Checked and
         Not GIsProgress and             //14.01.2011 - выделяем если щас не идет выполнение действия, тоесть не висит прогресс
         ((FIsHandlingtvWith = false) or (FTreeViewSelInPM = tvWith)) then
      begin
        SCSCatalog := nil;
        SCSComponent := nil;
        SCSInterface := nil;

        NodeObject := TObject(FTreeViewSelInPM.Selected.Data);
        if NodeObject is TSCSCatalog then
          SCSCatalog := TSCSCatalog(NodeObject)
        else
        if NodeObject is TSCSComponent then
          SCSComponent := TSCSComponent(NodeObject)
        else
        if NodeObject is TSCSInterface then
        begin
          SCSInterface := TSCSInterface(NodeObject);
          SCSComponent := SCSInterface.ComponentOwner;
        end
        else
        if NodeObject is TInterfInfo then
        begin
          SCSInterface := TInterfInfo(NodeObject).FInterface;
          SCSComponent := SCSInterface.ComponentOwner;
        end;
        if TF_Main(GForm).GDBMode = bkProjectManager then // Tolik 31/08/2021 --
        begin
          if SCSCatalog <> nil then
          begin
            if SCSCatalog.TreeViewNode = nil then
              TF_Main(GForm).FindComponOrDirInTree(SCSCatalog.ID, false);
            if SCSCatalog.TreeViewNode <> nil then
              TF_Main(GForm).SelectNodeDirect(SCSCatalog.TreeViewNode); //TF_Main(GForm).Tree_Catalog.Selected := SCSCatalog.TreeViewNode;
          end
          else
          if SCSComponent <> nil then
          begin
            if SCSComponent.TreeViewNode <> nil then
              TF_Main(GForm).SelectNodeDirect(SCSComponent.TreeViewNode) //TF_Main(GForm).Tree_Catalog.Selected := SCSComponent.TreeViewNode
            else
              TF_Main(GForm).SelectComponByIDInTree(SCSComponent.ID);
          end;
        end;

        if SCSInterface <> nil then
        begin
          GridIndex := cdliPort;
          MT := TF_Main(GForm).DM.MemTable_Port;
          if SCSInterface.IsPort = biFalse then
          begin
            GridIndex := cdliInterface;
            MT := TF_Main(GForm).DM.MemTable_InterfaceRel;
          end;
          if TF_Main(GForm).Grid_CompData.ActiveLevel.Index <> GridIndex then
            TF_Main(GForm).Grid_CompData.ActiveLevel := TF_Main(GForm).Grid_CompData.Levels[GridIndex];
          MT.Locate(fnID, SCSInterface.ID, []);
        end;
      end;
end;

procedure TF_MakeEditCrossConnection.Act_ExtProtocolExecute(
  Sender: TObject);
begin
  ShowLog;
end;

procedure TF_MakeEditCrossConnection.SetCorrectImage(PortNode: TFlyNode);
var
  ChNode: TFlyNode;
  flag: Boolean;
  ListFull,ListNotFull: Tlist;
begin
  Flag := false;
  ListFull := TList.Create;
  ListNotFull := TList.Create;
  if PortNode <> nil then
  begin
    if PortNode.HasChildren then
      ChNode := PortNode.getFirstChild;
    While ChNode <> nil do
    begin
      if TInterfInfo(ChNode.Data).IsBusy = 0{ChNode.ImageIndex = 36} then
        ListNotFull.Add(ChNode)
      else
        ListFull.Add(chNode);
      ChNode := PortNode.GetNextChild(ChNode);
    end;

    if (ListNotFull.Count > 0)and(ListFull.Count > 0) then   //Если есть занятые и пустые интерфейсы
    begin
      if TInterfInfo(PortNode.Data).IsBusy=0 {PortNode.ImageIndex = 65} then                     //Если ПОРТ не подключен
        PortNode.ImageIndex := 63
      else
      if TInterfInfo(PortNode.Data).IsBusy=1{PortNode.ImageIndex = 66} then                     //Если ПОРТ подключен
        PortNode.ImageIndex := 68;

      TInterfInfo(PortNode.Data).ImageIndex := PortNode.ImageIndex;
      PortNode.SelectedIndex := PortNode.ImageIndex;
    end
    else
    if (ListNotFull.Count = 0)and(ListFull.Count > 0) then  //Если все занятые интерфейсы
    begin
      if TInterfInfo(PortNode.Data).IsBusy=0 {PortNode.ImageIndex = 65} then                     //Если ПОРТ не подключен
        PortNode.ImageIndex := 64
      else
      if TInterfInfo(PortNode.Data).IsBusy=1{PortNode.ImageIndex = 66} then                     //Если ПОРТ подключен
        PortNode.ImageIndex := 67;

      TInterfInfo(PortNode.Data).ImageIndex := PortNode.ImageIndex;
      PortNode.SelectedIndex := PortNode.ImageIndex;
    {end
    else
    if (ListNotFull.Count > 0)and(ListFull.Count = 0) then  //Если все пустые интерфейсы
    begin }
    end;
  end;
  ListFull.Free;
  ListNotFull.Free;
end;

end.

