home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 October / PCWorld_2000-10_cd2.bin / Borland / interbase / IBConsole_src.ZIP / ibconsole / frmuDBRestore.pas < prev    next >
Pascal/Delphi Source File  |  2000-07-24  |  37KB  |  1,153 lines

  1. {
  2.  * The contents of this file are subject to the InterBase Public License
  3.  * Version 1.0 (the "License"); you may not use this file except in
  4.  * compliance with the License.
  5.  * 
  6.  * You may obtain a copy of the License at http://www.Inprise.com/IPL.html.
  7.  * 
  8.  * Software distributed under the License is distributed on an "AS IS"
  9.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  10.  * the License for the specific language governing rights and limitations
  11.  * under the License.  The Original Code was created by Inprise
  12.  * Corporation and its predecessors.
  13.  * 
  14.  * Portions created by Inprise Corporation are Copyright (C) Inprise
  15.  * Corporation. All Rights Reserved.
  16.  * 
  17.  * Contributor(s): ______________________________________.
  18. }
  19.  
  20. {****************************************************************
  21. *
  22. *  f r m u D B R e s t o r e
  23. *
  24. ****************************************************************
  25. *  Author: The Client Server Factory Inc.
  26. *  Date:   March 1, 1999
  27. *
  28. *  Description:  This unit provides an interface for performing
  29. *                a database restore
  30. *
  31. *****************************************************************
  32. * Revisions:
  33. *
  34. *****************************************************************}
  35. unit frmuDBRestore;
  36.                   
  37. interface
  38.  
  39. uses
  40.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  41.   StdCtrls, ComCtrls, ExtCtrls, zluibcClasses, Grids, IB, IBQuery, frmuDlgClass;
  42.  
  43. type
  44.   TfrmDBRestore = class(TDialog)
  45.     gbDatabaseFiles: TGroupBox;
  46.     lblDestinationServer: TLabel;
  47.     lblDBAlias: TLabel;
  48.     sgDatabaseFiles: TStringGrid;
  49.     cbDBServer: TComboBox;
  50.     cbDBAlias: TComboBox;
  51.     imgDownArrow: TImage;
  52.     gbBackupFiles: TGroupBox;
  53.     lblBackupServer: TLabel;
  54.     lblBackupAlias: TLabel;
  55.     stxBackupServer: TStaticText;
  56.     sgBackupFiles: TStringGrid;
  57.     cbBackupAlias: TComboBox;
  58.     lblOptions: TLabel;
  59.     sgOptions: TStringGrid;
  60.     btnOK: TButton;
  61.     btnCancel: TButton;
  62.     pnlOptionName: TPanel;
  63.     cbOptions: TComboBox;
  64.     procedure FormCreate(Sender: TObject);
  65.     procedure FormDestroy(Sender: TObject);
  66.     procedure btnCancelClick(Sender: TObject);
  67.     procedure btnOKClick(Sender: TObject);
  68.     procedure cbOptionsChange(Sender: TObject);
  69.     procedure cbOptionsDblClick(Sender: TObject);
  70.     procedure cbOptionsExit(Sender: TObject);
  71.     procedure cbOptionsKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  72.     procedure edtDestinationDBChange(Sender: TObject);
  73.     procedure edtSourceDBChange(Sender: TObject);
  74.     procedure sgBackupFilesKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  75.     procedure sgDatabaseFilesDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
  76.     procedure sgDatabaseFilesKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  77.     procedure sgOptionsDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
  78.     procedure sgOptionsSelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
  79.     procedure cbDBServerChange(Sender: TObject);
  80.     procedure cbDBAliasChange(Sender: TObject);
  81.     procedure cbBackupAliasChange(Sender: TObject);
  82.     function FormHelp(Command: Word; Data: Integer; var CallHelp: Boolean): Boolean;
  83.     procedure IncreaseRows(Sender: TObject; ACol, ARow: Integer;
  84.       var CanSelect: Boolean);
  85.   private
  86.     { Private declarations }
  87.     FVerboseFile: string;
  88.  
  89.     FSourceServerNode: TibcServerNode;
  90.     function VerifyInputData(): boolean;
  91.     procedure WMNCLButtonDown( var Message: TWMNCLBUTTONDOWN ); message WM_NCLBUTTONDOWN ;
  92.   public
  93.     { Public declarations }
  94.     FFileList: TStringList;
  95.   end;
  96.  
  97. function DoDBRestore(const SourceServerNode: TibcServerNode;
  98.                      const SourceBackupAliasNode: TibcTreeNode): integer;
  99.  
  100. implementation
  101.  
  102. uses zluGlobal,frmuServerRegister,IBServices,frmuMessage,
  103.   frmuMain, zluUtility, dmuMain, zluContextHelp, Registry, IBErrorCodes;
  104.  
  105. {$R *.DFM}
  106.  
  107. const
  108.   OPTION_NAME_COL = 0;
  109.   OPTION_VALUE_COL = 1;
  110.   PAGE_SIZE_ROW = 0;
  111.   OVERWRITE_ROW = 1;
  112.   COMMIT_EACH_TABLE_ROW = 2;
  113.   CREATE_SHADOW_FILES_ROW = 3;
  114.   DEACTIVATE_INDICES_ROW = 4;
  115.   VALIDITY_CONDITIONS_ROW = 5;
  116.   USE_ALL_SPACE_ROW = 6;
  117.   VERBOSE_OUTPUT_ROW = 7;
  118.  
  119. {****************************************************************
  120. *
  121. *  F o r m C r e a t e ( )
  122. *
  123. ****************************************************************
  124. *  Author: The Client Server Factory Inc.
  125. *  Date:   March 1, 1999
  126. *
  127. *  Input:  Sender - The object that initiated the event
  128. *
  129. *  Return: None
  130. *
  131. *  Description: Ths procedure intializes the form's controls when
  132. *               the form is initially created.
  133. *
  134. *****************************************************************
  135. * Revisions:
  136. *
  137. *****************************************************************}
  138. procedure TfrmDBRestore.FormCreate(Sender: TObject);
  139. begin
  140.   inherited;
  141.   FFileList := TStringList.Create;
  142.   sgOptions.DefaultRowHeight := cbOptions.Height;
  143.   cbOptions.Visible := True;
  144.   pnlOptionName.Visible := True;
  145.  
  146.   sgBackupFiles.Cells[0,0] := 'Filename(s)';
  147.  
  148.   sgDatabaseFiles.Cells[0,0] := 'Filename(s)';
  149.   sgDatabaseFiles.Cells[1,0] := 'Pages';
  150.  
  151.   sgOptions.RowCount := 8;
  152.  
  153.   sgOptions.Cells[OPTION_NAME_COL,PAGE_SIZE_ROW] := 'Page Size (Bytes)';
  154.   sgOptions.Cells[OPTION_VALUE_COL,PAGE_SIZE_ROW] := '1024';
  155.  
  156.   sgOptions.Cells[OPTION_NAME_COL,OVERWRITE_ROW] := 'Overwrite';
  157.   sgOptions.Cells[OPTION_VALUE_COL,OVERWRITE_ROW] := 'False';
  158.  
  159.   sgOptions.Cells[OPTION_NAME_COL,COMMIT_EACH_TABLE_ROW] := 'Commit After Each Table';
  160.   sgOptions.Cells[OPTION_VALUE_COL,COMMIT_EACH_TABLE_ROW] := 'False';
  161.  
  162.   sgOptions.Cells[OPTION_NAME_COL,CREATE_SHADOW_FILES_ROW] := 'Create Shadow Files';
  163.   sgOptions.Cells[OPTION_VALUE_COL,CREATE_SHADOW_FILES_ROW] := 'True';
  164.  
  165.   sgOptions.Cells[OPTION_NAME_COL,DEACTIVATE_INDICES_ROW] := 'Deactivate Indices';
  166.   sgOptions.Cells[OPTION_VALUE_COL,DEACTIVATE_INDICES_ROW] := 'False';
  167.  
  168.   sgOptions.Cells[OPTION_NAME_COL,VALIDITY_CONDITIONS_ROW] := 'Validity Conditions';
  169.   sgOptions.Cells[OPTION_VALUE_COL,VALIDITY_CONDITIONS_ROW] := 'Restore';
  170.  
  171.   sgOptions.Cells[OPTION_NAME_COL,USE_ALL_SPACE_ROW] := 'Use All Space';
  172.   sgOptions.Cells[OPTION_VALUE_COL,USE_ALL_SPACE_ROW] := 'False';
  173.  
  174.   sgOptions.Cells[OPTION_NAME_COL,VERBOSE_OUTPUT_ROW] := 'Verbose Output';
  175.   sgOptions.Cells[OPTION_VALUE_COL,VERBOSE_OUTPUT_ROW] := 'To Screen';
  176.  
  177.   pnlOptionName.Caption := 'Page Size (Bytes)';
  178.   cbOptions.Items.Add('1024');
  179.   cbOptions.Items.Add('2048');
  180.   cbOptions.Items.Add('4096');
  181.   cbOptions.Items.Add('8192');
  182.   cbOptions.ItemIndex := 0;
  183. end;
  184.  
  185. procedure TfrmDBRestore.FormDestroy(Sender: TObject);
  186. begin
  187.   FFileList.Free;
  188. end;
  189.  
  190. procedure TfrmDBRestore.btnCancelClick(Sender: TObject);
  191. begin
  192.   ModalResult := mrCancel;
  193. end;
  194.  
  195. procedure TfrmDBRestore.btnOKClick(Sender: TObject);
  196. var
  197.   j: integer;
  198.   lRestoreService: TIBRestoreService;
  199.   lOptions: TRestoreOptions;
  200.   lVerboseInfo: TStringList;
  201.   Reg: TRegistry;
  202. begin
  203.   if VerifyInputData() then
  204.   begin
  205.     Screen.Cursor := crHourglass;
  206.     lVerboseInfo := TStringList.Create;
  207.     lRestoreService := TIBRestoreService.Create(nil);
  208.     try
  209.       try
  210.         lRestoreService.LoginPrompt := false;
  211.         lRestoreService.ServerName := FSourceServerNode.Server.ServerName;
  212.         lRestoreService.Protocol := FSourceServerNode.Server.Protocol;
  213.         lRestoreService.Params.Clear;
  214.         lRestoreService.Params.Assign(FSourceServerNode.Server.Params);
  215.         lRestoreService.Attach();
  216.       except
  217.         on E:EIBError do
  218.         begin
  219.           DisplayMsg(E.IBErrorCode, E.Message);
  220.           Screen.Cursor := crDefault;
  221.           if (E.IBErrorCode = isc_lost_db_connection) or
  222.              (E.IBErrorCode = isc_unavailable) or
  223.              (E.IBErrorCode = isc_network_error) then
  224.             frmMain.SetErrorState;
  225.           SetErrorState;
  226.           Exit;
  227.         end;
  228.       end;
  229.  
  230.       if lRestoreService.Active = true then
  231.       begin
  232.         if sgOptions.Cells[OPTION_VALUE_COL,OVERWRITE_ROW] = 'True' then
  233.         begin
  234.           Include(lOptions, Replace);
  235.         end
  236.         else
  237.         begin
  238.           Include(lOptions, CreateNewDB);
  239.         end;
  240.  
  241.         if sgOptions.Cells[OPTION_VALUE_COL,COMMIT_EACH_TABLE_ROW] = 'True' then
  242.         begin
  243.           Include(lOptions, OneRelationAtATime);
  244.         end;
  245.  
  246.         if sgOptions.Cells[OPTION_VALUE_COL,CREATE_SHADOW_FILES_ROW] = 'False' then
  247.         begin
  248.           Include(lOptions, NoShadow);
  249.         end;
  250.  
  251.         if sgOptions.Cells[OPTION_VALUE_COL,DEACTIVATE_INDICES_ROW] = 'True' then
  252.         begin
  253.           Include(lOptions, DeactivateIndexes);
  254.         end;
  255.  
  256.         if sgOptions.Cells[OPTION_VALUE_COL,VALIDITY_CONDITIONS_ROW] = 'False' then
  257.         begin
  258.           Include(lOptions, NoValidityCheck);
  259.         end;
  260.  
  261.         lRestoreService.Options := lOptions;
  262.         lRestoreService.PageSize := StrToInt(sgOptions.Cells[OPTION_VALUE_COL,PAGE_SIZE_ROW]);
  263.  
  264.         if (sgOptions.Cells[OPTION_VALUE_COL,VERBOSE_OUTPUT_ROW] = 'To Screen') or
  265.           (sgOptions.Cells[OPTION_VALUE_COL,VERBOSE_OUTPUT_ROW] = 'To File') then
  266.         begin
  267.           lRestoreService.Verbose := true;
  268.         end;
  269.  
  270.         for j := 1 to sgBackupFiles.RowCount - 1 do
  271.         begin
  272.           if sgBackupFiles.Cells[0,j] <> '' then
  273.             lRestoreService.BackupFile.Add(Format('%s',[sgBackupFiles.Cells[0,j]]));
  274.         end;
  275.  
  276.         if cbDBServer.ItemIndex > -1 then
  277.         begin
  278.           for j := 1 to sgDatabaseFiles.RowCount - 1 do
  279.           begin
  280.             if not (IsValidDBName(sgDatabaseFiles.Cells[0,j])) then
  281.               DisplayMsg(WAR_REMOTE_FILENAME, Format('File: %s', [sgDatabaseFiles.Cells[0,j]]));
  282.  
  283.             if (sgDatabaseFiles.Cells[0,j] <> '') and (sgDatabaseFiles.Cells[1,j] <> '')then
  284.             begin
  285.               lRestoreService.DatabaseName.Add(Format('%s=%s',[sgDatabaseFiles.Cells[0,j],sgDatabaseFiles.Cells[1,j]]));
  286.             end
  287.             else
  288.             begin
  289.               lRestoreService.DatabaseName.Add(sgDatabaseFiles.Cells[0,j]);
  290.             end;
  291.           end;
  292.         end;
  293.         Screen.Cursor := crHourGlass;
  294.         try
  295.           lRestoreService.ServiceStart;
  296.           FSourceServerNode.OpenTextViewer (lRestoreService, 'Database Restore');
  297.           while (lRestoreService.IsServiceRunning) and (not gApplShutdown) do
  298.           begin
  299.             Application.ProcessMessages;
  300.             Screen.Cursor := crHourGlass;
  301.           end;
  302.  
  303.           if lRestoreService.Active then
  304.             lRestoreService.Detach();
  305.  
  306.           { If the database alias entered does not already exist, create it }
  307.           if not frmMain.AliasExists (cbDBAlias.Text) then
  308.           begin
  309.             Reg := TRegistry.Create;
  310.             if Reg.OpenKey(Format('%s%s\Databases\%s',[gRegServersKey, cbDBServer.Text, cbDBAlias.Text]),true) then
  311.             begin
  312.               Reg.WriteString('DatabaseFiles', lRestoreService.DatabaseName.Text);
  313.               Reg.WriteString('Username', FSourceServerNode.UserName);
  314.               Reg.CloseKey;
  315.               Reg.Free;
  316.               frmMain.tvMainChange(nil, nil);
  317.             end;
  318.           end;
  319.           ModalResult := mrOK;          
  320.         except
  321.           on E: EIBError do
  322.           begin
  323.             DisplayMsg(E.IBErrorCode, E.Message);
  324.             if (E.IBErrorCode = isc_lost_db_connection) or
  325.                (E.IBErrorCode = isc_unavailable) or
  326.                (E.IBErrorCode = isc_network_error) then
  327.               frmMain.SetErrorState;
  328.             SetErrorState;
  329.           end;
  330.         end;
  331.       end;
  332.     finally
  333.       if lRestoreService.Active then
  334.         lRestoreService.Detach();
  335.       lRestoreService.Free();
  336.       lVerboseInfo.Free;
  337.       Screen.Cursor := crDefault;
  338.     end;
  339.   end;
  340. end;
  341.  
  342. {****************************************************************
  343. *
  344. *  c b O p t i o n s C h a n g e ( )
  345. *
  346. ****************************************************************
  347. *  Author: The Client Server Factory Inc.
  348. *  Date:   March 1, 1999
  349. *
  350. *  Input:  Sender - The object that initiated the event
  351. *
  352. *  Return: None
  353. *
  354. *  Description: This procedure changes the value of the selected
  355. *               cell in the grid based on what was entered in the
  356. *               combobox.
  357. *
  358. *****************************************************************
  359. * Revisions:
  360. *
  361. *****************************************************************}
  362. procedure TfrmDBRestore.cbOptionsChange(Sender: TObject);
  363. var
  364.   lSaveDialog: TSaveDialog;
  365. begin
  366.   lSaveDialog := nil;
  367.   if (cbOptions.Text = 'To File') and (sgOptions.Row = VERBOSE_OUTPUT_ROW) then
  368.   begin
  369.     try
  370.       lSaveDialog := TSaveDialog.Create(Self);
  371.       lSaveDialog.Title := 'Select Verbose File';
  372.       lSaveDialog.DefaultExt := 'txt';
  373.       lSaveDialog.Filter := 'Text File (*.txt)|*.TXT|All files (*.*)|*.*';
  374.       lSaveDialog.Options := [ofHideReadOnly,ofEnableSizing];
  375.       if lSaveDialog.Execute then
  376.       begin
  377.         if FileExists(lSaveDialog.FileName) then
  378.         begin
  379.           if MessageDlg(Format('OK to overwrite %s', [lSaveDialog.FileName]),
  380.               mtConfirmation, mbYesNoCancel, 0) <> idYes then
  381.           begin
  382.             cbOptions.ItemIndex := cbOptions.Items.IndexOf('To Screen');
  383.             Exit;
  384.           end;
  385.         end;
  386.         FVerboseFile := lSaveDialog.FileName;
  387.       end
  388.       else
  389.         cbOptions.ItemIndex := cbOptions.Items.IndexOf('To Screen');
  390.     finally
  391.       lSaveDialog.free;
  392.     end;
  393.   end;
  394.  
  395.   {
  396.   sgOptions.Cells[sgOptions.Col,sgOptions.Row] :=
  397.     cbOptions.Items[cbOptions.ItemIndex];
  398.   cbOptions.Visible := false;
  399.   sgOptions.SetFocus;
  400.   }
  401. end;
  402.  
  403. {****************************************************************
  404. *
  405. *  c b O p t i o n s D b l C l i c k ( )
  406. *
  407. ****************************************************************
  408. *  Author: The Client Server Factory Inc.
  409. *  Date:   March 1, 1999
  410. *
  411. *  Input:  Sender - The object that initiated the event
  412. *
  413. *  Return: None
  414. *
  415. *  Description: This procedure rotates the values in the combobox
  416. *               and updates the selected cell in the grid each
  417. *               time is is double clicked
  418. *
  419. *****************************************************************
  420. * Revisions:
  421. *
  422. *****************************************************************}
  423. procedure TfrmDBRestore.cbOptionsDblClick(Sender: TObject);
  424. begin
  425.   if (sgOptions.Col = OPTION_VALUE_COL) or (sgOptions.Col = OPTION_NAME_COL) then
  426.   begin
  427.     if cbOptions.ItemIndex = cbOptions.Items.Count - 1 then
  428.       cbOptions.ItemIndex := 0
  429.     else
  430.       cbOptions.ItemIndex := cbOptions.ItemIndex + 1;
  431.  
  432.     if sgOptions.Col = OPTION_VALUE_COL then
  433.       sgOptions.Cells[sgOptions.Col,sgOptions.Row] := cbOptions.Items[cbOptions.ItemIndex];
  434.  
  435.     // cbOptions.Visible := True;
  436.     // sgOptions.SetFocus;
  437.   end;
  438. end;
  439.  
  440. {****************************************************************
  441. *
  442. *  c b O p t i o n s E x i t ( )
  443. *
  444. ****************************************************************
  445. *  Author: The Client Server Factory Inc.
  446. *  Date:   March 1, 1999
  447. *
  448. *  Input:  Sender - The object that initiated the event
  449. *
  450. *  Description: This procedure changes the value of the selected
  451. *               cell in the grid based on what was entered in the
  452. *               combobox.
  453. *
  454. *****************************************************************
  455. * Revisions:
  456. *
  457. *****************************************************************}
  458. procedure TfrmDBRestore.cbOptionsExit(Sender: TObject);
  459. var
  460.   lR : TRect;
  461.   iIndex : Integer;
  462. begin
  463.   iIndex := cbOptions.Items.IndexOf(cbOptions.Text);
  464.  
  465.   if (iIndex = -1) then
  466.   begin
  467.     MessageDlg('Invalid option value', mtError, [mbOK], 0);
  468.  
  469.     cbOptions.ItemIndex := 0;
  470.     //Size and position the combo box to fit the cell
  471.     lR := sgOptions.CellRect(OPTION_VALUE_COL, sgOptions.Row);
  472.     lR.Left := lR.Left + sgOptions.Left;
  473.     lR.Right := lR.Right + sgOptions.Left;
  474.     lR.Top := lR.Top + sgOptions.Top;
  475.     lR.Bottom := lR.Bottom + sgOptions.Top;
  476.     cbOptions.Left := lR.Left + 1;
  477.     cbOptions.Top := lR.Top + 1;
  478.     cbOptions.Width := (lR.Right + 1) - lR.Left;
  479.     cbOptions.Height := (lR.Bottom + 1) - lR.Top;
  480.     cbOptions.Visible := True;
  481.     cbOptions.SetFocus;
  482.   end
  483.   else if (sgOptions.Col <> OPTION_NAME_COL) then
  484.   begin
  485.     sgOptions.Cells[sgOptions.Col,sgOptions.Row] := cbOptions.Items[iIndex];
  486.   end
  487.   else
  488.   begin
  489.     sgOptions.Cells[OPTION_VALUE_COL,sgOptions.Row] := cbOptions.Items[iIndex];
  490.   end;
  491. end;
  492.  
  493. {****************************************************************
  494. *
  495. *  c b O p t i o n s K e y D o w n ( )
  496. *
  497. ****************************************************************
  498. *  Author: The Client Server Factory Inc.
  499. *  Date:   March 1, 1999
  500. *
  501. *  Input:  Sender - The object that initiated the event
  502. *
  503. *  Return: None
  504. *
  505. *  Description: This procedure drops down the combobox for the selected
  506. *               grid cell when the <DOWN ARROW> key is pressed.
  507. *
  508. *****************************************************************
  509. * Revisions:
  510. *
  511. *****************************************************************}
  512. procedure TfrmDBRestore.cbOptionsKeyDown(Sender: TObject; var Key: Word;
  513.   Shift: TShiftState);
  514. begin
  515.   if (Key = VK_DOWN) then
  516.     cbOptions.DroppedDown := true;
  517. end;
  518.  
  519. procedure TfrmDBRestore.edtDestinationDBChange(Sender: TObject);
  520. begin
  521. //  edtDestinationDB.Hint := edtDestinationDB.Text;
  522. end;
  523.  
  524. procedure TfrmDBRestore.edtSourceDBChange(Sender: TObject);
  525. begin
  526. //  edtSourceDB.Hint := edtSourceDB.Text;
  527. end;
  528.  
  529. {****************************************************************
  530. *
  531. *  s g B a c k u p F i l e s K e y D o w n ( )
  532. *
  533. ****************************************************************
  534. *  Author: The Client Server Factory Inc.
  535. *  Date:   March 1, 1999
  536. *
  537. *  Input:  Sender - The object that initiated the event
  538. *
  539. *  Return: None
  540. *
  541. *  Description:
  542. *
  543. *****************************************************************
  544. * Revisions:
  545. *
  546. *****************************************************************}
  547. procedure TfrmDBRestore.sgBackupFilesKeyDown(Sender: TObject; var Key: Word;
  548.   Shift: TShiftState);
  549. begin
  550.   if (Key = VK_TAB) and (ssCtrl in Shift) then
  551.   begin
  552.     if sgBackupFiles.Col < sgBackupFiles.ColCount - 1 then
  553.     begin
  554.       sgBackupFiles.Col := sgBackupFiles.Col + 1;
  555.     end
  556.     else
  557.     begin
  558.       if sgBackupFiles.Row = sgBackupFiles.RowCount - 1 then
  559.         sgBackupFiles.RowCount := sgBackupFiles.RowCount + 1;
  560.       sgBackupFiles.Col := 0;
  561.       sgBackupFiles.Row := sgBackupFiles.Row + 1;
  562.     end;
  563.   end;
  564. end;
  565.  
  566. {****************************************************************
  567. *
  568. *  s g D a t a b a s e F i l e s D r a w C e l l ( )
  569. *
  570. ****************************************************************
  571. *  Author: The Client Server Factory Inc.
  572. *  Date:   March 1, 1999
  573. *
  574. *  Input:  Sender - The object that initiated the event
  575. *
  576. *  Return: None
  577. *
  578. *  Description: This procedure is responsible for painting blue
  579. *               the option value text in the string grid
  580. *
  581. *****************************************************************
  582. * Revisions:
  583. *
  584. *****************************************************************}
  585. procedure TfrmDBRestore.sgDatabaseFilesDrawCell(Sender: TObject; ACol,
  586.   ARow: Integer; Rect: TRect; State: TGridDrawState);
  587. const
  588.   INDENT = 2;
  589. var
  590.   lLeft: integer;
  591.   lText: string;
  592. begin
  593.   with Sender as TStringGrid do //sgDatabaseFiles.canvas do
  594.   begin
  595.     if (ACol = 2) and (ARow <> 0) then
  596.     begin
  597.       canvas.font.color := clBlack;
  598.       if canvas.brush.color = clHighlight then
  599.         canvas.font.color := clWhite;
  600.       lText := Cells[ACol,ARow];
  601.       lLeft := Rect.Left + INDENT;
  602.       Canvas.TextRect(Rect, lLeft, Rect.top + INDENT, lText);
  603.     end;
  604.   end;
  605. end;
  606.  
  607. {****************************************************************
  608. *
  609. *  s g D a t a b a s e F i l e s K e y D o w n ( )
  610. *
  611. ****************************************************************
  612. *  Author: The Client Server Factory Inc.
  613. *  Date:   March 1, 1999
  614. *
  615. *  Input:  Sender - The object that initiated the event
  616. *
  617. *  Return: None
  618. *
  619. *  Description:
  620. *
  621. *****************************************************************
  622. * Revisions:
  623. *
  624. *****************************************************************}
  625. procedure TfrmDBRestore.sgDatabaseFilesKeyDown(Sender: TObject;
  626.   var Key: Word; Shift: TShiftState);
  627. var
  628.   lKey : Word;
  629. begin
  630.   if (Key = VK_TAB) and (ssCtrl in Shift) then
  631.   begin
  632.     if sgDatabaseFiles.Col < sgDatabaseFiles.ColCount - 1 then
  633.     begin
  634.       sgDatabaseFiles.Col := sgDatabaseFiles.Col + 1;
  635.     end
  636.     else
  637.     begin
  638.       if sgDatabaseFiles.Row = sgDatabaseFiles.RowCount - 1 then
  639.         sgDatabaseFiles.RowCount := sgDatabaseFiles.RowCount + 1;
  640.       sgDatabaseFiles.Col := 0;
  641.       sgDatabaseFiles.Row := sgDatabaseFiles.Row + 1;
  642.     end;
  643.   end;
  644.  
  645.   if (Key = VK_RETURN) and
  646.     (sgDatabaseFiles.Cells[sgDatabaseFiles.Col,sgDatabaseFiles.Row] <> '') then
  647.   begin
  648.     lKey := VK_TAB;
  649.     sgDatabaseFilesKeyDown(Self, lKey, [ssCtrl]);
  650.   end;
  651.  
  652. end;
  653.  
  654. {****************************************************************
  655. *
  656. *  s g O p t i o n s D r a w C e l l ( )
  657. *
  658. ****************************************************************
  659. *  Author: The Client Server Factory Inc.
  660. *  Date:   March 1, 1999
  661. *
  662. *  Input:  Sender - The object that initiated the event
  663. *
  664. *  Return: None
  665. *
  666. *  Description: This procedure is responsible for painting blue
  667. *               the option value text in the string grid
  668. *
  669. *****************************************************************
  670. * Revisions:
  671. *
  672. *****************************************************************}
  673. procedure TfrmDBRestore.sgOptionsDrawCell(Sender: TObject; ACol, ARow: Integer;
  674.   Rect: TRect; State: TGridDrawState);
  675. const
  676.   INDENT = 2;
  677. var
  678.   lLeft: integer;
  679.   lText: string;
  680. begin
  681.   with sgOptions.canvas do
  682.   begin
  683.     if ACol = OPTION_VALUE_COL then
  684.     begin
  685.       font.color := clBlue;
  686.       if brush.color = clHighlight then
  687.         font.color := clWhite;
  688.       lText := sgOptions.Cells[ACol,ARow];
  689.       lLeft := Rect.Left + INDENT;
  690.       TextRect(Rect, lLeft, Rect.top + INDENT, lText);
  691.     end;
  692.   end;
  693. end;
  694.  
  695. {****************************************************************
  696. *
  697. *  s g O p t i o n s S e l e c t C e l l ( )
  698. *
  699. ****************************************************************
  700. *  Author: The Client Server Factory Inc.
  701. *  Date:   March 1, 1999
  702. *
  703. *  Input:  Refer to the Delphi documentation.
  704. *
  705. *  Return: None
  706. *
  707. *  Description: This procedure initializes and positions the combobox
  708. *               depending on which cell in the grid is selected
  709. *
  710. *****************************************************************
  711. * Revisions:
  712. *
  713. *****************************************************************}
  714. procedure TfrmDBRestore.sgOptionsSelectCell(Sender: TObject; ACol,
  715.   ARow: Integer; var CanSelect: Boolean);
  716. var
  717.   lR, lName : TRect;
  718. begin
  719.   cbOptions.Items.Clear;
  720.   case ARow of
  721.     PAGE_SIZE_ROW:
  722.     begin
  723.       cbOptions.Items.Add('1024');
  724.       cbOptions.Items.Add('2048');
  725.       cbOptions.Items.Add('4096');
  726.       cbOptions.Items.Add('8192');
  727.     end;
  728.     OVERWRITE_ROW:
  729.     begin
  730.       cbOptions.Items.Add('True');
  731.       cbOptions.Items.Add('False');
  732.     end;
  733.     COMMIT_EACH_TABLE_ROW:
  734.     begin
  735.       cbOptions.Items.Add('True');
  736.       cbOptions.Items.Add('False');
  737.     end;
  738.     CREATE_SHADOW_FILES_ROW:
  739.     begin
  740.       cbOptions.Items.Add('True');
  741.       cbOptions.Items.Add('False');
  742.     end;
  743.     DEACTIVATE_INDICES_ROW:
  744.     begin
  745.       cbOptions.Items.Add('True');
  746.       cbOptions.Items.Add('False');
  747.     end;
  748.     VALIDITY_CONDITIONS_ROW:
  749.     begin
  750.       cbOptions.Items.Add('Restore');
  751.       cbOptions.Items.Add('Ignore');
  752.     end;
  753.     USE_ALL_SPACE_ROW:
  754.     begin
  755.       cbOptions.Items.Add('True');
  756.       cbOptions.Items.Add('False');
  757.     end;
  758.     VERBOSE_OUTPUT_ROW:
  759.     begin
  760.       cbOptions.Items.Add('None');
  761.       cbOptions.Items.Add('To Screen');
  762.       cbOptions.Items.Add('To File');
  763.     end;
  764.   end;
  765.  
  766.   pnlOptionName.Caption := sgOptions.Cells[OPTION_NAME_COL, ARow];
  767.  
  768.   if ACol = OPTION_NAME_COL then
  769.     cbOptions.ItemIndex := cbOptions.Items.IndexOf(sgOptions.Cells[ACol+1,ARow])
  770.   else if ACol = OPTION_VALUE_COL then
  771.     cbOptions.ItemIndex := cbOptions.Items.IndexOf(sgOptions.Cells[ACol,ARow]);
  772.  
  773.   if ACol = OPTION_NAME_COL then
  774.   begin
  775.     lName := sgOptions.CellRect(ACol, ARow);
  776.     lR := sgOptions.CellRect(ACol + 1, ARow);
  777.   end
  778.   else
  779.   begin
  780.     lName := sgOptions.CellRect(ACol - 1, ARow);
  781.     lR := sgOptions.CellRect(ACol, ARow);
  782.   end;
  783.  
  784.   // lName := sgOptions.CellRect(ACol, ARow);
  785.   lName.Left := lName.Left + sgOptions.Left;
  786.   lName.Right := lName.Right + sgOptions.Left;
  787.   lName.Top := lName.Top + sgOptions.Top;
  788.   lName.Bottom := lName.Bottom + sgOptions.Top;
  789.   pnlOptionName.Left := lName.Left + 1;
  790.   pnlOptionName.Top := lName.Top + 1;
  791.   pnlOptionName.Width := (lName.Right + 1) - lName.Left;
  792.   pnlOptionName.Height := (lName.Bottom + 1) - lName.Top;
  793.   pnlOptionName.Visible := True;
  794.  
  795.   // lR := sgOptions.CellRect(ACol, ARow);
  796.   lR.Left := lR.Left + sgOptions.Left;
  797.   lR.Right := lR.Right + sgOptions.Left;
  798.   lR.Top := lR.Top + sgOptions.Top;
  799.   lR.Bottom := lR.Bottom + sgOptions.Top;
  800.   cbOptions.Left := lR.Left + 1;
  801.   cbOptions.Top := lR.Top + 1;
  802.   cbOptions.Width := (lR.Right + 1) - lR.Left;
  803.   cbOptions.Height := (lR.Bottom + 1) - lR.Top;
  804.   cbOptions.Visible := True;
  805.   cbOptions.SetFocus;
  806. end;
  807.  
  808. {****************************************************************
  809. *
  810. *  V e r i f y I n p u t D a t a ( )
  811. *
  812. ****************************************************************
  813. *  Author: The Client Server Factory Inc.
  814. *  Date:   March 1, 1999
  815. *
  816. *  Input:  None
  817. *
  818. *  Return: boolean - Indicates the success/failure of the operation
  819. *
  820. *  Description:  Performs some basic validation on data entered by
  821. *                the user
  822. *
  823. *****************************************************************
  824. * Revisions:
  825. *
  826. *****************************************************************}
  827. function TfrmDBRestore.VerifyInputData(): boolean;
  828. var
  829.   lCnt: integer;
  830.   found: boolean;
  831.   fp: string;
  832.  
  833. begin
  834.   result := true;
  835.   found := false;
  836.  
  837.   // check if combo box is empty or nothing selected
  838.   if (cbDBServer.ItemIndex = -1) or (cbDBServer.Text = '') or (cbDBServer.Text = ' ') then
  839.   begin
  840.     DisplayMsg(ERR_SERVER_NAME,'');
  841.     cbDBServer.SetFocus;
  842.     result := false;
  843.     Exit;
  844.   end;
  845.  
  846.   // check if combo box is empty
  847.   if (cbDBAlias.Text = '') or (cbDBAlias.Text = ' ') then
  848.   begin
  849.     DisplayMsg(ERR_DB_ALIAS,'');
  850.     cbDBAlias.SetFocus;
  851.     result := false;
  852.     Exit;
  853.   end;
  854.  
  855.   for lCnt := 1 to sgDatabaseFiles.RowCount - 1 do
  856.   begin
  857.     if (sgDatabaseFiles.Cells[0,lCnt] <> '') then
  858.     begin
  859.       found := true;
  860.       fp := ExtractFilePath(sgDatabaseFiles.Cells[0,lCnt]);
  861.  
  862.       if fp = '' then
  863.       begin
  864.         DisplayMsg(ERR_NO_PATH, 'File: '+sgDatabaseFiles.Cells[0,lCnt]);
  865.         sgDatabaseFiles.SetFocus;
  866.         result := false;
  867.         exit;
  868.       end;
  869.     end;
  870.   end;
  871.  
  872.   if not found then
  873.   begin
  874.     DisplayMsg (ERR_NO_FILES,'');
  875.     result := false;
  876.     exit;
  877.   end;
  878.  
  879. end;
  880.  
  881. {*******************************************************************
  882. *
  883. *  D o R e s t o r e ( )
  884. *
  885. ********************************************************************
  886. *  Author: The Client Server Factory Inc.
  887. *  Date:   March 1, 1999
  888. *
  889. *  Input:  SelServerNode - Identifies the selected server
  890. *          SelTreeNode - Identifies the selected backup file
  891. *
  892. *  Return: None
  893. *
  894. *  Description: This procedure creates and displays the restore form
  895. *               in order to capture restore information. It then
  896. *               performs the restore and destroys the instance of
  897. *               the form.
  898. *
  899. *********************************************************************
  900. * Revisions:
  901. *
  902. *********************************************************************}
  903. function DoDBRestore(const SourceServerNode: TibcServerNode;
  904.                      const SourceBackupAliasNode: TibcTreeNode): integer;
  905. var
  906.   i: integer;
  907.   frmDBRestore: TfrmDBRestore;
  908.   lBackupAliasNode: TibcBackupAliasNode;
  909.   lCurrBackupAliasesNode: TTreeNode;
  910.   AliasName: String;
  911.  
  912. begin
  913.   frmDBRestore := nil;
  914.   lBackupAliasNode := nil;
  915.  
  916.   if SourceBackupAliasNode is TibcBackupAliasNode then
  917.     lBackupAliasNode := TibcBackupAliasNode(SourceBackupAliasNode);
  918.   try
  919.     frmDBRestore := TfrmDBRestore.Create(Application);
  920.     frmDBRestore.FSourceServerNode := SourceServerNode;
  921.     frmDBRestore.stxBackupServer.Caption := SourceServerNode.NodeName;
  922.     lCurrBackupAliasesNode := frmMain.tvMain.Items.GetNode(SourceServerNode.BackupFilesID);
  923.  
  924.     for i := 1 to TibcTreeNode(lCurrBackupAliasesNode.Data).ObjectList.Count - 1 do
  925.     begin
  926.       AliasName := TibcTreeNode(lCurrBackupAliasesNode.Data).ObjectList.Strings[i];
  927.  
  928.       frmDBRestore.cbBackupAlias.Items.AddObject(GetNextField (AliasName, DEL),
  929.       TibcBackupAliasNode(TTreeNode(TibcTreeNode(lCurrBackupAliasesNode.Data).ObjectList.Objects[i]).Data));
  930.     end;
  931.  
  932.     for i := 1 to TibcTreeNode(frmMain.tvMain.Items[0].Data).ObjectList.Count - 1 do
  933.     begin
  934.       AliasName := TibcTreeNode(frmMain.tvMain.Items[0].Data).ObjectList.Strings[i];
  935.       frmDBRestore.cbDBServer.Items.AddObject(GetNextField(AliasName, DEL),
  936.         TibcServerNode(TTreeNode(TibcTreeNode(frmMain.tvMain.Items[0].Data).ObjectList.Objects[i]).Data));
  937.     end;
  938.  
  939.     if Assigned(SourceBackupAliasNode) then
  940.     begin
  941.       frmDBRestore.cbBackupAlias.ItemIndex := frmDBRestore.cbBackupAlias.Items.IndexOf(SourceBackupAliasNode.NodeName);
  942.       frmDBRestore.cbBackupAliasChange(frmDBRestore);
  943.  
  944.       if Assigned (lBackupAliasNode) then
  945.       begin
  946.         frmDBRestore.cbDBServer.ItemIndex := frmDBRestore.cbDBServer.Items.IndexOf(lBackupAliasNode.SourceDBServer);
  947.         frmDBRestore.cbDBServerChange(frmDBRestore);
  948.         frmDBRestore.cbDBAlias.ItemIndex := frmDBRestore.cbDBAlias.Items.IndexOf(lBackupAliasNode.SourceDBAlias);
  949.         frmDBRestore.cbDBAliasChange(frmDBRestore);
  950.       end;
  951.     end;
  952.  
  953.     frmDBRestore.ShowModal;
  954.     if (frmDBRestore.ModalResult = mrOK) and
  955.        (not frmDBRestore.GetErrorState)then
  956.     begin
  957.       if Assigned (lBackupAliasNode) then
  958.       begin
  959.         if lBackupAliasNode.SourceDBAlias = '' then
  960.           lBackupAliasNode.SourceDBAlias := frmDBRestore.cbDBAlias.Text;
  961.       end;
  962.       DisplayMsg(INF_RESTORE_DB_SUCCESS,'');
  963.       result := SUCCESS;
  964.     end
  965.     else
  966.       result := FAILURE;
  967.   finally
  968.     frmDBRestore.Free;
  969.   end;
  970. end;
  971.  
  972. procedure TfrmDBRestore.cbDBServerChange(Sender: TObject);
  973. var
  974.   s: string;
  975.   i: integer;
  976.   lCurrDatabaseAliasesNode: TTreeNode;
  977. begin
  978.   cbDBAlias.Items.Clear;
  979.   cbDBAlias.Text := '';
  980.  
  981.   if cbDBServer.ItemIndex <> -1 then
  982.   begin
  983.     lCurrDatabaseAliasesNode := frmMain.tvMain.Items.GetNode(TibcServerNode(cbDBServer.Items.Objects[cbDBServer.ItemIndex]).DatabasesID);
  984.  
  985.     if Assigned(lCurrDatabaseAliasesNode) then
  986.     begin
  987.       if TibcServerNode(lCurrDatabaseAliasesNode.Data).ObjectList.Count <> 0 then
  988.       begin
  989.         for i := 1 to TibcServerNode(lCurrDatabaseAliasesNode.Data).ObjectList.Count - 1 do
  990.         begin
  991.           s := TibcTreeNode(lCurrDatabaseAliasesNode.Data).ObjectList.Strings[i];
  992.           cbDBAlias.Items.AddObject(GetNextField(s, DEL),
  993.             TibcDatabaseNode(TTreeNode(TibcTreeNode(lCurrDatabaseAliasesNode.Data).ObjectList.Objects[i]).Data));
  994.         end;
  995.       end;
  996.     end;
  997.   end;
  998. end;
  999.  
  1000. procedure TfrmDBRestore.cbDBAliasChange(Sender: TObject);
  1001. var
  1002.   i: integer;
  1003.   lCurrDBNode: TTreeNode;
  1004.   lCurrServerNode: TTreeNode;
  1005.   lCurrLine: string;
  1006. begin
  1007.   for i := 1 to sgDatabaseFiles.RowCount do
  1008.   begin
  1009.     sgDatabaseFiles.Cells[0,i] := '';
  1010.     sgDatabaseFiles.Cells[1,i] := '';
  1011.   end;
  1012.  
  1013.   if (cbDBAlias.ItemIndex > -1) and (Assigned(cbDBAlias.Items.Objects[cbDBAlias.ItemIndex])) then
  1014.     lCurrDBNode := frmMain.tvMain.Items.GetNode(TibcDatabaseNode(cbDBAlias.Items.Objects[cbDBAlias.ItemIndex]).NodeID)
  1015.   else
  1016.     lCurrDBNode := nil;
  1017.  
  1018.   if (cbDBAlias.ItemIndex > -1) and (Assigned(cbDBServer.Items.Objects[cbDBServer.ItemIndex])) then
  1019.     lCurrServerNode := frmMain.tvMain.Items.GetNode(TibcServerNode(cbDBServer.Items.Objects[cbDBServer.ItemIndex]).NodeID)
  1020.   else
  1021.     lCurrServerNode := nil;
  1022.  
  1023.   if Assigned(lCurrDBNode) and Assigned(lCurrServerNode) then
  1024.   begin
  1025.  
  1026.     for i := 1 to TibcDatabaseNode(lCurrDBNode.Data).DatabaseFiles.Count do
  1027.     begin
  1028.       lCurrLine := TibcDatabaseNode(lCurrDBNode.Data).DatabaseFiles.Strings[i - 1];
  1029.       while Length(lCurrLine) > 0 do
  1030.       begin
  1031.         sgDatabaseFiles.Cells[0,i] := zluUtility.GetNextField(lCurrLine,'=');
  1032.         sgDatabaseFiles.Cells[1,i] := zluUtility.GetNextField(lCurrLine,'=');
  1033.       end;
  1034.       sgDatabaseFiles.RowCount := sgDatabaseFiles.RowCount + 1;
  1035.     end;
  1036.   end;
  1037. end;
  1038.  
  1039. procedure TfrmDBRestore.cbBackupAliasChange(Sender: TObject);
  1040. var
  1041.   i: integer;
  1042.   lCurrBackupAliasNode: TTreeNode;
  1043.   lCurrLine: string;
  1044.   GridOptions: set of TGridOption;
  1045.   OpenDlg: TOpenDialog;
  1046. begin
  1047.  
  1048.   with cbBackupAlias do begin
  1049.     with sgBackupFiles do begin
  1050.       RowCount := 4;
  1051.       for i := 1 to RowCount do
  1052.       begin
  1053.         Cells[0,i] := '';
  1054.         Cells[1,i] := '';
  1055.       end;
  1056.  
  1057.       if ItemIndex = 0 then
  1058.         begin
  1059.         // Allow the user to select files for backup
  1060.         OnDrawCell := sgDatabaseFilesDrawCell;
  1061.         OnKeyDown := sgDatabaseFilesKeyDown;
  1062.         Color := clWindow;
  1063.         GridOptions := Options;
  1064.         Include (GridOptions, goEditing);
  1065.         Options := GridOptions;
  1066.         sgBackupFiles.SetFocus;
  1067.  
  1068.         // If the server is local, allow the user to browse for a file
  1069.         if FSourceServerNode.Server.Protocol = Local then
  1070.         begin
  1071.           OpenDlg := TOpenDialog.Create(Self);
  1072.           with OpenDlg do
  1073.           begin
  1074.             Options := [ofAllowMultiSelect, ofFileMustExist];
  1075.             Filter := 'Backup files (*.gbk)|*.gbk|All files (*.*)|*.*';
  1076.             FilterIndex := 1;
  1077.             if Execute then
  1078.             begin
  1079.               if RowCount < Files.Count then
  1080.                 RowCount := Files.Count;
  1081.  
  1082.               for i:= 0 to Files.Count - 1 do
  1083.                 Cells[0, i+1] := Files.Strings[i];
  1084.             end;
  1085.             Free;
  1086.           end;
  1087.         end;
  1088.       end
  1089.       else begin  // Read the alias for backup information
  1090.         if (ItemIndex > 0) and (Assigned(Items.Objects[ItemIndex])) then
  1091.         begin
  1092.           GridOptions := Options;
  1093.           Exclude (GridOptions, goEditing);
  1094.           Options := GridOptions;
  1095.           OnDrawCell := nil;
  1096.           OnKeyDown := nil;
  1097.           Color := clbtnFace;
  1098.           Row := 1;
  1099.           lCurrBackupAliasNode := frmMain.tvMain.Items.GetNode(TibcBackupAliasNode(Items.Objects[ItemIndex]).NodeID);
  1100.           for i := 1 to TibcBackupAliasNode(lCurrBackupAliasNode.Data).BackupFiles.Count do
  1101.           begin
  1102.             lCurrLine := TibcBackupAliasNode(lCurrBackupAliasNode.Data).BackupFiles.Strings[i-1];
  1103.             while Length(lCurrLine) > 0 do
  1104.             begin
  1105.               Cells[0,i] := zluUtility.GetNextField(lCurrLine,'=');
  1106.               Cells[1,i] := zluUtility.GetNextField(lCurrLine,'=');
  1107.             end;
  1108.             RowCount := RowCount + 1;
  1109.           end;
  1110.           cbDBServer.ItemIndex := cbDBServer.Items.IndexOf(TibcBackupAliasNode(lCurrBackupAliasNode.Data).SourceDBServer);
  1111.           cbDBServerChange(self);
  1112.           cbDBAlias.ItemIndex := cbDBAlias.Items.IndexOf(TibcBackupAliasNode(lCurrBackupAliasNode.Data).SourceDBAlias);
  1113.           cbDBAliasChange(self);
  1114.         end;
  1115.       end;
  1116.     end;
  1117.   end;
  1118. end;
  1119.  
  1120. function TfrmDBRestore.FormHelp(Command: Word; Data: Integer;
  1121.   var CallHelp: Boolean): Boolean;
  1122. begin
  1123.   CallHelp := False;
  1124.   Result := WinHelp(WindowHandle,CONTEXT_HELP_FILE,HELP_CONTEXT,DATABASE_RESTORE);
  1125. end;
  1126.  
  1127. procedure TfrmDBRestore.WMNCLButtonDown( var Message: TWMNCLButtonDown );
  1128. var
  1129.   ScreenPt: TPoint;
  1130.   ClientPt: TPoint;
  1131. begin
  1132.   ScreenPt.X := Message.XCursor;
  1133.   ScreenPt.Y := Message.YCursor;
  1134.   ClientPt := ScreenToClient( ScreenPt );
  1135.   if( ClientPt.X > Width-45 )and (ClientPt.X < Width-29) then
  1136.    begin
  1137.     WinHelp(WindowHandle,CONTEXT_HELP_FILE,HELP_CONTEXT,DATABASE_RESTORE);
  1138.     Message.Result := 0;
  1139.   end else
  1140.    inherited;
  1141. end;
  1142.  
  1143. procedure TfrmDBRestore.IncreaseRows(Sender: TObject; ACol,
  1144.   ARow: Integer; var CanSelect: Boolean);
  1145. begin
  1146.   with Sender as TStringGrid do begin
  1147.     if ARow = RowCount-1 then
  1148.       RowCount := RowCount + 1;
  1149.   end;
  1150. end;
  1151.  
  1152. end.
  1153.