unit uSelectedOrChecked;

//Собирает список узлов и всех их потомоков для копирования, вырезки, удаления
//Список это поле экземпляра класса FIDListToCopyOrCutOrDelete
// Собирается либо выделенный узел и все его потомки, либо выделенные галочками и потомки

interface

uses
  System.SysUtils, System.Classes, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param,
  FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf, FireDAC.Stan.Async,
  FireDAC.DApt, FireDAC.UI.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Phys,
  FireDAC.VCLUI.Wait, FireDAC.Phys.MySQLDef, FireDAC.Phys.MySQL, Data.DB, FireDAC.Comp.Client,
  FireDAC.Comp.DataSet,
  Vcl.ComCtrls, // Для TTreeView
  Contnrs,vcl.dialogs,
  syncobjs,vcl.Forms,vcl.Controls, uDBConnectionBPL,uTreeView,uSelectionOptions,uSQLQueries;

type
TSelectedOrChecked =class(TComponent)

private

  FCut:boolean;
  FIDListToCopyOrCutOrDelete:TStringList; // << Это список узлов для копирования, вырезки, удаления

  FSQLQueries:TSQLQueries;

  FDBTreeView:TDBTreeView; // Ccылка на экземпляр дерева

  Function FindNodeInTree(ID:Integer):TTreeNode;
  Procedure MarkCutted;
  Procedure ListParentAndAllChildren(NodeID:Integer);
  Procedure LimitLength(DBTreeViewLocal: TDBTreeView; var S: string);


  public

  Constructor Create(AOwner:TComponent); override;
  Destructor Destroy; override;

  Procedure List;


  property Cut:boolean Read FCut Write FCut;
  property DBTreeView:TDBTreeView read FDBTreeView write FDBTreeView;

  property IDListToCopyOrCutOrDelete:TstringList
  read FIDListToCopyOrCutOrDelete write FIDListToCopyOrCutOrDelete;

end;


//--------------------------------------------------------------------------------------------------
                                  IMPLEMENTATION
//--------------------------------------------------------------------------------------------------


{ TCopyOrCut }

//------------------------Конструктор, деструктор---------------------------------------------------

constructor TSelectedOrChecked.Create(AOwner: TComponent);
begin
  inherited;
  FIDListToCopyOrCutOrDelete:=TStringList.Create;

  FSQLQueries:=TSQLQueries.Create(Self);

//  ListCheckedOrSelected;
end;

destructor TSelectedOrChecked.Destroy;
begin
  FreeAndNil(FIDListToCopyOrCutOrDelete);
  FreeAndNil(FSQLQueries);
  inherited;
end;
//--------------------------------------------------------------------------------------------------

function TSelectedOrChecked.FindNodeInTree(ID: Integer): TTreeNode;
var i:integer; DBTreeViewLocal:TDBTreeView;

begin

 DBTreeViewLocal:=FDBTreeView;

 Result:=nil; //Если родитель не будет найден, то это нулевой уровень
//Иначе, это будет какой-то конкретный узел
 for i := 0 to DBTreeViewLocal.Items.Count-1 do

 if DBTreeViewLocal.Items.Item[i].Data<>nil then

 begin
     if Integer(DBTreeViewLocal.Items.Item[i].Data^)=ID then

   begin
     Result:=DBTreeViewLocal.Items.Item[i];
     Break;
   end;
 end;

end;



//--------------Вспомогательная процедура ограничения длины строки----------------------------------
procedure TSelectedOrChecked.LimitLength(DBTreeViewLocal: TDBTreeView; var S: string);
begin
  // Ограничение длины
  if length(DBTreeView.Selected.Text) > 7 then
  begin
    S := '';
    S := Copy(DBTreeView.Selected.Text, 0, 7);
    S := S + '...';
  end
  else
    S := DBTreeViewLocal.Selected.Text;
end;


//-------------------------Непосредственный сбор в список-------------------------------------------

procedure TSelectedOrChecked.List;
var i:integer; fSelectionOptions: TfSelectionOptions;
    fSelectionOptions2:TfSelectionOptions;

    IDSelected:integer;
    NodeID:integer;
    DBTreeViewLocal:TDBTreeView;
    Node:TTreeNode;
    S:String;

begin

DBTreeViewLocal:=FDBTreeView;

FIDListToCopyOrCutOrDelete.Clear;
//CutInMain:=false; //Изначально подразумевается копирование


  if Assigned(DBTreeViewLocal.Selected) then
     IDSelected:=integer(DBTreeViewLocal.Selected.Data^) else
     IDSelected:=-2; // << Означает, что узел не выбран


// Спрашиваем, что будем выделять
fSelectionOptions:=TfSelectionOptions.Create(nil);

   if Assigned(DBTreeViewLocal.Selected) then

        begin

        LimitLength(DBTreeViewLocal, S);
        fSelectionOptions.rbSelected.Caption:=fSelectionOptions.rbSelected.Caption+
        '  ( '+S+' )';

        end;


fSelectionOptions.ShowModal;

if fSelectionOptions.Tag<>-3 then

begin
             //Если один выделенный узел
          if (fSelectionOptions.Tag=0) then
           begin

               if IDSelected=-2 then
               begin
               showmessage('Ни один элемент не выбран');
               exit
               end else

               ListParentAndAllChildren(IDSelected);


           end else

             //Если нужно выбрать узлы отмеченные галочками
           begin


           if DBTreeViewLocal.Items.GetFirstNode=nil then exit else

              Node:=DBTreeViewLocal.Items.GetFirstNode;

              repeat

              if (Node.StateIndex=2) then
               begin
               // if Node.Text='GhostNode' then continue;


                NodeID:=Integer(Node.Data^);
                ListParentAndAllChildren(NodeID); // Добавляем в ListID
               end;


              Node:=Node.GetNext;
              until not Assigned(Node) ;


           end;

          MarkCutted;
end;

//showmessage(Self.IDListToCopyOrCutOrDelete.Count.ToString());

// Освобождение
FreeAndNil(fSelectionOptions);

end;


//---------------------------Рекурсивная процедура------------------------------------------------

procedure TSelectedOrChecked.ListParentAndAllChildren(NodeID: Integer);
var qSelectAllChildren:TFDQuery;
    DBConnectionLocal:TDBConnectionBPL;

    idField:string;



begin

   idField:=DBTreeViewGlobal.DBTreeViewTable.id;

   DBConnectionLocal:=TDBConnectionBPL.Create(nil);

   qSelectAllChildren:=TFDQuery.Create(nil);
   qSelectAllChildren.Connection:=DBConnectionLocal.FDConnection;

   //Если ID не был добавлен ранее, тогда добавляем
   if FIDListToCopyOrCutOrDelete.IndexOf(NodeID.Tostring)=-1 then
      FIDListToCopyOrCutOrDelete.Add(NodeID.Tostring); // Записываем родителя и всех детей


   //Ищем всех детей
   with qSelectAllChildren do
   begin

    SQL.Text:=FSQLQueries.SelectAllChildren.Text+NodeID.ToString;
    //'SELECT * FROM treeview_db.tree where IdParent='+NodeID.ToString;



    Open();

     while not eof do
     begin
     // Для каждого ребенка вызываем рекурсивно
     ListParentAndAllChildren(FieldByName(idField).AsInteger);

     Next;
     end;

    Close();
   end;


   FreeAndNil(qSelectAllChildren);
   FreeAndNil(DBConnectionLocal);


end;

//--------------------------------------------------------------------------------------------------

procedure TSelectedOrChecked.MarkCutted;
var i:integer;
    Node:TTreeNode;
    DBtreeViewLocal:TDBTreeView;

begin

DBtreeViewLocal:=FDBTreeView;



if FCut then
 begin

 for i := 0 to FIDListToCopyOrCutOrDelete.Count-1 do

     begin
     Node:=FindNodeInTree(FIDListToCopyOrCutOrDelete[i].ToInteger);
     Node.Cut:=true;
     end;

//  CutInMain:=true;
 end;



end;


END.
