home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 October / PCWorld_2000-10_cd2.bin / Borland / interbase / IBConsole_src.ZIP / ibconsole / frmuDBCreate.pas < prev    next >
Pascal/Delphi Source File  |  2000-07-24  |  31KB  |  896 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 C r e a t e
  23. *
  24. ****************************************************************
  25. *  Author: The Client Server Factory Inc.
  26. *  Date:   March 1, 1999
  27. *
  28. *  Description:  This unit provides an interface to create a
  29. *                database consisting of a single or multiple
  30. *                files.
  31. *
  32. *****************************************************************
  33. * Revisions:
  34. *
  35. *****************************************************************}
  36.  
  37. unit frmuDBCreate;
  38.  
  39. interface
  40.  
  41. uses
  42.   SysUtils, Forms, ExtCtrls, StdCtrls, Classes, Controls, Dialogs,
  43.   zluibcClasses, Grids, Windows, Graphics, IB, IBDatabase, IBServices, Messages,
  44.   frmuDlgClass;
  45.  
  46. type
  47.   TfrmDBCreate = class(TDialog)
  48.     lblServer: TLabel;
  49.     lblDBAlias: TLabel;
  50.     stxServer: TStaticText;
  51.     edtDBAlias: TEdit;
  52.     lblDatabaseFiles: TLabel;
  53.     sgDatabaseFiles: TStringGrid;
  54.     lblOptions: TLabel;
  55.     sgOptions: TStringGrid;
  56.     btnOK: TButton;
  57.     btnCancel: TButton;
  58.     cbOptions: TComboBox;
  59.     pnlOptionName: TPanel;
  60.     function FormHelp(Command: Word; Data: Integer; var CallHelp: Boolean): Boolean;
  61.     procedure FormCreate(Sender: TObject);
  62.     procedure btnCancelClick(Sender: TObject);
  63.     procedure btnOKClick(Sender: TObject);
  64.     procedure cbOptionsChange(Sender: TObject);
  65.     procedure cbOptionsExit(Sender: TObject);
  66.     procedure sgDatabaseFilesDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
  67.     procedure sgDatabaseFilesKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  68.     procedure sgDatabaseFilesSelectCell(Sender: TObject; ACol,ARow: Integer; var CanSelect: Boolean);
  69.     procedure sgOptionsDblClick(Sender: TObject);
  70.     procedure sgOptionsDrawCell(Sender: TObject; ACol, ARow: Integer;Rect: TRect; State: TGridDrawState);
  71.     procedure sgOptionsSelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
  72.     procedure cbOptionsDblClick(Sender: TObject);
  73.     procedure edtDBAliasChange(Sender: TObject);
  74.     procedure cbOptionsKeyDown(Sender: TObject; var Key: Word;
  75.       Shift: TShiftState);
  76.   private
  77.     { Private declarations }
  78.     function VerifyInputData(): boolean;
  79.     procedure WMNCLButtonDown( var Message: TWMNCLBUTTONDOWN ); message WM_NCLBUTTONDOWN ;
  80.   public
  81.     { Public declarations }
  82.     FCurrSelServer: TIbcServerNode;
  83.   end;
  84.  
  85. function CreateDB(var DBAlias: string; var DatabaseFiles: TStringList; const SelServerNode: TibcServerNode): integer;
  86.  
  87. implementation
  88.  
  89. uses zluGlobal,frmuMessage, zluContextHelp, zluUtility, Registry;
  90.  
  91. {$R *.DFM}
  92.  
  93. const
  94.   OPTION_NAME_COL = 0;            // option name column position
  95.   OPTION_VALUE_COL = 1;           // option value column position
  96.   PAGE_SIZE_ROW = 0;              // page size row position
  97.   DEFAULT_CHARSET_ROW = 1;        // char set row position
  98.   SQL_DIALECT_ROW = 2;
  99.   MIN_PRIMARY_FILE_SIZE = 230;    // min page size for primary file
  100.   MIN_SECONDARY_FILE_SIZE = 2;    // min page size for secondary files
  101.  
  102. {****************************************************************
  103. *
  104. *  C r e a t e D B ( )
  105. *
  106. ****************************************************************
  107. *  Author: The Client Server Factory Inc.
  108. *  Date:   March 1, 1999
  109. *
  110. *  Input:  TibcServerNode - specifies the currently selected
  111. *                           server
  112. *
  113. *  Return: Integer - indicates a success or failure during the
  114. *                    create database task
  115. *
  116. *  Description: This procedure performs the task of creating
  117. *               the database.
  118. *
  119. *****************************************************************
  120. * Revisions:
  121. *
  122. *****************************************************************}
  123.  
  124. function CreateDB(var DBAlias: string; var DatabaseFiles: TStringList; const SelServerNode: TibcServerNode): integer;
  125. var
  126.   frmDBCreate: TfrmDBCreate;          // create DB form
  127.   lDatabase: TIBDatabase;             // temp database object
  128.   iRow: Integer;                      // row counter for database string grid
  129.   lStr: String;                       // string value for starting page
  130. begin
  131.   frmDBCreate := TfrmDBCreate.Create(Application);
  132.   try
  133.     lDatabase := TIBDatabase.Create(Nil); // create database object
  134.                                           // set server name in form
  135.     frmDBCreate.stxServer.Caption := SelServerNode.Servername;
  136.     frmDBCreate.FCurrSelServer := SelServerNode;
  137.     frmDBCreate.ShowModal;                // show form as modal dialog
  138.     if frmDBCreate.ModalResult = mrOK then
  139.     begin
  140.       // of OK button is pressed and all data has been validated
  141.       // start setting create database parameters
  142.       // set the first database filename
  143.       case SelServerNode.Server.Protocol of
  144.         TCP: lDatabase.DatabaseName := Format('%s:%s',[SelServerNode.ServerName, frmDBCreate.sgDatabaseFiles.Cells[0,1]]);
  145.         NamedPipe: lDatabase.DatabaseName := Format('\\%s\%s',[SelServerNode.ServerName, frmDBCreate.sgDatabaseFiles.Cells[0,1]]);
  146.         SPX: lDatabase.DatabaseName := Format('%s@%s',[SelServerNode.ServerName, frmDBCreate.sgDatabaseFiles.Cells[0,1]]);
  147.         Local: lDatabase.DatabaseName := frmDBCreate.sgDatabaseFiles.Cells[0,1];
  148.       end;
  149.       DatabaseFiles.Add(frmDBCreate.sgDatabaseFiles.Cells[0,1]);
  150.  
  151.       // supply login info for the current server
  152.       lDatabase.Params.Add(Format('user ''%s''',[SelServerNode.UserName]));
  153.       lDatabase.Params.Add(Format('password ''%s''',[SelServerNode.Password]));
  154.  
  155.       // set page size
  156.       if frmDBCreate.sgOptions.Cells[1,0] <> '' then
  157.         lDatabase.Params.Add(Format('page_size %s',[frmDBCreate.sgOptions.Cells[1,0]]));
  158.  
  159.       // set default character set
  160.       if frmDBCreate.sgOptions.Cells[1,DEFAULT_CHARSET_ROW] <> 'None' then
  161.         lDatabase.Params.Add(Format('default character set %s',[frmDBCreate.sgOptions.Cells[1,1]]));
  162.  
  163.       // if more than 1 filename has been supplied then this is a
  164.       // multifile database
  165.       if frmDBCreate.sgDatabaseFiles.Cells[0,2] <> '' then
  166.       begin
  167.         // set length of first database file (in pages)
  168.         if frmDBCreate.sgDatabaseFiles.Cells[1,1] <> '' then
  169.           lDatabase.Params.Add(Format('length %s', [frmDBCreate.sgDatabaseFiles.Cells[1,1]]));
  170.  
  171.         iRow:=2;                       // begin looping through rows starting from third row
  172.         while (iRow < frmDBCreate.sgDatabaseFiles.RowCount) and
  173.           (frmDBCreate.sgDatabaseFiles.Cells[0,iRow] <> '') do
  174.         begin
  175.           // set secondary filename
  176.           lDatabase.Params.Add(Format('file ''%s''', [frmDBCreate.sgDatabaseFIles.Cells[0,iRow]]));
  177.           DatabaseFiles.Add(frmDBCreate.sgDatabaseFiles.Cells[0,iRow]);
  178.  
  179.           // set length of file (in pages)
  180.           if frmDBCreate.sgDatabaseFIles.Cells[1,iRow] <> '' then
  181.             lDatabase.Params.Add(Format('length %s', [frmDBCreate.sgDatabaseFiles.Cells[1,iRow]]));
  182.  
  183.           // set starting page (length of last file + 1)
  184.           lStr:=IntToStr(StrToInt(frmDBCreate.sgDatabaseFiles.Cells[1,iRow - 1]) + 1);
  185.           lDatabase.Params.Add(Format('starting %s', [lStr]));
  186.  
  187.           Inc(iRow);                   // increment row count
  188.         end;  // of loop through rows
  189.       end;  // of multifile check
  190.  
  191.       lDatabase.SQLDialect := StrToInt(frmDBCreate.sgOptions.Cells[1,SQL_DIALECT_ROW]);
  192.  
  193.       lDatabase.CreateDatabase;        // create database
  194.       lDatabase.Connected:=False;      // disconnect from database
  195.       DBAlias := frmDBCreate.edtDBAlias.text;
  196.       result := SUCCESS;               // set result as success
  197.     end
  198.     else                               // if OK button is pressed and data is bad or Cancel
  199.       result := FAILURE;               // button is pressed then set result as failure
  200.   finally
  201.     // deallocate memory
  202.     frmDBCreate.Free;
  203.   end;
  204. end;
  205.  
  206. procedure TfrmDBCreate.btnCancelClick(Sender: TObject);
  207. begin
  208.   ModalResult := mrCancel;
  209. end;
  210.  
  211. {****************************************************************
  212. *
  213. *  V e r i f y I n p u t D a t a ( )
  214. *
  215. ****************************************************************
  216. *  Author: The Client Server Factory Inc.
  217. *  Date:   March 1, 1999
  218. *
  219. *  Input:  None
  220. *
  221. *  Return: Boolean - inidicates whether or not all data is valid
  222. *
  223. *
  224. *  Description: This function performs the task of validating
  225. *               the data entered in the database files string
  226. *               grid and show the appropriate error message
  227. *               when needed.
  228. *
  229. *****************************************************************
  230. * Revisions:
  231. *
  232. *****************************************************************}
  233.  
  234. function TfrmDBCreate.VerifyInputData(): boolean;
  235. var
  236.   x, y      : Integer;                 // row and column counters
  237.   iMax      : Integer;                 // max row
  238.   iPageSize : Integer;                 // integer page size
  239.   lGridRect : TGridRect;               // current gridregion being validated
  240.   lRegistry : TRegistry;
  241. begin
  242.   result := true;                      // assume all data is valid
  243.  
  244.   // check if a database alias was specified
  245.   if (edtDBAlias.Text = '') or (edtDBAlias.Text = ' ') then
  246.   begin
  247.     DisplayMsg(ERR_DB_ALIAS,'');
  248.     edtDBAlias.SetFocus;
  249.     result := false;
  250.     Exit;
  251.   end;
  252.  
  253.   lRegistry := TRegistry.Create;
  254.   if lRegistry.KeyExists(Format('%s%s\Databases\%s',[gRegServersKey,FCurrSelServer.Nodename,edtDBAlias.Text])) then
  255.   begin                                // show error message
  256.     DisplayMsg(ERR_DB_ALIAS,'This database alias already exists.');
  257.     edtDBAlias.SetFocus;               // give focus to control
  258.     result := false;
  259.     lRegistry.Free;
  260.     Exit;
  261.   end;
  262.   lRegistry.Free;
  263.   
  264.   // determine the maximum number of rows that have been used
  265.   iMax:=1;
  266.   while (iMax < sgDatabaseFiles.RowCount - 1) and
  267.     (sgDatabaseFiles.Cells[0,iMax] <> '') and
  268.     (sgDatabaseFiles.Cells[1,iMax] <> '') do
  269.   begin
  270.     if not (IsValidDBName(sgDatabaseFiles.Cells[0,iMax])) then
  271.        DisplayMsg(WAR_REMOTE_FILENAME, Format('File: %s', [sgDatabaseFiles.Cells[0,iMax]]));
  272.     Inc(iMax);
  273.   end;
  274.  
  275.   // loop through every field in grid until the maximum row has been reached
  276.   for y:=1 to iMax - 1 do              // loop through rows
  277.   begin                                // loop through columns
  278.     for x:=0 to sgDatabaseFiles.ColCount - 1 do
  279.     begin
  280.       lGridRect.Left:=x;               // set current grid region
  281.       lGridRect.Top:=y;
  282.       lGridRect.Right:=x;
  283.       lGridRect.Bottom:=y;
  284.  
  285.       // if the current field is empty and it is not the last line
  286.       if ((sgDatabaseFiles.Cells[x,y] = '') or (sgDatabaseFiles.Cells[x,y] = ' ')) and
  287.         ((sgDatabaseFiles.Cells[0,y+1] <> '') and (sgDatabaseFiles.Cells[1,y+1] <> '')) then
  288.       begin
  289.         case x of
  290.           0 : DisplayMsg(ERR_DB_FILE,'');   // show the appropriate error message
  291.           1 : DisplayMsg(ERR_DB_SIZE,'');   // corresponding to the field that is blank
  292.         end;
  293.         sgDatabaseFiles.SetFocus;      // give focus to string grid and select the erring field
  294.         sgDatabaseFiles.Selection:=lGridRect;
  295.         result := false;               // set result to false
  296.         exit;
  297.       end
  298.       else   // if this is the last line check for a valid filename -
  299.       begin  // last file does not need a value for the filesize
  300.         if (sgDatabaseFiles.Cells[x,y] = '') or (sgDatabaseFiles.Cells[x,y] = ' ') then
  301.         begin
  302.           case x of
  303.             0 : DisplayMsg(ERR_DB_FILE,'');   // show the appropriate error message
  304.             1 : DisplayMsg(ERR_DB_SIZE,'');   // corresponding to the field that is blank
  305.           end;
  306.           sgDatabaseFiles.SetFocus;      // give focus to string grid and select the erring field
  307.           sgDatabaseFiles.Selection:=lGridRect;
  308.           result := false;               // set result to false
  309.           exit;
  310.         end;
  311.       end;
  312.  
  313.       // must check to see if all sizes are numeric and exceed minimum values
  314.       // if the current column is size column and this is not a blank line
  315.       if (x = 1) and (sgDatabaseFiles.Cells[0,y] <> '') and (sgDatabaseFIles.Cells[1,y] <> '') then
  316.       begin
  317.         try                            // then convert string to integer
  318.           iPageSize:=StrToInt(sgDatabaseFiles.Cells[x,y]);
  319.  
  320.           // check file size of primary file
  321.           if (y = 1) and (iPageSize < MIN_PRIMARY_FILE_SIZE) then
  322.           begin
  323.             DisplayMsg(ERR_DB_SIZE,'Minimum page size for primary file is 230 pages.');
  324.             sgDatabaseFiles.SetFocus;  // give focus to string grid and select the erring field
  325.             sgDatabaseFiles.Selection:=lGridRect;
  326.             result := false;           // set result to false
  327.             exit;
  328.           end;
  329.  
  330.           // check file size of secondary files
  331.           if (y <> 1) and (iPageSize < MIN_SECONDARY_FILE_SIZE) then
  332.           begin
  333.             DisplayMsg(ERR_DB_SIZE,'Minimum page size for secondary files is 2 pages.');
  334.             sgDatabaseFiles.SetFocus;  // give focus to string grid and select the erring field
  335.             sgDatabaseFiles.Selection:=lGridRect;
  336.             result := false;           // set result to false
  337.             exit;
  338.           end;
  339.         except on EConvertError do     // if an error occurs ten
  340.           begin                        // display error message
  341.             DisplayMsg(ERR_NUMERIC_VALUE,'');
  342.             sgDatabaseFiles.SetFocus;  // give focus to string grid and select the erring field
  343.             sgDatabaseFiles.Selection:=lGridRect;
  344.             result := false;           // set result to false
  345.             exit;
  346.           end;  // of exception
  347.         end;  // of try except block
  348.       end;  // of column and blank line check
  349.     end;  // of column loop
  350.   end;  // of row loop
  351. end;
  352.  
  353. procedure TfrmDBCreate.btnOKClick(Sender: TObject);
  354. begin
  355.   if VerifyInputData() then
  356.     ModalResult := mrOK;
  357. end;
  358.  
  359. {****************************************************************
  360. *
  361. *  F o r m C r e a t e
  362. *
  363. ****************************************************************
  364. *  Author: The Client Server Factory Inc.
  365. *  Date:   March 1, 1999
  366. *
  367. *  Input:  TObject - object that initiated the event
  368. *
  369. *  Return: None
  370. *
  371. *
  372. *  Description: This procedure is triggered when the form is
  373. *               created.  It is responsible for populating the
  374. *               string grids with default values.
  375. *
  376. *****************************************************************
  377. * Revisions:
  378. *
  379. *****************************************************************}
  380.  
  381. procedure TfrmDBCreate.FormCreate(Sender: TObject);
  382. begin
  383.   inherited;
  384.   sgOptions.DefaultRowHeight := cbOptions.Height;
  385.   cbOptions.Visible := True;
  386.   pnlOptionName.Visible := True;
  387.  
  388.   sgDatabaseFiles.Cells[0,0] := 'Filename(s)';
  389.   sgDatabaseFiles.Cells[1,0] := 'Size (Pages)';
  390.  
  391.   sgOptions.Cells[OPTION_NAME_COL,PAGE_SIZE_ROW] := 'Page Size';
  392.   sgOptions.Cells[OPTION_VALUE_COL,PAGE_SIZE_ROW] := '1024';
  393.  
  394.   sgOptions.Cells[OPTION_NAME_COL,DEFAULT_CHARSET_ROW] := 'Default Character Set';
  395.   sgOptions.Cells[OPTION_VALUE_COL,DEFAULT_CHARSET_ROW] := 'None';
  396.  
  397.   sgOptions.Cells[OPTION_NAME_COL,SQL_DIALECT_ROW] := 'SQL Dialect';
  398.   sgOptions.Cells[OPTION_VALUE_COL,SQL_DIALECT_ROW] := '3';
  399.  
  400.   pnlOptionName.Caption := 'Page Size';
  401.   cbOptions.Items.Add('1024');
  402.   cbOptions.Items.Add('2048');
  403.   cbOptions.Items.Add('4096');
  404.   cbOptions.Items.Add('8192');
  405.   cbOptions.ItemIndex := 2;
  406. end;
  407.  
  408. procedure TfrmDBCreate.cbOptionsChange(Sender: TObject);
  409. begin
  410.   {
  411.   if cbOptions.Style=csDropDownList then
  412.   begin
  413.     sgOptions.Cells[sgOptions.Col,sgOptions.Row] :=
  414.       cbOptions.Items[cbOptions.ItemIndex];
  415.     cbOptions.Visible := false;
  416.     sgOptions.SetFocus;
  417.   end
  418.   else
  419.   begin
  420.     sgOptions.Cells[sgOptions.Col,sgOptions.Row] :=
  421.       cbOptions.Text;
  422.   end;
  423.   }
  424. end;
  425.  
  426. procedure TfrmDBCreate.cbOptionsExit(Sender: TObject);
  427. var
  428.   lR     : TRect;
  429.   iIndex : Integer;
  430. begin
  431.   iIndex := cbOptions.Items.IndexOf(cbOptions.Text);
  432.  
  433.   if (iIndex = -1) then
  434.   begin
  435.     MessageDlg('Invalid option value', mtError, [mbOK], 0);
  436.  
  437.     cbOptions.ItemIndex := 0;
  438.     // Size and position the combo box to fit the cell
  439.     lR := sgOptions.CellRect(OPTION_VALUE_COL, sgOptions.Row);
  440.     lR.Left := lR.Left + sgOptions.Left;
  441.     lR.Right := lR.Right + sgOptions.Left;
  442.     lR.Top := lR.Top + sgOptions.Top;
  443.     lR.Bottom := lR.Bottom + sgOptions.Top;
  444.     cbOptions.Left := lR.Left + 1;
  445.     cbOptions.Top := lR.Top + 1;
  446.     cbOptions.Width := (lR.Right + 1) - lR.Left;
  447.     cbOptions.Height := (lR.Bottom + 1) - lR.Top;
  448.     cbOptions.Visible := True;
  449.     cbOptions.SetFocus;
  450.   end
  451.   else if (sgOptions.Col <> OPTION_NAME_COL) then
  452.   begin
  453.     sgOptions.Cells[sgOptions.Col,sgOptions.Row] := cbOptions.Items[iIndex];
  454.   end
  455.   else
  456.   begin
  457.     sgOptions.Cells[OPTION_VALUE_COL,sgOptions.Row] := cbOptions.Items[iIndex];
  458.   end;
  459. end;
  460.  
  461. {****************************************************************
  462. *
  463. *  s g O p t i o n s S e l e c t C e l l
  464. *
  465. ****************************************************************
  466. *  Author: The Client Server Factory Inc.
  467. *  Date:   March 1, 1999
  468. *
  469. *  Input:  TObject - object that initiated the event
  470. *          Integer - currently selected column
  471. *          Integer - currently selected row
  472. *          Boolean - inidicates whether or not the grid may
  473. 8                    selected
  474. *
  475. *  Return: None
  476. *
  477. *
  478. *  Description: This procedure determines whether or not the
  479. *               currently selected cell may be selected in the
  480. *               Options string grid.  it then shows the combo
  481. *               box and populates it
  482. *               with the appropriate values.
  483. *
  484. *****************************************************************
  485. * Revisions:
  486. *
  487. *****************************************************************}
  488.  
  489. procedure TfrmDBCreate.sgOptionsSelectCell(Sender: TObject; ACol,
  490.   ARow: Integer; var CanSelect: Boolean);
  491. var
  492.   lR,lName : TRect;
  493. begin
  494.   cbOptions.Items.Clear;               // clear items in combo box
  495.   case ARow of                         // determine which row is being selected
  496.     PAGE_SIZE_ROW:                     // if the page size is selected
  497.     begin                              // populate the combo with
  498.       cbOptions.Items.Add('1024');
  499.       cbOptions.Items.Add('2048');
  500.       cbOptions.Items.Add('4096');
  501.       cbOptions.Items.Add('8192');
  502.     end;
  503.     DEFAULT_CHARSET_ROW:               // if the default charset row is being selected
  504.     begin                              // populate the combo with
  505.       with cbOptions.Items do
  506.       begin
  507.         Add('ASCII');
  508.         Add('BIG_5');
  509.         Add('CYRL');
  510.         Add('DOS437');
  511.         Add('DOS850');
  512.         Add('DOS852');
  513.         Add('DOS857');
  514.         Add('DOS860');
  515.         Add('DOS861');
  516.         Add('DOS863');
  517.         Add('DOS865');
  518.         Add('EUCJ_0208');
  519.         Add('GB_2312');
  520.         Add('ISO8859_1');
  521.         Add('KSC_5601');
  522.         Add('NEXT');
  523.         Add('None');
  524.         Add('OCTETS');
  525.         Add('SJIS_0208');
  526.         Add('UNICODE_FSS');
  527.         Add('WIN1250');
  528.         Add('WIN1251');
  529.         Add('WIN1252');
  530.         Add('WIN1253');
  531.         Add('WIN1254');
  532.       end;
  533.     end;
  534.     SQL_DIALECT_ROW:
  535.     begin
  536.       cbOptions.Items.Add('1');
  537.       cbOptions.Items.Add('3');
  538.     end;
  539.   end;
  540.  
  541.   pnlOptionName.Caption := sgOptions.Cells[OPTION_NAME_COL, ARow];
  542.  
  543.   if ACol = OPTION_NAME_COL then       // copy selected combo item to proper grid location
  544.     cbOptions.ItemIndex := cbOptions.Items.IndexOf(sgOptions.Cells[ACol+1,ARow])
  545.   else if ACol = OPTION_VALUE_COL then
  546.     cbOptions.ItemIndex := cbOptions.Items.IndexOf(sgOptions.Cells[ACol,ARow]);
  547.  
  548.   if ACol = OPTION_NAME_COL then
  549.   begin
  550.     lName := sgOptions.CellRect(ACol, ARow);
  551.     lR := sgOptions.CellRect(ACol + 1, ARow);
  552.   end
  553.   else
  554.   begin
  555.     lName := sgOptions.CellRect(ACol - 1, ARow);
  556.     lR := sgOptions.CellRect(ACol, ARow);
  557.   end;
  558.  
  559.   // lName := sgOptions.CellRect(ACol, ARow);
  560.   lName.Left := lName.Left + sgOptions.Left;
  561.   lName.Right := lName.Right + sgOptions.Left;
  562.   lName.Top := lName.Top + sgOptions.Top;
  563.   lName.Bottom := lName.Bottom + sgOptions.Top;
  564.   pnlOptionName.Left := lName.Left + 1;
  565.   pnlOptionName.Top := lName.Top + 1;
  566.   pnlOptionName.Width := (lName.Right + 1) - lName.Left;
  567.   pnlOptionName.Height := (lName.Bottom + 1) - lName.Top;
  568.   pnlOptionName.Visible := True;
  569.  
  570.   // lR := sgOptions.CellRect(ACol, ARow);
  571.   lR.Left := lR.Left + sgOptions.Left;
  572.   lR.Right := lR.Right + sgOptions.Left;
  573.   lR.Top := lR.Top + sgOptions.Top;
  574.   lR.Bottom := lR.Bottom + sgOptions.Top;
  575.   cbOptions.Left := lR.Left + 1;
  576.   cbOptions.Top := lR.Top + 1;
  577.   cbOptions.Width := (lR.Right + 1) - lR.Left;
  578.   cbOptions.Height := (lR.Bottom + 1) - lR.Top;
  579.   cbOptions.Visible := True;
  580.   cbOptions.SetFocus;
  581. end;
  582.  
  583. {****************************************************************
  584. *
  585. *  s g O p t i o n s D b l C l i c k
  586. *
  587. ****************************************************************
  588. *  Author: The Client Server Factory Inc.
  589. *  Date:   March 1, 1999
  590. *
  591. *  Input:  TObject - object that initiated the event
  592. *
  593. *  Return: None
  594. *
  595. *
  596. *  Description: This procedure rotates through a list of values
  597. *               when the option name or value is double-clicked.
  598. *
  599. *****************************************************************
  600. * Revisions:
  601. *
  602. *****************************************************************}
  603.  
  604. procedure TfrmDBCreate.sgOptionsDblClick(Sender: TObject);
  605. begin
  606.   {
  607.   // if the option value column is selected
  608.   if sgOptions.Col = OPTION_VALUE_COL then
  609.   begin
  610.     // cycle through items
  611.     if cbOptions.ItemIndex = cbOptions.Items.Count - 1 then
  612.       cbOptions.ItemIndex := 0
  613.     else
  614.       cbOptions.ItemIndex := cbOptions.ItemIndex + 1;
  615.  
  616.     sgOptions.Cells[sgOptions.Col,sgOptions.Row] :=
  617.       cbOptions.Items[cbOptions.ItemIndex];
  618.     cbOptions.Visible := false;
  619.     sgOptions.SetFocus;
  620.   end;
  621.   // if the option name column is selected
  622.   else  if (sgOptions.Col = OPTION_NAME_COL) and
  623.     (sgOptions.Row >= PAGE_SIZE_ROW) and (sgOptions.Row <= DEFAULT_CHARSET_ROW) then
  624.   begin
  625.     // cycle through items
  626.     if cbOptions.ItemIndex = cbOptions.Items.Count - 1 then
  627.       cbOptions.ItemIndex := 0
  628.     else
  629.       cbOptions.ItemIndex := cbOptions.ItemIndex + 1;
  630.  
  631.     sgOptions.Cells[sgOptions.Col + 1,sgOptions.Row] :=
  632.       cbOptions.Items[cbOptions.ItemIndex];
  633.     cbOptions.Visible := false;
  634.     sgOptions.SetFocus;
  635.   end;
  636.   }
  637. end;
  638.  
  639. {****************************************************************
  640. *
  641. *  s g O p t i o n s D r a w C e l l
  642. *
  643. ****************************************************************
  644. *  Author: The Client Server Factory Inc.
  645. *  Date:   March 1, 1999
  646. *
  647. *  Input:  TObject - object that initiated the event
  648. *          Integer - currently selected column
  649. *          Integer - currently selected row
  650. *          TRect   - coordinates
  651. *          TGridDrawState - drawing state of grid
  652. *
  653. *  Return: None
  654. *
  655. *
  656. *  Description: This procedure draws contents to a specified cell in
  657. *               the options string grid.
  658. *
  659. *****************************************************************
  660. * Revisions:
  661. *
  662. *****************************************************************}
  663.  
  664. procedure TfrmDBCreate.sgOptionsDrawCell(Sender: TObject; ACol,
  665.   ARow: Integer; Rect: TRect; State: TGridDrawState);
  666. const
  667.   INDENT = 2;
  668. var
  669.   lLeft: integer;
  670.   lText: string;
  671. begin
  672.   with sgOptions.canvas do
  673.   begin
  674.     if ACol = OPTION_VALUE_COL then
  675.     begin
  676.       font.color := clBlue;
  677.       if brush.color = clHighlight then
  678.         font.color := clWhite;
  679.       lText := sgOptions.Cells[ACol,ARow];
  680.       lLeft := Rect.Left + INDENT;
  681.       TextRect(Rect, lLeft, Rect.top + INDENT, lText);
  682.     end;
  683.   end;
  684. end;
  685.  
  686. {****************************************************************
  687. *
  688. *  s g D a t a b a s e F i l e s S e l e c t C e l l
  689. *
  690. ****************************************************************
  691. *  Author: The Client Server Factory Inc.
  692. *  Date:   March 1, 1999
  693. *
  694. *  Input:  TObject - object that initiated the event
  695. *          Integer - currently selected column
  696. *          Integer - currently selected row
  697. *          Boolean - inidicates whether or not the grid may
  698. 8                    selected
  699. *
  700. *  Return: None
  701. *
  702. *
  703. *  Description: This procedure determines whether or not the
  704. *               currently selected cell may be selected in the
  705. *               database string grid.  it then shows the combo
  706. *               box and populates it
  707. *               with the appropriate values.
  708. *
  709. *****************************************************************
  710. * Revisions:
  711. *
  712. *****************************************************************}
  713.  
  714. procedure TfrmDBCreate.sgDatabaseFilesSelectCell(Sender: TObject; ACol,
  715.   ARow: Integer; var CanSelect: Boolean);
  716. begin
  717.   // the first cell in the grid (top left) is always selectable
  718.   if (ACol = 0) and (ARow = 1) then
  719.   begin
  720.     CanSelect:=True;
  721.   end
  722.  
  723.   // cell is selectable if previous column is populated
  724.   else if (ACol - 1 >= 0) and (sgDatabaseFiles.Cells[ACol-1,ARow] <> '') then
  725.   begin
  726.     CanSelect := True;
  727.   end
  728.  
  729.   // cell is selectable if last column in previous row is populated
  730.   else if (sgDatabaseFiles.Cells[1,ARow-1] <> '') and (ARow - 1 <> 0) and (ACol = 0) then
  731.   begin
  732.     CanSelect := True;
  733.   end
  734.  
  735.   // cell is not selectable if all other checks fail and current cell is empty
  736.   else if (sgDatabaseFiles.Cells[ACol,ARow] = '') then
  737.   begin
  738.     CanSelect := False;
  739.   end;
  740. end;
  741.  
  742. {****************************************************************
  743. *
  744. *  s g D a t a b a s e F i l e s D r a w C e l l
  745. *
  746. ****************************************************************
  747. *  Author: The Client Server Factory Inc.
  748. *  Date:   March 1, 1999
  749. *
  750. *  Input:  TObject - object that initiated the event
  751. *          Integer - currently selected column
  752. *          Integer - currently selected row
  753. *          TRect   - coordinates
  754. *          TGridDrawState - drawing state of grid
  755. *
  756. *  Return: None
  757. *
  758. *
  759. *  Description: This procedure draws contents to a specified cell in
  760. *               the database files string grid.
  761. *
  762. *****************************************************************
  763. * Revisions:
  764. *
  765. *****************************************************************}
  766.  
  767. procedure TfrmDBCreate.sgDatabaseFilesDrawCell(Sender: TObject; ACol,
  768.   ARow: Integer; Rect: TRect; State: TGridDrawState);
  769. const
  770.   INDENT = 2;
  771. var
  772.   lLeft: integer;
  773.   lText: string;
  774. begin
  775.   with sgDatabaseFiles.canvas do
  776.   begin
  777.     if (ACol = 2) and (ARow <> 0) then
  778.     begin
  779.       font.color := clBlack;
  780.       if brush.color = clHighlight then
  781.         font.color := clWhite;
  782.       lText := sgDatabaseFiles.Cells[ACol,ARow];
  783.       lLeft := Rect.Left + INDENT;
  784.       TextRect(Rect, lLeft, Rect.top + INDENT, lText);
  785.     end;
  786.   end;
  787. end;
  788.  
  789. {****************************************************************
  790. *
  791. *  s g D a t a b a s e F i l e s K e y D o w n
  792. *
  793. ****************************************************************
  794. *  Author: The Client Server Factory Inc.
  795. *  Date:   March 1, 1999
  796. *
  797. *  Input:  TObject - object that initiated the event
  798. *          Word    - key(s) being pressed
  799. *          TShiftState - state of alt, ctrl, shift, mouse btns
  800. *
  801. *  Return: None
  802. *
  803. *
  804. *  Description: This procedure enables users to navigate through
  805. *               the database files string grid using CTRL + TAB
  806. *               to advance through the grid.  If at end, a new
  807. *               row is created.
  808. *
  809. *****************************************************************
  810. * Revisions:
  811. *
  812. *****************************************************************}
  813.  
  814. procedure TfrmDBCreate.sgDatabaseFilesKeyDown(Sender: TObject;
  815.   var Key: Word; Shift: TShiftState);
  816. var
  817.   lKey : Word;
  818. begin
  819.   if (Key = VK_TAB) and (ssCtrl in Shift) then
  820.   begin
  821.     if sgDatabaseFiles.Col < sgDatabaseFiles.ColCount - 1 then
  822.     begin
  823.       sgDatabaseFiles.Col := sgDatabaseFiles.Col + 1;
  824.     end
  825.     else
  826.     begin
  827.       if sgDatabaseFiles.Row = sgDatabaseFiles.RowCount - 1 then
  828.         sgDatabaseFiles.RowCount := sgDatabaseFiles.RowCount + 1;
  829.       sgDatabaseFiles.Col := 0;
  830.       sgDatabaseFiles.Row := sgDatabaseFiles.Row + 1;
  831.     end;
  832.   end;
  833.  
  834.   if (Key = VK_RETURN) and
  835.     (sgDatabaseFiles.Cells[sgDatabaseFiles.Col,sgDatabaseFiles.Row] <> '') then
  836.   begin
  837.     lKey := VK_TAB;
  838.     sgDatabaseFilesKeyDown(Self, lKey, [ssCtrl]);
  839.   end;
  840.  
  841. end;
  842.  
  843. function TfrmDBCreate.FormHelp(Command: Word; Data: Integer;
  844.   var CallHelp: Boolean): Boolean;
  845. begin
  846.   CallHelp := False;
  847.   Result := WinHelp(WindowHandle,CONTEXT_HELP_FILE,HELP_CONTEXT,DATABASE_CREATE);
  848. end;
  849.  
  850. procedure TfrmDBCreate.cbOptionsDblClick(Sender: TObject);
  851. begin
  852.   if (sgOptions.Col = OPTION_VALUE_COL) or (sgOptions.Col = OPTION_NAME_COL) then
  853.   begin
  854.     if cbOptions.ItemIndex = cbOptions.Items.Count - 1 then
  855.       cbOptions.ItemIndex := 0
  856.     else
  857.       cbOptions.ItemIndex := cbOptions.ItemIndex + 1;
  858.  
  859.     if sgOptions.Col = OPTION_VALUE_COL then
  860.       sgOptions.Cells[sgOptions.Col,sgOptions.Row] := cbOptions.Items[cbOptions.ItemIndex];
  861.  
  862.     // cbOptions.Visible := True;
  863.     // sgOptions.SetFocus;
  864.   end;
  865. end;
  866.  
  867. procedure TfrmDBCreate.edtDBAliasChange(Sender: TObject);
  868. begin
  869.   edtDBAlias.Hint := edtDBAlias.Text;
  870. end;
  871.  
  872. procedure TfrmDBCreate.WMNCLButtonDown( var Message: TWMNCLButtonDown );
  873. var
  874.   ScreenPt: TPoint;
  875.   ClientPt: TPoint;
  876. begin
  877.   ScreenPt.X := Message.XCursor;
  878.   ScreenPt.Y := Message.YCursor;
  879.   ClientPt := ScreenToClient( ScreenPt );
  880.   if( ClientPt.X > Width-45 )and (ClientPt.X < Width-29) then
  881.    begin
  882.     WinHelp(WindowHandle,CONTEXT_HELP_FILE,HELP_CONTEXT,DATABASE_CREATE);
  883.     Message.Result := 0;
  884.   end else
  885.    inherited;
  886. end;
  887.  
  888. procedure TfrmDBCreate.cbOptionsKeyDown(Sender: TObject; var Key: Word;
  889.   Shift: TShiftState);
  890. begin
  891.   if (Key = VK_DOWN) then
  892.     cbOptions.DroppedDown := True;
  893. end;
  894.  
  895. end.
  896.