| [209] | 1 | unit MetaEditor;
 | 
|---|
| [217] | 2 | 
 | 
|---|
| [209] | 3 | interface
 | 
|---|
| [217] | 4 | 
 | 
|---|
| [209] | 5 | uses
 | 
|---|
 | 6 |   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 | 
|---|
| [232] | 7 |   Dialogs, _BaseTemplate, ExtCtrls, VirtualTrees, StdCtrls, ComCtrls, Grids,
 | 
|---|
| [233] | 8 |   MPHexEditor, Wrapgrid, VTHeaderPopup, Menus, _TreeElement;
 | 
|---|
| [209] | 9 | 
 | 
|---|
 | 10 | type
 | 
|---|
| [217] | 11 |   TForm_Meta = class(TForm_BaseTemplate)
 | 
|---|
| [209] | 12 |     VST: TVirtualStringTree;
 | 
|---|
| [217] | 13 |     splitter: TSplitter;
 | 
|---|
| [232] | 14 |     rightPages: TPageControl;
 | 
|---|
 | 15 |     tab_hex: TTabSheet;
 | 
|---|
 | 16 |     tab_meta: TTabSheet;
 | 
|---|
 | 17 |     panel_hex_actions: TPanel;
 | 
|---|
 | 18 |     hex: TMPHexEditor;
 | 
|---|
 | 19 |     splitter_hex_1: TSplitter;
 | 
|---|
 | 20 |     value_viewer: TWrapGrid;
 | 
|---|
 | 21 |     splitter_hex_2: TSplitter;
 | 
|---|
 | 22 |     structviewer: TVirtualStringTree;
 | 
|---|
| [233] | 23 |     value_viewer_context: TPopupMenu;
 | 
|---|
 | 24 |     value_viewer_context_copy: TMenuItem;
 | 
|---|
 | 25 |     value_viewer_context_copyasdec: TMenuItem;
 | 
|---|
 | 26 |     value_viewer_context_copyasfloat: TMenuItem;
 | 
|---|
 | 27 |     value_viewer_context_copyasbitset: TMenuItem;
 | 
|---|
 | 28 |     value_viewer_context_copyasstring: TMenuItem;
 | 
|---|
 | 29 |     value_viewer_context_copyashex: TMenuItem;
 | 
|---|
 | 30 |     VTHPopup: TVTHeaderPopupMenu;
 | 
|---|
 | 31 |     btn_export: TButton;
 | 
|---|
 | 32 |     btn_import: TButton;
 | 
|---|
| [238] | 33 |     vst_popup: TPopupMenu;
 | 
|---|
 | 34 |     vst_newRoot: TMenuItem;
 | 
|---|
 | 35 |     vst_setRoot: TMenuItem;
 | 
|---|
| [209] | 36 |     procedure FormCreate(Sender: TObject);
 | 
|---|
| [212] | 37 |     procedure VSTInitChildren(Sender: TBaseVirtualTree; Node: PVirtualNode;
 | 
|---|
 | 38 |       var ChildCount: Cardinal);
 | 
|---|
| [217] | 39 |     procedure FormClose(Sender: TObject; var Action: TCloseAction);
 | 
|---|
| [214] | 40 |     procedure VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
 | 
|---|
 | 41 |       Column: TColumnIndex);
 | 
|---|
 | 42 |     procedure VSTFocusChanging(Sender: TBaseVirtualTree; OldNode,
 | 
|---|
 | 43 |       NewNode: PVirtualNode; OldColumn, NewColumn: TColumnIndex;
 | 
|---|
 | 44 |       var Allowed: Boolean);
 | 
|---|
| [217] | 45 |     procedure VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
 | 
|---|
 | 46 |       Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
 | 
|---|
 | 47 |     procedure VSTPaintText(Sender: TBaseVirtualTree;
 | 
|---|
 | 48 |       const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
 | 
|---|
 | 49 |       TextType: TVSTTextType);
 | 
|---|
| [238] | 50 |     procedure VSTGetPopupMenu(Sender: TBaseVirtualTree; Node: PVirtualNode;
 | 
|---|
 | 51 |       Column: TColumnIndex; const P: TPoint; var AskParent: Boolean;
 | 
|---|
 | 52 |       var PopupMenu: TPopupMenu);
 | 
|---|
 | 53 |     procedure vst_setRootClick(Sender: TObject);
 | 
|---|
| [239] | 54 |     procedure vst_newRootClick(Sender: TObject);
 | 
|---|
| [241] | 55 |     procedure VSTGetHint(Sender: TBaseVirtualTree; Node: PVirtualNode;
 | 
|---|
 | 56 |       Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle;
 | 
|---|
 | 57 |       var HintText: WideString);
 | 
|---|
| [209] | 58 |   private
 | 
|---|
| [233] | 59 |     root: TTreeElement;
 | 
|---|
| [217] | 60 |     procedure NewCon(ID: Integer);
 | 
|---|
| [209] | 61 |   public
 | 
|---|
| [238] | 62 |     procedure SetRoot(TreeElem: TTreeElement);
 | 
|---|
| [209] | 63 |   end;
 | 
|---|
 | 64 | 
 | 
|---|
 | 65 | 
 | 
|---|
 | 66 | implementation
 | 
|---|
 | 67 | {$R *.dfm}
 | 
|---|
| [241] | 68 | uses _MetaManager, _MetaTypes, ConnectionManager, Data, _FileTypes, Main, 
 | 
|---|
 | 69 |   TypeDefs;
 | 
|---|
| [209] | 70 | 
 | 
|---|
 | 71 | type
 | 
|---|
 | 72 |   PNodeData = ^TNodeData;
 | 
|---|
 | 73 | 
 | 
|---|
 | 74 |   TNodeData = record
 | 
|---|
| [233] | 75 |     Field: TTreeElement;
 | 
|---|
| [209] | 76 |   end;
 | 
|---|
 | 77 | 
 | 
|---|
 | 78 | function AddVSTEntry(AVST: TCustomVirtualStringTree; ANode: PVirtualNode;
 | 
|---|
 | 79 |   ARecord: TNodeData): PVirtualNode;
 | 
|---|
 | 80 | var
 | 
|---|
 | 81 |   Data: PNodeData;
 | 
|---|
 | 82 | begin
 | 
|---|
 | 83 |   Result := AVST.AddChild(ANode);
 | 
|---|
 | 84 |   Data   := AVST.GetNodeData(Result);
 | 
|---|
 | 85 |   AVST.ValidateNode(Result, False);
 | 
|---|
 | 86 |   Data^ := ARecord;
 | 
|---|
 | 87 | end;
 | 
|---|
 | 88 | 
 | 
|---|
 | 89 | 
 | 
|---|
| [217] | 90 | procedure TForm_Meta.NewCon(ID: Integer);
 | 
|---|
| [238] | 91 | begin
 | 
|---|
 | 92 |   if ID >= 0 then
 | 
|---|
 | 93 |     SetRoot(ConManager.Connection[FConnectionID].MetaData.Root);
 | 
|---|
| [241] | 94 | //SetRoot(ConManager.Connection[FConnectionID].MetaData.FileById[454]);
 | 
|---|
| [238] | 95 | end;
 | 
|---|
 | 96 | 
 | 
|---|
 | 97 | 
 | 
|---|
 | 98 | procedure TForm_Meta.SetRoot(TreeElem: TTreeElement);
 | 
|---|
| [212] | 99 | var
 | 
|---|
 | 100 |   i: Integer;
 | 
|---|
 | 101 |   data: TNodeData;
 | 
|---|
 | 102 |   node: PVirtualNode;
 | 
|---|
| [244] | 103 |   basenode: PVirtualNode;
 | 
|---|
| [212] | 104 | begin
 | 
|---|
| [238] | 105 |   if FConnectionID <> TreeElem.ConnectionID then
 | 
|---|
 | 106 |     SelectConnection(TreeElem.ConnectionID);
 | 
|---|
 | 107 |   root := TreeElem;
 | 
|---|
 | 108 |   VST.Clear;
 | 
|---|
 | 109 |   VST.BeginUpdate;
 | 
|---|
| [244] | 110 |   data.Field := root;
 | 
|---|
 | 111 |   basenode := AddVSTEntry(VST, nil, data);
 | 
|---|
| [238] | 112 |   for i := 0 to root.ChildCount - 1 do
 | 
|---|
| [212] | 113 |   begin
 | 
|---|
| [238] | 114 |     data.Field := root.Child[i];
 | 
|---|
| [244] | 115 |     node := AddVSTEntry(VST, basenode, data);
 | 
|---|
| [238] | 116 |     if data.Field.ChildCount > 0 then
 | 
|---|
| [232] | 117 |       VST.HasChildren[node] := True;
 | 
|---|
| [212] | 118 |   end;
 | 
|---|
| [238] | 119 |   VST.EndUpdate;
 | 
|---|
| [212] | 120 | end;
 | 
|---|
 | 121 | 
 | 
|---|
| [217] | 122 | procedure TForm_Meta.VSTInitChildren(Sender: TBaseVirtualTree;
 | 
|---|
 | 123 |   Node: PVirtualNode; var ChildCount: Cardinal);
 | 
|---|
| [209] | 124 | var
 | 
|---|
| [217] | 125 |   data: PNodeData;
 | 
|---|
 | 126 |   newdata: TNodeData;
 | 
|---|
 | 127 |   newnode: PVirtualNode;
 | 
|---|
| [209] | 128 |   i: Integer;
 | 
|---|
 | 129 | begin
 | 
|---|
| [231] | 130 |   data := Sender.GetNodeData(node);
 | 
|---|
| [233] | 131 | 
 | 
|---|
 | 132 |   if data.Field.ChildCount > 0 then
 | 
|---|
| [232] | 133 |   begin
 | 
|---|
| [233] | 134 |     for i := 0 to data.Field.ChildCount - 1 do
 | 
|---|
| [232] | 135 |     begin
 | 
|---|
| [233] | 136 |       newdata.Field := data.Field.Child[i];
 | 
|---|
| [232] | 137 |       newnode := AddVSTEntry(TCustomVirtualStringTree(Sender), Node, newdata);
 | 
|---|
| [233] | 138 |       if newdata.Field.ChildCount > 0 then
 | 
|---|
| [232] | 139 |         Sender.HasChildren[newnode] := True;
 | 
|---|
 | 140 |     end;
 | 
|---|
 | 141 |   end;
 | 
|---|
| [231] | 142 |   ChildCount := Sender.ChildCount[Node];
 | 
|---|
| [209] | 143 | end;
 | 
|---|
 | 144 | 
 | 
|---|
 | 145 | 
 | 
|---|
| [240] | 146 | 
 | 
|---|
| [214] | 147 | procedure TForm_Meta.VSTFocusChanged(Sender: TBaseVirtualTree;
 | 
|---|
 | 148 |   Node: PVirtualNode; Column: TColumnIndex);
 | 
|---|
 | 149 | var
 | 
|---|
 | 150 |   data: PNodeData;
 | 
|---|
| [248] | 151 |   ffile: TResource;
 | 
|---|
| [214] | 152 | begin
 | 
|---|
 | 153 |   data := Sender.GetNodeData(Node);
 | 
|---|
| [240] | 154 |   ffile := nil;
 | 
|---|
| [248] | 155 |   if data.Field is TResource then
 | 
|---|
 | 156 |     ffile := TResource(data.Field);
 | 
|---|
| [241] | 157 |   if data.Field is _MetaTypes.TDatLink then
 | 
|---|
 | 158 |     if Assigned(_MetaTypes.TDatLink(data.Field).TargetFile) then
 | 
|---|
| [248] | 159 |       ffile := TResource(_MetaTypes.TDatLink(data.Field).TargetFile);
 | 
|---|
| [240] | 160 |   if Assigned(ffile) then
 | 
|---|
| [214] | 161 |   begin
 | 
|---|
| [240] | 162 |     if Assigned(ffile.Editor) then
 | 
|---|
| [214] | 163 |     begin
 | 
|---|
| [240] | 164 |       ffile.Editor.Align := alClient;
 | 
|---|
 | 165 |       tab_meta.InsertControl(ffile.Editor);
 | 
|---|
 | 166 |       ffile.Opened := True;
 | 
|---|
| [214] | 167 |     end;
 | 
|---|
 | 168 |   end;
 | 
|---|
 | 169 | end;
 | 
|---|
 | 170 | 
 | 
|---|
| [217] | 171 | 
 | 
|---|
| [214] | 172 | procedure TForm_Meta.VSTFocusChanging(Sender: TBaseVirtualTree; OldNode,
 | 
|---|
 | 173 |   NewNode: PVirtualNode; OldColumn, NewColumn: TColumnIndex;
 | 
|---|
 | 174 |   var Allowed: Boolean);
 | 
|---|
 | 175 | var
 | 
|---|
 | 176 |   data: PNodeData;
 | 
|---|
 | 177 |   i: Integer;
 | 
|---|
 | 178 | begin
 | 
|---|
 | 179 |   data := Sender.GetNodeData(NewNode);
 | 
|---|
| [248] | 180 |   if data.Field is TResource then
 | 
|---|
| [214] | 181 |   begin
 | 
|---|
| [248] | 182 |     if Assigned(TResource(data.Field).Editor) then
 | 
|---|
 | 183 |       Allowed := not TResource(data.Field).Opened
 | 
|---|
| [214] | 184 |     else
 | 
|---|
 | 185 |       Allowed := True;
 | 
|---|
 | 186 |   end;
 | 
|---|
 | 187 |   if Allowed and Assigned(OldNode) then
 | 
|---|
 | 188 |   begin
 | 
|---|
 | 189 |     data := Sender.GetNodeData(OldNode);
 | 
|---|
| [248] | 190 |     if data.Field is TResource then
 | 
|---|
| [214] | 191 |     begin
 | 
|---|
| [248] | 192 |       if TResource(data.Field).Opened then
 | 
|---|
| [214] | 193 |       begin
 | 
|---|
| [232] | 194 |         if tab_meta.ControlCount > 0 then
 | 
|---|
 | 195 |           for i := 0 to tab_meta.ControlCount - 1 do
 | 
|---|
 | 196 |             tab_meta.RemoveControl(tab_meta.Controls[i]);
 | 
|---|
| [248] | 197 |         TResource(data.Field).Opened := False;
 | 
|---|
| [214] | 198 |       end;
 | 
|---|
 | 199 |     end;
 | 
|---|
 | 200 |   end;
 | 
|---|
 | 201 | end;
 | 
|---|
 | 202 | 
 | 
|---|
| [217] | 203 | 
 | 
|---|
| [209] | 204 | procedure TForm_Meta.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
 | 
|---|
 | 205 |   Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
 | 
|---|
 | 206 | var
 | 
|---|
 | 207 |   Data: PNodeData;
 | 
|---|
 | 208 | begin
 | 
|---|
 | 209 |   Data     := Sender.GetNodeData(Node);
 | 
|---|
 | 210 |   CellText := '';
 | 
|---|
 | 211 |   if TextType = ttNormal then
 | 
|---|
 | 212 |   begin
 | 
|---|
 | 213 |     case Column of
 | 
|---|
| [241] | 214 |       0: CellText := Data.Field.Caption;
 | 
|---|
 | 215 |       1: CellText := data.Field.VType;
 | 
|---|
| [209] | 216 |       2:
 | 
|---|
| [212] | 217 |         begin
 | 
|---|
| [236] | 218 |           if Data.Field is TDataField then
 | 
|---|
 | 219 |             CellText := TDataField(Data.Field).ValueAsString;
 | 
|---|
 | 220 |         end;
 | 
|---|
| [212] | 221 |     end;
 | 
|---|
| [209] | 222 |   end;
 | 
|---|
 | 223 | end;
 | 
|---|
 | 224 | 
 | 
|---|
| [217] | 225 | 
 | 
|---|
| [212] | 226 | procedure TForm_Meta.VSTPaintText(Sender: TBaseVirtualTree;
 | 
|---|
 | 227 |   const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
 | 
|---|
 | 228 |   TextType: TVSTTextType);
 | 
|---|
 | 229 | var
 | 
|---|
 | 230 |   Data: PNodeData;
 | 
|---|
 | 231 | begin
 | 
|---|
 | 232 |   Data     := Sender.GetNodeData(Node);
 | 
|---|
 | 233 |   if TextType = ttNormal then
 | 
|---|
 | 234 |   begin
 | 
|---|
 | 235 |     case Column of
 | 
|---|
 | 236 |       0:
 | 
|---|
 | 237 |         begin
 | 
|---|
| [248] | 238 |           if Data.Field is TResource then
 | 
|---|
| [213] | 239 |           begin
 | 
|---|
| [248] | 240 |             if Length(TResource(Data.Field).FileInfo.Name) = 0 then
 | 
|---|
| [213] | 241 |               TargetCanvas.Font.Color := $C06060;
 | 
|---|
| [248] | 242 |             if TResource(Data.Field).FileInfo.Size = 0 then
 | 
|---|
| [213] | 243 |               TargetCanvas.Font.Color := $2020A0;
 | 
|---|
 | 244 |           end;
 | 
|---|
| [212] | 245 |         end;
 | 
|---|
 | 246 |     end;
 | 
|---|
 | 247 |   end;
 | 
|---|
 | 248 | end;
 | 
|---|
 | 249 | 
 | 
|---|
| [209] | 250 | 
 | 
|---|
| [217] | 251 | 
 | 
|---|
| [241] | 252 | procedure TForm_Meta.VSTGetHint(Sender: TBaseVirtualTree; Node: PVirtualNode;
 | 
|---|
 | 253 |   Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle;
 | 
|---|
 | 254 |   var HintText: WideString);
 | 
|---|
 | 255 | var
 | 
|---|
 | 256 |   data: PNodeData;
 | 
|---|
 | 257 |   CellText: WideString;
 | 
|---|
 | 258 | 
 | 
|---|
| [248] | 259 |   ifile: TResource;
 | 
|---|
| [241] | 260 | begin
 | 
|---|
 | 261 |   inherited;
 | 
|---|
 | 262 |   if Assigned(Node) then
 | 
|---|
 | 263 |   begin
 | 
|---|
 | 264 |     VSTGetText(Sender, Node, Column, ttNormal, CellText);
 | 
|---|
 | 265 |     if Length(CellText) > 0 then
 | 
|---|
 | 266 |     begin
 | 
|---|
 | 267 |       data := Sender.GetNodeData(Node);
 | 
|---|
 | 268 |       if data.Field is TDataField then
 | 
|---|
 | 269 |       begin
 | 
|---|
 | 270 |         case Column of
 | 
|---|
 | 271 |           0,1: HintText := TDataField(data.Field).Description;
 | 
|---|
 | 272 |           2: HintText := '';
 | 
|---|
 | 273 |         end;
 | 
|---|
 | 274 |       end;
 | 
|---|
| [248] | 275 |       if data.Field is TResource then
 | 
|---|
| [241] | 276 |       begin
 | 
|---|
| [248] | 277 |         ifile := TResource(data.Field);
 | 
|---|
| [243] | 278 |         case Column of
 | 
|---|
 | 279 |           0: HintText :=
 | 
|---|
 | 280 |             'FileID:    ' + IntToStr(ifile.FileInfo.ID) + #13#10 +
 | 
|---|
 | 281 |             'Name:      ' + ifile.FileInfo.Name + #13#10 +
 | 
|---|
 | 282 |             'Extension: ' + ifile.FileInfo.Extension + #13#10 +
 | 
|---|
 | 283 |             '.dat-size: ' + IntToStr(ifile.FileInfo.Size) + #13#10;
 | 
|---|
| [241] | 284 |         end;
 | 
|---|
 | 285 |       end;
 | 
|---|
 | 286 |     end;
 | 
|---|
 | 287 |   end
 | 
|---|
 | 288 |   else
 | 
|---|
 | 289 |     HintText := '';
 | 
|---|
 | 290 | end;
 | 
|---|
 | 291 | 
 | 
|---|
| [238] | 292 | procedure TForm_Meta.VSTGetPopupMenu(Sender: TBaseVirtualTree;
 | 
|---|
 | 293 |   Node: PVirtualNode; Column: TColumnIndex; const P: TPoint;
 | 
|---|
 | 294 |   var AskParent: Boolean; var PopupMenu: TPopupMenu);
 | 
|---|
 | 295 | var
 | 
|---|
 | 296 |   data: PNodeData;
 | 
|---|
 | 297 | begin
 | 
|---|
 | 298 |   inherited;
 | 
|---|
 | 299 |   AskParent := False;
 | 
|---|
 | 300 |   if Assigned(Node) then
 | 
|---|
 | 301 |   begin
 | 
|---|
 | 302 |     Sender.Selected[Node] := True;
 | 
|---|
 | 303 |     Sender.FocusedNode := Node;
 | 
|---|
 | 304 |     data := Sender.GetNodeData(Node);
 | 
|---|
 | 305 |     if Column = 0 then
 | 
|---|
 | 306 |     begin
 | 
|---|
| [241] | 307 |       if TTreeElement(data.Field).ChildCount > 0 then
 | 
|---|
| [238] | 308 |         PopupMenu := vst_popup
 | 
|---|
 | 309 |       else
 | 
|---|
 | 310 |         PopupMenu := nil;
 | 
|---|
 | 311 |     end;
 | 
|---|
 | 312 |   end;
 | 
|---|
 | 313 | end;
 | 
|---|
 | 314 | 
 | 
|---|
| [239] | 315 | procedure TForm_Meta.vst_newRootClick(Sender: TObject);
 | 
|---|
 | 316 | var
 | 
|---|
 | 317 |   data: PNodeData;
 | 
|---|
 | 318 |   form: TForm_BaseTemplate;
 | 
|---|
 | 319 | begin
 | 
|---|
 | 320 |   inherited;
 | 
|---|
 | 321 |   data := VST.GetNodeData(VST.FocusedNode);
 | 
|---|
 | 322 |   form := nil;
 | 
|---|
 | 323 |   form := Form_Main.open_child('meta');
 | 
|---|
 | 324 |   if form is TForm_Meta then
 | 
|---|
 | 325 |     TForm_Meta(form).SetRoot(data.Field);
 | 
|---|
 | 326 | end;
 | 
|---|
 | 327 | 
 | 
|---|
| [238] | 328 | procedure TForm_Meta.vst_setRootClick(Sender: TObject);
 | 
|---|
 | 329 | var
 | 
|---|
 | 330 |   data: PNodeData;
 | 
|---|
 | 331 | begin
 | 
|---|
 | 332 |   inherited;
 | 
|---|
 | 333 |   data := VST.GetNodeData(VST.FocusedNode);
 | 
|---|
 | 334 |   SetRoot(data.Field);
 | 
|---|
 | 335 | end;
 | 
|---|
 | 336 | 
 | 
|---|
| [217] | 337 | procedure TForm_Meta.FormClose(Sender: TObject; var Action: TCloseAction);
 | 
|---|
| [209] | 338 | begin
 | 
|---|
| [229] | 339 | //  Meta.Free;
 | 
|---|
| [217] | 340 |   inherited;
 | 
|---|
| [209] | 341 | end;
 | 
|---|
| [217] | 342 | 
 | 
|---|
 | 343 | procedure TForm_Meta.FormCreate(Sender: TObject);
 | 
|---|
 | 344 | begin
 | 
|---|
 | 345 |   inherited;
 | 
|---|
 | 346 |   OnNewConnection := NewCon;
 | 
|---|
 | 347 | 
 | 
|---|
 | 348 |   VST.NodeDataSize := SizeOf(TNodeData);
 | 
|---|
 | 349 |   VST.Font.Charset := AppSettings.CharSet;
 | 
|---|
 | 350 |   VST.Clear;
 | 
|---|
 | 351 | 
 | 
|---|
 | 352 |   UpdateConList;
 | 
|---|
 | 353 | end;
 | 
|---|
 | 354 | 
 | 
|---|
| [209] | 355 | end.
 | 
|---|