Recent

Author Topic: Copy and paste rows in a stringgrid  (Read 2882 times)

bobonwhidbey

  • Hero Member
  • *****
  • Posts: 590
    • Double Dummy Solver - free download
Copy and paste rows in a stringgrid
« on: October 02, 2021, 08:05:58 pm »
When I copy and paste in my stringgrid, it overwrites existing rows. The number of new lines held in the ClipBoard is easily obtained with SelectRowCount := Grid.SelectedRangeCount;  What I need to do (I think) is add some blank lines, below Grid.Row which will be able to receive the pasted rows.

I've tried, unsuccessfully, to use the Grid's OnKeyUp event:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.GridKeyUp(Sender: TObject; var Key: word; Shift: TShiftState);
  2. begin
  3.   if (ssCtrl in Shift) and (Key = VK_V) then // paste
  4.       now what??????
  5. end;

I think the rows are already copied by the time the ctrl-V is processed. 

How can I copy the rows from the Grid's Clipboard underneath the selected row, without overwriting any of the existing rows?
Lazarus 3.0RC2, FPC 3.2.2 x86_64-win64-win32/win64

Joanna

  • Hero Member
  • *****
  • Posts: 723
Re: Copy and paste rows in a stringgrid
« Reply #1 on: October 06, 2021, 05:04:43 pm »
I've never tried to copy into a stringgrid but i know you have to add rows first
here is some code of how to do it.

Code: Pascal  [Select][+][-]
  1. PROCEDURE TFRAME_STRING_GRID_2021.ADD_ROW( CONST ROW_NUMBER: WORD; CONST STRINGS: TSTRINGARRAY) ;
  2.             var X:integer;
  3.  BEGIN
  4.  WITH GRID DO
  5.       BEGIN
  6.       WITH Columns DO
  7.            FOR X:= Count TO HIGH(STRINGS) DO
  8.                BEGIN
  9.                Add;
  10.                Columns[X].Alignment := taCenter;
  11.                END;
  12.       IF RowCount < ROW_NUMBER + 1
  13.          THEN RowCount := ROW_NUMBER + 1;
  14.       FOR X:= 0 TO HIGH(STRINGS) DO
  15.           Cells[X + Ord(FixedCols = 1),ROW_NUMBER]:= STRINGS [X];
  16.       IF goFixedRowNumbering IN Options
  17.          THEN cells [0,ROW_NUMBER]:= ROW_NUMBER.ToString;
  18.       END;
  19.  END;  
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

bobonwhidbey

  • Hero Member
  • *****
  • Posts: 590
    • Double Dummy Solver - free download
Re: Copy and paste rows in a stringgrid
« Reply #2 on: October 06, 2021, 10:00:27 pm »
If you leave the StringGrid option goEditing unchecked then you are able to handle the Ctrl-V (paste) exactly how you want. In the desired (IMO) way, this would mean adding the selected rows directly below the current row. It's under your control.  However, with goEditing unchecked, you lose out on all the default editing capabilities of a stringgrid cell. :(

If you check goEditing, you get the desired editing capabilities but you lose control over all paste capabilities. As far as I can tell, the only 'solution' is to leave goEditing unchecked and then roll your own cell editing capabilities as well as copy/paste capabilities. I was hoping there was an event that would let me stop Lazarus from performing the paste function when goEditing was checked, but I guess not.

Lazarus 3.0RC2, FPC 3.2.2 x86_64-win64-win32/win64

Joanna

  • Hero Member
  • *****
  • Posts: 723
Re: Copy and paste rows in a stringgrid
« Reply #3 on: October 06, 2021, 11:53:22 pm »
If you have the inclination it’s possible to make your own class that inherits tstringgrid and override the methods that aren’t doing what you want.

After you get the descendant class created you can find the the ancestor code and copy it and modify it
 :)

« Last Edit: October 06, 2021, 11:56:06 pm by Joanna »
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

wp

  • Hero Member
  • *****
  • Posts: 11854
Re: Copy and paste rows in a stringgrid
« Reply #4 on: October 07, 2021, 12:01:09 am »
I've tried, unsuccessfully, to use the Grid's OnKeyUp event:

How can I copy the rows from the Grid's Clipboard underneath the selected row, without overwriting any of the existing rows?
In the attached sample project I am subclassing the TStringGrid in order to override the DoPasteFromClipboard method. At first I determine whether the clipboard sends a fully selected row or column and, in this case, add an empty row/column and paste the clipboard into these new cells. Otherwise there is a normal paste overwriting the destination cells. Of course you can change the logic here in any way needed.

I disagree that Ctrl-V works without goEditing. This is clear from the original TStringGrid.DoPastefromClipboard:
Code: Pascal  [Select][+][-]
  1. procedure TCustomStringGrid.DoPasteFromClipboard;
  2. begin
  3.   if HasMultiSelection then
  4.     exit;
  5.  
  6.   if EditingAllowed(Col) then  // <--- Editing required, otherwise clipboard actions are skipped.
  7.   begin
  8.     if Clipboard.HasFormat(CF_TEXT) and not Clipboard.HasFormat(CF_HTML) then SelectionSetText(Clipboard.AsText);
  9.     if Clipboard.HasFormat(CF_TEXT) and Clipboard.HasFormat(CF_HTML) then SelectionSetHTML(Clipboard.GetAsHtml(True), Clipboard.AsText);
  10.   end;
  11. end;

Joanna

  • Hero Member
  • *****
  • Posts: 723
Re: Copy and paste rows in a stringgrid
« Reply #5 on: October 07, 2021, 12:23:19 am »
Is there a way to intercept the text in the onpaste event and then put it into some format that can be entered programmatically?

How is it determined which text goes into which cell?
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

bobonwhidbey

  • Hero Member
  • *****
  • Posts: 590
    • Double Dummy Solver - free download
Re: Copy and paste rows in a stringgrid
« Reply #6 on: October 07, 2021, 01:29:07 am »
What I meant is that it's possible to write your own code for copying and pasting. If goEditing is checked then you will end up pasting the data twice; once with your own code and once with the stringgrid code. The only way to prevent the stringgrid from pasting is to uncheck goEditing.

Thank you very much for the code. I'll dig into it tomorrow.
Lazarus 3.0RC2, FPC 3.2.2 x86_64-win64-win32/win64

Zvoni

  • Hero Member
  • *****
  • Posts: 2317
Re: Copy and paste rows in a stringgrid
« Reply #7 on: October 07, 2021, 09:30:59 am »
Use OnKeyDown.......
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

wp

  • Hero Member
  • *****
  • Posts: 11854
Re: Copy and paste rows in a stringgrid
« Reply #8 on: October 07, 2021, 11:00:45 am »
Of course. The OnKeyDown event is more accessible than subclassing...

Here is the code from above modified such that it uses the OnKeyDown. It first detects whether CTRL-V is pressed and whether the clipboard contains text (this check was missing from the other code). Then it checkes whether the clipboard contains a full row or full column and, if true, inserts an empty row/column and moves the active cell to the start of this row/column. The inherited method, finally, pastes the clipboard at his new location.

@Joanna:
The paste operation goes to the position of the active cell (StringGrid.Col, StringGrid.Row).

When copying cells to the clipboard, the LCL grids put a tab character between cells in the same row, and a Lineending string (#13#10 on Windows) at the end of each row. The pasting process expects exactly these delimiters in order to be able to separate the individual cells.

In addition to the text format, the LCL grids also copy a html-coded string to the clipboard (not sure at which version this came in).

bobonwhidbey

  • Hero Member
  • *****
  • Posts: 590
    • Double Dummy Solver - free download
Re: Copy and paste rows in a stringgrid
« Reply #9 on: October 07, 2021, 07:28:54 pm »
WP, your program handles copying cells, whether full or partial rows, very nicely. My problem is perhaps centered around the meaning of "Paste". In all of the text editing programs I'm familiar with, the Ctrl-C / Ctrl-V Copy/Paste operations will INSERT the copied text. They do not overwrite text.

OTOH, it is most logical for the Copy/Paste operations to behave as you have programmed them when dealing with a stringgrid. For my app, I think the most logical way to proceed is to keep Copy/Paste as you have programmed and then include a separate "Insert Row(s)" button to handle the addition or rows followed by a paste of the copied cells.

It's easy enough to add the correct number of rows below the current row. What I then need to do in the "InsertRowsClick" event is to trigger the Ctrl-V event in real time. How would I do that?
Code: Pascal  [Select][+][-]
  1. procedure TForm2.InsertRowsClick(Sender: TObject);
  2. var
  3.   sa: TStringArray;
  4.   s: string;
  5.   i : integer;
  6. begin
  7.   s := Clipboard.AsText;
  8.   sa := s.Split([Lineending]);
  9.   i := 0;
  10.   while sa[i] <> '' do
  11.   begin
  12.     StringGrid1.InsertRowWithValues(StringGrid1.Row+1, ['']);
  13.     Inc(i);
  14.   end;
  15. end;  
  16.  
« Last Edit: October 07, 2021, 07:36:34 pm by bobonwhidbey »
Lazarus 3.0RC2, FPC 3.2.2 x86_64-win64-win32/win64

 

TinyPortal © 2005-2018