Index: oup/current/Tools/BinEdit.pas
===================================================================
--- oup/current/Tools/BinEdit.pas	(revision 216)
+++ oup/current/Tools/BinEdit.pas	(revision 217)
@@ -3,7 +3,8 @@
 uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, Template, StdCtrls, ExtCtrls, VirtualTrees, Grids, Wrapgrid,
-  MPHexEditor, VTHeaderPopup, Menus, StrUtils, Clipbrd,
-  Data, TypeDefs, ConnectionManager, Buttons;
+  Dialogs, VirtualTrees, Grids, Wrapgrid, MPHexEditor, StdCtrls,
+  Menus, VTHeaderPopup, ExtCtrls, Buttons, StrUtils, Clipbrd,
+  Data, TypeDefs, ConnectionManager, Template,
+  _BaseTemplate, _TemplateFile, _TemplateFileList;
 
 type
@@ -760,5 +761,5 @@
   nodedata: PNodeData;
   rawinfo: TRawDataInfo;
-  form: TForm_ToolTemplate;
+  form: TForm_TemplateFileList;
 begin
   if VST.FocusedColumn = 3 then
@@ -781,5 +782,5 @@
         begin
           form := nil;
-          form := Form_Main.open_child('rawedit', ConID, fileid);
+          form := TForm_TemplateFileList(Form_Main.open_child('rawedit', ConID, fileid));
           if Assigned(form) then
             TForm_RawEdit(form).LoadRaw(rawinfo);
@@ -800,5 +801,5 @@
       if (nodedata.DataType >= 100) and (nodedata.DataType <= 300) then
       begin
-        form := Form_Main.open_child('binedit', ConID, -1);
+        form := TForm_TemplateFileList(Form_Main.open_child('binedit', ConID));
         if Assigned(form) then
           form.SetFileFilters(nodedata.Value, '', False);
Index: oup/current/Tools/MetaEditor.dfm
===================================================================
--- oup/current/Tools/MetaEditor.dfm	(revision 216)
+++ oup/current/Tools/MetaEditor.dfm	(revision 217)
@@ -1,132 +1,87 @@
-object Form_Meta: TForm_Meta
-  Left = 0
-  Top = 0
+inherited Form_Meta: TForm_Meta
   Caption = 'Form_Meta'
-  ClientHeight = 393
-  ClientWidth = 472
-  Color = clBtnFace
-  Constraints.MinHeight = 100
-  Constraints.MinWidth = 200
-  Font.Charset = DEFAULT_CHARSET
-  Font.Color = clWindowText
-  Font.Height = -11
-  Font.Name = 'Tahoma'
-  Font.Style = []
-  FormStyle = fsMDIChild
-  OldCreateOrder = False
-  Visible = True
-  WindowState = wsMaximized
-  OnClose = FormClose
   OnCreate = FormCreate
   PixelsPerInch = 96
   TextHeight = 13
-  object Splitter1: TSplitter
-    Left = 384
-    Top = 29
-    Width = 8
-    Height = 364
-    Align = alRight
-    AutoSnap = False
-    Beveled = True
-    MinSize = 75
-    ExplicitLeft = 301
-    ExplicitHeight = 336
-  end
-  object VST: TVirtualStringTree
-    Left = 0
-    Top = 29
-    Width = 384
-    Height = 364
-    Align = alClient
-    AnimationDuration = 0
-    Header.AutoSizeIndex = 0
-    Header.Font.Charset = DEFAULT_CHARSET
-    Header.Font.Color = clWindowText
-    Header.Font.Height = -11
-    Header.Font.Name = 'Tahoma'
-    Header.Font.Style = []
-    Header.Options = [hoColumnResize, hoDrag, hoVisible]
-    TabOrder = 0
-    TreeOptions.AutoOptions = [toAutoDropExpand, toAutoScrollOnExpand, toAutoDeleteMovedNodes]
-    TreeOptions.MiscOptions = [toFullRepaintOnResize, toInitOnSave, toToggleOnDblClick, toWheelPanning]
-    OnFocusChanged = VSTFocusChanged
-    OnFocusChanging = VSTFocusChanging
-    OnGetText = VSTGetText
-    OnPaintText = VSTPaintText
-    OnInitChildren = VSTInitChildren
-    Columns = <
-      item
-        Position = 0
-        Width = 250
-        WideText = 'FName'
-      end
-      item
-        Position = 1
-        WideText = 'FType'
-      end
-      item
-        Position = 2
-        WideText = 'FID'
-      end
-      item
-        Position = 3
-        WideText = 'Data'
-      end>
-  end
-  object Panel1: TPanel
-    Left = 0
-    Top = 0
-    Width = 472
-    Height = 29
-    Align = alTop
-    BevelOuter = bvNone
-    TabOrder = 1
-    ExplicitWidth = 446
-    DesignSize = (
-      472
-      29)
-    object Label3: TLabel
-      Left = 3
-      Top = 6
-      Width = 61
-      Height = 13
-      Caption = 'Connection: '
-    end
-    object Button1: TButton
-      Left = 379
-      Top = 1
-      Width = 75
-      Height = 25
-      Anchors = [akTop, akRight]
-      Caption = 'Load'
-      Default = True
-      TabOrder = 0
-      OnClick = Button1Click
-      ExplicitLeft = 196
-    end
-    object combo_connection: TComboBox
-      Left = 64
-      Top = 3
-      Width = 309
-      Height = 21
-      Style = csDropDownList
-      Anchors = [akLeft, akTop, akRight]
-      DropDownCount = 12
-      ItemHeight = 13
-      TabOrder = 1
-      ExplicitWidth = 126
+  inherited panel_connection: TPanel
+    ExplicitWidth = 598
+    inherited combo_connection: TComboBox
+      ExplicitWidth = 532
     end
   end
-  object Panel2: TPanel
-    Left = 392
-    Top = 29
-    Width = 80
-    Height = 364
-    Align = alRight
-    BevelOuter = bvNone
-    Caption = 'Panel2'
-    TabOrder = 2
-    ExplicitLeft = 329
-    ExplicitHeight = 336
+  inherited panel_basecontent: TPanel
+    ExplicitLeft = 0
+    ExplicitTop = 25
+    ExplicitWidth = 598
+    ExplicitHeight = 532
+    object splitter: TSplitter
+      Left = 502
+      Top = 0
+      Width = 8
+      Height = 532
+      Align = alRight
+      AutoSnap = False
+      Beveled = True
+      MinSize = 200
+      ExplicitLeft = 353
+    end
+    object VST: TVirtualStringTree
+      Left = 0
+      Top = 0
+      Width = 502
+      Height = 532
+      Align = alClient
+      AnimationDuration = 0
+      Header.AutoSizeIndex = 0
+      Header.Font.Charset = DEFAULT_CHARSET
+      Header.Font.Color = clWindowText
+      Header.Font.Height = -11
+      Header.Font.Name = 'Tahoma'
+      Header.Font.Style = []
+      Header.Options = [hoColumnResize, hoDrag, hoVisible]
+      TabOrder = 0
+      TreeOptions.AutoOptions = [toAutoDropExpand, toAutoScrollOnExpand, toAutoDeleteMovedNodes]
+      TreeOptions.MiscOptions = [toFullRepaintOnResize, toInitOnSave, toToggleOnDblClick, toWheelPanning]
+      OnFocusChanged = VSTFocusChanged
+      OnFocusChanging = VSTFocusChanging
+      OnGetText = VSTGetText
+      OnPaintText = VSTPaintText
+      OnInitChildren = VSTInitChildren
+      ExplicitLeft = 8
+      ExplicitTop = 60
+      ExplicitWidth = 353
+      ExplicitHeight = 325
+      Columns = <
+        item
+          Position = 0
+          Width = 250
+          WideText = 'FName'
+        end
+        item
+          Position = 1
+          WideText = 'FType'
+        end
+        item
+          Position = 2
+          WideText = 'FID'
+        end
+        item
+          Position = 3
+          WideText = 'Data'
+        end>
+    end
+    object Panel2: TPanel
+      Left = 510
+      Top = 0
+      Width = 88
+      Height = 532
+      Align = alRight
+      BevelOuter = bvNone
+      Caption = 'Panel2'
+      TabOrder = 1
+      ExplicitLeft = 376
+      ExplicitTop = 92
+      ExplicitHeight = 285
+    end
   end
 end
Index: oup/current/Tools/MetaEditor.pas
===================================================================
--- oup/current/Tools/MetaEditor.pas	(revision 216)
+++ oup/current/Tools/MetaEditor.pas	(revision 217)
@@ -1,27 +1,19 @@
 unit MetaEditor;
+
 interface
+
 uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, VirtualTrees, _MetaManager, StdCtrls, ExtCtrls;
+  Dialogs, _BaseTemplate, ExtCtrls, VirtualTrees, StdCtrls;
 
 type
-  TForm_Meta = class(TForm)
+  TForm_Meta = class(TForm_BaseTemplate)
     VST: TVirtualStringTree;
-    Panel1: TPanel;
-    Button1: TButton;
-    combo_connection: TComboBox;
-    Label3: TLabel;
-    Splitter1: TSplitter;
     Panel2: TPanel;
-    procedure FormClose(Sender: TObject; var Action: TCloseAction);
+    splitter: TSplitter;
     procedure FormCreate(Sender: TObject);
-    procedure VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
-      Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
-    procedure Button1Click(Sender: TObject);
     procedure VSTInitChildren(Sender: TBaseVirtualTree; Node: PVirtualNode;
       var ChildCount: Cardinal);
-    procedure VSTPaintText(Sender: TBaseVirtualTree;
-      const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
-      TextType: TVSTTextType);
+    procedure FormClose(Sender: TObject; var Action: TCloseAction);
     procedure VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
       Column: TColumnIndex);
@@ -29,5 +21,11 @@
       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;
@@ -37,7 +35,6 @@
 
 implementation
-uses
-  Data, _DataTypes, _FileTypes, ConnectionManager, TypeDefs, StrUtils;
 {$R *.dfm}
+uses _MetaManager, _FileTypes, Data;
 
 type
@@ -60,33 +57,6 @@
 
 
-
-procedure TForm_Meta.VSTInitChildren(Sender: TBaseVirtualTree;
-  Node: PVirtualNode; var ChildCount: Cardinal);
-var
-  data: PNodeData;
-  newdata: TNodeData;
-  newnode: PVirtualNode;
-  i: Integer;
-  id: Integer;
-begin
-  data := VST.GetNodeData(node);
-  for i := 0 to Meta.FileById[TFile(data.Field).FileID].ChildCount - 1 do
-  begin
-    id := Meta.FileById[TFile(data.Field).FileID].LinkByIndex[i].DestID;
-    Meta.InitFile(id);
-    newdata.Field := Meta.FileById[id];
-    newnode := AddVSTEntry(VST, Node, newdata);
-    if Meta.FileById[id].ChildCount > 0 then
-      VST.HasChildren[newnode] := True;
-  end;
-  ChildCount := Meta.FileById[TFile(data.Field).FileID].ChildCount;
-end;
-
-
-procedure TForm_Meta.Button1Click(Sender: TObject);
-var
-  name: String;
-  conid: Integer;
-
+procedure TForm_Meta.NewCon(ID: Integer);
+var
   a,b,c: Int64;
   i: Integer;
@@ -94,13 +64,10 @@
   node: PVirtualNode;
 begin
-  if combo_connection.ItemIndex >= 0 then
-  begin
-    name := combo_connection.Items.Strings[combo_connection.ItemIndex];
-    conid := StrToInt(MidStr(name, Pos('[', name) + 1, Pos(']', name) - Pos('[', name)  - 1));
-
+  if ID >= 0 then
+  begin
     QueryPerformanceFrequency(c);
     QueryPerformanceCounter(a);
     if not Assigned(Meta) then
-      Meta := TMetaManager.Create(conid);
+      Meta := TMetaManager.Create(ID);
     QueryPerformanceCounter(b);
     ShowMessage('Loading Done - ' + FloatToStr((b-a)/c) + 's');
@@ -122,47 +89,26 @@
 end;
 
-procedure TForm_Meta.FormClose(Sender: TObject; var Action: TCloseAction);
-begin
-  Meta.Free;
-  Action := caFree;
-end;
-
-
-procedure TForm_Meta.FormCreate(Sender: TObject);
-var
+
+procedure TForm_Meta.VSTInitChildren(Sender: TBaseVirtualTree;
+  Node: PVirtualNode; var ChildCount: Cardinal);
+var
+  data: PNodeData;
+  newdata: TNodeData;
+  newnode: PVirtualNode;
   i: Integer;
-
-  fn, datatype, boxstring: String;
-  level: Integer;
-begin
-  combo_connection.ItemIndex := -1;
-  combo_connection.Items.Clear;
-  if ConManager.Count > 0 then
-  begin
-    for i := 0 to ConManager.Count - 1 do
-    begin
-      level := ConManager.ConnectionByIndex[i].LevelNumber;
-      fn := ExtractFileName(ConManager.ConnectionByIndex[i].FileName);
-      if ConManager.ConnectionByIndex[i].Backend = DB_ONI then
-        datatype := 'ONI-.dat: '
-      else if ConManager.ConnectionByIndex[i].Backend = DB_ADB then
-        datatype := 'OUP-DB: '
-      else
-        datatype := 'Unknown: ';
-      boxstring := datatype + fn + ' (Level: ' + IntToStr(level) + ') [' + IntToStr(ConManager.ConnectionByIndex[i].ConnectionID) + ']';
-      combo_connection.Items.Add(boxstring);
-    end;
-    if combo_connection.ItemIndex = -1 then
-    begin
-      combo_connection.ItemIndex := 0;
-    end;
-  end;
-
-
-  VST.NodeDataSize := SizeOf(TNodeData);
-  VST.Font.Charset := AppSettings.CharSet;
-  VST.Clear;
-end;
-
+  id: Integer;
+begin
+  data := VST.GetNodeData(node);
+  for i := 0 to Meta.FileById[TFile(data.Field).FileID].ChildCount - 1 do
+  begin
+    id := Meta.FileById[TFile(data.Field).FileID].LinkByIndex[i].DestID;
+    Meta.InitFile(id);
+    newdata.Field := Meta.FileById[id];
+    newnode := AddVSTEntry(VST, Node, newdata);
+    if Meta.FileById[id].ChildCount > 0 then
+      VST.HasChildren[newnode] := True;
+  end;
+  ChildCount := Meta.FileById[TFile(data.Field).FileID].ChildCount;
+end;
 
 
@@ -183,4 +129,5 @@
   end;
 end;
+
 
 procedure TForm_Meta.VSTFocusChanging(Sender: TBaseVirtualTree; OldNode,
@@ -216,4 +163,5 @@
 end;
 
+
 procedure TForm_Meta.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
   Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
@@ -248,4 +196,5 @@
   end;
 end;
+
 
 procedure TForm_Meta.VSTPaintText(Sender: TBaseVirtualTree;
@@ -273,87 +222,24 @@
 end;
 
-{
-
-procedure WriteStructureInfos;
-var
-  i, j:    Integer;
-  pdata:   PNodeData;
-  Data:    TNodeData;
-  node:    PVirtualNode;
-begin
-  VST.BeginUpdate;
-  if VST.RootNodeCount = 0 then
-  begin
-    structs := LoadStructureDefinition(ConID, fileid);
-    if structs.Data then
-    begin
-      if Length(structs.Global) > 0 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);
-        end;
-      end;
-      if Length(structs.Subs) > 0 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;
-        end;
-      end;
-    end;
-    if VST.RootNodeCount > 0 then
-      VST.FocusedNode := VST.GetFirst;
-  end
-  else
-  begin
-    Node := VST.GetFirst;
-    while Assigned(Node) do
-    begin
-      pdata := VST.GetNodeData(Node);
-      if pdata.DataType > 0 then
-        pdata.Value := GetValue(pdata.Datatype, pdata.Offset);
-      Node := VST.GetNext(Node);
-    end;
-  end;
-  VST.EndUpdate;
-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;
+  FConnectionID := -1;
+
+  VST.NodeDataSize := SizeOf(TNodeData);
+  VST.Font.Charset := AppSettings.CharSet;
+  VST.Clear;
+
+  UpdateConList;
+end;
+
 end.
Index: oup/current/Tools/Template.pas
===================================================================
--- oup/current/Tools/Template.pas	(revision 216)
+++ oup/current/Tools/Template.pas	(revision 217)
@@ -266,5 +266,5 @@
   Form_WhatLinksHere.ConID := FConnectionID;
   Form_WhatLinksHere.FileID := FSelectedFile.ID;
-  Form_WhatLinksHere.SenderForm := Self;
+//  Form_WhatLinksHere.SenderForm := Self;
   Form_WhatLinksHere.Show;
 end;
Index: oup/current/Tools/_BaseTemplate.dfm
===================================================================
--- oup/current/Tools/_BaseTemplate.dfm	(revision 217)
+++ oup/current/Tools/_BaseTemplate.dfm	(revision 217)
@@ -0,0 +1,68 @@
+object Form_BaseTemplate: TForm_BaseTemplate
+  Left = 0
+  Top = 0
+  Caption = 'Form_BaseTemplate'
+  ClientHeight = 557
+  ClientWidth = 598
+  Color = clBtnFace
+  Font.Charset = DEFAULT_CHARSET
+  Font.Color = clWindowText
+  Font.Height = -11
+  Font.Name = 'Tahoma'
+  Font.Style = []
+  FormStyle = fsMDIChild
+  OldCreateOrder = False
+  Visible = True
+  WindowState = wsMaximized
+  OnActivate = FormActivate
+  OnClose = FormClose
+  PixelsPerInch = 96
+  TextHeight = 13
+  object panel_connection: TPanel
+    Left = 0
+    Top = 0
+    Width = 598
+    Height = 25
+    Align = alTop
+    BevelOuter = bvNone
+    TabOrder = 0
+    ExplicitWidth = 200
+    DesignSize = (
+      598
+      25)
+    object label_connection: TLabel
+      Left = 3
+      Top = 6
+      Width = 61
+      Height = 13
+      Caption = '&Connection: '
+      FocusControl = combo_connection
+    end
+    object combo_connection: TComboBox
+      Left = 64
+      Top = 3
+      Width = 532
+      Height = 21
+      Style = csDropDownList
+      Anchors = [akLeft, akTop, akRight]
+      DropDownCount = 12
+      ItemHeight = 13
+      TabOrder = 0
+      OnChange = combo_connectionChange
+      ExplicitWidth = 134
+    end
+  end
+  object panel_basecontent: TPanel
+    Left = 0
+    Top = 25
+    Width = 598
+    Height = 532
+    Align = alClient
+    BevelOuter = bvNone
+    TabOrder = 1
+    ExplicitLeft = 212
+    ExplicitTop = 272
+    ExplicitWidth = 185
+    ExplicitHeight = 41
+  end
+end
Index: oup/current/Tools/_BaseTemplate.pas
===================================================================
--- oup/current/Tools/_BaseTemplate.pas	(revision 217)
+++ oup/current/Tools/_BaseTemplate.pas	(revision 217)
@@ -0,0 +1,142 @@
+unit _BaseTemplate;
+
+interface
+
+uses
+  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+  Dialogs, ExtCtrls, StdCtrls, StrUtils,
+  TypeDefs;
+
+type
+  TNewConnectionEvent = procedure(ConnectionID: Integer) of object;
+  TCheckCloseableEvent = function: Boolean of object;
+
+  TForm_BaseTemplate = class(TForm)
+    panel_connection: TPanel;
+    label_connection: TLabel;
+    combo_connection: TComboBox;
+    panel_basecontent: TPanel;
+    procedure FormClose(Sender: TObject; var Action: TCloseAction);
+    procedure FormActivate(Sender: TObject);
+    procedure combo_connectionChange(Sender: TObject);
+  protected
+    FOnNewConnection: TNewConnectionEvent;
+    FOnCheckCloseable: TCheckCloseableEvent;
+    FConnectionID: Integer;
+    function GetToolCloseable: Boolean;
+  public
+    constructor Create(AOwner: TComponent); override;
+    procedure UpdateConList;
+    procedure SelectConnection(ConnectionID: Integer);
+  published
+    property OnNewConnection: TNewConnectionEvent read FOnNewConnection write FOnNewConnection;
+    property OnCheckCloseable: TCheckCloseableEvent read FOnCheckCloseable write FOnCheckCloseable;
+    property ConnectionID: Integer read FConnectionID;
+    property Closeable: Boolean read GetToolCloseable;
+  end;
+
+  
+implementation
+{$R *.dfm}
+uses Main, ConnectionManager;
+
+
+procedure TForm_BaseTemplate.UpdateConList;
+var
+  i: Integer;
+  fn, datatype, boxstring: String;
+  level: Integer;
+begin
+  combo_connection.ItemIndex := -1;
+  combo_connection.Items.Clear;
+  if ConManager.Count > 0 then
+  begin
+    for i := 0 to ConManager.Count - 1 do
+    begin
+      level := ConManager.ConnectionByIndex[i].LevelNumber;
+      fn := ExtractFileName(ConManager.ConnectionByIndex[i].FileName);
+      if ConManager.ConnectionByIndex[i].Backend = DB_ONI then
+        datatype := 'ONI-.dat: '
+      else if ConManager.ConnectionByIndex[i].Backend = DB_ADB then
+        datatype := 'OUP-DB: '
+      else
+        datatype := 'Unknown: ';
+      boxstring := datatype + fn + ' (Level: ' + IntToStr(level) + ') [' + IntToStr(ConManager.ConnectionByIndex[i].ConnectionID) + ']';
+      combo_connection.Items.Add(boxstring);
+      if ConManager.ConnectionByIndex[i].ConnectionID = FConnectionID then
+        combo_connection.ItemIndex := combo_connection.Items.Count - 1;
+    end;
+    if combo_connection.ItemIndex = -1 then
+    begin
+      combo_connection.ItemIndex := 0;
+      combo_connectionChange(Self);
+    end;
+  end
+  else
+  begin
+    FConnectionID := 0;
+    combo_connectionChange(Self);
+  end;
+end;
+
+
+
+procedure TForm_BaseTemplate.combo_connectionChange(Sender: TObject);
+var
+  name: String;
+begin
+  if combo_connection.ItemIndex >= 0 then
+  begin
+    name := combo_connection.Items.Strings[combo_connection.ItemIndex];
+    FConnectionID := StrToInt(MidStr(name, Pos('[', name) + 1, Pos(']', name) - Pos('[', name)  - 1));
+  end
+  else
+    FConnectionID := -1;
+  if Assigned(FOnNewConnection) then
+    FOnNewConnection(FConnectionID);
+end;
+
+
+procedure TForm_BaseTemplate.SelectConnection(ConnectionID: Integer);
+begin
+  if FConnectionID <> ConnectionID then
+  begin
+    combo_connection.ItemIndex := ConManager.ConnectionIndexByID[ConnectionID];
+    combo_connectionChange(Self);
+  end;
+end;
+
+
+function TForm_BaseTemplate.GetToolCloseable: Boolean;
+begin
+  if Assigned(FOnCheckCloseable) then
+    Result := FOnCheckCloseable
+  else
+    Result := True;
+end;
+
+
+constructor TForm_BaseTemplate.Create(AOwner: TComponent);
+begin
+  inherited;
+  Self.Width  := 260;
+  Self.Height := 300;
+  FOnNewConnection := nil;
+  FOnCheckCloseable := nil;
+  FConnectionID := -1;
+  UpdateConList;
+end;
+
+procedure TForm_BaseTemplate.FormActivate(Sender: TObject);
+begin
+  if panel_basecontent.CanFocus then
+    panel_basecontent.SetFocus;
+end;
+
+procedure TForm_BaseTemplate.FormClose(Sender: TObject; var Action: TCloseAction);
+begin
+  Action := caFree;
+end;
+
+
+end.
Index: oup/current/Tools/_TemplateFile.dfm
===================================================================
--- oup/current/Tools/_TemplateFile.dfm	(revision 217)
+++ oup/current/Tools/_TemplateFile.dfm	(revision 217)
@@ -0,0 +1,17 @@
+inherited Form_TemplateFile: TForm_TemplateFile
+  Caption = 'Form_TemplateFile'
+  PixelsPerInch = 96
+  TextHeight = 13
+  inherited panel_connection: TPanel
+    ExplicitWidth = 598
+    inherited combo_connection: TComboBox
+      ExplicitWidth = 532
+    end
+  end
+  inherited panel_basecontent: TPanel
+    ExplicitLeft = 0
+    ExplicitTop = 25
+    ExplicitWidth = 598
+    ExplicitHeight = 532
+  end
+end
Index: oup/current/Tools/_TemplateFile.pas
===================================================================
--- oup/current/Tools/_TemplateFile.pas	(revision 217)
+++ oup/current/Tools/_TemplateFile.pas	(revision 217)
@@ -0,0 +1,102 @@
+unit _TemplateFile;
+
+interface
+
+uses
+  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+  Dialogs, _BaseTemplate, StdCtrls, ExtCtrls,
+  TypeDefs;
+
+type
+  TNewFileSelectedEvent = procedure(FileInfo: TFileInfo) of object;
+
+  TForm_TemplateFile = class(TForm_BaseTemplate)
+  protected
+    FOnNewFileSelected: TNewFileSelectedEvent;
+    FSelectedFile: TFileInfo;
+  public
+    constructor Create(AOwner: TComponent); override;
+    procedure SelectFileID(ConnectionID, FileID: Integer);
+  published
+    property OnNewFileSelected: TNewFileSelectedEvent read FOnNewFileSelected write FOnNewFileSelected;
+    property SelectedFile: TFileInfo read FSelectedFile;
+  end;
+
+var
+  ToolList: TToolList;
+procedure AddToolListEntry(context, name, exts: String);
+
+implementation
+{$R *.dfm}
+uses ConnectionManager;
+
+
+constructor TForm_TemplateFile.Create(AOwner: TComponent);
+begin
+  inherited;
+  FOnNewFileSelected := nil;
+  FSelectedFile.ID := -1;
+end;
+
+
+procedure TForm_TemplateFile.SelectFileID(ConnectionID, FileID: Integer);
+begin
+  if FConnectionID <> ConnectionID then
+    SelectConnection(ConnectionID);
+
+  if FileID < ConManager.Connection[FConnectionID].GetFileCount then
+    FSelectedFile := ConManager.Connection[FConnectionID].GetFileInfo(FileID)
+  else
+    FSelectedFile.ID := -1;
+  if Assigned(FOnNewFileSelected) then
+    FOnNewFileSelected(FSelectedFile);
+end;
+
+
+
+procedure AddToolListEntryExt(context, ext: String);
+var
+  i: Integer;
+begin
+  for i := 0 to High(ToolList) do
+    if ToolList[i].context = context then
+    begin
+      if Pos(ext, ToolList[i].exts) = 0 then
+      begin
+        if Length(ToolList[i].exts) = 0 then
+          ToolList[i].exts := ext
+        else
+          ToolList[i].exts := ToolList[i].exts + ',' + ext;
+      end;
+      Exit;
+    end;
+end;
+
+procedure AddToolListEntry(context, name, exts: String);
+var
+  i: Integer;
+begin
+  if Length(ToolList) > 0 then
+  begin
+    for i := 0 to High(ToolList) do
+      if ToolList[i].context = context then
+      begin
+        if (Length(ToolList[i].name) = 0) and (Length(name) > 0) then
+          ToolList[i].name := name;
+        if Length(exts) > 0 then
+          AddToolListEntryExt(context, exts);
+        Exit;
+      end;
+  end;
+  SetLength(ToolList, Length(ToolList) + 1);
+  for i := High(ToolList) downto 1 do
+    if ToolList[i - 1].name > name then
+      ToolList[i] := ToolList[i - 1]
+    else
+      Break;
+  ToolList[i].context := context;
+  ToolList[i].name := name;
+  ToolList[i].exts := exts;
+end;
+
+end.
Index: oup/current/Tools/_TemplateFileList.dfm
===================================================================
--- oup/current/Tools/_TemplateFileList.dfm	(revision 217)
+++ oup/current/Tools/_TemplateFileList.dfm	(revision 217)
@@ -0,0 +1,293 @@
+inherited Form_TemplateFileList: TForm_TemplateFileList
+  Caption = 'Form_TemplateFileList'
+  PixelsPerInch = 96
+  TextHeight = 13
+  inherited panel_basecontent: TPanel
+    object splitter_content: TSplitter
+      Left = 200
+      Top = 0
+      Width = 8
+      Height = 532
+      AutoSnap = False
+      Beveled = True
+      MinSize = 150
+    end
+    object panel_files: TPanel
+      Left = 0
+      Top = 0
+      Width = 200
+      Height = 532
+      Align = alLeft
+      BevelOuter = bvNone
+      TabOrder = 0
+      ExplicitHeight = 423
+      object filelist: TListBox
+        Left = 0
+        Top = 125
+        Width = 200
+        Height = 407
+        Align = alClient
+        ItemHeight = 13
+        TabOrder = 0
+        ExplicitTop = 153
+        ExplicitHeight = 379
+      end
+      object panel_extension: TPanel
+        Left = 0
+        Top = 0
+        Width = 200
+        Height = 125
+        Align = alTop
+        BevelOuter = bvNone
+        TabOrder = 1
+        DesignSize = (
+          200
+          125)
+        object label_sort2: TLabel
+          Left = 98
+          Top = 105
+          Width = 17
+          Height = 18
+          AutoSize = False
+          Caption = '.'
+          Font.Charset = DEFAULT_CHARSET
+          Font.Color = clWindowText
+          Font.Height = -13
+          Font.Name = 'Tahoma'
+          Font.Style = [fsBold]
+          ParentFont = False
+        end
+        object label_sort1: TLabel
+          Left = 45
+          Top = 105
+          Width = 17
+          Height = 18
+          AutoSize = False
+          Caption = '-'
+          Font.Charset = DEFAULT_CHARSET
+          Font.Color = clWindowText
+          Font.Height = -13
+          Font.Name = 'Tahoma'
+          Font.Style = [fsBold]
+          ParentFont = False
+        end
+        object label_extension: TLabel
+          Left = 0
+          Top = 62
+          Width = 100
+          Height = 17
+          AutoSize = False
+          Caption = 'Filter by &extension:'
+          FocusControl = combo_extension
+        end
+        object btn_sort_id_asc: TSpeedButton
+          Left = 1
+          Top = 101
+          Width = 20
+          Height = 22
+          Hint = 'Sort files by id, ascending'
+          GroupIndex = 1
+          Down = True
+          Glyph.Data = {
+            F6000000424DF600000000000000760000002800000010000000100000000100
+            0400000000008000000000000000000000001000000000000000C0C0C0000000
+            9900990000000000000000000000000000000000000000000000000000000000
+            0000000000000000000000000000000000000000000000000000000000000000
+            0000000001100000300000001001000030000000000100033300000001110003
+            3300000010010033333000001001000030000000011000003000000000000000
+            3000000002200000300000002002000030000000200200003000000020020000
+            3000000020020000300000002002000030000000022000003000}
+          ParentShowHint = False
+          ShowHint = True
+        end
+        object btn_sort_id_desc: TSpeedButton
+          Left = 21
+          Top = 101
+          Width = 20
+          Height = 22
+          Hint = 'Sort files by id, descending'
+          GroupIndex = 1
+          Glyph.Data = {
+            F6000000424DF600000000000000760000002800000010000000100000000100
+            0400000000008000000000000000000000001000000000000000C0C0C0000000
+            9900990000000000000000000000000000000000000000000000000000000000
+            0000000000000000000000000000000000000000000000000000000000000000
+            0000000002200000300000002002000030000000200200033300000020020003
+            3300000020020033333000002002000030000000022000003000000000000000
+            3000000001100000300000001001000030000000000100003000000001110000
+            3000000010010000300000001001000030000000011000003000}
+          ParentShowHint = False
+          ShowHint = True
+        end
+        object btn_sort_name_asc: TSpeedButton
+          Left = 56
+          Top = 101
+          Width = 20
+          Height = 22
+          Hint = 'Sort files by name, ascending'
+          GroupIndex = 1
+          Glyph.Data = {
+            F6000000424DF600000000000000760000002800000010000000100000000100
+            0400000000008000000000000000000000001000000000000000C0C0C0000000
+            9900990000000000000000000000000000000000000000000000000000000000
+            0000000000000000000000000000000000000000000000000000000000000000
+            0000011111100000300001100010000030000011000000033300000110000003
+            3300000011000033333001000110000030000111111000003000000000000000
+            3000022202220000300000200020000030000022222000003000000202000000
+            3000000222000000300000002000000030000000200000003000}
+          ParentShowHint = False
+          ShowHint = True
+        end
+        object btn_sort_name_desc: TSpeedButton
+          Left = 76
+          Top = 101
+          Width = 20
+          Height = 22
+          Hint = 'Sort files by name, descending'
+          GroupIndex = 1
+          Glyph.Data = {
+            F6000000424DF600000000000000760000002800000010000000100000000100
+            0400000000008000000000000000000000001000000000000000C0C0C0000000
+            9900990000000000000000000000000000000000000000000000000000000000
+            0000000000000000000000000000000000000000000000000000000000000000
+            0000022202220000300000200020000030000022222000033300000202000003
+            3300000222000033333000002000000030000000200000003000000000000000
+            3000011111100000300001100010000030000011000000003000000110000000
+            3000000011000000300001000110000030000111111000003000}
+          ParentShowHint = False
+          ShowHint = True
+        end
+        object btn_sort_ext_asc: TSpeedButton
+          Left = 106
+          Top = 101
+          Width = 20
+          Height = 22
+          Hint = 'Sort files by extension, ascending'
+          GroupIndex = 1
+          Glyph.Data = {
+            F6000000424DF600000000000000760000002800000010000000100000000100
+            0400000000008000000000000000000000001000000000000000C0C0C0000000
+            9900990000000000000000000000000000000000000000000000000000000000
+            0000000000000000000000000000000000000000000000000000000000000000
+            0000011111100000300001100010000030000011000000033300000110000003
+            3300000011000033333001000110000030000111111000003000000000000000
+            3000022202220000300000200020000030000022222000003000000202000000
+            3000000222000000300000002000000030000000200000003000}
+          ParentShowHint = False
+          ShowHint = True
+        end
+        object btn_sort_ext_desc: TSpeedButton
+          Left = 126
+          Top = 101
+          Width = 20
+          Height = 22
+          Hint = 'Sort files by extension, descending'
+          GroupIndex = 1
+          Glyph.Data = {
+            F6000000424DF600000000000000760000002800000010000000100000000100
+            0400000000008000000000000000000000001000000000000000C0C0C0000000
+            9900990000000000000000000000000000000000000000000000000000000000
+            0000000000000000000000000000000000000000000000000000000000000000
+            0000022202220000300000200020000030000022222000033300000202000003
+            3300000222000033333000002000000030000000200000003000000000000000
+            3000011111100000300001100010000030000011000000003000000110000000
+            3000000011000000300001000110000030000111111000003000}
+          ParentShowHint = False
+          ShowHint = True
+        end
+        object bevel_filelist: TBevel
+          Left = 0
+          Top = 0
+          Width = 199
+          Height = 3
+          Anchors = [akLeft, akTop, akRight]
+          Style = bsRaised
+        end
+        object combo_extension: TComboBox
+          Left = 0
+          Top = 76
+          Width = 196
+          Height = 21
+          Style = csDropDownList
+          Anchors = [akLeft, akTop, akRight]
+          DropDownCount = 20
+          Font.Charset = DEFAULT_CHARSET
+          Font.Color = clWindowText
+          Font.Height = -11
+          Font.Name = 'Courier'
+          Font.Style = []
+          ItemHeight = 13
+          ParentFont = False
+          Sorted = True
+          TabOrder = 3
+        end
+        object check_zerobyte: TCheckBox
+          Left = 0
+          Top = 44
+          Width = 130
+          Height = 13
+          Caption = 'Show &zero-byte files'
+          TabOrder = 2
+        end
+        object edit_filtername: TEdit
+          Left = 0
+          Top = 20
+          Width = 196
+          Height = 18
+          Anchors = [akLeft, akTop, akRight]
+          AutoSize = False
+          TabOrder = 1
+        end
+        object check_filtername: TCheckBox
+          Left = 0
+          Top = 5
+          Width = 130
+          Height = 15
+          Caption = 'Filter by file&name:'
+          TabOrder = 0
+        end
+      end
+    end
+    object panel_content: TPanel
+      Left = 208
+      Top = 0
+      Width = 390
+      Height = 532
+      Align = alClient
+      BevelOuter = bvNone
+      TabOrder = 1
+      ExplicitTop = 248
+      ExplicitWidth = 185
+      ExplicitHeight = 41
+    end
+  end
+  object filepopup: TPopupMenu
+    Left = 72
+    Top = 216
+    object popup_separator2: TMenuItem
+      Caption = '-'
+    end
+    object popup_linkshere: TMenuItem
+      Caption = 'What links here? Where does this file link to?'
+    end
+    object popup_separator: TMenuItem
+      Caption = '-'
+    end
+    object popup_import: TMenuItem
+      Caption = 'Import binary .dat-file'
+    end
+    object popup_export: TMenuItem
+      Caption = 'Export binary .dat-file'
+    end
+  end
+  object importd: TOpenDialog
+    Options = [ofExtensionDifferent, ofPathMustExist, ofFileMustExist, ofEnableSizing]
+    Left = 136
+    Top = 232
+  end
+  object exportd: TSaveDialog
+    Options = [ofHideReadOnly, ofExtensionDifferent, ofPathMustExist, ofEnableSizing]
+    Left = 144
+    Top = 256
+  end
+end
Index: oup/current/Tools/_TemplateFileList.pas
===================================================================
--- oup/current/Tools/_TemplateFileList.pas	(revision 217)
+++ oup/current/Tools/_TemplateFileList.pas	(revision 217)
@@ -0,0 +1,349 @@
+unit _TemplateFileList;
+
+interface
+
+uses
+  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+  Dialogs, _TemplateFile, StdCtrls, ExtCtrls, Menus, Buttons,
+  TypeDefs;
+
+type
+  TForm_TemplateFileList = class(TForm_TemplateFile)
+    panel_files: TPanel;
+    filelist: TListBox;
+    panel_extension: TPanel;
+    label_sort2: TLabel;
+    label_sort1: TLabel;
+    label_extension: TLabel;
+    btn_sort_id_asc: TSpeedButton;
+    btn_sort_id_desc: TSpeedButton;
+    btn_sort_name_asc: TSpeedButton;
+    btn_sort_name_desc: TSpeedButton;
+    btn_sort_ext_asc: TSpeedButton;
+    btn_sort_ext_desc: TSpeedButton;
+    combo_extension: TComboBox;
+    check_zerobyte: TCheckBox;
+    edit_filtername: TEdit;
+    check_filtername: TCheckBox;
+    bevel_filelist: TBevel;
+    splitter_content: TSplitter;
+    panel_content: TPanel;
+    filepopup: TPopupMenu;
+    popup_separator2: TMenuItem;
+    popup_linkshere: TMenuItem;
+    popup_separator: TMenuItem;
+    popup_import: TMenuItem;
+    popup_export: TMenuItem;
+    importd: TOpenDialog;
+    exportd: TSaveDialog;
+  private
+    FSortBy: TSortType;
+    FAllowedExts: String;
+    FAllowMultiSelect: Boolean;
+    procedure SetAllowedExts(exts: String);
+    procedure SetMultiSelect(allow: Boolean);
+
+    procedure check_filternameClick(Sender: TObject);
+    procedure check_zerobyteClick(Sender: TObject);
+    procedure combo_extensionClick(Sender: TObject);
+    procedure btn_sortClick(Sender: TObject);
+    procedure listClick(Sender: TObject);
+    procedure listMouseDown(Sender: TObject; Button: TMouseButton;
+      Shift: TShiftState; X, Y: Integer);
+
+    procedure popup_importClick(Sender: TObject);
+    procedure popup_exportClick(Sender: TObject);
+    procedure popup_opentool(Sender: TObject);
+    procedure popup_linkshereClick(Sender: TObject);
+    procedure filepopupPopup(Sender: TObject);
+  public
+    constructor Create(AOwner: TComponent); override;
+    procedure RecreateExtList;
+    procedure LoadFileNames;
+    procedure SetFileFilters(pattern, extension: String; zerobytes: Boolean);
+    property AllowedExts: String read FAllowedExts write SetAllowedExts;
+    property AllowMultiSelect: Boolean read FAllowMultiSelect write SetMultiSelect;
+  end;
+
+var
+  Form_TemplateFileList: TForm_TemplateFileList;
+
+implementation
+{$R *.dfm}
+uses ConnectionManager, Exporters, Functions, StrUtils, WhatLinksHere, Main;
+
+
+procedure TForm_TemplateFileList.RecreateExtList;
+var
+  i:    Integer;
+  exts: TStrings;
+begin
+  combo_extension.Items.Clear;
+  if FConnectionID > -1 then
+  begin
+    combo_extension.Items.Add('_All files_ (' +
+      IntToStr(ConManager.Connection[FConnectionID].GetFileCount) + ')');
+    exts := nil;
+    exts := ConManager.Connection[FConnectionID].GetExtensionsList(EF_ExtCount);
+    for i := 0 to exts.Count - 1 do
+      if Length(FAllowedExts) > 0 then
+      begin
+        if Pos(MidStr(exts.Strings[i],1,4), FAllowedExts) > 0 then
+          combo_extension.Items.Add(exts.Strings[i]);
+      end
+      else
+        combo_extension.Items.Add(exts.Strings[i]);
+    combo_extension.ItemIndex := 0;
+    combo_extensionClick(Self);
+    exts.Free;
+  end;
+end;
+
+procedure TForm_TemplateFileList.LoadFileNames;
+var
+  Extension: String;
+  no_zero_bytes: Boolean;
+  pattern: String;
+  files: TStrings;
+begin
+  if FConnectionID > -1 then
+  begin
+    Extension := MidStr(combo_extension.Items.Strings[combo_extension.ItemIndex], 1, 4);
+    no_zero_bytes := not check_zerobyte.Checked;
+    pattern := '';
+    if check_filtername.Checked then
+      pattern := edit_filtername.Text;
+    if Extension = '_All' then
+      if Length(FAllowedExts) > 0 then
+        Extension := FAllowedExts
+      else
+        Extension := '';
+
+    files := nil;
+    files := ConManager.Connection[FConnectionID].GetFilesList(extension, pattern, no_zero_bytes, FSortBy);
+
+    filelist.Visible := False;
+    filelist.Items.Clear;
+    if files.Count > 0 then
+      filelist.Items.AddStrings(files);
+    filelist.Visible := True;
+  end;
+end;
+
+
+procedure TForm_TemplateFileList.popup_exportClick(Sender: TObject);
+var
+  id: Integer;
+  ext: String;
+begin
+  id := ConManager.Connection[FConnectionID].ExtractFileIDOfName(filelist.Items.Strings[filelist.ItemIndex]);
+  ext := RightStr(filelist.Items.Strings[filelist.ItemIndex], 4);
+  exportd.Filter := 'Files of matching extension (*.' + ext + ')|*.' + ext + '|All files|*.*';
+  exportd.DefaultExt := ext;
+  if exportd.Execute then
+    ExportDatFile(FConnectionID, id, exportd.FileName);
+end;
+
+procedure TForm_TemplateFileList.popup_importClick(Sender: TObject);
+var
+  id: Integer;
+  finfo: TFileInfo;
+  fs: TFileStream;
+begin
+  if CR_EditDat in ConManager.Connection[FConnectionID].ChangeRights then
+  begin
+    id := ConManager.Connection[FConnectionID].ExtractFileIDOfName(filelist.Items.Strings[filelist.ItemIndex]);
+    finfo := ConManager.Connection[FConnectionID].GetFileInfo(id);
+
+    importd.Filter := 'Files of matching extension (*.' + finfo.Extension + ')|*.' +
+          finfo.Extension + '|All files|*.*';
+    if importd.Execute then
+    begin
+      fs := TFileStream.Create(importd.FileName, fmOpenRead);
+      if fs.Size <> finfo.Size then
+      begin
+        if not (CR_ResizeDat in ConManager.Connection[FConnectionID].ChangeRights) then
+        begin
+          ShowMessage('Can''t import ' + ExtractFilename(importd.FileName) +
+            ', file has to have same size as file in .dat with this backend.' + CrLf +
+            'Size of file in .dat: ' + FormatFileSize(finfo.Size) + CrLf +
+            'Size of chosen file: ' + FormatFileSize(fs.Size));
+          Exit;
+        end else begin
+          if MessageBox(Self.Handle,
+              PChar('File has different size from the file in the .dat.' + CrLf +
+                    'Size of file in .dat: ' + FormatFileSize(finfo.Size) + CrLf +
+                    'Size of chosen file: ' + FormatFileSize(fs.Size) + CrLf +
+                    'Replace anyway?'), PChar('Different size'), MB_YESNO + MB_ICONWARNING) = ID_NO then
+          begin
+            Exit;
+          end;
+        end;
+      end;
+      ConManager.Connection[FConnectionID].UpdateDatFile(id, fs);
+      Self.listClick(Self);
+      fs.Free;
+    end;
+  end else begin
+    ShowMessage('Editing .dat-contents not allowed with this backend.');
+  end;
+end;
+
+
+procedure TForm_TemplateFileList.popup_linkshereClick(Sender: TObject);
+begin
+  Form_WhatLinksHere.ConID := FConnectionID;
+  Form_WhatLinksHere.FileID := FSelectedFile.ID;
+  Form_WhatLinksHere.SenderForm := Self;
+  Form_WhatLinksHere.Show;
+end;
+
+procedure TForm_TemplateFileList.popup_opentool(Sender: TObject);
+var
+  sender_name, context: String;
+  id: Integer;
+begin
+  sender_name := TComponent(Sender).Name;
+  id := ConManager.Connection[FConnectionID].ExtractFileIDOfName(filelist.Items.Strings[filelist.ItemIndex]);
+  context := MidStr(sender_name, Pos('_', sender_name) + 1, Length(sender_name) - Pos('_', sender_name));
+  Form_Main.open_child(context, FConnectionID, id);
+end;
+
+procedure TForm_TemplateFileList.filepopupPopup(Sender: TObject);
+var
+  ext: String;
+  i: Integer;
+begin
+  ext := RightStr(filelist.Items.Strings[filelist.ItemIndex], 4);
+  for i := 0 to High(ToolList) do
+  begin
+    filepopup.Items.Items[i].Enabled := True;
+    if Length(ToolList[i].exts) > 0 then
+      if Pos(ext, ToolList[i].exts) = 0 then
+        filepopup.Items.Items[i].Enabled := False;
+  end;
+end;
+
+
+procedure TForm_TemplateFileList.check_zerobyteClick(Sender: TObject);
+begin
+  LoadFileNames;
+end;
+
+procedure TForm_TemplateFileList.btn_sortClick(Sender: TObject);
+begin
+  if btn_sort_id_asc.Down then
+    FSortBy := ST_IDAsc
+  else if btn_sort_id_desc.Down then
+    FSortBy := ST_IDDesc
+  else if btn_sort_name_asc.Down then
+    FSortBy := ST_NameAsc
+  else if btn_sort_name_desc.Down then
+    FSortBy := ST_NameDesc
+  else if btn_sort_ext_asc.Down then
+    FSortBy := ST_ExtAsc
+  else if btn_sort_ext_desc.Down then
+    FSortBy := ST_ExtDesc;
+  LoadFileNames;
+end;
+
+procedure TForm_TemplateFileList.check_filternameClick(Sender: TObject);
+begin
+  edit_filtername.Enabled := not check_filtername.Checked;
+  LoadFileNames;
+end;
+
+procedure TForm_TemplateFileList.combo_extensionClick(Sender: TObject);
+begin
+  LoadFileNames;
+end;
+
+procedure TForm_TemplateFileList.listClick(Sender: TObject);
+var
+  fileid: Integer;
+begin
+  if filelist.ItemIndex > -1 then
+  begin
+    fileid := ConManager.Connection[FConnectionID].ExtractFileIDOfName(
+          filelist.Items.Strings[filelist.ItemIndex]);
+    FSelectedFile := ConManager.Connection[FConnectionID].GetFileInfo(fileid);
+    if Assigned(FOnNewFileSelected) then
+      FOnNewFileSelected(FSelectedFile);
+  end;
+end;
+
+procedure TForm_TemplateFileList.listMouseDown(Sender: TObject; Button: TMouseButton;
+  Shift: TShiftState; X, Y: Integer);
+var
+  pt: TPoint;
+begin
+  pt.X := x;
+  pt.Y := y;
+  if Shift = [ssRight] then
+  begin
+    filelist.ItemIndex := filelist.ItemAtPos(pt, true);
+    Self.listClick(Self);
+  end;
+end;
+
+
+
+procedure TForm_TemplateFileList.SetAllowedExts(exts: String);
+begin
+  FAllowedExts := exts;
+  RecreateExtList;
+end;
+
+procedure TForm_TemplateFileList.SetFileFilters(pattern, extension: String;
+  zerobytes: Boolean);
+var
+  i: Integer;
+begin
+  if Length(pattern) > 0 then
+    Self.edit_filtername.Text := pattern;
+  Self.check_filtername.Checked := Length(pattern) > 0;
+  if Length(extension) > 0 then
+  begin
+    for i := 0 to Self.combo_extension.Items.Count - 1 do
+      if Pos(extension, Self.combo_extension.Items.Strings[i]) > 0 then
+        Break;
+    if i < Self.combo_extension.Items.Count then
+      Self.combo_extension.ItemIndex := i
+    else
+      Self.combo_extension.ItemIndex := -1;
+  end;
+  Self.check_zerobyte.Checked := zerobytes;
+  Self.LoadFileNames;
+end;
+
+procedure TForm_TemplateFileList.SetMultiSelect(allow: Boolean);
+begin
+  FAllowMultiSelect := allow;
+  filelist.MultiSelect := allow;
+end;
+
+
+
+constructor TForm_TemplateFileList.Create(AOwner: TComponent);
+var
+  i: Integer;
+  item: TMenuItem;
+begin
+  inherited;
+  FAllowedExts := '';
+  FAllowMultiSelect := False;
+  if Length(ToolList) > 0 then
+  begin
+    for i := 0 to High(ToolList) do
+    begin
+      item := TMenuItem.Create(filepopup);
+      item.Name := 'popup_' + ToolList[i].context;
+      item.Caption := 'Open with ' + ToolList[i].name;
+      item.OnClick := Self.popup_opentool;
+      filepopup.Items.Insert(i, item);
+    end;
+  end;
+end;
+
+
+end.
