home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 April A / Pcwk4a98.iso / PROGRAM / DELPHI16 / Calmira / Src / SRC / FOURDOS.PAS < prev    next >
Pascal/Delphi Source File  |  1997-01-11  |  5KB  |  189 lines

  1. unit FourDOS;
  2.  
  3. { 4DOS file descriptions
  4.  
  5.   The main problem with supporting descriptions is maintaining consistency.
  6.   An obvious solution would be to associate a PString with each TDirItem
  7.   object.  But considering the turmoil during copying and moving, keeping
  8.   track of everything would be very difficult during updating. Also, not
  9.   all files are shown at once (depending on the filter), so the need to
  10.   reconcile the disk file with the memory descriptions would complicate
  11.   matters.
  12.  
  13.   Hence the current implementation uses a centralized approach.  The
  14.   entire set of descriptions is kept inside a TStringList, one for each
  15.   TDirectory.  When we need to find a description, the list must be
  16.   searched, but updating is OK since there are no pointers floating around
  17.   as with the PString approach, and consistency is guaranteed because each
  18.   TStringList exactly mirrors a descript.ion file.
  19.  
  20.   The Directry unit contains optimizations to avoid accessing the list
  21.   when it is already known that an object doesn't have a description.  A
  22.   further speedup is obtained by storing a pointer to the TDirItem
  23.   object so that a full string search occurs rarely.
  24.  
  25.   This unit assumes that a "description" is the entire string following the
  26.   first space character.  Actually, there may be 04 markers (Ctrl-D) in the
  27.   text which indicates extra data maintained by programs other than 4DOS.
  28.   These are filtered and maintained by each TDirItem because it would be
  29.   too complicated to regard the data as another "column" when replacing the
  30.   strings in the list.
  31.  
  32.   4DOS is a registered trademark of JP Software Inc.
  33. }
  34.  
  35. interface
  36.  
  37. uses Classes, SysUtils;
  38.  
  39. const
  40.   DescriptionFile : TFilename = 'descript.ion';
  41.  
  42. type
  43.   TDescriptions = class(TStringList)
  44.   private
  45.     FModified : Boolean;
  46.   protected
  47.     procedure Changed; override;
  48.   public
  49.     function Get(const filename: string; Item: TObject): string;
  50.     procedure Put(const filename: string; Item: TObject;
  51.       const value: string);
  52.     procedure LoadFromPath(const path: TFilename);
  53.     procedure SaveToPath(const path : TFilename);
  54.     property Modified : Boolean read FModified;
  55.   end;
  56.  
  57.  
  58. var
  59.   SharedDesc : TDescriptions;
  60.  
  61.   { SharedDesc is a special shared description file used during copying }
  62.  
  63. implementation
  64.  
  65. uses Directry, Strings;
  66.  
  67.  
  68. procedure TDescriptions.Changed;
  69. begin
  70.   inherited Changed;
  71.   FModified := True;
  72. end;
  73.  
  74.  
  75. function TDescriptions.Get(const filename: string;
  76.   Item: TObject): string;
  77. var
  78.   i, p, compare: Integer;
  79.   s: string;
  80. begin
  81.   { Retrieves a file description.  If the Item parameter is nil,
  82.     the object pointers are ignored. }
  83.  
  84.   Result := '';
  85.   if Count = 0 then Exit;
  86.  
  87.   if Item = nil then i := -1
  88.   else i:= IndexOfObject(Item);
  89.  
  90.   if i > -1 then begin
  91.     { found an object match }
  92.     s := Strings[i];
  93.     p := Pos(' ', s);
  94.     Result := Copy(s, p+1, 255);
  95.   end
  96.   else begin
  97.     { must do a string search }
  98.     for i := 0 to Count-1 do begin
  99.       s := Strings[i];
  100.       p := Pos(' ', s);
  101.       if CompareText(Copy(s, 1, p-1), filename)= 0 then begin
  102.         Objects[i] := Item;
  103.         Result := Copy(s, p+1, 255);
  104.         Exit;
  105.       end
  106.     end;
  107.   end;
  108. end;
  109.  
  110.  
  111. procedure TDescriptions.Put(const filename: string; Item: TObject;
  112.   const value: string);
  113. var
  114.   i, p: Integer;
  115.   s: string;
  116. begin
  117.   if Item = nil then i := -1
  118.   else i := IndexOfObject(Item);
  119.  
  120.   if i > -1 then
  121.     { found an object match }
  122.     if value = '' then Delete(i)
  123.     else Strings[i] := Format('%s %s', [filename, value])
  124.  
  125.   else begin
  126.     { must do a string search }
  127.     for i := 0 to Count-1 do begin
  128.       s := Strings[i];
  129.       p := Pos(' ', s);
  130.       if CompareText(Copy(s, 1, p-1), filename) = 0 then begin
  131.         if value = '' then Delete(i)
  132.         else begin
  133.           Objects[i] := Item;
  134.           Strings[i] := Format('%s %s', [filename, value]);
  135.         end;
  136.         Exit;
  137.       end;
  138.     end;
  139.  
  140.     if value > '' then
  141.       AddObject(filename + ' ' + value, Item);
  142.   end;
  143. end;
  144.  
  145.  
  146. procedure TDescriptions.LoadFromPath(const path: TFilename);
  147. var
  148.   rec : TSearchRec;
  149.   code : Integer;
  150. begin
  151.   Clear;
  152.   FModified := False;
  153.  
  154.   code := FindFirst(path + DescriptionFile, faHidden, rec);
  155.   if code = -3 then
  156.     raise EScanError.CreateFmt('Cannot open %s', [MakeDirname(path)])
  157.   else if code = 0 then
  158.     inherited LoadFromFile(path + DescriptionFile);
  159. end;
  160.  
  161.  
  162. procedure TDescriptions.SaveToPath(const path : TFilename);
  163. var
  164.   filename : TFilename;
  165. begin
  166.   if FModified then begin
  167.     filename := path + DescriptionFile;
  168.     if Count= 0 then DeleteFile(filename)
  169.     else begin
  170.       FileSetAttr(filename, faArchive);
  171.       inherited SaveToFile(filename);
  172.       FileSetAttr(filename, faHidden);
  173.     end;
  174.     FModified := False;
  175.   end;
  176. end;
  177.  
  178.  
  179. procedure DoneFourDOS; far;
  180. begin
  181.   SharedDesc.Free;
  182. end;
  183.  
  184.  
  185. initialization
  186.   AddExitProc(DoneFourDOS);
  187.   SharedDesc := TDescriptions.Create;
  188. end.
  189.