unit U_MasterDefectAct;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, RzEdit, RzTabs, RzPanel, ExtCtrls, Mask, RzSpnEdt, ComCtrls,
  RzButton, exgrid, RapTree, FlytreePro, Menus,

  U_BaseConstants, U_BaseCommon, U_SCSComponent, U_SCSLists, U_SCSClasses, U_ProtectionCommon, ActnList, XPMenu, siComp,
  siLngLnk, bz2, CommCtrl, ToolWin, RzRadChk, U_ResourceReport;

const
  //Group Type
  gtDefect = 1;
  gtNormal = 2;

type
  TF_MasterDefectAct = class(TForm)
    RzPanel1: TRzPanel;
    pnOkCancel: TRzPanel;
    btClose: TRzBitBtn;
    tvCompons: TFlyTreeViewPro;
    Splitter1: TSplitter;
    pmCompons: TPopupMenu;
    ActionList1: TActionList;
    Act_SetDefectToCompons: TAction;
    Act_SetNormalToCompons: TAction;
    N1: TMenuItem;
    N2: TMenuItem;
    XPMenu1: TXPMenu;
    lng_Forms: TsiLangLinked;
    btOk: TRzBitBtn;
    btCancel: TRzBitBtn;
    RzPanel2: TRzPanel;
    RzGroupBox1: TRzGroupBox;
    pcDefectAct: TRzPageControl;
    tsFindDefect: TRzTabSheet;
    Splitter2: TSplitter;
    RzGroupBox3: TRzGroupBox;
    meFindDefectAdress: TRzMemo;
    RzGroupBox4: TRzGroupBox;
    meFindDefectDescription: TRzMemo;
    tsLinkTransport: TRzTabSheet;
    Splitter4: TSplitter;
    RzPanel3: TRzPanel;
    Splitter3: TSplitter;
    RzGroupBox5: TRzGroupBox;
    meLinkTransportPointA: TRzMemo;
    RzGroupBox6: TRzGroupBox;
    meLinkTransportPointB: TRzMemo;
    RzPanel5: TRzPanel;
    lbLinkTransportCable: TLabel;
    seLinkTransportCable: TRzSpinEdit;
    RzPanel4: TRzPanel;
    RzGroupBox7: TRzGroupBox;
    meLinkTransportMaterials: TRzMemo;
    tsSetEquipment: TRzTabSheet;
    Splitter5: TSplitter;
    Splitter6: TSplitter;
    RzGroupBox8: TRzGroupBox;
    meSetEquipmentAddress: TRzMemo;
    RzGroupBox9: TRzGroupBox;
    meSetEquipmentEqipm: TRzMemo;
    RzGroupBox10: TRzGroupBox;
    meSetEquipmentMaterial: TRzMemo;
    tsMoveEquipment: TRzTabSheet;
    Splitter8: TSplitter;
    Splitter9: TSplitter;
    RzPanel6: TRzPanel;
    Splitter7: TSplitter;
    RzGroupBox11: TRzGroupBox;
    meMoveEquipmentPointA: TRzMemo;
    RzGroupBox12: TRzGroupBox;
    meMoveEquipmentPointB: TRzMemo;
    RzGroupBox13: TRzGroupBox;
    meMoveEquipmentEqipm: TRzMemo;
    RzGroupBox14: TRzGroupBox;
    meMoveEquipmentMaterial: TRzMemo;
    RzGroupBox2: TRzGroupBox;
    Label14: TLabel;
    Label15: TLabel;
    Label16: TLabel;
    edContractor: TRzEdit;
    dtDateGetting: TRzDateTimeEdit;
    dtDateExecution: TRzDateTimeEdit;
    btApply_: TRzBitBtn;
    _btShowReport: TRzBitBtn;
    ToolBar1: TToolBar;
    btApply: TToolButton;
    btShowReport: TToolButton;
    RzPanel10: TRzPanel;
    cbMoveEquipmentChecked: TRzCheckBox;
    RzPanel9: TRzPanel;
    cbFindDefectChecked: TRzCheckBox;
    RzPanel7: TRzPanel;
    cbSetEquipmentChecked: TRzCheckBox;
    RzPanel8: TRzPanel;
    cbLinkTransportChecked: TRzCheckBox;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure tvComponsDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    procedure tvComponsDragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure tvComponsGetNodeAttributes(Node: TFlyNode; Column: Integer;
      aFont: TFont; var BackColor: TColor; var Alignment: TAlignment);
    procedure tvComponsSelectCell(Sender: TObject; ACol, ARow: Integer;
      var CanSelect: Boolean);
    procedure Act_SetDefectToComponsExecute(Sender: TObject);
    procedure Act_SetNormalToComponsExecute(Sender: TObject);
    procedure pmComponsPopup(Sender: TObject);
    procedure tvComponsSelectedChanged(OldNode, NewNode: TFlyNode);
    procedure btApplyClick(Sender: TObject);
    procedure pnOkCancelResize(Sender: TObject);
    procedure pcDefectActTabClick(Sender: TObject);
    procedure pcDefectActMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure btShowReportClick(Sender: TObject);

  private
    GForm: TForm;

    FCatalog: TSCSCatalog;
    FUOM: Integer;
    FDefActStream: TMemoryStream;

    FDefectGroupNode: TFlyNode;
    FNormalGroupNode: TFlyNode;

    function AddNodeToComponTree(AParentNode: TFlyNode; const ACaption: String; AImageindex: Integer; AData: Pointer): TFlyNode;
    function AddComponGroupToTree(AGroupCaption: string; AGroupIndex: Integer; ACompons: TStringList): TFlyNode;
    function GetComponFromNode(ANode: TFlyNode): TSCSComponent;
    function GetDefectActFromNode(ANode: TFlyNode): TDefectAct;
    function GetObjectsBlobFromNode(ANode: TFlyNode): TObjectsBlob;
    procedure LoadTree;
    procedure MoveSelectedComponsGroupNode(AGroupNode: TFlyNode);
    procedure SendDefActFromClassToForm(ADefectAct: TDefectAct);
    procedure SendDefActFromFormToClass(ADefectAct: TDefectAct);
    procedure SendDefActFromNodeToForm(ANode: TFlyNode);
    procedure SendDefActFromFormToNodes;
    procedure SetComponIsDefect(AComponent: TSCSComponent; AGroupIndex: Integer);
  public
    Constructor Create(AOwner: TComponent; AForm: TForm);
    Destructor Destroy; override;

    procedure Execute(AFormMode: TFormMode; ACatalog: TSCSCatalog; ACanReport: Boolean; AUOM: Integer);
  end;

//var
//  Form1: TForm1;

implementation
Uses U_Main, Unit_DM_SCS, USCS_Main, ImgList;

{$R *.dfm}

function TF_MasterDefectAct.AddNodeToComponTree(AParentNode: TFlyNode;
  const ACaption: String; AImageindex: Integer; AData: Pointer): TFlyNode;
begin
  Result := AddNodeToTreeViewFly(tvCompons, AParentNode, ACaption, AImageindex, -1, AData);
end;

function TF_MasterDefectAct.AddComponGroupToTree(AGroupCaption: string; AGroupIndex: Integer; ACompons: TStringList): TFlyNode;
var
  GroupNode: TFlyNode;
  i: integer;
  SCSComponent: TSCSComponent;
begin
  GroupNode := AddNodeToComponTree(nil, AGroupCaption, -1, Pointer(AGroupIndex));
  Result := GroupNode;
  for i := 0 to ACompons.Count - 1 do
  begin
    SCSComponent := TSCSComponent(ACompons.Objects[i]);
    AddNodeToComponTree(GroupNode, ACompons[i], GetComponImageIndexByFilling(SCSComponent.IsLine, foNone, false), SCSComponent);
  end;
  if GroupNode.Count > 0 then
    GroupNode.Expanded := true;
end;

function TF_MasterDefectAct.GetComponFromNode(ANode: TFlyNode): TSCSComponent;
begin
  Result := nil;
  if ANode <> nil then
    if ANode.Level > 0 then
      if TObject(ANode.Data) is TSCSComponent then
        Result := TSCSComponent(ANode.Data);
end;

function TF_MasterDefectAct.GetDefectActFromNode(ANode: TFlyNode): TDefectAct;
var
  //ObjBlob: TObjectsBlob;
  //UnpackedStream: TMemoryStream;
  Compon: TSCSComponent;
begin
  Result := nil;

  {ObjBlob := GetObjectsBlobFromNode(ANode);
  if ObjBlob <> nil then
  begin
    UnpackedStream := TMemoryStream.Create;
    UnPakStream(ObjBlob.ObjectData, UnpackedStream);
    UnpackedStream.Position := 0;

    Result := TDefectAct.Create(nil);
    Result.LoadFromStream(UnpackedStream);

    FreeAndNil(UnpackedStream);
  end;}
  Compon := GetComponFromNode(ANode);
  if Compon <> nil then
    Result := Compon.ProjectOwner.GetComponDefectAct(Compon);
end;

function TF_MasterDefectAct.GetObjectsBlobFromNode(ANode: TFlyNode): TObjectsBlob;
var
  Compon: TSCSComponent;
begin
  Result := nil;
  Compon := GetComponFromNode(ANode);
  if Compon <> nil then
    Result := Compon.ProjectOwner.GetObjectsBlobByParams(tiComponent, obdkDefectAct, Compon.ID);
end;

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

destructor TF_MasterDefectAct.Destroy;
begin
  inherited;
end;

procedure TF_MasterDefectAct.Execute(AFormMode: TFormMode; ACatalog: TSCSCatalog; ACanReport: Boolean; AUOM: Integer);
begin
  FCatalog := ACatalog;
  FUOM := AUOM;
  LoadTree;

  btShowReport.Visible := ACanReport;

  btOk.Visible := AFormMode <> fmView;
  btCancel.Visible := AFormMode <> fmView;
  btClose.Visible := AFormMode = fmView;

  Caption := cMasterDefectAct_Msg2 + ' '+cInterfaceInfo_Msg8+' '+ ACatalog.GetNameForVisible;
  lbLinkTransportCable.Caption := cMakeEditComponentType_Msg5_18 +', '+ GetNameUOM(AUOM, true);

  pnOkCancelResize(pnOkCancel);

  ShowModal;

  TF_Main(GForm).RefreshNode(false);
end;

procedure TF_MasterDefectAct.FormCreate(Sender: TObject);
var
  FButtonstImageIndex: Integer;
begin
  seLinkTransportCable.Max := 0;

  //tvCompons.Columns.Clear;
  tvCompons.Items.Clear;
  tvCompons.Images.Clear;
  tvCompons.Images.AddImages(TF_Main(GForm).DM.ImageList_Dir);
  FButtonstImageIndex := tvCompons.Images.Count;
  tvCompons.Images.AddImages(TF_Main(GForm).DM.ImageList_FlyTree);
  //tvCompons.ButtonCollapsedIndex := (TF_Main(GForm).DM.ImageList_Dir.Count-1) + 1;
  //tvCompons.ButtonExpandedIndex := (TF_Main(GForm).DM.ImageList_Dir.Count-1) + 2;
  tvCompons.ButtonCollapsedIndex := tbiCollapsed + FButtonstImageIndex;
  tvCompons.ButtonCheckedIndex := tbiChecked + FButtonstImageIndex;
  tvCompons.ButtonExpandedIndex := tbiExpanded + FButtonstImageIndex;
  tvCompons.ButtonGrayedIndex := tbiGrayed + FButtonstImageIndex;
  tvCompons.ButtonUnCheckedIndex := tbiUnchecked + FButtonstImageIndex;
  tvCompons.DefaultRowHeight := 17;
  tvCompons.FixedRows := 0;
  tvCompons.FitColumnToClientWidth := true;
  tvCompons.Indent := 17;
  //tvCompons.Options := tvCompons.Options + [goColSizing] - [goDrawFocusSelected, goHorzLine, goVertLine, goRangeSelect];
  tvCompons.Options := tvCompons.Options + [goColSizing, goRangeSelect, goRowMoving] - [goDrawFocusSelected, goHorzLine, goVertLine];
  tvCompons.ShowImages := true;
  tvCompons.ShowLogic := true;
  tvCompons.StatesDrawed := false;

  SetStyleToRZDateTimeEdit(dtDateGetting);
  SetStyleToRZDateTimeEdit(dtDateExecution);

  Act_SetDefectToCompons.Tag := gtDefect;
  Act_SetNormalToCompons.Tag := gtNormal;

  FDefActStream := TMemoryStream.Create;
end;

procedure TF_MasterDefectAct.LoadTree;
var
  DefectCompons: TStringList;
  NormalCompons: TStringList;
  SCSComponent: TSCSComponent;

  i: Integer;
  LookedWholeIDs: TIntList;
begin
  tvCompons.Items.Clear;

  DefectCompons := TStringList.Create; //}CreateStringListSorted;
  NormalCompons := TStringList.Create; //}CreateStringListSorted;

  LookedWholeIDs := TIntList.Create;

  for i := 0 to FCatalog.ComponentReferences.Count - 1 do
  begin
    SCSComponent := FCatalog.ComponentReferences[i];
    // Tolik
    // учтем тип сетей, выбранных пользователем на форме отчетов
    if (F_ProjMan.F_ResourceReport.AllNetTypes or (F_ProjMan.F_ResourceReport.NetTypeGuidListSelected.IndexOf(SCSComponent.GUIDNetType) <> -1)) then
    begin
      if (SCSComponent.Whole_ID = 0) or (LookedWholeIDs.IndexOf(SCSComponent.Whole_ID) = -1) then
      begin
        case SCSComponent.GetPropertyValueAsBooleanDef(pnDefect, false) of
          true:
            DefectCompons.AddObject(SCSComponent.GetNameForVisible, SCSComponent);
          false:
            NormalCompons.AddObject(SCSComponent.GetNameForVisible, SCSComponent);
        end;
        if SCSComponent.Whole_ID <> 0 then
          LookedWholeIDs.Add(SCSComponent.Whole_ID);
      end;
    end;
  end;

  FreeAndNil(LookedWholeIDs);

  DefectCompons.Sort;
  NormalCompons.Sort;

  FDefectGroupNode := AddComponGroupToTree(cMasterDefectAct_Msg1_1, gtDefect, DefectCompons);
  FNormalGroupNode := AddComponGroupToTree(cMasterDefectAct_Msg1_2, gtNormal, NormalCompons);

  FreeAndNil(DefectCompons);
  FreeAndNil(NormalCompons);
end;

procedure TF_MasterDefectAct.MoveSelectedComponsGroupNode(AGroupNode: TFlyNode);
var
  SelectedNode: TFlyNode;
  SelectedNodes: TList;
  i: integer;
begin
  if AGroupNode <> nil then
  begin
    SelectedNodes := TList.Create;
    tvCompons.FillSelectedList(SelectedNodes);
    if SelectedNodes.Count > 0 then
    begin
      try
        for i := 0 to SelectedNodes.Count - 1 do
        begin
          SelectedNode := TFlyNode(SelectedNodes[i]);

          SelectedNode.MoveTo(AGroupNode, naAddChild);
          SetComponIsDefect(TSCSComponent(SelectedNode.Data), Integer(AGroupNode.Data));
        end;
      finally
        tvCompons.Selected := nil; //SrcNode;
        tvCompons.Selected := TFlyNode(SelectedNodes[0]);
        SelectTreeViewNodesFly(tvCompons, SelectedNodes, true);
      end;
    end;

    FreeAndNil(SelectedNodes);
  end;
end;

procedure TF_MasterDefectAct.SendDefActFromClassToForm(
  ADefectAct: TDefectAct);
var
  DefectAct: TDefectAct;
begin
  DefectAct := ADefectAct;
  // Если не определен ДА, то создаем пустой для очистки полей
  if DefectAct = nil then
    DefectAct := TDefectAct.Create(nil);
  try
    cbFindDefectChecked.Checked := DefectAct.FindDefectChecked;
    meFindDefectAdress.Lines.Text := DefectAct.FindDefectAdress;
    meFindDefectDescription.Lines.Text := DefectAct.FindDefectDescription;

    cbLinkTransportChecked.Checked := DefectAct.LinkTransportChecked;
    meLinkTransportPointA.Lines.Text := DefectAct.LinkTransportPointA;
    meLinkTransportPointB.Lines.Text := DefectAct.LinkTransportPointB;
    seLinkTransportCable.Value := FloatInUOM(DefectAct.LinkTransportCable, umMetr, FUOM);
    meLinkTransportMaterials.Lines.Text := DefectAct.LinkTransportMaterials;

    cbSetEquipmentChecked.Checked := DefectAct.SetEquipmentChecked;
    meSetEquipmentAddress.Lines.Text := DefectAct.SetEquipmentAddress;
    meSetEquipmentEqipm.Lines.Text := DefectAct.SetEquipmentEqipm;
    meSetEquipmentMaterial.Lines.Text := DefectAct.SetEquipmentMaterial;

    cbMoveEquipmentChecked.Checked := DefectAct.MoveEquipmentChecked;
    meMoveEquipmentPointA.Lines.Text := DefectAct.MoveEquipmentPointA;
    meMoveEquipmentPointB.Lines.Text := DefectAct.MoveEquipmentPointB;
    meMoveEquipmentEqipm.Lines.Text := DefectAct.MoveEquipmentEqipm;
    meMoveEquipmentMaterial.Lines.Text := DefectAct.MoveEquipmentMaterial;

    edContractor.Text := DefectAct.Contractor;
    dtDateGetting.Date := DefectAct.DateGetting;
    dtDateExecution.Date := DefectAct.DateExecution;
  finally
    if ADefectAct = nil then
      FreeAndNil(DefectAct);
  end;
end;

procedure TF_MasterDefectAct.SendDefActFromFormToClass(
  ADefectAct: TDefectAct);
begin
  ADefectAct.FindDefectChecked := cbFindDefectChecked.Checked;
  ADefectAct.FindDefectAdress := meFindDefectAdress.Lines.Text;
  ADefectAct.FindDefectDescription := meFindDefectDescription.Lines.Text;

  ADefectAct.LinkTransportChecked := cbLinkTransportChecked.Checked;
  ADefectAct.LinkTransportPointA := meLinkTransportPointA.Lines.Text;
  ADefectAct.LinkTransportPointB := meLinkTransportPointB.Lines.Text;
  ADefectAct.LinkTransportCable := FloatInUOM(seLinkTransportCable.Value, FUOM, umMetr);
  ADefectAct.LinkTransportMaterials := meLinkTransportMaterials.Lines.Text;

  ADefectAct.SetEquipmentChecked := cbSetEquipmentChecked.Checked;
  ADefectAct.SetEquipmentAddress := meSetEquipmentAddress.Lines.Text;
  ADefectAct.SetEquipmentEqipm := meSetEquipmentEqipm.Lines.Text;
  ADefectAct.SetEquipmentMaterial := meSetEquipmentMaterial.Lines.Text;

  ADefectAct.MoveEquipmentChecked := cbMoveEquipmentChecked.Checked;
  ADefectAct.MoveEquipmentPointA := meMoveEquipmentPointA.Lines.Text;
  ADefectAct.MoveEquipmentPointB := meMoveEquipmentPointB.Lines.Text;
  ADefectAct.MoveEquipmentEqipm := meMoveEquipmentEqipm.Lines.Text;
  ADefectAct.MoveEquipmentMaterial := meMoveEquipmentMaterial.Lines.Text;

  ADefectAct.Contractor := edContractor.Text;
  ADefectAct.DateGetting := dtDateGetting.Date;
  ADefectAct.DateExecution := dtDateExecution.Date;
end;

procedure TF_MasterDefectAct.SendDefActFromNodeToForm(ANode: TFlyNode);
var
  DefectAct: TDefectAct;
begin
  DefectAct := GetDefectActFromNode(ANode);
  SendDefActFromClassToForm(DefectAct);
end;

procedure TF_MasterDefectAct.SendDefActFromFormToNodes;
var
  SelectedNodes: TList;
  i: integer;
  Node: TFlyNode;

  DefectAct: TDefectAct;
  DefectActStream: TmemoryStream;

  Compon: TSCSComponent;
  ObjBlob: TObjectsBlob;
begin
  try        
    SelectedNodes := TList.Create;
    tvCompons.FillSelectedList(SelectedNodes);
    if SelectedNodes.Count > 0 then
    begin
      DefectAct := TDefectAct.Create(nil);
      SendDefActFromFormToClass(DefectAct);
      DefectActStream := TmemoryStream.Create;
      DefectAct.SaveToStream(DefectActStream);
      FreeAndNil(DefectAct);

      PakStream(DefectActStream, DefectActStream, clBetter);
      DefectActStream.Position := 0;

      for i := 0 to SelectedNodes.Count - 1 do
      begin
        Node := TFlyNode(SelectedNodes[i]);

        Compon := GetComponFromNode(Node);
        if Compon <> nil then
        begin
          ObjBlob := GetObjectsBlobFromNode(Node);
          if ObjBlob = nil then
          begin
            ObjBlob := TObjectsBlob.Create(Compon.ActiveForm);
            ObjBlob.ID := Compon.ProjectOwner.GenIDByGeneratorIndex(giObjectsBlobID);
            ObjBlob.TableKind := tiComponent;
            ObjBlob.DataKind := obdkDefectAct;
            if Compon.IsLine = biFalse then
              ObjBlob.ObjIDs.Add(Compon.ID)
            else
            begin
              Compon.LoadWholeComponent(false);
              ObjBlob.ObjIDs.Assign(Compon.WholeComponent);
            end;
            Compon.ProjectOwner.ObjectsBlobs.AddObjectsBlob(ObjBlob);
          end;

          ObjBlob.ObjectData.Position := 0;
          DefectActStream.Position := 0;
          ObjBlob.ObjectData.CopyFrom(DefectActStream, 0);
          ObjBlob.ObjectData.Position := 0;
        end;
      end;
      FreeAndNil(DefectActStream);
    end;
    FreeAndNil(SelectedNodes);
  except
    on E: Exception do AddExceptionToLogEx('TF_MasterDefectAct.SendDefActFromFormToNodes', E.Message);
  end;
end;

procedure TF_MasterDefectAct.SetComponIsDefect(AComponent: TSCSComponent; AGroupIndex: Integer);
var
  SprProperty: TNBProperty;
  ptrProperty: PProperty;
  ComponList: TSCSComponents;
  i: Integer;
  Compon: TSCSComponent;
begin
  // Если нету свойства в справочнике, то создаем его
  SprProperty := AComponent.ProjectOwner.Spravochnik.CreatePropertyByStandartGUID(pnDefect, guidPropDefect, false);
  if SprProperty <> nil then
  begin
    ComponList := nil;
    if AComponent.IsLine = biTrue then
      ComponList := AComponent.ProjectOwner.GetComponentsByWholeID(AComponent.Whole_ID)
    else
    begin
      ComponList := TSCSComponents.Create(false);
      ComponList.Add(AComponent);
    end;

    if ComponList <> nil then
    begin
      for i := 0 to ComponList.Count - 1 do
      begin
        Compon := ComponList[i];

        ptrProperty := Compon.GetPropertyBySysName(pnDefect);
        if ptrProperty = nil then
        begin
          ptrProperty := Compon.GetPropertyAsNew;
          SprProperty.AssignToPProperty(ptrProperty);
        end;

        case AGroupIndex of
          gtDefect:
            Compon.SetPropertyValueAsBoolean(pnDefect, True);
          gtNormal:
            Compon.SetPropertyValueAsBoolean(pnDefect, False);
        end;
         TF_Main(GForm).OnChangeComponPropertyVal(ptrProperty, Compon);
      end;
      FreeAndNil(ComponList);
    end;
  end;
end;

procedure TF_MasterDefectAct.FormDestroy(Sender: TObject);
begin
  FreeAndNil(FDefActStream);
end;

procedure TF_MasterDefectAct.tvComponsDragOver(Sender, Source: TObject; X,
  Y: Integer; State: TDragState; var Accept: Boolean);
var
  TrgNode: TFlyNode;
  SrcNode: TFlyNode;
begin
  Accept := false;
  if Sender = Source then
  begin
    SrcNode := TFlyTreeViewPro(Source).Selected;
    TrgNode := TFlyTreeViewPro(Sender).GetNodeAt(X, Y);
    if (SrcNode <> nil) and (TrgNode <> nil) then
      if SrcNode.Level > 0 then // тащим не верхнюю ветку
        if GetParentNodeByLevelFly(SrcNode, 0) <> TrgNode then
        begin
          Accept := true;
        end;
  end;
end;

procedure TF_MasterDefectAct.tvComponsDragDrop(Sender, Source: TObject; X,
  Y: Integer);
var
  TrgNode: TFlyNode;
  SrcNode: TFlyNode;
  //SelectedNodes: TList;
  i: integer;
  //SelectedNode: TFlyNode;
begin
  if Sender = Source then
  begin
    SrcNode := TFlyTreeViewPro(Source).Selected;
    TrgNode := TFlyTreeViewPro(Sender).GetNodeAt(X, Y);
    if (SrcNode <> nil) and (TrgNode <> nil) then
    begin
      TrgNode := GetParentNodeByLevelFly(TrgNode, 0);

      {SelectedNodes := TList.Create;
      tvCompons.FillSelectedList(SelectedNodes);
      if SelectedNodes.IndexOf(SrcNode) <> -1 then
      begin
        try
          for i := 0 to SelectedNodes.Count - 1 do
          begin
            SelectedNode := TFlyNode(SelectedNodes[i]);

            SelectedNode.MoveTo(TrgNode, naAddChild);
            SetComponIsDefect(TSCSComponent(SelectedNode.Data), Integer(TrgNode.Data));
          end;
        finally
          tvCompons.Selected := SrcNode;
          SelectTreeViewNodesFly(tvCompons, SelectedNodes, true);
        end;
      end;

      FreeAndNil(SelectedNodes);}

      MoveSelectedComponsGroupNode(TrgNode);
    end;
  end;
end;

procedure TF_MasterDefectAct.tvComponsGetNodeAttributes(Node: TFlyNode;
  Column: Integer; aFont: TFont; var BackColor: TColor;
  var Alignment: TAlignment);
begin
  if (Node <> nil) and (Node.Level = 0) then
    aFont.Style := aFont.Style + [fsBold];
end;

procedure TF_MasterDefectAct.tvComponsSelectCell(Sender: TObject; ACol,
  ARow: Integer; var CanSelect: Boolean);
var
  SelectedNodes: TList;
  NodeToSelect: TFlyNode;
begin
  try
    //если нажат CTRL или SHIFT
    if ((GetKeyState(VK_SHIFT) AND $80) = $80) or ((GetKeyState(VK_CONTROL) AND $80) = $80) then
    begin
      SelectedNodes := TList.Create;
      TFlyTreeViewPro(Sender).FillSelectedList(SelectedNodes);
      if SelectedNodes.Count > 0 then
      begin
        NodeToSelect := TFlyTreeViewPro(Sender).GetNodeAtRow(ARow);
        if NodeToSelect <> nil then
          SelectedNodes.Add(NodeToSelect);
        if Not CheckNodesSameParentFly(SelectedNodes) then
          CanSelect := false;
      end;
      FreeAndNil(SelectedNodes);
    end;
  except
    on E: Exception do AddExceptionToLogEx('TF_MasterDefectAct.tvComponsSelectCell', E.Message);
  end;
end;

procedure TF_MasterDefectAct.Act_SetDefectToComponsExecute(
  Sender: TObject);
begin
  MoveSelectedComponsGroupNode(FDefectGroupNode);
end;

procedure TF_MasterDefectAct.Act_SetNormalToComponsExecute(
  Sender: TObject);
begin
  MoveSelectedComponsGroupNode(FNormalGroupNode);
end;

procedure TF_MasterDefectAct.pmComponsPopup(Sender: TObject);
var
  IsCanSetDefect: Boolean;
  IsCanSetNormal: Boolean;
  CurrGroupNode: TFlyNode;
begin
  IsCanSetDefect := false;
  IsCanSetNormal := false;

  if tvCompons.Selected <> nil then
    if tvCompons.Selected.Level > 0 then // Если выделена не группа
    if CheckSelectedNodesHaveSameParentFly(tvCompons) then
    begin
      CurrGroupNode := GetParentNodeByLevelFly(tvCompons.Selected, 0);
      case Integer(CurrGroupNode.Data) of
        gtDefect:
          IsCanSetNormal := true;
        gtNormal:
          IsCanSetDefect := true;
      end;
    end;

  Act_SetDefectToCompons.Enabled := IsCanSetDefect;
  Act_SetNormalToCompons.Enabled := IsCanSetNormal;
end;

procedure TF_MasterDefectAct.tvComponsSelectedChanged(OldNode,
  NewNode: TFlyNode);
begin
  if NewNode <> nil then
    if GetTreeViewSelectedNodesCountFly(tvCompons) <= 1 then
      SendDefActFromNodeToForm(tvCompons.Selected);
end;

procedure TF_MasterDefectAct.btApplyClick(Sender: TObject);
begin
  SendDefActFromFormToNodes;
end;

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

procedure TF_MasterDefectAct.pcDefectActTabClick(Sender: TObject);
var
  HitTestInfo: {TC_HITTESTINFO; //}TTCHitTestInfo;
  HitIndex: Integer;
  ScrCursorPos: TPoint;
  CursorPos: TPoint;
begin
  {GetCursorPos(ScrCursorPos);
  CursorPos := pcDefectAct.ScreenToClient(ScrCursorPos);

  HitTestInfo.pt.X := CursorPos.X;
  HitTestInfo.pt.Y := CursorPos.Y;
  HitTestInfo.flags := TCHT_ONITEM; //TCHT_ONITEMICON;//0;
  HitIndex := SendMessage(pcDefectAct.Handle, TCM_HITTEST, 0, Longint(@HitTestInfo));
  case HitIndex of
    1:
      ;
  end; }

  //pcDefectAct.ActivePage.
end;

procedure TF_MasterDefectAct.pcDefectActMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  HitTestInfo: {TC_HITTESTINFO; //}TTCHitTestInfo;
  HitIndex: Integer;
  ScrCursorPos: TPoint;
  CursorPos: TPoint;
begin
  {GetCursorPos(ScrCursorPos);
  CursorPos := pcDefectAct.ScreenToClient(ScrCursorPos);

  HitTestInfo.pt.X := X;
  HitTestInfo.pt.Y := Y;
  HitTestInfo.flags := TCHT_ONITEM; //TCHT_ONITEMICON;//0;
  HitIndex := SendMessage(pcDefectAct.Handle, TCM_HITTEST, 0, Longint(@HitTestInfo));
  case HitIndex of
    1:
      ;
  end;}
end;

procedure TF_MasterDefectAct.btShowReportClick(Sender: TObject);
var
  Compon: TSCSComponent;
  DefectAct: TDefectAct;
begin
  Compon := GetComponFromNode(tvCompons.Selected);
  if Compon <> nil then
  begin
    DefectAct := TDefectAct.Create(nil);
    SendDefActFromFormToClass(DefectAct);

    TF_Main(GForm).CreateFResourceReport.ShowDefectActForCompon(Compon, nil, DefectAct);
    FreeAndNil(DefectAct);
  end;
end;

end.
