unit MetaEditor; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, _BaseTemplate, ExtCtrls, VirtualTrees, StdCtrls, ComCtrls, Grids, MPHexEditor, Wrapgrid; type TForm_Meta = class(TForm_BaseTemplate) VST: TVirtualStringTree; splitter: TSplitter; rightPages: TPageControl; tab_hex: TTabSheet; tab_meta: TTabSheet; panel_hex_actions: TPanel; hex: TMPHexEditor; splitter_hex_1: TSplitter; value_viewer: TWrapGrid; splitter_hex_2: TSplitter; structviewer: TVirtualStringTree; procedure FormCreate(Sender: TObject); procedure VSTInitChildren(Sender: TBaseVirtualTree; Node: PVirtualNode; var ChildCount: Cardinal); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex); procedure VSTFocusChanging(Sender: TBaseVirtualTree; OldNode, NewNode: PVirtualNode; OldColumn, NewColumn: TColumnIndex; var Allowed: Boolean); procedure VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString); procedure VSTPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType); private procedure NewCon(ID: Integer); public end; implementation {$R *.dfm} uses _MetaManager, _MetaTypes, ConnectionManager, Data, _FileTypes; type PNodeData = ^TNodeData; TNodeData = record Field: TObject; end; function AddVSTEntry(AVST: TCustomVirtualStringTree; ANode: PVirtualNode; ARecord: TNodeData): PVirtualNode; var Data: PNodeData; begin Result := AVST.AddChild(ANode); Data := AVST.GetNodeData(Result); AVST.ValidateNode(Result, False); Data^ := ARecord; end; procedure TForm_Meta.NewCon(ID: Integer); var i: Integer; data: TNodeData; node: PVirtualNode; Meta: TMetaManager; root: TExtensions; begin if ID >= 0 then begin //VST VST.Clear; VST.BeginUpdate; root := ConManager.Connection[FConnectionID].MetaData.Root; for i := 0 to High(root) do begin data.Field := root[i]; node := AddVSTEntry(VST, nil, data); VST.HasChildren[node] := True; end; VST.EndUpdate; end; end; procedure TForm_Meta.VSTInitChildren(Sender: TBaseVirtualTree; Node: PVirtualNode; var ChildCount: Cardinal); var data: PNodeData; newdata: TNodeData; newnode: PVirtualNode; i: Integer; id: Integer; Meta: TMetaManager; begin data := Sender.GetNodeData(node); Meta := ConManager.Connection[ConnectionID].MetaData; if data.Field is TFile then begin if TFile(data.Field).ChildCount > 0 then begin for i := 0 to TFile(data.Field).ChildCount - 1 do begin id := TFile(data.Field).LinkByIndex[i].DestID; Meta.InitFile(id); newdata.Field := Meta.FileById[id]; newnode := AddVSTEntry(TCustomVirtualStringTree(Sender), Node, newdata); if Meta.FileById[id].ChildCount > 0 then Sender.HasChildren[newnode] := True; end; end; if TFile(data.Field).RawCount > 0 then begin for i := 0 to TFile(data.Field).RawCount - 1 do begin // Exit; end; end; end; if data.Field is TExtension then begin if TExtension(data.Field).FileCount = 0 then TExtension(data.Field).InitList; for i := 0 to TExtension(data.Field).FileCount - 1 do begin id := TExtension(data.Field).Files[i]; Meta.InitFile(id); newdata.Field := Meta.FileById[id]; newnode := AddVSTEntry(TCustomVirtualStringTree(Sender), Node, newdata); if Meta.FileById[id].ChildCount > 0 then Sender.HasChildren[newnode] := True; end; end; ChildCount := Sender.ChildCount[Node]; end; procedure TForm_Meta.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex); var data: PNodeData; begin data := Sender.GetNodeData(Node); if data.Field is TFile then begin TFile(data.Field).InitEditor; if Assigned(TFile(data.Field).Editor) then begin TFile(data.Field).Editor.Align := alClient; tab_meta.InsertControl(TFile(data.Field).Editor); TFile(data.Field).Opened := True; end; end; end; procedure TForm_Meta.VSTFocusChanging(Sender: TBaseVirtualTree; OldNode, NewNode: PVirtualNode; OldColumn, NewColumn: TColumnIndex; var Allowed: Boolean); var data: PNodeData; i: Integer; begin data := Sender.GetNodeData(NewNode); if data.Field is TFile then begin TFile(data.Field).InitEditor; if Assigned(TFile(data.Field).Editor) then Allowed := not TFile(data.Field).Opened else Allowed := True; end; if Allowed and Assigned(OldNode) then begin data := Sender.GetNodeData(OldNode); if data.Field is TFile then begin if TFile(data.Field).Opened then begin if tab_meta.ControlCount > 0 then for i := 0 to tab_meta.ControlCount - 1 do tab_meta.RemoveControl(tab_meta.Controls[i]); TFile(data.Field).Opened := False; end; end; end; end; procedure TForm_Meta.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString); var Data: PNodeData; begin Data := Sender.GetNodeData(Node); CellText := ''; if TextType = ttNormal then begin case Column of 0: begin if Data.Field is TFile then begin CellText := TFile(Data.Field).FileInfo.Name; if CellText = '' then CellText := 'Unnamed'; end; if Data.Field is TExtension then CellText := TExtension(Data.Field).Ext; end; 1: begin if Data.Field is TFile then CellText := TFile(Data.Field).FileInfo.Extension; end; 2: begin if Data.Field is TFile then CellText := IntToStr(TFile(Data.Field).FileInfo.ID); end; end; end; end; procedure TForm_Meta.VSTPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType); var Data: PNodeData; begin Data := Sender.GetNodeData(Node); if TextType = ttNormal then begin case Column of 0: begin if Data.Field is TFile then begin if Length(TFile(Data.Field).FileInfo.Name) = 0 then TargetCanvas.Font.Color := $C06060; if TFile(Data.Field).FileInfo.Size = 0 then TargetCanvas.Font.Color := $2020A0; end; end; end; end; end; procedure TForm_Meta.FormClose(Sender: TObject; var Action: TCloseAction); begin // Meta.Free; inherited; end; procedure TForm_Meta.FormCreate(Sender: TObject); begin inherited; OnNewConnection := NewCon; VST.NodeDataSize := SizeOf(TNodeData); VST.Font.Charset := AppSettings.CharSet; VST.Clear; UpdateConList; end; end.