unit U_Layers;

interface

uses
  Windows, U_LNG, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, cxLookAndFeelPainters, StdCtrls, cxButtons, ExtCtrls, Menus,
  ComCtrls,
  // POWERCAD
  PCPanel, PCDrawBox, PCDrawing, PowerCad, pcMsbar, XP_Panel, PCTypesUtils,
  DrawObjects, DlgBase,  ExtDlgs, PCLayerDlg, OleCtnrs, PCgui, GuiStrings,
  DrawEngine, U_ESCadClasess, siComp, siLngLnk, cxControls, cxContainer,
  cxEdit, cxCheckBox, RzButton, RzRadChk,
  U_SCSLists, RzPanel, RzTrkBar, cxGraphics, cxLookAndFeels;

type
  {TLayerItemData = record
    IsManualVisible: Boolean; // Вручную поставили видимость
    IsManualGrayed: Boolean; // Вручную поставили прозрачность
  end;}

  TF_LayersDialog = class(TForm)
    Panel1: TPanel;
    bLayersList: TcxButton;
    pmLayersList: TPopupMenu;
    N1: TMenuItem;
    N2: TMenuItem;
    N3: TMenuItem;
    N4: TMenuItem;
    N5: TMenuItem;
    N6: TMenuItem;
    N7: TMenuItem;
    N8: TMenuItem;
    N9: TMenuItem;
    lvLayersList: TListView;
    Panel2: TPanel;
    Label1: TLabel;
    lng_Forms: TsiLangLinked;
    Panel4: TPanel;
    lbCurLayer: TLabel;
    cbAllNetworks: TRzCheckBox;
    cbComputerNetwork: TRzCheckBox;
    cbTelephonNetwork: TRzCheckBox;
    cbElectricNetwork: TRzCheckBox;
    cbTelevisionNetwork: TRzCheckBox;
    cbGasNetwork: TRzCheckBox;
    cbShowCableChannelsOnly: TRzCheckBox;
    RzGroupBox1: TRzGroupBox;
    btSetDefGrayedColor: TButton;
    pnGrayedSample: TPanel;
    tbGrayed: TRzTrackBar;
    TimerTBGrayed: TTimer;
    E1: TMenuItem;
    N10: TMenuItem;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormShow(Sender: TObject);
    procedure lvLayersListMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormCreate(Sender: TObject);
    procedure lvLayersListSelectItem(Sender: TObject; Item: TListItem;
      Selected: Boolean);
    procedure lvLayersListMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure cbAllNetworksClick(Sender: TObject);
    procedure cbComputerNetworkClick(Sender: TObject);
    procedure cbTelephonNetworkClick(Sender: TObject);
    procedure cbElectricNetworkClick(Sender: TObject);
    procedure cbTelevisionNetworkClick(Sender: TObject);
    procedure cbGasNetworkClick(Sender: TObject);
    procedure cbShowCableChannelsOnlyClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure tbGrayedChange(Sender: TObject);
    procedure btSetDefGrayedColorClick(Sender: TObject);
    procedure tbGrayedDrawTick(TrackBar: TRzTrackBar; Canvas: TCanvas;
      Location: TPoint; Index: Integer);
    procedure TimerTBGrayedTimer(Sender: TObject);
    procedure E1Click(Sender: TObject);
    procedure N10Click(Sender: TObject);
  private
    FCADForm: TForm;
    FLSubstrate: TLayer;
    FLayersListItems: TList; //21.08.2012 - Соответствующие ListItem слоям из PCad
  public
    { Public declarations }
    DxfLayersOpened: Boolean;
    isGrayed: TShow;
    ListGrayed: TStringList;
    FIsManualGrayed: TIntList;
    FCreateDxfLayer: Boolean; // Tolik 30/08/2019 --
    function AddLayer(const aName: String): TListItem;
    procedure InitGrayedControls;
    procedure LoadFromCADForm(aCADForm: TForm);
    procedure SetGrayedColor(aColor: TColor; aFromControl: TObject);
    procedure Unload;
    procedure UpdateLayersList;
    procedure UpdateOptions(ALNbr: Integer; ASetFlag: Boolean);
    procedure UpdateNetworksOptions;
    function FinditemByLayer(aLayerIdx: Integer; aLayer: TLayer): TListItem;
  end;

var
  F_LayersDialog: TF_LayersDialog;

implementation
uses USCS_Main, U_CAD, U_Common, U_BaseCommon, U_Constants, U_NewLayer;

{$R *.dfm}

procedure TF_LayersDialog.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FSCS_Main.aViewLayers.Checked := false;
  Unload;
end;

procedure TF_LayersDialog.FormShow(Sender: TObject);
begin
  try
    LoadFromCADForm(GCadForm);
    {//06.08.2012
    UpdateLayersList;

    cbAllNetworks.OnClick := nil;
    cbComputerNetwork.OnClick := nil;
    cbTelephonNetwork.OnClick := nil;
    cbElectricNetwork.OnClick := nil;
    cbTelevisionNetwork.OnClick := nil;
    cbGasNetwork.OnClick := nil;

    if nt_All in GCadForm.FShowNetworkTypes then
    begin
      cbAllNetworks.Checked := True;
      cbComputerNetwork.Checked := false;
      cbComputerNetwork.Enabled := false;
      cbTelephonNetwork.Checked := false;
      cbTelephonNetwork.Enabled := false;
      cbElectricNetwork.Checked := false;
      cbElectricNetwork.Enabled := false;
      cbTelevisionNetwork.Checked := false;
      cbTelevisionNetwork.Enabled := false;
      cbGasNetwork.Checked := false;
      cbGasNetwork.Enabled := false;
    end
    else
    begin
      cbAllNetworks.Checked := false;
      cbComputerNetwork.Enabled := true;
      cbTelephonNetwork.Enabled := true;
      cbElectricNetwork.Enabled := true;
      cbTelevisionNetwork.Enabled := true;
      cbGasNetwork.Enabled := true;
      cbComputerNetwork.Checked := false;
      cbTelephonNetwork.Checked := false;
      cbElectricNetwork.Checked := false;
      cbTelevisionNetwork.Checked := false;
      cbGasNetwork.Checked := false;

      if nt_Computer in GCadForm.FShowNetworkTypes then
        cbComputerNetwork.Checked := True;
      if nt_Telephon in GCadForm.FShowNetworkTypes then
        cbTelephonNetwork.Checked := True;
      if nt_Electric in GCadForm.FShowNetworkTypes then
        cbElectricNetwork.Checked := True;
      if nt_Television in GCadForm.FShowNetworkTypes then
        cbTelevisionNetwork.Checked := True;
      if nt_Gas in GCadForm.FShowNetworkTypes then
       cbGasNetwork.Checked := True;
    end;

    cbAllNetworks.OnClick := cbAllNetworksClick;
    cbComputerNetwork.OnClick := cbComputerNetworkClick;
    cbTelephonNetwork.OnClick := cbTelephonNetworkClick;
    cbElectricNetwork.OnClick := cbElectricNetworkClick;
    cbTelevisionNetwork.OnClick := cbTelevisionNetworkClick;
    cbGasNetwork.OnClick := cbGasNetworkClick;

    InitGrayedControls;}
  except
    on E: Exception do AddExceptionToLogEx('TF_LayersDialog.FormShow', E.Message);
  end;
  {$IF Defined(ES_GRAPH_SC)}
    Panel4.Visible := False;
  {$ifend}
end;

function TF_LayersDialog.AddLayer(const aName: String): TListItem;
var
  NewLayer: TLayer;
  Item: TListItem;
  LayerNbr: Integer; // tolik 30/08/2019 --
begin
  NewLayer := TLayer.create(aName);
  // Tolik 30/08/2019 --
  if FCreateDxfLayer then
  begin
    NewLayer.isDxf := true;
    FCreateDxfLayer := False;
  end;

 { if FCreateDxfLayer then
  begin
    LayerNbr := GCadForm.PCad.NewLayer(aName);
    NewLayer := TLayer(GCadForm.PCad.Layers[LayerNbr]);
    NewLayer.isDxf := true;
    FCreateDxfLayer := False;
  end
  else
  begin
    NewLayer := TLayer.create(aName);
    TF_CAD(FCadForm).PCad.Layers.Add(NewLayer);
  end;  //
  }
  TF_CAD(FCadForm).PCad.Layers.Add(NewLayer);
  FSCS_Main.cbLayers.Properties.Items.Add(aName);
  Item := lvLayersList.Items.Add;
  Item.Caption := NewLayer.Name;
  // Tolik 31/08/2019 --
  if NewLayer.isDxf then
    Item.ImageIndex := 177
  else
  //
    Item.ImageIndex := 176; //06.08.2012 -1;
  Item.SubItems.Add('');
  Item.SubItems.Add('');
  Item.SubItemImages[0] := 136;
  Item.SubItemImages[1] := -1;
  Item.Data := NewLayer;
  listGrayed.Add('seen');
  if not GProjectChanged then // Tolik 28/08/2019 --
    SetProjectChanged(True);
  FIsManualGrayed.Add(biNone);

  //FLayersListItems[TF_CAD(FCadForm).PCad.Layers.Count - 1] := Item;
  FLayersListItems.Add(Item);
  // Tolik 01/11/2021 --
  if not GProjectChanged then
    SetProjectChanged(True);
  //
end;

procedure TF_LayersDialog.InitGrayedControls;
var
  Params: TListParams;
begin
  tbGrayed.Min := 0;
  tbGrayed.Max := Length(GrayedColors) - 1;

  Params := GetListParams(TF_CAD(FCADForm).FCADListID);
  SetGrayedColor(Params.Settings.CADGrayedColor, nil);
end;

procedure TF_LayersDialog.LoadFromCADForm(aCADForm: TForm);
begin
  if FCADForm <> aCADForm then
  begin
    FCADForm := aCADForm;
    FLSubstrate := TLayer(TF_CAD(FCADForm).PCad.GetLayer(lnSubstrate));
    UpdateLayersList;

    cbAllNetworks.OnClick := nil;
    cbComputerNetwork.OnClick := nil;
    cbTelephonNetwork.OnClick := nil;
    cbElectricNetwork.OnClick := nil;
    cbTelevisionNetwork.OnClick := nil;
    cbGasNetwork.OnClick := nil;

    if nt_All in TF_CAD(FCADForm).FShowNetworkTypes then
    begin
      cbAllNetworks.Checked := True;
      cbComputerNetwork.Checked := false;
      cbComputerNetwork.Enabled := false;
      cbTelephonNetwork.Checked := false;
      cbTelephonNetwork.Enabled := false;
      cbElectricNetwork.Checked := false;
      cbElectricNetwork.Enabled := false;
      cbTelevisionNetwork.Checked := false;
      cbTelevisionNetwork.Enabled := false;
      cbGasNetwork.Checked := false;
      cbGasNetwork.Enabled := false;
    end
    else
    begin
      cbAllNetworks.Checked := false;
      cbComputerNetwork.Enabled := true;
      cbTelephonNetwork.Enabled := true;
      cbElectricNetwork.Enabled := true;
      cbTelevisionNetwork.Enabled := true;
      cbGasNetwork.Enabled := true;
      cbComputerNetwork.Checked := false;
      cbTelephonNetwork.Checked := false;
      cbElectricNetwork.Checked := false;
      cbTelevisionNetwork.Checked := false;
      cbGasNetwork.Checked := false;

      if nt_Computer in TF_CAD(FCADForm).FShowNetworkTypes then
        cbComputerNetwork.Checked := True;
      if nt_Telephon in TF_CAD(FCADForm).FShowNetworkTypes then
        cbTelephonNetwork.Checked := True;
      if nt_Electric in TF_CAD(FCADForm).FShowNetworkTypes then
        cbElectricNetwork.Checked := True;
      if nt_Television in TF_CAD(FCADForm).FShowNetworkTypes then
        cbTelevisionNetwork.Checked := True;
      if nt_Gas in TF_CAD(FCADForm).FShowNetworkTypes then
       cbGasNetwork.Checked := True;
    end;

    cbAllNetworks.OnClick := cbAllNetworksClick;
    cbComputerNetwork.OnClick := cbComputerNetworkClick;
    cbTelephonNetwork.OnClick := cbTelephonNetworkClick;
    cbElectricNetwork.OnClick := cbElectricNetworkClick;
    cbTelevisionNetwork.OnClick := cbTelevisionNetworkClick;
    cbGasNetwork.OnClick := cbGasNetworkClick;

    InitGrayedControls;
  end;
end;

procedure TF_LayersDialog.SetGrayedColor(aColor: TColor; aFromControl: TObject);
var
  i: Integer;
  TrackPos: Integer;
  Params: TListParams;
begin
  // Tolik 01/11/2021 --
  if not GProjectChanged then
    SetProjectChanged(True);
  //
  //06.08.2012 GrayedColor := aColor;
  if aFromControl <> tbGrayed then
  begin
    TrackPos := -1;
    for i := 0 to Length(GrayedColors) - 1 do
      if GrayedColors[i] = aColor then
      begin
        TrackPos := i;
        Break; //// BREAK ////
      end;
    if TrackPos <> -1 then
      //tbGrayed.Position := TrackPos;
      tbGrayed.Position := Length(GrayedColors)-1 - TrackPos;
  end;
  if (aFromControl <> nil) and (FCADForm <> nil) then
  begin
    TF_CAD(FCADForm).PCad.FGrayedColor := aColor;
    //Tolik 21/10/2021 - -

    for i := 0 to TF_CAD(FCADForm).PCad.Figures.Count - 1 do
    begin
      if TFigure(TF_CAD(FCADForm).PCad.Figures[i]) is TBmpObject then
        TbmpObject(TF_CAD(FCADForm).PCad.Figures[i]).ImageEdited := True;
    end;

    //
    Params := GetListParams(TF_CAD(FCADForm).FCADListID);
    Params.Settings.CADGrayedColor := aColor;
    SaveCADListParams(TF_CAD(FCADForm).FCADListID, Params);

    Repaint;
    RefreshCAD(TF_CAD(FCADForm).PCad);
  end;
  pnGrayedSample.Color := aColor;
end;

procedure TF_LayersDialog.Unload;
begin
  lvLayersList.Items.BeginUpdate;
  try
    lvLayersList.Items.Clear;
  finally
    lvLayersList.Items.EndUpdate;
  end;
  FIsManualGrayed.Clear;
  FLayersListItems.Clear;
  FCADForm := nil;
end;

procedure TF_LayersDialog.UpdateLayersList;
var
  SubstItem, Item: TListItem;
  LayerName: string;
  CurLayer: TLayer;
  i: integer;
  DxfExist: Boolean;
begin
  try
    while listGrayed.Count < TF_CAD(FCADForm).PCad.Layers.Count do
      listGrayed.Add('seen');

    lvLayersList.Items.BeginUpdate;
    try
      lvLayersList.Items.Clear;
      FLayersListItems.Clear;
      for i := 0 to TF_CAD(FCADForm).PCad.Layers.Count - 1 do
        FLayersListItems.Add(nil);
      i := 0;

      // добавить слой подложки
      CurLayer := Tlayer(TF_CAD(FCADForm).PCad.Layers[1]);
      SubstItem := lvLayersList.Items.Add;
      SubstItem.Caption := CurLayer.Name;
      SubstItem.ImageIndex := 176;
      SubstItem.SubItems.Add('');
      SubstItem.SubItems.Add('');
      SubstItem.Data := CurLayer;
      FLayersListItems[1] := SubstItem;
      if CurLayer.visible = seen then
      begin
        SubstItem.SubItemImages[0] := 136;
        if listGrayed[i] = 'seen' then
          SubstItem.SubItemImages[1] := -1
        else
        if listGrayed[i] = 'grayed' then
          SubstItem.SubItemImages[1] := 137;
      end
      else
      if CurLayer.visible = grayed then
      begin
        SubstItem.SubItemImages[0] := 136;
        SubstItem.SubItemImages[1] := 137;
      end
      else
      begin
        SubstItem.SubItemImages[0] := -1;
        SubstItem.SubItemImages[1] := -1;
      end;

      // отобрать дхф слои
      DxfExist := false;
      for i := 10 to TF_CAD(FCADForm).PCad.Layers.Count - 1 do
      begin
        CurLayer := Tlayer(TF_CAD(FCADForm).PCad.Layers[i]);
        // если это ДХФ слой
        if CurLayer.IsDxf then
        begin
          Item := lvLayersList.Items.Add;
          Item.Caption := CurLayer.Name;
          Item.ImageIndex := 177;
          Item.SubItems.Add('');
          Item.SubItems.Add('');
          Item.Data := CurLayer;
          FLayersListItems[i] := Item;
          if CurLayer.visible = seen then
          begin
            Item.SubItemImages[0] := 136;
            if listGrayed[i] = 'seen' then
              Item.SubItemImages[1] := -1
            else
            if listGrayed[i] = 'grayed' then
              Item.SubItemImages[1] := 137;
          end
          else
          if CurLayer.visible = grayed then
          begin
            Item.SubItemImages[0] := 136;
            Item.SubItemImages[1] := 137;
          end
          else
          begin
            Item.SubItemImages[0] := -1;
            Item.SubItemImages[1] := -1;
          end;
        end;
      end;

      // добавить остальные
      for i := 2 to TF_CAD(FCADForm).PCad.Layers.Count - 1 do
      begin
        CurLayer := Tlayer(TF_CAD(FCADForm).PCad.Layers[i]);
        // если это НЕ ДХФ слой
        if not CurLayer.IsDxf then
        begin
          Item := lvLayersList.Items.Add;
          Item.Caption := CurLayer.Name;
          Item.ImageIndex := 176;
          Item.SubItems.Add('');
          Item.SubItems.Add('');
          Item.Data := CurLayer;
          FLayersListItems[i] := Item;
          if CurLayer.visible = seen then
          begin
            Item.SubItemImages[0] := 136;
            if listGrayed[i] = 'seen' then
              Item.SubItemImages[1] := -1
            else
            if listGrayed[i] = 'grayed' then
              Item.SubItemImages[1] := 137;
          end
          else
          if CurLayer.visible = grayed then
          begin
            Item.SubItemImages[0] := 136;
            Item.SubItemImages[1] := 137;
          end
          else
          begin
            Item.SubItemImages[0] := -1;
            Item.SubItemImages[1] := -1;
          end;
        end;
      end;
    finally
      lvLayersList.Items.EndUpdate;
    end;

    FIsManualGrayed.Clear;
    for i := 0 to TF_CAD(FCADForm).PCad.Layers.Count - 1 do
    begin
      CurLayer := Tlayer(TF_CAD(FCADForm).PCad.Layers[i]);
      //21.08.2012 if CurLayer.IsDxf and (CurLayer.visible = seen) then
      //21.08.2012 Если подложка серая, а dxf не серый, то ставим признак
      if CurLayer.IsDxf and (CurLayer.visible = seen) and (FLSubstrate.visible = grayed) then
        FIsManualGrayed.Add(biFalse)
      else
        FIsManualGrayed.Add(biNone);
    end;

    lbCurLayer.Caption := TF_CAD(FCADForm).PCad.GetLayerName(TF_CAD(FCADForm).PCad.ActiveLayer);
    //
    if (TF_CAD(FCADForm).PCad.Layers.Count - 1) <> FSCS_Main.cbLayers.Properties.Items.Count then
    begin
      FSCS_Main.cbLayers.Properties.BeginUpdate;
      try
        FSCS_Main.cbLayers.Properties.Items.Clear;
        for i := 1 to TF_CAD(FCADForm).PCad.LayerCount - 1 do
          FSCS_Main.cbLayers.Properties.Items.Add(TF_CAD(FCADForm).PCad.GetLayerName(i));
      finally
        FSCS_Main.cbLayers.Properties.EndUpdate;
      end;
    end;
  except
    on E: Exception do AddExceptionToLogEx('TF_LayersDialog.UpdateLayersList', E.Message);
  end;
end;

procedure TF_LayersDialog.lvLayersListMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  i: Integer;
  LayerItem, DxfItem: TListItem;
  CurLayer, DxfLayer: TLayer;
  LNbr, DxfLNbr: integer;
  ListSettings: TListSettingRecord;
  LayerIdx: Integer;

  Procedure BringtofrontSCSFigures; // Tolik 02/08/2023 --
  var i: integer;
      RefreshFlag: boolean;
      figList: TList;
  begin
    RefreshFlag := GCanRefreshCad;
    GCanRefreshCad := False;
    for i := 0 to GCadForm.FSCSFigures.Count - 1 do
    begin
      if TFigure(GCadForm.FSCSFigures[i]) is TConnectorObject then
      begin
        if TConnectorObject(GCadForm.FSCSFigures[i]).ConnectorType = ct_NB then
          if TConnectorObject(GCadForm.FSCSFigures[i]).DrawFigure <> nil then
            FigureBringToFront(Tfigure(TConnectorObject(GCadForm.FSCSFigures[i]).drawfigure));

      end
      else
      if TFigure(GCadForm.FSCSFigures[i]) is TOrthoLine then
      begin

      end;
      FigureBringToFront(TFigure(GCadForm.FSCSFigures[i]));
    end;
    GCanRefreshCad := True;
  end;
begin
  try
    //Tolik 01/11/2021 --
    if not GProjectChanged then
      SetProjectChanged(True);
    //
    TF_CAD(FCADForm).PCad.DeselectAll(TF_CAD(FCADForm).PCad.ActiveLayer);
    LayerItem := lvLayersList.GetItemAt(lvLayersList.TopItem.Position.X, Y);
    if LayerItem = nil then
      Exit;
    // колонка с именами, нафиг нам не нужна
    if X < 190 then
      Exit;
    // Layer с которым производиться операция !!!
    LNbr := TF_CAD(FCADForm).PCad.GetLayerNbr(LayerItem.Caption);
    CurLayer := TLayer(TF_CAD(FCADForm).PCad.Layers[LNbr]);
    LayerIdx := TF_CAD(FCADForm).PCad.Layers.IndexOf(CurLayer); //lvLayersList.Items.IndexOf(LayerItem);

    // колонка с видимостью слоев
    if (X > 190) and (X < 210) then
    begin
      // если это слой ДХФ, а видимость подложки отключена
      if (CurLayer.IsDxf) and (TLayer(TF_CAD(FCADForm).PCad.GetLayer(1)).visible = lost) then
        Exit;

      // слой был отображен - выключить
      if CurLayer.visible <> lost then
      begin
        if CurLayer.visible = seen then
          listGrayed[LNbr] := 'seen';
        if CurLayer.visible = grayed then
          listGrayed[LNbr] := 'grayed';
        LayerItem.SubItemImages[1] := -1;
        LayerItem.SubItemImages[0] := -1;
        CurLayer.visible := lost;
        UpdateOptions(LNbr, False);

        // если слой подложка, то отрегулировать дхф слои
        if LNbr = 1 then
        begin
          lvLayersList.Items.BeginUpdate;
          try
            for i := 10 to TF_CAD(FCADForm).PCad.LayerCount - 1 do
            begin
              DxfLayer := Tlayer(TF_CAD(FCADForm).PCad.Layers[i]);
              if DxfLayer.IsDxf then
              begin
                DxfItem := FinditemByLayer(i, DxfLayer);
                DxfItem.SubItemImages[0] := -1;
                DxfItem.SubItemImages[1] := -1;
                if DxfLayer.visible = seen then
                  listGrayed[i] := 'seen';
                if DxfLayer.visible = grayed then
                  listGrayed[i] := 'grayed';
                DxfLayer.tmpVisible := DxfLayer.visible;
                DxfLayer.visible := lost;
              end;
            end;
          finally
            lvLayersList.Items.EndUpdate;
          end;
        end;
        // **********************************************
      end
      else
      // слой был скрыт - включить
      if CurLayer.visible = lost then
      begin
        LayerItem.SubItemImages[0] := 136;
        if listGrayed[LNbr] = 'seen' then
          CurLayer.visible := seen;
        if listGrayed[LNbr] = 'grayed' then
        begin
          CurLayer.visible := grayed;
          LayerItem.SubItemImages[1] := 137;
        end;
        UpdateOptions(LNbr, True);

        // если слой подложка, то отрегулировать дхф слои
        if LNbr = 1 then
        begin
          lvLayersList.Items.BeginUpdate;
          try
            for i := 10 to TF_CAD(FCADForm).PCad.LayerCount - 1 do
            begin
              DxfLayer := Tlayer(TF_CAD(FCADForm).PCad.Layers[i]);
              if DxfLayer.IsDxf then
              begin
                DxfItem := FinditemByLayer(i, DxfLayer);
                if DxfLayer.tmpVisible = seen then
                begin
                  DxfItem.SubItemImages[0] := 136;
                  DxfItem.SubItemImages[1] := -1;
                  DxfLayer.visible := seen;
                end
                else
                if DxfLayer.tmpVisible = grayed then
                begin
                  // если подложка сама как подложка
                  if CurLayer.visible = grayed then
                  begin
                    DxfItem.SubItemImages[0] := 136;
                    DxfItem.SubItemImages[1] := 137;
                    DxfLayer.visible := grayed;
                  end
                  else
                  // если нет, то сделать из слоя обычный видимый
                  begin
                    DxfItem.SubItemImages[0] := 136;
                    DxfItem.SubItemImages[1] := -1;
                    DxfLayer.visible := seen;
                  end;
                end
                else
                if DxfLayer.tmpVisible = lost then
                begin
                  DxfItem.SubItemImages[0] := -1;
                  DxfItem.SubItemImages[1] := -1;
                  DxfLayer.visible := lost;
                end;
              end;
            end;
          finally
            lvLayersList.Items.EndUpdate;
          end;
        end;
        // **********************************************
      end;
      if not GProjectChanged then // Tolik 28/08/2019 --
        SetProjectChanged(True);
    end;

    // колонка с отображениями вида нормально-подложка
    if (X > 210) and (X < 230) then
    begin
      // если это слой ДХФ, а видимость подложки как подложки отключена
      if (CurLayer.IsDxf) and (TLayer(TF_CAD(FCADForm).PCad.GetLayer(1)).visible <> grayed) then
        Exit;

      // слой был прозрачным - сделать нормальным
      if CurLayer.visible = grayed then
      begin
        FIsManualGrayed[LayerIdx] := biFalse;

        CurLayer.visible := seen;
        LayerItem.SubItemImages[1] := -1;
        // если слой подложка, то отрегулировать дхф слои
        if LNbr = 1 then
        begin
          lvLayersList.Items.BeginUpdate;
          try
            for i := 10 to TF_CAD(FCADForm).PCad.LayerCount - 1 do
            begin
              DxfLayer := Tlayer(TF_CAD(FCADForm).PCad.Layers[i]);
              if DxfLayer.IsDxf then
              begin
                DxfItem := FinditemByLayer(i, DxfLayer);
                DxfItem.SubItemImages[1] := -1;
                DxfLayer.tmpVisible := DxfLayer.visible;
                if DxfLayer.visible = grayed then
                  DxfLayer.visible := seen;
              end;
            end;
          finally
            lvLayersList.Items.EndUpdate;
          end;
        end;
      end
      else
      // слой был обычным - сделать прозрачным
      if CurLayer.visible = seen then
      begin
        BringtofrontSCSFigures; // Tolik 02/08/2023 --
        CurLayer.visible := grayed;
        LayerItem.SubItemImages[1] := 137;

        FIsManualGrayed[LayerIdx] := biTrue;

        // если слой подложка, то отрегулировать дхф слои
        if LNbr = 1 then
        begin
          lvLayersList.Items.BeginUpdate;
          try
            for i := 10 to TF_CAD(FCADForm).PCad.LayerCount - 1 do
            begin
              DxfLayer := Tlayer(TF_CAD(FCADForm).PCad.Layers[i]);
              if DxfLayer.IsDxf then
              begin
                DxfItem := FinditemByLayer(i, DxfLayer);
                {//03.08.2012
                if DxfLayer.tmpVisible = grayed then
                begin
                  DxfItem.SubItemImages[1] := 137;
                  DxfLayer.visible := grayed;
                end
                else
                begin
                  DxfItem.SubItemImages[1] := -1;
                  //DxfLayer.visible := seen;
                end;}

                if FIsManualGrayed[i] <> biFalse then
                begin
                  DxfLayer.visible := grayed; //03.08.2012
                  DxfItem.SubItemImages[1] := 137;
                end
                else
                  DxfItem.SubItemImages[1] := -1;
              end;
            end;
          finally
            lvLayersList.Items.EndUpdate;
          end;
        end;
      end;
      //Tolik 20/10/2021 --
      for i := 0 to TF_CAD(FCADForm).PCad.Figures.Count - 1 do
      begin
        if TFigure(TF_CAD(FCADForm).PCad.Figures[i]) is TBMPObject then
        begin
          if TFigure(TF_CAD(FCADForm).PCad.Figures[i]).LayerHandle = integer(CurLayer) then
            TBMPObject(TF_CAD(FCADForm).PCad.Figures[i]).ImageEdited := true;
        end;
      end;
      //
      if not GProjectChanged then // Tolik 28/08/2019 --
        SetProjectChanged(True);
    end;

    RefreshCAD(TF_CAD(FCADForm).PCad);
  except
    on E: Exception do AddExceptionToLogEx('TF_LayersDialog.lvLayersListMouseDown', E.Message);
  end;
end;

procedure TF_LayersDialog.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  try
    FCADForm := nil;
    DxfLayersOpened := False;
    ListGrayed := TStringList.Create;
    for i := 0 to 9 do
      ListGrayed.Add('seen');

    FIsManualGrayed := TIntList.Create;
    FLayersListItems := TList.Create;
    FCreateDxfLayer := False; // Tolik 30/08/2019 --
  except
    on E: Exception do AddExceptionToLogEx('TF_LayersDialog.FormCreate', E.Message);
  end;
end;


procedure TF_LayersDialog.lvLayersListSelectItem(Sender: TObject;
  Item: TListItem; Selected: Boolean);
var
  LNbr: integer;
  LayerName: string;
begin
  try
    Selected := True;
    if lvLayersList.Selected <> nil then
    begin
      TF_CAD(FCADForm).PCad.DeselectAll(TF_CAD(FCADForm).PCad.ActiveLayer);
      LayerName := lvLayersList.Selected.Caption;
      TF_CAD(FCADForm).PCad.DeselectAll(TF_CAD(FCADForm).PCad.ActiveLayer);
      LNbr := TF_CAD(FCADForm).PCad.GetLayerNbr(LayerName);
      TF_CAD(FCADForm).CurrentLayer := LNbr;
      lbCurLayer.Caption := LayerName + '  ';
      if FSCS_Main.tbCADToolsExpert.Visible then
        FSCS_Main.tbSelectExpert.Down := True
      else
        FSCS_Main.tbSelectNoob.Down := True;
    end;
  except
    on E: Exception do AddExceptionToLogEx('TF_LayersDialog.lvLayersListSelectItem', E.Message);
  end;
end;

procedure TF_LayersDialog.N10Click(Sender: TObject);
begin
  FCreateDxfLayer := true;
  F_NewLayer.ShowModal;
end;

procedure TF_LayersDialog.UpdateOptions(ALNbr: Integer; ASetFlag: Boolean);
var
  ListSettings: TListSettingRecord;
  ListParams: TListParams;
begin
  try
    ListParams := GetListParams(TF_CAD(FCADForm).FCADListID);
    ListSettings := ListParams.Settings;
    if ALNbr = 3 then
    begin
      TF_CAD(FCADForm).FShowLinesCaptions := ASetFlag;
      ListSettings.ShowLineObjectCaption := ASetFlag;
    end;
    if ALNbr = 4 then
    begin
      TF_CAD(FCADForm).FShowConnectorsCaptions := ASetFlag;
      ListSettings.ShowConnObjectCaption := ASetFlag;
    end;
    if ALNbr = 5 then
    begin
      TF_CAD(FCADForm).FShowLinesNotes := ASetFlag;
      ListSettings.ShowLineObjectNote := ASetFlag;
    end;
    if ALNbr = 6 then
    begin
      TF_CAD(FCADForm).FShowConnectorsNotes := ASetFlag;
      ListSettings.ShowConnObjectNote := ASetFlag;
    end;
    ListParams.Settings := ListSettings;
    SaveListParams(TF_CAD(FCADForm).FCADListID, ListParams, True, False);
  except
    on E: Exception do AddExceptionToLogEx('TF_LayersDialog.UpdateOptions', E.Message);
  end;
end;

procedure TF_LayersDialog.lvLayersListMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
  LayerItem: TListItem;
  Layer: TLayer;
  LNbr: Integer;
begin
  try
    LayerItem := nil;
    if lvLayersList.TopItem <> nil then
      LayerItem := lvLayersList.GetItemAt(lvLayersList.TopItem.Position.X, Y);
    if LayerItem <> nil then
    begin
      if X < 190 then
      begin
        Layer := Tlayer(LayerItem.Data);
        LNbr := TF_CAD(FCADForm).PCad.GetLayerNbr(Layer);
        if LNbr = 0 then
          lvLayersList.Hint := cLayers_Mes1;
        if LNbr = 1 then
          lvLayersList.Hint := cLayers_Mes2;
        if LNbr = 2 then
          lvLayersList.Hint := cLayers_Mes3;
        if LNbr = 3 then
          lvLayersList.Hint := cLayers_Mes4;
        if LNbr = 4 then
          lvLayersList.Hint := cLayers_Mes5;
        if LNbr = 5 then
          lvLayersList.Hint := cLayers_Mes6;
        if LNbr = 6 then
          lvLayersList.Hint := cLayers_Mes7;
        if LNbr = 7 then
          lvLayersList.Hint := cLayers_Mes8;
        if LNbr = 8 then
          lvLayersList.Hint := cLayers_Mes11;
      end
      else
      if (X > 190) and (X < 210) then
      begin
        lvLayersList.Hint := cLayers_Mes9;
      end
      else
      if (X > 210) and (X < 230) then
      begin
        lvLayersList.Hint := cLayers_Mes10;
      end;
    end;
  except
    on E: Exception do AddExceptionToLogEx('TF_LayersDialog.lvLayersListMouseMove', E.Message);
  end;
end;

procedure TF_LayersDialog.cbAllNetworksClick(Sender: TObject);
begin
  try
    if cbAllNetworks.Checked then
    begin
      cbComputerNetwork.Checked := False;
      cbTelephonNetwork.Checked := False;
      cbElectricNetwork.Checked := False;
      cbTelevisionNetwork.Checked := False;
      cbGasNetwork.Checked := False;
      cbComputerNetwork.Enabled := False;
      cbTelephonNetwork.Enabled := False;
      cbElectricNetwork.Enabled := False;
      cbTelevisionNetwork.Enabled := False;
      cbGasNetwork.Enabled := False;
    end
    else
    begin
      cbComputerNetwork.Enabled := True;
      cbTelephonNetwork.Enabled := True;
      cbElectricNetwork.Enabled := True;
      cbTelevisionNetwork.Enabled := True;
      cbGasNetwork.Enabled := True;
    end;
    UpdateNetworksOptions;    
  except
    on E: Exception do AddExceptionToLogEx('TF_LayersDialog.cbAllNetworksClick', E.Message);
  end;
end;

procedure TF_LayersDialog.UpdateNetworksOptions;
begin
  try
    if not GProjectChanged then // Tolik 01/11/2021 --
      SetProjectChanged(True);
    TF_CAD(FCADForm).FShowNetworkTypes := [];
    if cbAllNetworks.Checked then
      TF_CAD(FCADForm).FShowNetworkTypes := [nt_All];
    if cbComputerNetwork.Enabled then
      if cbComputerNetwork.Checked then
        TF_CAD(FCADForm).FShowNetworkTypes := TF_CAD(FCADForm).FShowNetworkTypes + [nt_Computer];
    if cbTelephonNetwork.Enabled then
      if cbTelephonNetwork.Checked then
        TF_CAD(FCADForm).FShowNetworkTypes := TF_CAD(FCADForm).FShowNetworkTypes + [nt_Telephon];
    if cbElectricNetwork.Enabled then
      if cbElectricNetwork.Checked then
        TF_CAD(FCADForm).FShowNetworkTypes := TF_CAD(FCADForm).FShowNetworkTypes + [nt_Electric];
    if cbTelevisionNetwork.Enabled then
      if cbTelevisionNetwork.Checked then
        TF_CAD(FCADForm).FShowNetworkTypes := TF_CAD(FCADForm).FShowNetworkTypes + [nt_Television];
    if cbGasNetwork.Enabled then
      if cbGasNetwork.Checked then
        TF_CAD(FCADForm).FShowNetworkTypes := TF_CAD(FCADForm).FShowNetworkTypes + [nt_Gas];
    TF_CAD(FCADForm).PCad.DrawFigures;
    DeselectNoDrawed(TF_CAD(FCADForm).PCad); //05.04.2011
    RefreshCAD(TF_CAD(FCADForm).PCad);
  except
    on E: Exception do AddExceptionToLogEx('TF_LayersDialog.UpdateNetworksOptions', E.Message);
  end;
end;

procedure TF_LayersDialog.cbComputerNetworkClick(Sender: TObject);
begin
  UpdateNetworksOptions;
end;

procedure TF_LayersDialog.cbTelephonNetworkClick(Sender: TObject);
begin
  UpdateNetworksOptions;
end;

procedure TF_LayersDialog.cbElectricNetworkClick(Sender: TObject);
begin
  UpdateNetworksOptions;
end;

procedure TF_LayersDialog.cbTelevisionNetworkClick(Sender: TObject);
begin
  UpdateNetworksOptions;
end;

// Tolik 30/08/2019 -- удалить пустые DXF слои с подложки
procedure TF_LayersDialog.E1Click(Sender: TObject);
var i: Integer;
    DxfLayersList, LayerCheckList: TList;
    Layer: Tlayer;
    fLNbr: integer;

    Procedure CheckFigureLayer(aFigure:TFigure);
    var i: Integer;
    begin
      for i := 0 to GCadForm.PCad.LayerCount - 1 do
      begin
        Layer := TLayer(GCadForm.PCad.Layers[i]);
        if Layer.IsDxf then
        begin
          if (aFigure.LayerHandle = LongInt(Layer)) then
          begin
            DxfLayersList.Remove(Layer);
            break;
          end;
        end;
      end;
    end;

begin
  try
    if Assigned(GCadForm) then
    begin
      DxfLayersList := TList.Create;
      for i := 0 to GCadForm.PCad.LayerCount - 1 do
      begin
        if TLayer(GCadForm.PCad.Layers[i]).IsDxf then
          DxfLayersList.Add(TLayer(GCadForm.PCad.Layers[i]));
      end;
    end
    else
      exit;

    if DxfLayersList.Count > 0 then
    begin
      LayerCheckList := TList.Create;
      for i := 0 to GCadForm.PCad.Figures.Count - 1  do
        CheckFigureLayer(TFigure(GCadForm.PCad.Figures[i]));
    end;

    if DxfLayersList.Count > 0 then
    begin
      for i := 0 to DxfLayersList.Count - 1 do
      begin
        Layer := TLayer(DxfLayersList[i]);
        if CheckCanDelLayer(Layer) then  // если на слое нет фигур, которые принадлежат каким-нибудь групповым фигурам
                                         // с других слоев, то можно и удалить
        begin
          fLNbr := GCadForm.PCad.GetLayerNbr(Layer);
          if fLNbr > 0 then
            GCadForm.PCad.DeleteLayerWithNbr(fLNbr);
        end;
      end;
    end;

    DxfLayersList.Free;
    UpdateLayersList;
    if not GProjectChanged then
      SetProjectChanged(True);
  except
    on E: Exception do AddExceptionToLogEx('TF_LayersDialog.DeleteEmptySubstrateLayers: ', E.Message);
  end;
end;
//

procedure TF_LayersDialog.cbGasNetworkClick(Sender: TObject);
begin
  UpdateNetworksOptions;
end;

procedure TF_LayersDialog.cbShowCableChannelsOnlyClick(Sender: TObject);
var
  i: Integer;
  CurLayer: TLayer;
  LayerItem: TListItem;
  ListSettings: TListSettingRecord;
  ListParams: TListParams;
begin
  try
    if cbShowCableChannelsOnly.Checked then
    begin
      for i := 3 to 6 do
      begin
        CurLayer := TLayer(TF_CAD(FCADForm).PCad.Layers[i]);
        LayerItem := FinditemByLayer(i, CurLayer);
//        LayerItem := lvLayersList.Items[i - 1];
        if CurLayer.visible = seen then
          listGrayed[i - 1] := 'seen';
        if CurLayer.visible = grayed then
          listGrayed[i - 1] := 'grayed';
        if CurLayer.visible = lost then
          listGrayed[i - 1] := 'lost';

        CurLayer.visible := lost;
        LayerItem.SubItemImages[1] := -1;
        LayerItem.SubItemImages[0] := -1;
      end;
    end
    else
    begin
      for i := 3 to 6 do
      begin
        CurLayer := Tlayer(TF_CAD(FCADForm).PCad.Layers[i]);
        LayerItem := FinditemByLayer(i, CurLayer);        
//        LayerItem := lvLayersList.Items[i - 1];
        if listGrayed[i - 1] = 'seen' then
        begin
          CurLayer.visible := seen;
          LayerItem.SubItemImages[0] := 136;
          LayerItem.SubItemImages[1] := -1;
        end;
        if listGrayed[i - 1] = 'grayed' then
        begin
          CurLayer.visible := grayed;
          LayerItem.SubItemImages[0] := 136;
          LayerItem.SubItemImages[1] := 137;
        end;
        if listGrayed[i - 1] = 'lost' then
        begin
          CurLayer.visible := lost;
          LayerItem.SubItemImages[0] := -1;
          LayerItem.SubItemImages[1] := -1;
        end

      end;
    end;
    // записать в настройки листа
    ListParams := GetListParams(TF_CAD(FCADForm).FCADListID);
    ListSettings := ListParams.Settings;
    TF_CAD(FCADForm).FShowLinesCaptions := cbShowCableChannelsOnly.Checked;
    ListSettings.ShowLineObjectCaption := cbShowCableChannelsOnly.Checked;
    TF_CAD(FCADForm).FShowConnectorsCaptions := cbShowCableChannelsOnly.Checked;
    ListSettings.ShowConnObjectCaption := cbShowCableChannelsOnly.Checked;
    TF_CAD(FCADForm).FShowLinesNotes := cbShowCableChannelsOnly.Checked;
    ListSettings.ShowLineObjectNote := cbShowCableChannelsOnly.Checked;
    TF_CAD(FCADForm).FShowConnectorsNotes := cbShowCableChannelsOnly.Checked;
    ListSettings.ShowConnObjectNote := cbShowCableChannelsOnly.Checked;
    ListParams.Settings := ListSettings;
    SaveListParams(TF_CAD(FCADForm).FCADListID, ListParams, True, False);
    // включить/выключить отображение плана кабельных каналов
    if cbShowCableChannelsOnly.Checked then
    begin
      TF_CAD(FCADForm).FShowCableChannelsOnly := True;
    end
    else
    begin
      TF_CAD(FCADForm).FShowCableChannelsOnly := False;
    end;
    TF_CAD(FCADForm).Pcad.DrawFigures;
    RefreshCAD_T(TF_CAD(FCADForm).PCad);
  except
    on E: Exception do AddExceptionToLogEx('TF_LayersDialog.cbShowCableChannelsOnlyClick', E.Message);
  end;
end;

function TF_LayersDialog.FinditemByLayer(aLayerIdx: Integer; aLayer: TLayer): TListItem;
var
  i: integer;
  Item: TListItem;
begin
  try
    Result := nil;
    //21.08.2012 - поиске через массив соответствий по индексу
    if (aLayerIdx > -1) and (aLayerIdx < FLayersListItems.Count) then
      if FLayersListItems[aLayerIdx] <> nil then
        if TListItem(FLayersListItems[aLayerIdx]).Data = aLayer then
          Result := TListItem(FLayersListItems[aLayerIdx]);

    if Result = nil then
      for i := 0 to lvLayersList.Items.Count - 1 do
      begin
        Item := TListItem(lvLayersList.Items[i]);
        if Item.Data = aLayer then
        begin
          Result := Item;
          Break; //// BREAK ////
        end;
      end;
  except
    on E: Exception do AddExceptionToLogEx('TF_LayersDialog.FinditemByLayer', E.Message);
  end;
end;

procedure TF_LayersDialog.FormDestroy(Sender: TObject);
begin
  FLayersListItems.Free;
  FIsManualGrayed.Free;
end;

procedure TF_LayersDialog.tbGrayedChange(Sender: TObject);
begin
  //SetGrayedColor(GrayedColors[TRzTrackBar(Sender).Position], Sender);
  RestartTimer(TimerTBGrayed);
end;

procedure TF_LayersDialog.TimerTBGrayedTimer(Sender: TObject);
begin
  TTimer(Sender).Enabled := false;
  //SetGrayedColor(GrayedColors[tbGrayed.Position], tbGrayed);
  SetGrayedColor(GrayedColors[Length(GrayedColors)-1-tbGrayed.Position], tbGrayed);
end;

procedure TF_LayersDialog.btSetDefGrayedColorClick(Sender: TObject);
begin
  SetGrayedColor(DefGrayedColor, Sender);
end;

procedure TF_LayersDialog.tbGrayedDrawTick(TrackBar: TRzTrackBar;
  Canvas: TCanvas; Location: TPoint; Index: Integer);
var
  W, Degree : Integer;
  Txt: String;
begin
  {//Degree := Index;
  Degree := Trunc(Index / tbGrayed.Max * 100);
  if ( Degree mod 10 ) = 0 then
  begin
    Canvas.Brush.Style := bsClear;
    Canvas.Font.Name := 'Small Fonts';
    Canvas.Font.Size := 7;
    Canvas.Font.Style := [];
    W := Canvas.TextWidth( IntToStr( Degree ) );
    Canvas.TextOut( Location.X - (W div 2), 1, IntToStr( Degree )+'%' );
  end;}

  Txt := '';
  if Index = 0 then
    Txt := '0';
  if Index = tbGrayed.Max then
    Txt := '100';
  if Txt <> '' then
  begin
    Canvas.Brush.Style := bsClear;
    Canvas.Font.Name := 'Small Fonts';
    Canvas.Font.Size := 7;
    Canvas.Font.Style := [];
    W := Canvas.TextWidth(Txt);
    Canvas.TextOut( Location.X - (W div 2), 1, Txt );
  end;

  if GrayedColors[Length(GrayedColors)-1-Index] = DefGrayedColor then
  begin
    Canvas.MoveTo(Location.X, Location.Y-3);
    Canvas.LineTo(Location.X, Location.Y+10);
  end;
end;

end.
