--- oup/current/Tools/MetaEditor.pas 2007/06/04 22:07:29 209 +++ oup/current/Tools/MetaEditor.pas 2007/08/10 17:26:03 243 @@ -1,34 +1,78 @@ unit MetaEditor; + interface + uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, - Dialogs, VirtualTrees, _FileManager; + Dialogs, _BaseTemplate, ExtCtrls, VirtualTrees, StdCtrls, ComCtrls, Grids, + MPHexEditor, Wrapgrid, VTHeaderPopup, Menus, _TreeElement; type - TForm_Meta = class(TForm) + TForm_Meta = class(TForm_BaseTemplate) VST: TVirtualStringTree; - procedure FormClose(Sender: TObject; var Action: TCloseAction); + 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; + value_viewer_context: TPopupMenu; + value_viewer_context_copy: TMenuItem; + value_viewer_context_copyasdec: TMenuItem; + value_viewer_context_copyasfloat: TMenuItem; + value_viewer_context_copyasbitset: TMenuItem; + value_viewer_context_copyasstring: TMenuItem; + value_viewer_context_copyashex: TMenuItem; + VTHPopup: TVTHeaderPopupMenu; + btn_export: TButton; + btn_import: TButton; + vst_popup: TPopupMenu; + vst_newRoot: TMenuItem; + vst_setRoot: TMenuItem; 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); + procedure VSTGetPopupMenu(Sender: TBaseVirtualTree; Node: PVirtualNode; + Column: TColumnIndex; const P: TPoint; var AskParent: Boolean; + var PopupMenu: TPopupMenu); + procedure vst_setRootClick(Sender: TObject); + procedure vst_newRootClick(Sender: TObject); + procedure VSTGetHint(Sender: TBaseVirtualTree; Node: PVirtualNode; + Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle; + var HintText: WideString); private + root: TTreeElement; + procedure NewCon(ID: Integer); public - FileManager: TFileManager; + procedure SetRoot(TreeElem: TTreeElement); end; -var - Form_Meta: TForm_Meta; implementation -uses - Data, _DataTypes, _FileTypes; {$R *.dfm} +uses _MetaManager, _MetaTypes, ConnectionManager, Data, _FileTypes, Main, + TypeDefs; type PNodeData = ^TNodeData; TNodeData = record - Field: TObject; + Field: TTreeElement; end; function AddVSTEntry(AVST: TCustomVirtualStringTree; ANode: PVirtualNode; @@ -43,39 +87,125 @@ begin end; - -procedure TForm_Meta.FormClose(Sender: TObject; var Action: TCloseAction); +procedure TForm_Meta.NewCon(ID: Integer); begin - FileManager.Free; - Action := caFree; + if ID >= 0 then + SetRoot(ConManager.Connection[FConnectionID].MetaData.Root); +//SetRoot(ConManager.Connection[FConnectionID].MetaData.FileById[454]); end; -procedure TForm_Meta.FormCreate(Sender: TObject); +procedure TForm_Meta.SetRoot(TreeElem: TTreeElement); var - a,b,c: Int64; i: Integer; data: TNodeData; + node: PVirtualNode; begin - VST.NodeDataSize := SizeOf(TNodeData); - VST.Font.Charset := AppSettings.CharSet; + if FConnectionID <> TreeElem.ConnectionID then + SelectConnection(TreeElem.ConnectionID); + root := TreeElem; VST.Clear; + VST.BeginUpdate; + for i := 0 to root.ChildCount - 1 do + begin + data.Field := root.Child[i]; + node := AddVSTEntry(VST, nil, data); + if data.Field.ChildCount > 0 then + VST.HasChildren[node] := True; + end; + VST.EndUpdate; +end; - QueryPerformanceFrequency(c); - QueryPerformanceCounter(a); - FileManager := TFileManager.Create(1); - QueryPerformanceCounter(b); - ShowMessage('Loading Done - ' + FloatToStr((b-a)/c) + 's'); +procedure TForm_Meta.VSTInitChildren(Sender: TBaseVirtualTree; + Node: PVirtualNode; var ChildCount: Cardinal); +var + data: PNodeData; + newdata: TNodeData; + newnode: PVirtualNode; + i: Integer; +begin + data := Sender.GetNodeData(node); - for i := 0 to FileManager.FileCount - 1 do + if data.Field.ChildCount > 0 then begin - data.Field := FileManager.FileById[i]; - AddVSTEntry(VST, nil, data); + for i := 0 to data.Field.ChildCount - 1 do + begin + newdata.Field := data.Field.Child[i]; + newnode := AddVSTEntry(TCustomVirtualStringTree(Sender), Node, newdata); + if newdata.Field.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; + ffile: TFile; +//******************************************************************* + fs: TFileStream; +//******************************************************************* +begin + data := Sender.GetNodeData(Node); + ffile := nil; + if data.Field is TFile then + ffile := TFile(data.Field); + if data.Field is _MetaTypes.TDatLink then + if Assigned(_MetaTypes.TDatLink(data.Field).TargetFile) then + ffile := TFile(_MetaTypes.TDatLink(data.Field).TargetFile); + if Assigned(ffile) then + begin + if Assigned(ffile.Editor) then + begin + ffile.Editor.Align := alClient; + tab_meta.InsertControl(ffile.Editor); + ffile.Opened := True; + end; +//******************************************************************* +// fs := TFileStream.Create('C:\Spiele\Oni\GameDataFolder\tests\'+IntToStr(ffile.FileInfo.ID)+'_recreated.hex', fmCreate); +// ffile.ReCreateFile(fs); +// fs.Free; +//******************************************************************* + 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 + 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 @@ -86,115 +216,147 @@ begin if TextType = ttNormal then begin case Column of - 0: begin - if Data.Field is TFile then + 0: CellText := Data.Field.Caption; + 1: CellText := data.Field.VType; + 2: begin - CellText := TFile(Data.Field).FileName; + if Data.Field is TDataField then + CellText := TDataField(Data.Field).ValueAsString; end; - end; -{ 0: - CellText := Data.Caption; - 1: - if Data.DataType > 0 then - CellText := '0x' + IntToHex(Data.Offset, 8) - else if Data.Offset > 0 then - CellText := '0x' + IntToHex(Data.Offset, 8); - 2: - if Data.DataType > 0 then - CellText := GetDataType(Data.DataType); - 3: - if Data.DataType > 0 then - CellText := Data.Value //GetValue(data.DataType, data.Offset) - else if Length(Data.Value) > 0 then - CellText := IntToStr(StrToInt(Data.Value)) + ' Bytes'; - 4: - CellText := Data.Description; -} end; + end; end; end; -{ - -procedure WriteStructureInfos; -var - i, j: Integer; - pdata: PNodeData; - Data: TNodeData; - node: PVirtualNode; + +procedure TForm_Meta.VSTPaintText(Sender: TBaseVirtualTree; + const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; + TextType: TVSTTextType); +var + Data: PNodeData; begin - VST.BeginUpdate; - if VST.RootNodeCount = 0 then + Data := Sender.GetNodeData(Node); + if TextType = ttNormal then begin - structs := LoadStructureDefinition(ConID, fileid); - if structs.Data then + 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.VSTGetHint(Sender: TBaseVirtualTree; Node: PVirtualNode; + Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle; + var HintText: WideString); +var + data: PNodeData; + CellText: WideString; + + i: Integer; + links: TStrings; + ifile: TFile; +begin + inherited; + if Assigned(Node) then + begin + VSTGetText(Sender, Node, Column, ttNormal, CellText); + if Length(CellText) > 0 then begin - if Length(structs.Global) > 0 then + data := Sender.GetNodeData(Node); + if data.Field is TDataField then begin - for i := 0 to High(structs.Global) do - begin - Data.Caption := structs.Global[i].Name; - Data.Offset := structs.Global[i].offset; - Data.DataType := structs.Global[i].datatype; - Data.Value := GetValue(structs.Global[i].datatype, structs.Global[i].offset); - Data.Description := structs.Global[i].description; - AddVSTEntry(VST, nil, Data); + case Column of + 0,1: HintText := TDataField(data.Field).Description; + 2: HintText := ''; end; end; - if Length(structs.Subs) > 0 then + if data.Field is TFile then begin - for i := 0 to High(structs.Subs) do - begin - with structs.Subs[i] do - begin - if Length(Entries) > 0 then - begin - if Pos('#', SubName) > 0 then - begin - Data.Offset := StrToInt('$'+MidStr(SubName, Pos('#', SubName) + 1, 8)); - Data.Value := '$' + - MidStr(SubName, PosEx('#', SubName, Pos('#', SubName) + 1) + 1, 8); - Data.Caption := MidStr(SubName, 1, Pos('#', SubName) - 1); - Data.Description := SubDesc; - end - else - begin - Data.Caption := SubName; - Data.Description := SubDesc; - Data.Offset := 0; - Data.Value := ''; - end; - Data.DataType := 0; - node := AddVSTEntry(VST, nil, Data); - Data.Description := ''; - for j := 0 to High(Entries) do - begin - Data.Caption := Entries[j].Name; - Data.Offset := Entries[j].offset; - Data.DataType := Entries[j].datatype; - Data.Value := GetValue(Entries[j].datatype, Entries[j].offset); - Data.Description := Entries[j].description; - AddVSTEntry(VST, node, Data); - end; - end; - end; + ifile := TFile(data.Field); + case Column of + 0: HintText := + 'FileID: ' + IntToStr(ifile.FileInfo.ID) + #13#10 + + 'Name: ' + ifile.FileInfo.Name + #13#10 + + 'Extension: ' + ifile.FileInfo.Extension + #13#10 + + '.dat-size: ' + IntToStr(ifile.FileInfo.Size) + #13#10; end; end; end; - if VST.RootNodeCount > 0 then - VST.FocusedNode := VST.GetFirst; end else + HintText := ''; +end; + +procedure TForm_Meta.VSTGetPopupMenu(Sender: TBaseVirtualTree; + Node: PVirtualNode; Column: TColumnIndex; const P: TPoint; + var AskParent: Boolean; var PopupMenu: TPopupMenu); +var + data: PNodeData; +begin + inherited; + AskParent := False; + if Assigned(Node) then begin - Node := VST.GetFirst; - while Assigned(Node) do + Sender.Selected[Node] := True; + Sender.FocusedNode := Node; + data := Sender.GetNodeData(Node); + if Column = 0 then begin - pdata := VST.GetNodeData(Node); - if pdata.DataType > 0 then - pdata.Value := GetValue(pdata.Datatype, pdata.Offset); - Node := VST.GetNext(Node); + if TTreeElement(data.Field).ChildCount > 0 then + PopupMenu := vst_popup + else + PopupMenu := nil; end; end; - VST.EndUpdate; end; -} + +procedure TForm_Meta.vst_newRootClick(Sender: TObject); +var + data: PNodeData; + form: TForm_BaseTemplate; +begin + inherited; + data := VST.GetNodeData(VST.FocusedNode); + form := nil; + form := Form_Main.open_child('meta'); + if form is TForm_Meta then + TForm_Meta(form).SetRoot(data.Field); +end; + +procedure TForm_Meta.vst_setRootClick(Sender: TObject); +var + data: PNodeData; +begin + inherited; + data := VST.GetNodeData(VST.FocusedNode); + SetRoot(data.Field); +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.