home *** CD-ROM | disk | FTP | other *** search
/ Chip 1999 January / Chip_1999-01_cd.bin / zkuste / delphi / QDB / QDBP.ZIP / qdbpanel.pas next >
Encoding:
Pascal/Delphi Source File  |  1998-07-29  |  18.0 KB  |  789 lines

  1. (*
  2.  
  3. QDBPanel v2.00 Beta Release 3
  4. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  5.  
  6. This is the third beta release of QDBPanel for QDB v2.00. QDB itself is 
  7. now ready for release but QDBPanel remains in beta for a while longer as
  8. certain design issues still need to be addressed.
  9.  
  10. There is no help file for this release -- this file will have to serve 
  11. for the moment. Although I have decided to release the source code for
  12. this beta version please bear in mind that it will change greatly from
  13. version to version. I will, however, try to keep the interface 
  14. functionally the same and the file structure unchanged.
  15.  
  16. Please be aware that you are quite likely to find bugs or other problems. 
  17. Please let me know about them at rrm@sprynet.com. Thanks for your help. 
  18. If you have any ideas for QDBPanel send them along too. A related 
  19. component, QDBGrid, is still in the alpha stage.
  20.  
  21. QDBPanel, which remains free, is Copyright (c) 1997 Robert R. Marsh, SJ & 
  22. the British Province of the Society of Jesus.
  23.  
  24. *)
  25.  
  26. {$F+}
  27.  
  28. unit QDBPanel;
  29.  
  30. interface
  31.  
  32. uses
  33. {$IFDEF WIN32}Windows, {$ELSE}WinTypes, WinProcs, {$ENDIF}
  34.   Messages, SysUtils, Classes, Graphics, Controls, Forms,
  35.   Dialogs, ExtCtrls, StdCtrls, QDB;
  36.  
  37. type
  38.   TClassProc = procedure(AControl: TControl; Stream: TStream);
  39.   TKeyEvent = procedure(Sender: TObject; var key: TKey) of object;
  40.  
  41. type
  42.   TProcKind = (pkClear, pkFetch, pkStore);
  43.  
  44. type
  45.   TProcList = class(TList)
  46.   public
  47.     constructor Create;
  48.     destructor Destroy; override;
  49.     procedure AddProcs(AClass: TControlClass; ClearProc, FetchProc, StoreProc: TClassProc);
  50.     function GetProc(Instance: TControl; ProcKind: TProcKind): TClassProc;
  51.   end;
  52.  
  53. type
  54.   TFieldList = class(TStringList)
  55.   public
  56.     constructor Create;
  57.     destructor Destroy; override;
  58.     procedure AddField(ThisControl: TControl; ClearProc, FetchProc, StoreProc: TClassProc);
  59.   end;
  60.  
  61. type
  62.   TQDBPanel = class(TPanel)
  63.   private
  64.     Fields: TFieldList;
  65.     Procs: TProcList;
  66.     CurrentItem: TMemoryStream;
  67.     FEnabled: boolean;
  68.     FExcludeTag: longint;
  69.     FQDB: TQDB;
  70.     FOnKey: TKeyEvent;
  71.   protected
  72.     procedure Loaded; override;
  73.     procedure BuildFieldList;
  74.     procedure SetEnabled(value: boolean);
  75.     function GetCount: integer;
  76. {    function GetField(index: integer): TStream;}
  77.     function GetName(index: integer): string;
  78.   public
  79.     constructor Create(AOwner: TComponent); override;
  80.     destructor Destroy; override;
  81.     procedure RegisterProcs(AClass: TControlClass; ClearProc, FetchProc, StoreProc: TClassProc);
  82.     procedure RegisterGraphicFormat(const AExtension: string; AGraphicClass: TGraphicClass);
  83.     procedure Clear;
  84.     procedure Fetch;
  85.     procedure Store;
  86.     procedure Cancel;
  87.     procedure Delete;
  88.     procedure Edit;
  89.     procedure FirstItem;
  90.     procedure Insert;
  91.     procedure LastItem;
  92.     procedure NextItem;
  93.     procedure Post;
  94.     procedure PrevItem;
  95.     procedure Refresh;
  96.     property FieldCount: integer read GetCount;
  97.     property FieldNames[index: integer]: string read GetName; default;
  98.   published
  99.     property Enabled: boolean read FEnabled write SetEnabled;
  100.     property ExcludeTag: longint read FExcludeTag write FExcludeTag;
  101.     property QDB: TQDB read FQDB write FQDB;
  102.     property OnKey: TKeyEvent read FOnKey write FOnKey;
  103.   end;
  104.  
  105. implementation
  106.  
  107. uses
  108.   Clipbrd
  109. {$IFDEF WIN32}
  110.   , ComCtrls
  111. {$ENDIF};
  112.  
  113. { Default control handlers registered in TQDBPanel.Create }
  114.  
  115. procedure ClearCustomEdit(AControl: TControl; Stream: TStream);
  116. begin
  117.   (AControl as TCustomEdit).Text := '';
  118. end;
  119.  
  120. procedure FetchCustomEdit(AControl: TControl; Stream: TStream);
  121. var
  122.   con: TCustomEdit;
  123.   p: pchar;
  124. begin
  125.   con := (AControl as TCustomEdit);
  126.   p := StrAlloc(Stream.Size);
  127.   try
  128.     Stream.ReadBuffer(p^, Stream.Size);
  129.     con.SetTextBuf(p);
  130.   finally
  131.     StrDispose(p);
  132.   end;
  133. end;
  134.  
  135. procedure StoreCustomEdit(AControl: TControl; Stream: TStream);
  136. var
  137.   con: TCustomEdit;
  138.   len: longint;
  139.   p: pchar;
  140. begin
  141.   con := (AControl as TCustomEdit);
  142.   len := con.GetTextLen + 1;
  143.   p := StrAlloc(len);
  144.   try
  145.     con.GetTextBuf(p, len);
  146.     Stream.Write(p^, len);
  147.   finally
  148.     StrDispose(p);
  149.   end;
  150. end;
  151.  
  152. {$IFDEF WIN32}
  153.  
  154. procedure ClearRichEdit(AControl: TControl; Stream: TStream);
  155. begin
  156.   (AControl as TRichEdit).Text := '';
  157. end;
  158.  
  159. procedure FetchRichEdit(AControl: TControl; Stream: TStream);
  160. begin
  161.   (AControl as TRichEdit).Lines.LoadFromStream(Stream);
  162. end;
  163.  
  164. procedure StoreRichEdit(AControl: TControl; Stream: TStream);
  165. begin
  166.   (AControl as TRichEdit).Lines.SaveToStream(Stream);
  167. end;
  168. {$ENDIF}
  169.  
  170. procedure ClearCustomRadioGroup(AControl: TControl; Stream: TStream);
  171. begin
  172.   TRadioGroup(AControl).ItemIndex := -1;
  173. end;
  174.  
  175. procedure FetchCustomRadioGroup(AControl: TControl; Stream: TStream);
  176. var
  177.   n: longint;
  178. begin
  179.   Stream.ReadBuffer(n, SizeOf(n));
  180.   TRadioGroup(AControl).ItemIndex := n;
  181. end;
  182.  
  183. procedure StoreCustomRadioGroup(AControl: TControl; Stream: TStream);
  184. var
  185.   n: longint;
  186. begin
  187.   n := TRadioGroup(AControl).ItemIndex;
  188.   Stream.WriteBuffer(n, SizeOf(n));
  189. end;
  190.  
  191. procedure ClearCustomCheckBox(AControl: TControl; Stream: TStream);
  192. begin
  193.   TCheckBox(AControl).Checked := false;
  194. end;
  195.  
  196. procedure FetchCustomCheckBox(AControl: TControl; Stream: TStream);
  197. var
  198.   n: longint;
  199. begin
  200.   Stream.ReadBuffer(n, SizeOf(n));
  201.   TCheckBox(AControl).State := TCheckBoxState(n);
  202. end;
  203.  
  204. procedure StoreCustomCheckBox(AControl: TControl; Stream: TStream);
  205. var
  206.   n: longint;
  207. begin
  208.   n := longint(TCheckBox(AControl).State);
  209.   Stream.WriteBuffer(n, SizeOf(n));
  210. end;
  211.  
  212. procedure ClearCustomComboBox(AControl: TControl; Stream: TStream);
  213. begin
  214.   (AControl as TCustomComboBox).SetTextBuf(nil);
  215. end;
  216.  
  217. procedure FetchCustomComboBox(AControl: TControl; Stream: TStream);
  218. var
  219.   p: pchar;
  220. begin
  221.   p := StrAlloc(Stream.Size);
  222.   try
  223.     Stream.ReadBuffer(p^, Stream.Size);
  224.     (Acontrol as TCustomComboBox).SetTextBuf(p);
  225.     ;
  226.   finally
  227.     StrDispose(p);
  228.   end;
  229. end;
  230.  
  231. procedure StoreCustomComboBox(AControl: TControl; Stream: TStream);
  232. var
  233.   con: TCustomComboBox;
  234.   len: longint;
  235.   p: pchar;
  236. begin
  237.   con := (AControl as TCustomComboBox);
  238.   len := con.GetTextLen + 1;
  239.   p := StrAlloc(len);
  240.   try
  241.     con.GetTextBuf(p, len);
  242.     Stream.Write(p^, len);
  243.   finally
  244.     StrDispose(p);
  245.   end;
  246. end;
  247.  
  248. procedure ClearCustomListBox(AControl: TControl; Stream: TStream);
  249. var
  250.   con: TCustomListBox;
  251.   n: longint;
  252. begin
  253.   con := (AControl as TCustomListBox);
  254.   for n := 1 to con.Items.Count do
  255.   begin
  256.     con.Selected[n - 1] := false;
  257.   end;
  258.   con.ItemIndex := -1;
  259. end;
  260.  
  261. procedure FetchCustomListBox(AControl: TControl; Stream: TStream);
  262. var
  263.   con: TCustomListBox;
  264.   n: longint;
  265. begin
  266.   con := (AControl as TCustomListBox);
  267.   for n := 1 to con.Items.Count do
  268.   begin
  269.     con.Selected[n - 1] := false;
  270.   end;
  271.   while true do
  272.   begin
  273.     Stream.ReadBuffer(n, SizeOf(longint));
  274.     if (n < 0) or (n > con.Items.Count) then
  275.       Break;
  276.     con.Selected[n] := true;
  277.   end;
  278. end;
  279.  
  280. procedure StoreCustomListBox(AControl: TControl; Stream: TStream);
  281. var
  282.   con: TCustomListBox;
  283.   n: longint;
  284.   i: longint;
  285. begin
  286.   con := (AControl as TCustomListBox);
  287.   for n := 1 to con.Items.Count do
  288.     if con.Selected[n - 1] then
  289.     begin
  290.       i := n - 1;
  291.       Stream.Write(i, SizeOf(longint));
  292.     end;
  293.   i := -1;
  294.   Stream.Write(i, SizeOf(longint));
  295. end;
  296.  
  297. type
  298.   PFileFormat = ^TFileFormat;
  299.   TFileFormat = record
  300.     GraphicClass: TGraphicClass;
  301.     Extension: string;
  302.     Next: PFileFormat;
  303.   end;
  304.  
  305. const
  306.   WMFMetafileFormat: TFileFormat = (
  307.     GraphicClass: TMetafile;
  308.     Extension: 'wmf';
  309.     Next: nil);
  310.   MetaFileFormat: TFileFormat = (
  311.     GraphicClass: TMetafile;
  312.     Extension: 'emf';
  313.     Next: @WMFMetaFileFormat);
  314.   IconFormat: TFileFormat = (
  315.     GraphicClass: TIcon;
  316.     Extension: 'ico';
  317.     Next: @MetafileFormat);
  318.   BitmapFormat: TFileFormat = (
  319.     GraphicClass: TBitmap;
  320.     Extension: 'bmp';
  321.     Next: @IconFormat);
  322.  
  323. const
  324.   FileFormatList: PFileFormat = @BitmapFormat;
  325.  
  326. procedure ClearImage(AControl: TControl; Stream: TStream);
  327. begin
  328.   (AControl as TImage).Picture.Assign(nil);
  329. end;
  330.  
  331. procedure FetchImage(AControl: TControl; Stream: TStream);
  332. var
  333.   con: TImage;
  334.   ext: array[0..3] of char;
  335.   Graphic: PFileFormat;
  336.   NewGraphic: TGraphic;
  337. begin
  338.   con := (AControl as TImage);
  339.   ext[3] := #0;
  340.   Stream.ReadBuffer(ext[0], 3);
  341.   Graphic := FileFormatList;
  342.   while Graphic <> nil do
  343.     with Graphic^ do
  344.     begin
  345.       if Extension <> StrPas(Ext) then
  346.         Graphic := Next
  347.       else
  348.       begin
  349.         NewGraphic := GraphicClass.Create;
  350.         try
  351.           try
  352.             NewGraphic.LoadFromStream(Stream);
  353.           except
  354.             NewGraphic.Free;
  355.             raise;
  356.           end;
  357.           con.Picture.Assign(NewGraphic);
  358.           Exit;
  359.         finally
  360.           NewGraphic.Free;
  361.         end;
  362.       end;
  363.     end;
  364.   raise Exception.Create('invalid graphic format');
  365. end;
  366.  
  367. procedure StoreImage(AControl: TControl; Stream: TStream);
  368. var
  369.   con: TImage;
  370.   ext: array[0..3] of char;
  371. begin
  372.   con := (AControl as TImage);
  373.   StrPCopy(ext, LowerCase(GraphicExtension(TGraphicClass(con.Picture.Graphic.ClassType))));
  374.   if StrPas(ext) <> '' then
  375.   begin
  376.     Stream.WriteBuffer(ext[0], 3);
  377.     con.Picture.Graphic.SaveToStream(Stream);
  378.   end
  379.   else
  380.     raise Exception.Create('unknown graphic class');
  381. end;
  382.  
  383. { TProcList }
  384.  
  385. type
  386.   TInfo = record
  387.     AClass: TControlClass;
  388.     ClearProc: TClassProc;
  389.     FetchProc: TClassProc;
  390.     StoreProc: TClassProc;
  391.   end;
  392.  
  393. constructor TProcList.Create;
  394. begin
  395.   inherited Create;
  396. end;
  397.  
  398. destructor TProcList.Destroy;
  399. var
  400.   n: integer;
  401. begin
  402.   for n := 1 to Count do
  403.     FreeMem(Items[n - 1], SizeOf(TInfo));
  404.   inherited Destroy;
  405. end;
  406.  
  407. procedure TProcList.AddProcs(AClass: TControlClass; ClearProc, FetchProc, StoreProc: TClassProc);
  408. var
  409.   i: ^TInfo;
  410. begin
  411.   GetMem(i, SizeOf(TInfo));
  412.   i^.AClass := AClass;
  413.   @i^.ClearProc := @ClearProc;
  414.   @i^.FetchProc := @FetchProc;
  415.   @i^.StoreProc := @StoreProc;
  416.   Add(i);
  417. end;
  418.  
  419. function TProcList.GetProc(Instance: TControl; ProcKind: TProcKind): TClassProc;
  420. var
  421.   n: integer;
  422. begin
  423.   for n := Count downto 1 do
  424.   begin
  425.     with TInfo(Items[n - 1]^) do
  426.     begin
  427.       if Instance.InheritsFrom(AClass) then
  428.       begin
  429.         case ProcKind of
  430.           pkClear:
  431.             @Result := @TClassProc(ClearProc);
  432.           pkFetch:
  433.             @Result := @TClassProc(FetchProc);
  434.           pkStore:
  435.             @Result := @TClassProc(StoreProc);
  436.         else
  437.           @Result := nil
  438.         end;
  439.         Exit;
  440.       end;
  441.     end;
  442.   end;
  443.   Result := nil;
  444. end;
  445.  
  446. { TFieldList }
  447.  
  448. type
  449.   TFieldInfo = class
  450.     TheControl: TControl;
  451.     ClearProc: TClassProc;
  452.     FetchProc: TClassProc;
  453.     StoreProc: TClassProc;
  454.   end;
  455.  
  456. constructor TFieldList.Create;
  457. begin
  458.   inherited Create;
  459.   Sorted := false;
  460. end;
  461.  
  462. destructor TFieldList.Destroy;
  463. var
  464.   n: integer;
  465. begin
  466.   for n := Count downto 1 do
  467.   begin
  468.     TFieldInfo(Objects[n - 1]).Free;
  469.     Delete(n - 1);
  470.   end;
  471.   inherited Destroy;
  472. end;
  473.  
  474. procedure TFieldList.AddField(ThisControl: TControl; ClearProc, FetchProc, StoreProc: TClassProc);
  475. var
  476.   i: TFieldInfo;
  477. begin
  478.   i := TFieldInfo.Create;
  479.   i.TheControl := ThisControl;
  480.   @i.ClearProc := @ClearProc;
  481.   @i.FetchProc := @FetchProc;
  482.   @i.StoreProc := @StoreProc;
  483.   AddObject(ThisControl.Name, i);
  484. end;
  485.  
  486.  
  487. { TQDBPanel }
  488.  
  489. constructor TQDBPanel.Create(AOwner: TComponent);
  490. begin
  491.   inherited Create(AOwner);
  492.   ExcludeTag := -999;
  493.   Caption := '';
  494.   Fields := TFieldList.Create;
  495.   Procs := TProcList.Create;
  496.   CurrentItem := TMemoryStream.Create;
  497. { Register the storage mechanism for default control types }
  498. { Entries later in the list override ones earlier          }
  499.   RegisterProcs(TCustomEdit, ClearCustomEdit, FetchCustomEdit, StoreCustomEdit);
  500. {$IFDEF WIN32}
  501.   RegisterProcs(TRichEdit, ClearRichEdit, FetchRichEdit, StoreRichEdit);
  502. {$ENDIF}
  503.   RegisterProcs(TCustomRadioGroup, ClearCustomRadioGroup, FetchCustomRadioGroup, StoreCustomRadioGroup);
  504.   RegisterProcs(TCustomCheckBox, ClearCustomCheckBox, FetchCustomCheckBox, StoreCustomCheckBox);
  505.   RegisterProcs(TCustomComboBox, ClearCustomComboBox, FetchCustomComboBox, StoreCustomComboBox);
  506.   RegisterProcs(TCustomListBox, ClearCustomListBox, FetchCustomListBox, StoreCustomListBox);
  507.   RegisterProcs(TImage, ClearImage, FetchImage, StoreImage);
  508.   Enabled := false;
  509. end;
  510.  
  511. destructor TQDBPanel.Destroy;
  512. begin
  513.   CurrentItem.Free;
  514.   Fields.Free;
  515.   Procs.Free;
  516.   inherited Destroy;
  517. end;
  518.  
  519. procedure TQDBPanel.Loaded;
  520. begin
  521.   BuildFieldList;
  522. end;
  523.  
  524. procedure TQDBPanel.BuildFieldList;
  525.  
  526.   procedure ForEachControl(AWinControl: TWinControl); forward;
  527.  
  528.   procedure ProcessControl(ThisControl: TControl);
  529.   begin
  530.     { do nothing with a control if the tag is set to exclude them }
  531.     if (ThisControl.Tag = ExcludeTag) then
  532.       Exit;
  533.     { if a control owns others  ... }
  534.     if (ThisControl is TWinControl) and (TWinControl(ThisControl).ControlCount <> 0) then
  535.     begin
  536.         { if it's the original QDBPanel or not a QDBPanel at all }
  537.       if (ThisControl.Name = Name) or not (ThisControl is TQDBPanel) then
  538.         ForEachControl(TWinControl(ThisControl));
  539.     end
  540.     else
  541.     begin
  542.         { it's an ordinary control }
  543.       Fields.AddField(ThisControl, Procs.GetProc(ThisControl, pkClear),
  544.                                    Procs.GetProc(ThisControl, pkFetch),
  545.                                    Procs.GetProc(ThisControl, pkStore));
  546.     end;
  547.   end;
  548.  
  549.   procedure ForEachControl(AWinControl: TWinControl);
  550.   var
  551.     n: integer;
  552.   begin
  553. {$IFDEF WIN32}
  554.     if (AWinControl is TPageControl) then
  555.       with (AWinControl as TPageControl) do
  556.         for n := 1 to PageCount do
  557.           ProcessControl(Pages[n - 1])
  558.     else
  559. {$ENDIF}
  560.       for n := 1 to AWinControl.ControlCount do
  561.         ProcessControl(AWinControl.Controls[n - 1]);
  562.   end;
  563.  
  564. begin
  565.   ForEachControl(self);
  566. end;
  567.  
  568. function TQDBPanel.GetCount: integer;
  569. begin
  570.   Result := Fields.Count;
  571. end;
  572.  
  573. function TQDBPanel.GetName(index: integer): string;
  574. begin
  575.   if index < Fields.Count then
  576.     Result := Fields[index]
  577.   else
  578.     Result := ''
  579. end;
  580.  
  581. procedure TQDBPanel.SetEnabled(value: boolean);
  582. var
  583.   n: integer;
  584. begin
  585.   for n := 1 to Fields.Count do
  586.   begin
  587.     TFieldInfo(Fields.Objects[n - 1]).TheControl.Enabled := value;
  588.   end;
  589.   FEnabled := value;
  590. end;
  591.  
  592. procedure TQDBPanel.Clear;
  593. var
  594.   n: integer;
  595.   ThisTypeProc: TClassProc;
  596.   ThisControl: TControl;
  597. begin
  598.   for n := 1 to Fields.Count do
  599.   begin
  600.     ThisControl := TFieldInfo(Fields.Objects[n - 1]).TheControl;
  601.     ThisTypeProc := TFieldInfo(Fields.Objects[n - 1]).ClearProc;
  602.     if @ThisTypeProc <> nil then ThisTypeProc(ThisControl, nil);
  603.   end;
  604.   CurrentItem.Clear;
  605. end;
  606.  
  607. procedure TQDBPanel.Fetch;
  608. var
  609.   n: integer;
  610.   m: TMemoryStream;
  611.   ThisControl: TControl;
  612.   ThisTypeProc: TClassProc;
  613.   len: longint;
  614. begin
  615.   if FQDB.Count > 0 then
  616.   begin
  617.     CurrentItem.Clear;
  618.     FQDB.Get(CurrentItem);
  619.     for n := 1 to Fields.Count do
  620.     begin
  621.       ThisControl := TFieldInfo(Fields.Objects[n - 1]).TheControl;
  622.       ThisTypeProc := TFieldInfo(Fields.Objects[n - 1]).FetchProc;
  623.       if @ThisTypeProc <> nil then
  624.       begin
  625.         m := TMemoryStream.Create;
  626.         try
  627.           CurrentItem.ReadBuffer(len, SizeOf(len));
  628.           m.CopyFrom(CurrentItem, len);
  629.           m.Position := 0;
  630.           ThisTypeProc(ThisControl, m);
  631.         finally
  632.           m.Free;
  633.         end;
  634.       end;
  635.     end;
  636.   end;
  637. end;
  638.  
  639. procedure TQDBPanel.Store;
  640. var
  641.   n: integer;
  642.   m: TMemoryStream;
  643.   ThisControl: TControl;
  644.   ThisTypeProc: TClassProc;
  645.   len: longint;
  646.   Key: TKey;
  647. begin
  648.   CurrentItem.Clear;
  649.   for n := 1 to Fields.Count do
  650.   begin
  651.     ThisControl := TFieldInfo(Fields.Objects[n - 1]).TheControl;
  652.     ThisTypeProc := TFieldInfo(Fields.Objects[n - 1]).StoreProc;
  653.     if @ThisTypeProc <> nil then
  654.     begin
  655.       m := TMemoryStream.Create;
  656.       try
  657.         ThisTypeProc(ThisControl, m);
  658.         m.Position := 0;
  659.         len := m.Size;
  660.         CurrentItem.WriteBuffer(len, SizeOf(len));
  661.         CurrentItem.CopyFrom(m, len);
  662.       finally
  663.         m.Free;
  664.       end;
  665.     end;
  666.   end;
  667.   if Assigned(FOnKey) then
  668.     FOnKey(Self, Key)
  669.   else
  670.     Key := '';
  671.   if Key <> '' then
  672.   begin
  673.     if FQDB.ExactMatch(Key) then
  674.     begin
  675.       FQDB.Change(CurrentItem);
  676.     end
  677.     else
  678.     begin
  679.       FQDB.Add(CurrentItem, Key);
  680.     end;
  681.   end;
  682. end;
  683.  
  684. procedure TQDBPanel.RegisterProcs(AClass: TControlClass; ClearProc, FetchProc, StoreProc: TClassProc);
  685. begin
  686.   Procs.AddProcs(AClass, ClearProc, FetchProc, StoreProc);
  687. end;
  688.  
  689. procedure TQDBPanel.RegisterGraphicFormat(const AExtension: string; AGraphicClass: TGraphicClass);
  690. var
  691.   NewRec: PFileFormat;
  692. begin
  693.   New(NewRec);
  694.   with NewRec^ do
  695.   begin
  696.     Extension := LowerCase(AExtension);
  697.     GraphicClass := AGraphicClass;
  698.     Next := FileFormatList;
  699.   end;
  700.   FileFormatList := NewRec;
  701. end;
  702.  
  703. procedure TQDBPanel.Cancel;
  704. begin
  705.   Enabled := false;
  706.   if Assigned(FQDB) then
  707.   begin
  708.     Fetch;
  709.   end;
  710. end;
  711.  
  712. procedure TQDBPanel.Delete;
  713. begin
  714.   if Assigned(FQDB) then
  715.   begin
  716.     Enabled := false;
  717.     FQDB.Delete;
  718.     Fetch;
  719.   end;
  720. end;
  721.  
  722. procedure TQDBPanel.Edit;
  723. begin
  724.   Enabled := true;
  725. end;
  726.  
  727. procedure TQDBPanel.FirstItem;
  728. begin
  729.   if Assigned(FQDB) then
  730.   begin
  731.     FQDB.FirstItem;
  732.     Fetch;
  733.   end;
  734. end;
  735.  
  736. procedure TQDBPanel.Insert;
  737. begin
  738.   Enabled := true;
  739.   Clear;
  740. end;
  741.  
  742. procedure TQDBPanel.LastItem;
  743. begin
  744.   if Assigned(FQDB) then
  745.   begin
  746.     FQDB.LastItem;
  747.     Fetch;
  748.   end;
  749. end;
  750.  
  751. procedure TQDBPanel.NextItem;
  752. begin
  753.   if Assigned(FQDB) then
  754.   begin
  755.     FQDB.NextItem;
  756.     Fetch;
  757.   end;
  758. end;
  759.  
  760. procedure TQDBPanel.Post;
  761. begin
  762.   if Assigned(FQDB) and Assigned(FOnKey) then
  763.   begin
  764.     if Enabled then
  765.       Store;
  766.     Enabled := false;
  767.   end;
  768. end;
  769.  
  770. procedure TQDBPanel.PrevItem;
  771. begin
  772.   if Assigned(FQDB) then
  773.   begin
  774.     FQDB.PrevItem;
  775.     Fetch;
  776.   end;
  777. end;
  778.  
  779. procedure TQDBPanel.Refresh;
  780. begin
  781.   if Assigned(FQDB) then
  782.   begin
  783.     Fetch;
  784.   end;
  785. end;
  786.  
  787. end.
  788.  
  789.