unit uInsertFolderFileNode;

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, uDBConnection;

type
 TInsertFolderFileNode=class(TObject)


 private
 FqIsFolder:TFDQuery;

 Constructor Create;
 Destructor Destroy;

 function FindParentNode(Key: integer; TreeView: TTreeView): TTreeNode;


 public

 property qIsFolder:TFDQuery read FqIsFolder;

 //Вставка произвольного узла
 function InsertNodeInDB(const idParent, index: Integer; const name: string;
      const TreeView: TTreeView): integer;

 procedure InsertNodeInTree(TreeView: TTreeView);

 //Вставка папки или файла

 function IsFolder(Node:TTreeNode):boolean;


 function InsertFolderOrFileInDB(const idParent, index: Integer;
  const name: string; const TreeView: TTreeView; IsFolder: boolean): integer;

 procedure InsertFolderOrFileInTree(TreeView: TTreeView; IsFolderLocalVar:boolean; name:string);

 end;

 var
// Глобальные переменные
 DBConnection:TDBConnection;


implementation



{ TInsertFolderFileNode }


constructor TInsertFolderFileNode.Create;
begin
DBConnection:=TDBConnection.Create(nil);
FqIsFolder:=TFDQuery.Create(nil);
FqIsFolder.SQL.Text:='SELECT IsFolder FROM treeview_db.tree;';
Self.qIsFolder:=TFDQuery.Create(nil);

//qIsFolder.Open();
end;

destructor TInsertFolderFileNode.Destroy;
begin
DBConnection.Free;
FqIsFolder.Free;
end;

function TInsertFolderFileNode.FindParentNode(Key: integer; TreeView: TTreeView): TTreeNode;
//Поиск родительского узла
var i:integer;
begin

 Result:=nil; //Если родитель не будет найден, то это нулевой уровень
//Иначе, это будет какой-то конкретный узел
 for i := 0 to TreeView.Items.Count-1 do
  if Integer(TreeView.Items.Item[i].Data^)=Key then

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


end;

//---------------------------ВСТАВКА ПРОИЗВОЛЬНОГО УЗЛА В ДЕРЕВО-------------------------------

function TInsertFolderFileNode.InsertNodeInDB(const idParent, index: Integer; const name: string;
  const TreeView: TTreeView): integer;
var qInsert:TFDQuery;
    qGetKey:TFDQuery;
    DBConnection:TDBConnection;


begin

 //Создание
// DBConnection:=TDBConnection.Create(nil);

//---------------------Создание qInsert-------------------------------
 qInsert:=TFDQuery.Create(nil);

 qInsert.Connection:=DBConnection.FDConnection;

 qInsert.SQL.Text:=
'INSERT INTO `treeview_db`.`tree` (`IdParent`, `Name`, `Index`,`isChecked`,`Level`)'+
 'VALUES (:idParent, :name, :index,:isChecked,:Level);';

 //---------------------Создание qGetKey------------------------
 //Даст ID последней добавленной записи
 qGetKey:=TFDQuery.Create(nil);
 qGetKey.Connection:=DBConnection.FDConnection;
 qGetKey.SQL.Text:='SELECT Max(id) as newkey FROM treeview_db.tree;';

//---------------------Основная работа по вставке узла в БД----------------

//Вставка записи
  with qInsert.Params do
   begin
     ParamValues['idParent']:=idParent;
     ParamValues['Index']:=Index;
     ParamValues['Name']:=Trim(Name);
     ParamValues['isChecked']:=false; // По умолчанию галочка не отмечена


   // Записываем уровень вставляемого узла в базу
   if  FindParentNode(idParent,TreeView)<>nil then
   begin
     ParamValues['Level']:=FindParentNode(idParent,TreeView).Level+1
   end else ParamValues['Level']:=0;

   end;

qInsert.ExecSQL;

 //Получение id последней записи
 with qGetKey do
 begin
   Open;
   Result:=qGetKey.FieldByName('NewKey').AsInteger;
   Close;
 end;


 //Уничтожение созданных переменных
 DBConnection.Free;
 qInsert.Free;
 qGetKey.Free;

end;

procedure TInsertFolderFileNode.InsertNodeInTree(TreeView: TTreeView);

var name:string;
    Node:TTreeNode;
    idParent,ItemIndex:integer; // Ключ и индекс узла

    ID:^Integer;
begin
    if InputQuery('Новая запись','',name)=true then
    begin

      if Assigned(TreeView.Selected) then
       begin
         //Назначаем родителя новому узлу
         idParent:=Integer(TreeView.Selected.Data^);
         ItemIndex:=TreeView.Items.Count+1;

       end else
       //Если никакой узел не выбран, владельца нет
       begin
        idParent:=-1;
        ItemIndex:=0;
       end;


       //Собственно вставка в дерево

       New(ID);
            // Вставка в БД
       ID^:=InsertNodeInDB(idParent, Itemindex, name, TreeView);

            // Вставка в само дерево
       Node:=TreeView.Items.AddChildObject(TreeView.Selected,name,ID);

          //Проверка "чекнутости" родителя в базе, чтобы
         //выставить Checked/not Checked ребенку

             if (Node.Parent<>nil) then
             begin
               if (Node.Parent.StateIndex=2) then Node.StateIndex:=2 else
               Node.StateIndex:=1;
             end else Node.StateIndex:=1;




   // Оставляем фокус на том узле, на который нажали
      if TreeView.Selected<>nil then
      begin
      TreeView.Selected.Expanded:=true;
      TreeView.SetFocus;
      TreeView.Selected.Selected:=true;
      end;




    //   Node .Selected:=true;

      //Dispose(Obj) <<Высвобождать будем при закрытии либо
      //Удалении, иначе выскакивает ошибка Invalid Pointer Operation
    end;

// InsertNodeInTree
end;


//---------------------------ВСТАВКА ПАПКИ ИЛИ ФАЙЛА В ДЕРЕВО-------------------------------



function TInsertFolderFileNode.IsFolder(Node:TTreeNode): boolean;
// Проверка папка это или нет
var qCheckIsFolder:TFDQuery; ID:^integer;
begin

//DBConnection:=TDBConnection.Create(nil);
qCheckIsFolder:=TFDQuery.Create(nil);
qCheckIsFolder.Connection:=DBConnection.FDConnection;

new(ID);
if assigned(Node) then ID^:=Integer(Node.Data^);


qCheckIsFolder.SQL.Text:='Select * from `treeview_db`.`tree` where id='+ID^.ToString();

qCheckIsFolder.Open();

if qCheckIsFolder.FieldByName('IsFolder').AsBoolean=true then result:=true else
Result:=false;


qCheckIsFolder.Close;
qCheckIsFolder.Free;
DBConnection.Free;
Dispose(ID);

end;





function TInsertFolderFileNode.InsertFolderOrFileInDB(const idParent, index: Integer;
  const name: string; const TreeView: TTreeView; IsFolder: boolean): integer;
// Вставка папки или файла в БД


var qInsert:TFDQuery;
    qGetKey:TFDQuery;
    DBConnection:TDBConnection;


begin

 //Создание
// DBConnection:=TDBConnection.Create(nil);

//---------------------Создание qInsert-------------------------------
 qInsert:=TFDQuery.Create(nil);

 qInsert.Connection:=DBConnection.FDConnection;

 qInsert.SQL.Text:=
'INSERT INTO `treeview_db`.`tree` (`IdParent`, `Name`, `Index`,`isChecked`,`Level`,`IsFolder`)'+
 'VALUES (:idParent, :name, :index,:isChecked,:Level,:IsFolder);';

 //---------------------Создание qGetKey------------------------

 qGetKey:=TFDQuery.Create(nil);
 qGetKey.Connection:=DBConnection.FDConnection;
 qGetKey.SQL.Text:='SELECT Max(id) as newkey FROM treeview_db.tree;';

//---------------------Основная работа по вставке узла в БД----------------

//Вставка записи
  with qInsert.Params do
   begin

     if IsFolder then

     begin

       ParamValues['idParent']:=idParent;
       ParamValues['Index']:=Index;
       ParamValues['Name']:=Trim(Name);
       ParamValues['isChecked']:=false; // По умолчанию галочка не отмечена
       ParamValues['IsFolder']:=true;

     end else

      begin

       ParamValues['idParent']:=idParent;
       ParamValues['Index']:=Index;
       ParamValues['Name']:=Trim(Name);
       ParamValues['isChecked']:=false; // По умолчанию галочка не отмечена
       ParamValues['IsFolder']:=false;

      end;



   // Записываем уровень вставляемого узла в базу
   if  FindParentNode(idParent,TreeView)<>nil then
   begin
     ParamValues['Level']:=FindParentNode(idParent,TreeView).Level+1
   end else ParamValues['Level']:=0;

   end;

qInsert.ExecSQL;

 //Получение id последней записи
 with qGetKey do
 begin
   Open;
   Result:=qGetKey.FieldByName('NewKey').AsInteger;
   Close;
 end;

end;


procedure TInsertFolderFileNode.InsertFolderOrFileInTree(TreeView: TTreeView; IsFolderLocalVar: boolean;
  name: string);
// Вставка папки или файла в дерево и БД
var
    Node:TTreeNode;
    idParent,ItemIndex:integer; // Ключ и индекс узла

    ID:^Integer;
begin

//      if not Assigned(TreeView.Selected) then exit;

      if Assigned(TreeView.Selected) then
       begin
         //Назначаем родителя новому узлу
         idParent:=Integer(TreeView.Selected.Data^);
         ItemIndex:=TreeView.Items.Count+1;

       end else
       //Если никакой узел не выбран, владельца нет
       begin
        idParent:=-1;
        ItemIndex:=0;
       end;


       //Собственно вставка в дерево

       New(ID);
            // Вставка в БД

       if IsFolderLocalVar then // Если папка
       begin
                        //Вставка в базу
           ID^:=InsertFolderOrFileInDB(idParent, Itemindex, name, TreeView, true);
                       // Вставка в само дерево
           Node:=TreeView.Items.AddChildObject(TreeView.Selected,name,ID);


             // Ставим "чек" как у родителя
                 if (Node.Parent<>nil) then
                 begin
                   if (Node.Parent.StateIndex=2) then Node.StateIndex:=2 else
                   Node.StateIndex:=1;
                 end else Node.StateIndex:=1;


            //Ставим иконку папки
   //             Node.ImageIndex:=1;


       end else
        // Если файл...
       begin

           //Вставка в базу
           ID^:=InsertFolderOrFileInDB(idParent, Itemindex, name, TreeView, false);
                       // Вставка в само дерево
           Node:=TreeView.Items.AddChildObject(TreeView.Selected,name,ID);


             // Ставим "чек" как у родителя
                 if (Node.Parent<>nil) then
                 begin
                   if (Node.Parent.StateIndex=2) then Node.StateIndex:=2 else
                   Node.StateIndex:=1;
                 end else Node.StateIndex:=1;


             //Ставим иконку файла
     //           Node.ImageIndex:=0;



       end;




   // Оставляем фокус на том узле, на который нажали
      if TreeView.Selected<>nil then
      begin
      TreeView.Selected.Expanded:=true;
      TreeView.SetFocus;
      TreeView.Selected.Selected:=true;
      end;


    //   Node .Selected:=true;

      //Dispose(ID) <<Высвобождать будем при закрытии либо
      //Удалении, иначе выскакивает ошибка Invalid Pointer Operation


// InsertNodeInTree
end;


end.
