Index: oup/current/Code/OniDataClass.pas
===================================================================
--- oup/current/Code/OniDataClass.pas	(revision 46)
+++ oup/current/Code/OniDataClass.pas	(revision 51)
@@ -2,5 +2,5 @@
 interface
 uses Data, DataStructures, Classes, SysUtils, StrUtils,
-  Dialogs, ABSDecUtil, ABSMain, DB;
+  Dialogs, ABSDecUtil, ABSMain, DB, Windows;
 
 type
@@ -103,4 +103,6 @@
     FDatabase: TABSDatabase;
     FQuery:    TABSQuery;
+    Fdat_files:    TFiles;
+    Fdat_extensionsmap: TExtensionsMap;
   protected
   public
@@ -108,4 +110,5 @@
     procedure Close; override;
 
+    procedure UpdateListCache;
     //      function GetDatLinks(srcid:LongWord):TDatLinks;
     function GetFileInfo(fileid: LongWord): TFileInfo; override;
@@ -849,4 +852,6 @@
   FQuery.Close;
 
+  UpdateListCache;
+
   Result   := True;
   FBackend := ODB_ADB;
@@ -865,99 +870,28 @@
 
 
-
-function TOniDataADB.GetFileInfo(fileid: LongWord): TFileInfo;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    FQuery.SQL.Text := 'SELECT * FROM datfiles WHERE id=' + IntToStr(
-      fileid) + ' ORDER BY id ASC;';
-    FQuery.Open;
-    if FQuery.RecordCount = 1 then
-    begin
-      FQuery.First;
-      Result.ID      := FQuery.FieldByName('id').AsInteger;
-      Result.Name    := FQuery.FieldByName('name').AsString;
-      Result.Extension := FQuery.FieldByName('extension').AsString;
-      Result.FileName := FormatNumber(Result.ID, 5, '0') + '-' + Result.Name + '.' +
-        Result.Extension;
-      Result.Size    := FQuery.FieldByName('size').AsInteger;
-      Result.FileType := HexToLong(FQuery.FieldByName('contenttype').AsString);
-      Result.DatAddr := 0;
-      Result.opened  := False;
-    end;
-    FQuery.Close;
-  end
-  else
-  begin
-    Result.ID := -1;
-  end;
-end;
-
-
-
-
-function TOniDataADB.GetFilesList(ext: String; pattern: String;
-  NoEmptyFiles: Boolean; sort: TSortType): TStringArray;
+procedure TOniDataADB.UpdateListCache;
 var
   i:     LongWord;
-  where: String;
-  where_ext: String;
-  order: String;
-begin
-  where := '';
-  if Length(ext) > 0 then
-  begin
-    if Length(where) > 0 then
-      where := where + ' AND ';
-    if Pos(',', ext) > 0 then
-    begin
-      i := 1;
-      where_ext := '';
-      while i < Length(ext) do
-      begin
-        if Length(where_ext) > 0 then
-          where_ext := where_ext + ' OR ';
-        where_ext := where_ext + '(extension="' + MidStr(ext, i, 4) + '")';
-        i := i + 5;
-      end;
-      where := where + '(' + where_ext + ')';
-    end
-    else
-    begin
-      where := where + '(extension="' + ext + '")';
-    end;
-  end;
-  if Length(pattern) > 0 then
-  begin
-    if Length(where) > 0 then
-      where := where + ' AND ';
-    where := where + '(name LIKE "%' + pattern + '%")';
-  end;
-  if NoEmptyFiles then
-  begin
-    if Length(where) > 0 then
-      where := where + ' AND ';
-    where := where + '(contenttype<>2)';
-  end;
-  if Length(where) > 0 then
-    where := ' WHERE ' + where;
-  case sort of
-    stIDAsc:    order := ' ORDER BY id ASC';
-    stIDDesc:   order := ' ORDER BY id DESC';
-    stNameAsc:  order := ' ORDER BY name ASC, id ASC';
-    stNameDesc: order := ' ORDER BY name DESC, id ASC';
-    stExtAsc:   order := ' ORDER BY extension ASC, id ASC';
-    stExtDesc:  order := ' ORDER BY extension DESC, id ASC';
-  end;
-  FQuery.SQL.Text := 'SELECT id,name,extension FROM datfiles' + where + order + ';';
+  temps: String;
+begin
+  FQuery.SQL.Text := 'SELECT id,name,extension,[size],contenttype FROM datfiles ORDER BY id ASC;';
   FQuery.Open;
   if FQuery.RecordCount > 0 then
   begin
     FQuery.First;
-    SetLength(Result, FQuery.RecordCount);
+    SetLength(Fdat_files, FQuery.RecordCount);
     i := 0;
     repeat
-      Result[i] := FormatNumber(FQuery.FieldByName('id').AsInteger, 5, '0') + '-' +
-        FQuery.FieldByName('name').AsString + '.' + FQuery.FieldByName('extension').AsString;
+      Fdat_files[i].ID := FQuery.FieldByName('id').AsInteger;
+      Fdat_files[i].Name := FQuery.FieldByName('name').AsString;
+      Fdat_files[i].Extension := FQuery.FieldByName('extension').AsString;
+      Fdat_files[i].FileName := FormatNumber(Fdat_files[i].ID, 5, '0') + '-' +
+          Fdat_files[i].Name + '.' + Fdat_files[0].Extension;
+      Fdat_files[i].FileNameHex := IntToHex(Fdat_files[i].ID, 4) + '-' +
+          Fdat_files[i].Name + '.' + Fdat_files[0].Extension;
+      Fdat_files[i].Size := FQuery.FieldByName('size').AsInteger;
+      Fdat_files[i].FileType := HexToLong(FQuery.FieldByName('contenttype').AsString);
+      Fdat_files[i].DatAddr := 0;
+      Fdat_files[i].opened := False;
       Inc(i);
       FQuery.Next;
@@ -965,31 +899,6 @@
   end;
   FQuery.Close;
-end;
-
-
-
-
-function TOniDataADB.GetFilesCount: LongWord;
-begin
-  FQuery.SQL.Text := 'SELECT Count(*) AS cnumber FROM datfiles;';
-  FQuery.Open;
-  if FQuery.RecordCount > 0 then
-  begin
-    FQuery.First;
-    Result := FQuery.FieldByName('cnumber').AsInteger;
-  end
-  else
-    Result := 0;
-  FQuery.Close;
-end;
-
-
-
-
-function TOniDataADB.GetExtensionsList: TStringArray;
-var
-  i: LongWord;
-begin
-  SetLength(Result, 0);
+
+  SetLength(Fdat_extensionsmap, 0);
   FQuery.SQL.Text :=
     'SELECT extension,count(extension) AS x FROM datfiles GROUP BY extension ORDER BY extension ASC;';
@@ -997,9 +906,13 @@
   if FQuery.RecordCount > 0 then
   begin
-    SetLength(Result, FQuery.RecordCount);
+    SetLength(Fdat_extensionsmap, FQuery.RecordCount);
     i := 0;
     repeat
-      Result[i] := FQuery.FieldByName('extension').AsString + ' (' +
-        IntToStr(FQuery.FieldByName('x').AsInteger) + ')';
+      temps := FQuery.FieldByName('extension').AsString[1];
+      Fdat_extensionsmap[i].Extension[3] := temps[1];
+      Fdat_extensionsmap[i].Extension[2] := temps[2];
+      Fdat_extensionsmap[i].Extension[1] := temps[3];
+      Fdat_extensionsmap[i].Extension[0] := temps[4];
+      Fdat_extensionsmap[i].ExtCount := FQuery.FieldByName('x').AsInteger;
       Inc(i);
       FQuery.Next;
@@ -1007,4 +920,129 @@
   end;
   FQuery.Close;
+end;
+
+
+function TOniDataADB.GetFileInfo(fileid: LongWord): TFileInfo;
+var
+  i: Integer;
+begin
+  if fileid < Self.GetFilesCount then
+  begin
+    for i := 0 to High(Fdat_files) do
+      if Fdat_files[i].ID = fileid then
+        Break;
+    if i < Length(Fdat_files) then
+      Result := Fdat_files[i]
+    else
+      Result.ID := -1;
+  end
+  else
+  begin
+    Result.ID := -1;
+  end;
+end;
+
+
+
+
+function TOniDataADB.GetFilesList(ext: String; pattern: String;
+  NoEmptyFiles: Boolean; sort: TSortType): TStringArray;
+var
+  i: LongWord;
+  list: TStringList;
+  id, name, extension: String;
+  fields: TStrings;
+
+  procedure getfields;
+  begin
+     fields.CommaText := StringReplace(AnsiQuotedStr(list.Strings[i], '"'), ';', '","', [rfReplaceAll]);
+    if sort in [stIDAsc, stIDDesc] then
+    begin
+      id := fields.Strings[0];
+      name := fields.Strings[1];
+      extension := fields.Strings[2];
+    end;
+    if sort in [stNameAsc, stNameDesc] then
+    begin
+      id := fields.Strings[1];
+      name := fields.Strings[0];
+      extension := fields.Strings[2];
+    end;
+    if sort in [stExtAsc, stExtDesc] then
+    begin
+      id := fields.Strings[1];
+      name := fields.Strings[2];
+      extension := fields.Strings[0];
+    end;
+  end;
+
+begin
+  list := TStringList.Create;
+  list.Sorted := True;
+  for i := 0 to High(Fdat_files) do
+  begin
+    if ((Length(ext) = 0) or (Pos(Fdat_files[i].Extension, ext) > 0)) and
+      ((Length(pattern) = 0) or
+      (Pos(UpperCase(pattern), UpperCase(Fdat_files[i].Name)) > 0)) then
+    begin
+      if (NoEmptyFiles = False) or ((Fdat_files[i].FileType and $02) = 0) then
+      begin
+        if AppSettings.FilenumbersAsHex then
+          id := IntToHex(Fdat_files[i].ID, 4)
+        else
+          id := FormatNumber(Fdat_files[i].ID, 5, '0');
+        name := Fdat_files[i].Name;
+        extension := Fdat_files[i].Extension;
+
+        case sort of
+          stIDAsc, stIDDesc:     list.Add(id + ';' + name + ';' + extension);
+          stNameAsc, stNameDesc: list.Add(name + ';' + id + ';' + extension);
+          stExtAsc, stExtDesc:   list.Add(extension + ';' + id + ';' + name);
+        end;
+      end;
+    end;
+  end;
+  SetLength(Result, list.Count);
+  fields := TStringList.Create;
+  if sort in [stIDAsc, stNameAsc, stExtAsc] then
+    for i := 0 to list.Count - 1 do
+    begin
+      getfields;
+      Result[i] := id + '-' + name + '.' + extension;
+    end
+  else
+    for i := list.Count - 1 downto 0 do
+    begin
+      getfields;
+      Result[list.Count - i - 1] := id + '-' + name + '.' + extension;
+    end;
+  list.Free;
+  fields.Free;
+end;
+
+
+
+
+function TOniDataADB.GetFilesCount: LongWord;
+begin
+  Result := Length(Fdat_files);
+end;
+
+
+
+
+function TOniDataADB.GetExtensionsList: TStringArray;
+var
+  i: LongWord;
+begin
+  SetLength(Result, Length(Fdat_extensionsmap));
+  for i := 0 to High(Result) do
+  begin
+    with Fdat_extensionsmap[i] do
+    begin
+      Result[i] := Extension[3] + Extension[2] + Extension[1] + Extension[0] +
+        ' (' + IntToStr(ExtCount) + ')';
+    end;
+  end;
 end;
 
@@ -1139,9 +1177,11 @@
     mem.Seek(0, soFromBeginning);
     FQuery.SQL.Text := 'UPDATE datfiles SET data=MimeToBin("' +
-      MimeCoder.StrTo(mem.Memory, mem.Size) + '") WHERE id=' + IntToStr(fileid) + ';';
+      MimeCoder.StrTo(mem.Memory, mem.Size) + '"), size=' + IntToStr(mem.Size) +
+      ' WHERE id=' + IntToStr(fileid) + ';';
     FQuery.ExecSQL;
     mem.Free;
     mimecoder.Free;
   end;
+  UpdateListCache;
 end;
 
