Recent

Author Topic: Click to select row using TStringGrid?  (Read 1984 times)

tearsfornations

  • New Member
  • *
  • Posts: 35
  • Jesus is worth talking about.
    • Lightning Bolt Quiz - How many Lightning Bolts do you deserve?
Click to select row using TStringGrid?
« on: June 11, 2023, 06:14:09 am »
I have a TStringGrid with 2 columns Game Info and Moves
When I double click on a row (or cell in row), I want to highlight that whole row and then load the game.

I tried gridPGNDatabaseSelectCell and gridPGNDatabaseSelection with no luck.
I'm sorry I am a newbie.
Thanks,
-
Used C++Builder for the longest time, got macOS, How many Lightning Bolts do you deserve? Find out at my website: https://boltquiz.org

cdbc

  • Hero Member
  • *****
  • Posts: 722
    • http://www.cdbc.dk
Re: Click to select row using TStringGrid?
« Reply #1 on: June 11, 2023, 07:43:57 am »
Hi
1) To be able to select an entire row in the grid, you have to first, enable
   "RowSelect" in "gridPGNDatabase", in OI.
2) Then in "gridPGNDatabaseDbClick", "gridPGNDatabaseSelectCell" or
   "gridPGNDatabaseSelection" event-handlers, you read the "Row" and "Col"
   properties and then load the corresponding game...
It goes something like this excerpt from an app of mine:
Code: Pascal  [Select][+][-]
  1. procedure TfraBook.grdMainDblClick(Sender: TObject);
  2. begin
  3.   case grdMain.Row of
  4.     2: fBook.ArchiveDir:= InputBox('Input property','Enter Directory name:','NO path!');
  5.     3: if dlgDir.Execute then fBook.BackupDir:= dlgDir.FileName+bcPathDelimiter;
  6.     7: fBook.Name:= InputBox('Input property','Enter Name:','NO \ / . , or *');
  7.     9: fBook.SalesTax:= StrToBool(InputBox('Input property','Enter False/0 or True/1:','False'));
  8.     10: if dlgDir.Execute then fBook.WorkingDir:= dlgDir.FileName+bcPathDelimiter;
  9.   end;
  10. end;
  11.  
  12. procedure TfraBook.grdMainKeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);
  13. begin
  14.   case Key of
  15.     $0D: grdMainDblClick(Sender);
  16.   end;
  17. end;
  18.  
HTH
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6

tearsfornations

  • New Member
  • *
  • Posts: 35
  • Jesus is worth talking about.
    • Lightning Bolt Quiz - How many Lightning Bolts do you deserve?
Re: Click to select row using TStringGrid?
« Reply #2 on: June 11, 2023, 02:45:24 pm »
I appreciate your reply, but I cannot get it to work.
When I double click the row, it keeps saying the row is 41 when I do a ShowMessage()  (which is the last row), see the screenshot.

My code is here as well:
Code: Pascal  [Select][+][-]
  1. unit unitFrmPgnDatabase;
  2.  
  3. {$mode ObjFPC}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  9.   ExtCtrls, Grids, Menus, Types;
  10.  
  11. type
  12.  
  13.   { TfrmPGNDatabase }
  14.  
  15.   TfrmPGNDatabase = class(TForm)
  16.     mniLoadGame: TMenuItem;
  17.     pnlDatabase: TPanel;
  18.     gridPGNDatabase: TStringGrid;
  19.     pmnPGNDatabase: TPopupMenu;
  20.     procedure gridPGNDatabaseClick(Sender: TObject);
  21.     procedure gridPGNDatabaseDblClick(Sender: TObject);
  22.     procedure gridPGNDatabaseDrawCell(Sender: TObject; aCol, aRow: Integer;
  23.       aRect: TRect; aState: TGridDrawState);
  24.     procedure gridPGNDatabaseMouseMove(Sender: TObject; Shift: TShiftState; X,
  25.       Y: Integer);
  26.     procedure gridPGNDatabasePrepareCanvas(Sender: TObject; aCol,
  27.       aRow: Integer; aState: TGridDrawState);
  28.     procedure gridPGNDatabaseSelectCell(Sender: TObject; aCol, aRow: Integer;
  29.       var CanSelect: Boolean);
  30.     procedure gridPGNDatabaseSelection(Sender: TObject; aCol, aRow: Integer);
  31.     procedure mniLoadGameClick(Sender: TObject);
  32.   private
  33.  
  34.   public
  35.  
  36.   end;
  37.  
  38. var
  39.   frmPGNDatabase: TfrmPGNDatabase;
  40.   My_Grid_Highlight_BackGround_Color:Tcolor=ClGreen;
  41.   My_Grid_Highlight_Font_Color:Tcolor=clYellow;
  42.   My_Grid_Highlight_Font_Multiplier:Real=1.5;  // FOnt Multiplier for selected row
  43.   LastRow : Integer;
  44. implementation
  45.  
  46. uses
  47.   MainUnit, GraphUtil, LCLIntf;
  48. {$R *.lfm}
  49.  
  50. { TfrmPGNDatabase }
  51.  
  52. procedure TfrmPGNDatabase.gridPGNDatabaseDblClick(Sender: TObject);
  53. begin
  54.   ShowMessage(IntToStr(gridPGNDatabase.Row));
  55.   if LastRow <> -1 then
  56.   begin
  57.     gridPGNDatabase.Row := LastRow;
  58.     MainForm.FGame.ChessNotation.PGNString := gridPGNDatabase.Rows[gridPGNDatabase.Row].Strings[1] + ' ' + gridPGNDatabase.Rows[gridPGNDatabase.Row].Strings[2];
  59.   end;
  60. end;
  61.  
  62. procedure TfrmPGNDatabase.gridPGNDatabaseClick(Sender: TObject);
  63. begin
  64.   if LastRow <> -1 then
  65.   begin
  66.     gridPGNDatabase.Row := LastRow;
  67.   end;
  68. end;
  69.  
  70. procedure TfrmPGNDatabase.gridPGNDatabaseDrawCell(Sender: TObject; aCol,
  71.   aRow: Integer; aRect: TRect; aState: TGridDrawState);
  72. begin
  73.   If Sender is TStringGrid then
  74.   begin
  75.     With (sender as TStringGrid) Do
  76.     Begin
  77.       Canvas.Brush.Style := bsSolid;
  78.       canvas.Font.Color:=clWhite;
  79.       if arow=row then       // Selected Row
  80.       begin
  81.         FocusColor:=My_Grid_Highlight_BackGround_Color;
  82.         Canvas.Brush.Color:=My_Grid_Highlight_BackGround_Color;
  83.         canvas.Font.Color:=My_Grid_Highlight_Font_Color;
  84.         canvas.Font.Size:=round(font.Size*My_Grid_Highlight_Font_Multiplier);
  85.       end
  86.       else
  87.       begin
  88.         canvas.Font.Color:=font.Color;
  89.         Canvas.Brush.Color:=color;
  90.         canvas.Font.Size:=font.Size;
  91.       end;
  92.       defaultdrawcell(Acol, Arow, arect, astate);
  93.     end;
  94.   end;
  95. end;
  96.  
  97. procedure TfrmPGNDatabase.gridPGNDatabaseMouseMove(Sender: TObject;
  98.   Shift: TShiftState; X, Y: Integer);
  99. var
  100.   R, C:        Integer;
  101.   Start, Size: Integer;
  102.   i:           Integer;
  103. begin
  104.   // Row
  105.   R     := -1;
  106.   Start := 0;
  107.   for i := 0 to gridPGNDatabase.RowCount-1 do
  108.   begin
  109.     Size := gridPGNDatabase.RowHeights[i];
  110.     if (Y > Start) and (Y < Start + Size) then
  111.     begin
  112.       R := i;
  113.       Break;
  114.     end;
  115.     Inc(Start, Size);
  116.   end;
  117.   // Column
  118.   C     := -1;
  119.   Start := 0;
  120.   for i := 0 to gridPGNDatabase.ColCount-1 do
  121.   begin
  122.     Size := gridPGNDatabase.ColWidths[i];
  123.     if (X > Start) and (X < Start + Size) then
  124.     begin
  125.       C := i;
  126.       Break;
  127.     end;
  128.     Inc(Start, Size);
  129.   end;
  130.   // Show result
  131.   //Caption := 'Mouse X:Y = ' +  X.ToString + ':' + Y.ToString;
  132.   case (R < 0) or (C < 0) of
  133.     True:  LastRow := -1;
  134.     False: LastRow := R;
  135.   end;
  136.   gridPGNDatabase.Invalidate();
  137. end;
  138.  
  139. procedure TfrmPGNDatabase.gridPGNDatabasePrepareCanvas(Sender: TObject; aCol,
  140.   aRow: Integer; aState: TGridDrawState);
  141. var
  142.   P: TPoint;
  143.   c, r: LongInt;
  144.   obe: Boolean;
  145. begin
  146.   P := gridPGNDatabase.ScreenToClient(Mouse.CursorPos);
  147.   if (aState = []) or (gdFixed in aState) then
  148.   begin
  149.     obe := gridPGNDatabase.AllowOutBoundEvents;
  150.     gridPGNDatabase.AllowOutBoundEvents := false;
  151.     gridPGNDatabase.MouseToCell(P.X, P.Y, c, r);
  152.     gridPGNDatabase.AllowOutBoundEvents := obe;
  153.     if (aRow = r) and (aRow >= gridPGNDatabase.FixedRows) then
  154.     begin
  155.       if aState = [] then
  156.         gridPGNDatabase.Canvas.Brush.Color := rgb(232, 232, 232)
  157.       else
  158.         gridPGNDatabase.Canvas.Brush.Color := GetShadowColor(ColorToRGB(gridPGNDatabase.FixedColor), -20);
  159.     end;
  160.   end;
  161. end;
  162.  
  163. procedure TfrmPGNDatabase.gridPGNDatabaseSelectCell(Sender: TObject; aCol,
  164.   aRow: Integer; var CanSelect: Boolean);
  165. begin
  166.  
  167. end;
  168.  
  169. procedure TfrmPGNDatabase.gridPGNDatabaseSelection(Sender: TObject; aCol,
  170.   aRow: Integer);
  171. begin
  172.  
  173. end;
  174.  
  175. procedure TfrmPGNDatabase.mniLoadGameClick(Sender: TObject);
  176. begin
  177.    if LastRow <> -1 then
  178.    begin
  179.      gridPGNDatabase.Row := LastRow;
  180.      gridPGNDatabase.Invalidate();
  181.      MainForm.FGame.ChessNotation.PGNString := gridPGNDatabase.Rows[LastRow].Strings[1] + ' ' + gridPGNDatabase.Rows[LastRow].Strings[2];
  182.      while (not MainForm.FGame.ChessNotation.Iterator.IsFirst) do
  183.      begin
  184.         MainForm.FGame.ChessNotation.Iterator.PrevMove();
  185.      end;
  186.    end;
  187. end;
  188.  
  189. { TfrmPGNDatabase }
  190.  
  191.  
  192. end.
  193.  
  194.  

and here is how I load the pgns in there:

Code: Pascal  [Select][+][-]
  1. procedure TMainForm.actLoadPGNFileExecute(Sender: TObject);
  2. var
  3.   SList : TStringList;
  4.   PGNList : array of AnsiString;
  5.   i, R : Integer;
  6.   s, s2, pgn : AnsiString;
  7.   RegexObj: TRegExpr;
  8. begin
  9.   //load pgn file
  10.   RegexObj := TRegExpr.Create();
  11.   RegexObj.Expression := '((((\[.*?\])\s*)+)(1\.[^[]+(0-1|1-0|1/2-1/2)))';
  12.   if dlgOpenPGN.Execute() then
  13.   begin
  14.     frmPGNDatabase.Show();
  15.     //frmPGNDatabase.listPGNs.Items.Clear();
  16.     frmPGNDatabase.gridPGNDatabase.Clear();
  17.     pgn := '';
  18.     s := '';
  19.     s2 := '';
  20.     R := 1;
  21.     SList := TStringList.Create();
  22.     SList.LoadFromFile(dlgOpenPGN.FileName);
  23.     for i := 0 to SList.Count-1 do
  24.     begin
  25.       s2 := SList[i];
  26.       s += s2 + #13#10;
  27.        if (s2.Contains(' 1-0') or s2.Contains(' 1/2-1/2') or s2.Contains(' 0-1')) and RegexObj.Exec(s) then
  28.        begin
  29.          pgn := RegexObj.Match[1];
  30.          //ShowMessage(pgn);
  31.          PGNList := [ RegexObj.Match[2], RegexObj.Match[5] ];
  32.  
  33.          frmPGNDatabase.gridPGNDatabase.RowCount := frmPGNDatabase.gridPGNDatabase.FixedRows + 2;
  34.          frmPGNDatabase.gridPGNDatabase.FixedRows := frmPGNDatabase.gridPGNDatabase.FixedRows + 1;
  35.          frmPGNDatabase.gridPGNDatabase.InsertRowWithValues(R,PGNList);
  36.  
  37.          pgn := StringReplace(pgn, #13#10, '', [rfReplaceAll]);
  38.          pgn := StringReplace(pgn, #13, '', [rfReplaceAll]);
  39.          pgn := StringReplace(pgn, #10, '', [rfReplaceAll]);
  40.  
  41.          s := '';
  42.          R := R + 1;
  43.        end
  44.     end;
  45.     try
  46.        CreateNewGame();
  47.        FGame.ChessNotation.PGNString := s2;
  48.     except
  49.       on E: Exception do
  50.         MessageDlg(E.Message, mtError, [mbOK], 0);
  51.     end;
  52.     SList.Free();
  53.   end;
  54.   RegexObj.Free();
  55. end;
  56.  
« Last Edit: June 11, 2023, 02:48:21 pm by tearsfornations »
-
Used C++Builder for the longest time, got macOS, How many Lightning Bolts do you deserve? Find out at my website: https://boltquiz.org

cdbc

  • Hero Member
  • *****
  • Posts: 722
    • http://www.cdbc.dk
Re: Click to select row using TStringGrid?
« Reply #3 on: June 11, 2023, 05:08:42 pm »
Hi
What has this got to do in there?!?:
Code: Pascal  [Select][+][-]
  1. procedure TfrmPGNDatabase.gridPGNDatabaseClick(Sender: TObject);
  2. begin
  3.   if LastRow <> -1 then
  4.   begin
  5.     gridPGNDatabase.Row := LastRow;
  6.   end;
  7. end;
  8. //-------- try like this...
  9. procedure TfrmPGNDatabase.gridPGNDatabaseClick(Sender: TObject);
  10. begin
  11. (*  if LastRow <> -1 then
  12.   begin
  13.     gridPGNDatabase.Row := LastRow;
  14.   end; *)
  15. end;
  16.  
This get fired first in a dblclick(2 clicks... you know)  %)
Comment all this and see what happens  ;)
edit:
Code: Pascal  [Select][+][-]
  1. procedure TfrmPGNDatabase.gridPGNDatabaseMouseMove(Sender: TObject;
  2.   Shift: TShiftState; X, Y: Integer);
  3.  
I'm a bit puzzled of what you're trying to achieve, with that code?
It could throw your "LastRow" off course...
Regards Benny
« Last Edit: June 11, 2023, 05:34:07 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6

jamie

  • Hero Member
  • *****
  • Posts: 5852
Re: Click to select row using TStringGrid?
« Reply #4 on: June 11, 2023, 05:38:42 pm »
I see the code in the MouseMove is way over kill! :D

Use the MouseToCell method to obtain your Column and row markers, the grid takes care of that for you.
The only true wisdom is knowing you know nothing

cdbc

  • Hero Member
  • *****
  • Posts: 722
    • http://www.cdbc.dk
Re: Click to select row using TStringGrid?
« Reply #5 on: June 11, 2023, 05:50:03 pm »
Hi
@jamie: +1, I was wondering the exact same thing  :D
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6

tearsfornations

  • New Member
  • *
  • Posts: 35
  • Jesus is worth talking about.
    • Lightning Bolt Quiz - How many Lightning Bolts do you deserve?
Re: Click to select row using TStringGrid?
« Reply #6 on: June 11, 2023, 09:41:59 pm »
I get that some of the code is not optimal, that is why I posted it, but it still doesn't answer my question, how do I make it so that on click or double click, I can highlight the row and use it to load in my chess game with MainForm.FGame.ChessNotation.PGNString := gridPGNDatabase.Rows[LastRow].Strings[1] + ' ' + gridPGNDatabase.Rows[LastRow].Strings[2];
-
Used C++Builder for the longest time, got macOS, How many Lightning Bolts do you deserve? Find out at my website: https://boltquiz.org

cdbc

  • Hero Member
  • *****
  • Posts: 722
    • http://www.cdbc.dk
Re: Click to select row using TStringGrid?
« Reply #7 on: June 12, 2023, 07:33:03 am »
Hi
Right, first off the bat e.g.:
Code: Pascal  [Select][+][-]
  1. procedure TfraBook.grdMainMouseMove(Sender: TObject; Shift: TShiftState; X,
  2.   Y: Integer);
  3. var
  4.   lcol,lrow: Longint;
  5. begin
  6.   { convert the mousecoordinates to column & row }
  7.   grdMain.MouseToCell(X,Y,lcol,lrow);
  8.   { show hints from array, corresponding to the items under the mouse }
  9.   pnlBottom.Caption:= 'Property: ' + fBra[lrow-1].brName + fBra[lrow-1].brHint;
  10.   { keep focus on grid, mainly for "KeyDown" events to work }
  11.   if grdMain.CanSetFocus then grdMain.SetFocus;
  12. end;
  13.  
In your case it will look like this:
Code: Pascal  [Select][+][-]
  1. procedure TfrmPGNDatabase.gridPGNDatabaseMouseMove(Sender: TObject;
  2.   Shift: TShiftState; X, Y: Integer);
  3. var
  4.   R, C:        Integer;
  5. begin
  6.   { convert the mousecoordinates to column & row }
  7.   gridPGNDatabase.MouseToCell(X,Y,C,R);
  8.   case (R < 0) or (C < 0) of
  9.     True:  LastRow := -1;
  10.     False: LastRow := R;
  11.   end; { IS all of this really necessarry??? See DblClick-handler }
  12.   gridPGNDatabase.Invalidate();
  13. end;
  14.  
But why would you want to do all that, when a dblclick, 1) selects a row with the first click and 2) keep you from opening a game, when you just wanted to focus... So:
Code: Pascal  [Select][+][-]
  1. procedure TfrmPGNDatabase.gridPGNDatabaseDblClick(Sender: TObject);
  2. begin
  3. //  ShowMessage(IntToStr(gridPGNDatabase.Row));
  4.   LastRow := gridPGNDatabase.Row;
  5.   MainForm.FGame.ChessNotation.PGNString := gridPGNDatabase.Cells[1,LastRow] +' '+ gridPGNDatabase.Cells[2,LastRow];
  6. end;
  7.  
If you have enabled "goRowSelect" in gridPGNDatabase.Options, either via the object-inspector or with this call somewhere in your startup code:
Code: Pascal  [Select][+][-]
  1. Include(gridPGNDatabase.Options,goRowSelect)
Then the dbl-click handler should be enough.
Oh, and you've got some cleaning up to do...
1) single click events are mostly annoying, e.g.: you want to bring form to
   front / focus, then it starts opening games...
2) selection events are mainly useful for keyboard actions...
3) selectcell could double for your dbl-click event, but again it's a "One Hit
   Wonder" i.e.: acts on first click...
4) mouse-over events are great for hot-tracking, but if you go out of bounds,
   you're left with the last first/last row or column...
In your case the KISS principle is sound advice, the grid knows when and where you clicked and all your unused (by now, anyway) code that's laying around clutters it up, so it's hard to read.
Ok, that was my "Nickles Worth"  8-)
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6

tearsfornations

  • New Member
  • *
  • Posts: 35
  • Jesus is worth talking about.
    • Lightning Bolt Quiz - How many Lightning Bolts do you deserve?
Re: Click to select row using TStringGrid?
« Reply #8 on: June 12, 2023, 10:26:22 am »
ok I seem to have achieved what I wanted, thank you very much for your replies!, but still I'm left with a lot of extra blank rows.

See screenshot.

Here is the code I am using to add the rows:
What am I doing wrong?

Code: Pascal  [Select][+][-]
  1. procedure TMainForm.actLoadPGNFileExecute(Sender: TObject);
  2. var
  3.   SList : TStringList;
  4.   PGNList : array of AnsiString;
  5.   i, R, j : Integer;
  6.   s, s2, pgn, pgntags, white, black : AnsiString;
  7.   RegexObj: TRegExpr;
  8. begin
  9.   //load pgn file
  10.   RegexObj := TRegExpr.Create();
  11.   RegexObj.Expression := '((((\[.*?\])\s*)+)(1\.[^[]+(0-1|1-0|1/2-1/2)))';
  12.   if dlgOpenPGN.Execute() then
  13.   begin
  14.     frmPGNDatabase.Show();
  15.     //frmPGNDatabase.listPGNs.Items.Clear();
  16.     frmPGNDatabase.gridPGNDatabase.RowCount := 1;
  17.     frmPGNDatabase.gridPGNDatabase.Clear();
  18.     pgn := '';
  19.     s := '';
  20.     s2 := '';
  21.     R := 1;
  22.     SList := TStringList.Create();
  23.     SList.LoadFromFile(dlgOpenPGN.FileName);
  24.     for i := 0 to SList.Count-1 do
  25.     begin
  26.       s2 := SList[i];
  27.       s += s2 + #13#10;
  28.        if (s2.Contains(' 1-0') or s2.Contains(' 1/2-1/2') or s2.Contains(' 0-1')) and RegexObj.Exec(s) then
  29.        begin
  30.          pgn := RegexObj.Match[1];
  31.          pgntags := RegexObj.Match[2];
  32.          j := pgntags.IndexOf('[White "');
  33.          white := '';
  34.          if (j > 0) then
  35.          begin
  36.            white := pgntags.Substring(j+8, pgntags.Substring(j+8).IndexOf('"]'));
  37.          end;
  38.          j := pgntags.IndexOf('[Black "');
  39.          black := '';
  40.          if (j > 0) then
  41.          begin
  42.            black := pgntags.Substring(j+8, pgntags.Substring(j+8).IndexOf('"]'));
  43.          end;
  44.  
  45.          PGNList := [ RegexObj.Match[2], white, black, RegexObj.Match[5] ];
  46.          frmPGNDatabase.gridPGNDatabase.RowCount := frmPGNDatabase.gridPGNDatabase.RowCount + 1;
  47.          //frmPGNDatabase.gridPGNDatabase.RowCount := frmPGNDatabase.gridPGNDatabase.FixedRows + 1;
  48.          //frmPGNDatabase.gridPGNDatabase.FixedRows := frmPGNDatabase.gridPGNDatabase.FixedRows + 1;
  49.          frmPGNDatabase.gridPGNDatabase.InsertRowWithValues(R,PGNList);
  50.  
  51.          pgn := StringReplace(pgn, #13#10, '', [rfReplaceAll]);
  52.          pgn := StringReplace(pgn, #13, '', [rfReplaceAll]);
  53.          pgn := StringReplace(pgn, #10, '', [rfReplaceAll]);
  54.  
  55.          s := '';
  56.          R := R + 1;
  57.        end
  58.     end;
  59.     try
  60.        CreateNewGame();
  61.        FGame.ChessNotation.PGNString := s2;
  62.     except
  63.       on E: Exception do
  64.         MessageDlg(E.Message, mtError, [mbOK], 0);
  65.     end;
  66.     SList.Free();
  67.   end;
  68.   RegexObj.Free();
  69. end;                            
  70.  
-
Used C++Builder for the longest time, got macOS, How many Lightning Bolts do you deserve? Find out at my website: https://boltquiz.org

cdbc

  • Hero Member
  • *****
  • Posts: 722
    • http://www.cdbc.dk
Re: Click to select row using TStringGrid?
« Reply #9 on: June 12, 2023, 12:44:29 pm »
Hi
Well, let's see what gives:
Code: Pascal  [Select][+][-]
  1. procedure TMainForm.actLoadPGNFileExecute(Sender: TObject);
  2. var
  3.   SList : TStringList;
  4.   PGNList : array of AnsiString;
  5.   i, R, j : Integer;
  6.   s, s2, pgn, pgntags, white, black : AnsiString;
  7.   RegexObj: TRegExpr;
  8. begin
  9.   //load pgn file
  10.   RegexObj := TRegExpr.Create();
  11.   RegexObj.Expression := '((((\[.*?\])\s*)+)(1\.[^[]+(0-1|1-0|1/2-1/2)))';
  12.   if dlgOpenPGN.Execute() then
  13.   begin
  14.     frmPGNDatabase.Show();
  15.     { these 2 swapped places }
  16.     frmPGNDatabase.gridPGNDatabase.Clear();
  17.     frmPGNDatabase.gridPGNDatabase.RowCount := 1;
  18.    
  19.     pgn := '';
  20.     s := '';
  21.     s2 := '';
  22.     R := 1;
  23.     SList := TStringList.Create();
  24.     SList.LoadFromFile(dlgOpenPGN.FileName);
  25.     for i := 0 to SList.Count-1 do
  26.     begin
  27.       s2 := SList[i];
  28.       s += s2 + #13#10;
  29.        if (s2.Contains(' 1-0') or s2.Contains(' 1/2-1/2') or s2.Contains(' 0-1'))
  30.         and RegexObj.Exec(s) then
  31.        begin
  32.          pgn := RegexObj.Match[1];
  33.          pgntags := RegexObj.Match[2];
  34.          j := pgntags.IndexOf('[White "');
  35.          white := '';
  36.          if (j > 0) then
  37.          begin
  38.            white := pgntags.Substring(j+8, pgntags.Substring(j+8).IndexOf('"]'));
  39.          end;
  40.          j := pgntags.IndexOf('[Black "');
  41.          black := '';
  42.          if (j > 0) then
  43.          begin
  44.            black := pgntags.Substring(j+8, pgntags.Substring(j+8).IndexOf('"]'));
  45.          end;
  46.          { are you sure that regex doesn't return empty lines in its resultset? }
  47.          PGNList := [ RegexObj.Match[2], white, black, RegexObj.Match[5] ];
  48.          { set R = rowcount before you increment it }
  49.          R:= frmPGNDatabase.gridPGNDatabase.RowCount;
  50.          frmPGNDatabase.gridPGNDatabase.RowCount:= R + 1;
  51.          { now R points to the second to last row }
  52.          frmPGNDatabase.gridPGNDatabase.InsertRowWithValues(R,PGNList);
  53.          { does "InsertRowWithValues" add a row on its own accord?!? }
  54.  
  55.          pgn := StringReplace(pgn, #13#10, '', [rfReplaceAll]);
  56.          pgn := StringReplace(pgn, #13, '', [rfReplaceAll]);
  57.          pgn := StringReplace(pgn, #10, '', [rfReplaceAll]);
  58.          s := '';
  59.        end
  60.     end;
  61.     try
  62.        CreateNewGame();
  63.        FGame.ChessNotation.PGNString := s2;
  64.     except
  65.       on E: Exception do
  66.         MessageDlg(E.Message, mtError, [mbOK], 0);
  67.     end;
  68.     SList.Free();
  69.   end;
  70.   RegexObj.Free();
  71. end;                            
  72.  
Maybe you can try this out for size... Then we'll have a looksee if more has to be done.
Regards Benny
« Last Edit: June 12, 2023, 12:53:04 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6

tearsfornations

  • New Member
  • *
  • Posts: 35
  • Jesus is worth talking about.
    • Lightning Bolt Quiz - How many Lightning Bolts do you deserve?
Re: Click to select row using TStringGrid?
« Reply #10 on: June 12, 2023, 03:35:27 pm »
I fixed it by not using InsertRowWithValues and just using Cells[]
Code: Pascal  [Select][+][-]
  1. procedure TMainForm.actLoadPGNFileExecute(Sender: TObject);
  2. var
  3.   SList : TStringList;
  4.   i, R, j, row : Integer;
  5.   s, s2, pgntags, white, black : AnsiString;
  6.   RegexObj: TRegExpr;
  7. begin
  8.   //load pgn file
  9.   RegexObj := TRegExpr.Create();
  10.   RegexObj.Expression := '((((\[.*?\])\s*)+)(1\..+?(0-1|1-0|1/2-1/2)))';
  11.   if dlgOpenPGN.Execute() then
  12.   begin
  13.     frmPGNDatabase.Show();
  14.     frmPGNDatabase.gridPGNDatabase.Clear();
  15.     frmPGNDatabase.gridPGNDatabase.RowCount := 1 + frmPGNDatabase.gridPGNDatabase.FixedRows;
  16.     s := '';
  17.     s2 := '';
  18.     R := 1;
  19.     row := frmPGNDatabase.gridPGNDatabase.FixedRows;
  20.     SList := TStringList.Create();
  21.     SList.LoadFromFile(dlgOpenPGN.FileName);
  22.     for i := 0 to SList.Count-1 do
  23.     begin
  24.       s2 := SList[i];
  25.       s += s2 + #13#10;
  26.        if (s2.Contains(' 1-0') or s2.Contains(' 1/2-1/2') or s2.Contains(' 0-1')) and RegexObj.Exec(s) then
  27.        begin
  28.          pgntags := RegexObj.Match[2];
  29.          j := pgntags.IndexOf('[White "');
  30.          white := '';
  31.          if (j > 0) then
  32.          begin
  33.            white := pgntags.Substring(j+8, pgntags.Substring(j+8).IndexOf('"]'));
  34.          end;
  35.          j := pgntags.IndexOf('[Black "');
  36.          black := '';
  37.          if (j > 0) then
  38.          begin
  39.            black := pgntags.Substring(j+8, pgntags.Substring(j+8).IndexOf('"]'));
  40.          end;
  41.  
  42.          frmPGNDatabase.gridPGNDatabase.RowCount := frmPGNDatabase.gridPGNDatabase.RowCount + 1;
  43.  
  44.          frmPGNDatabase.gridPGNDatabase.Cells[0, row] := RegexObj.Match[2];
  45.          frmPGNDatabase.gridPGNDatabase.Cells[1, row] := white;
  46.          frmPGNDatabase.gridPGNDatabase.Cells[2, row] := black;
  47.          frmPGNDatabase.gridPGNDatabase.Cells[3, row] := RegexObj.Match[5];
  48.          Inc(row);
  49.          s := '';
  50.          R := R + 1;
  51.        end
  52.     end;
  53.     if (R-1 = 1) then
  54.     begin
  55.        frmPGNDatabase.Caption := FormatFloat('#,',R-1) + ' PGN Game';
  56.     end else
  57.     begin
  58.        frmPGNDatabase.Caption := FormatFloat('#,',R-1) + ' PGN Games';
  59.     end;
  60.  
  61.     try
  62.        CreateNewGame();
  63.     except
  64.       on E: Exception do
  65.         MessageDlg(E.Message, mtError, [mbOK], 0);
  66.     end;
  67.     SList.Free();
  68.   end;
  69.   RegexObj.Free();
  70. end;
  71.  
-
Used C++Builder for the longest time, got macOS, How many Lightning Bolts do you deserve? Find out at my website: https://boltquiz.org

tearsfornations

  • New Member
  • *
  • Posts: 35
  • Jesus is worth talking about.
    • Lightning Bolt Quiz - How many Lightning Bolts do you deserve?
Re: Click to select row using TStringGrid?
« Reply #11 on: June 12, 2023, 03:36:10 pm »
Thanks for all your help!
-
Used C++Builder for the longest time, got macOS, How many Lightning Bolts do you deserve? Find out at my website: https://boltquiz.org

cdbc

  • Hero Member
  • *****
  • Posts: 722
    • http://www.cdbc.dk
Re: Click to select row using TStringGrid?
« Reply #12 on: June 12, 2023, 09:25:25 pm »
Hehehe... Tried your quiz... It's Cool  ;D
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6

 

TinyPortal © 2005-2018