Recent

Author Topic: [SOLVED]I implemented the undo/redo method,but it doesn't work properly at Linux  (Read 7613 times)

tomitomy

  • Sr. Member
  • ****
  • Posts: 251
Please visit the new version through the link bollow(support undo by word):
https://forum.lazarus.freepascal.org/index.php/topic,54069.0.html



I solved this problem, see:
http://forum.lazarus.freepascal.org/index.php/topic,38714.0.html

Thanks for Handoko's help, and thanks for accorp, he fixes TMemo's BUG. Thank you very much both!
« Last Edit: April 11, 2021, 07:08:31 am by tomitomy »

tomitomy

  • Sr. Member
  • ****
  • Posts: 251
The following code also has the same problem:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   i: Integer;
  4. begin
  5.   Memo1.Text := 'abcdefg';
  6.   for i := 1 to 5 do begin
  7.     Memo1.SelStart := 1;
  8.     Memo1.SelLength := 2;
  9.     Memo1.SelText := 'a';
  10.   end;
  11. end;

The result should be ‘aa', which is correct in Windows, but it is 'abcdefgaaaaa' in Linux.

Handoko

  • Hero Member
  • *****
  • Posts: 5149
  • My goal: build my own game engine using Lazarus
I tested on Lazarus 1.8.0RC5 Linux 64 Gtk2 and yes it is a bug in TMemo.SelText := something.

I checked into the source code (WSStdCtrl.pas) and I found this code seems not correct:
Code: Pascal  [Select][+][-]
  1. class procedure TWSCustomEdit.SetSelText(const ACustomEdit: TCustomEdit;
  2.   const NewSelText: string);
  3. var
  4.   OldText, NewText: string;
  5.   OldPos: Integer;
  6. begin
  7.   OldPos := ACustomEdit.SelStart;
  8.   OldText := ACustomEdit.Text;
  9.   NewText := UTF8Copy(OldText, 1, OldPos) +
  10.              NewSelText +
  11.              UTF8Copy(OldText, OldPos + ACustomEdit.SelLength + 1, MaxInt);
  12.   ACustomEdit.Text := NewText;
  13.   ACustomEdit.SelStart := OldPos + UTF8Length(NewSelText);
  14. end;
The SelStart on line #7 does not give the correct value.

Do you already have account in the bug report forum? If not, you can create an account there and submit report this bug. Or if you want, I can help you submit this bug too.
« Last Edit: October 20, 2017, 05:23:18 am by Handoko »

tomitomy

  • Sr. Member
  • ****
  • Posts: 251
Do you already have account in the bug report forum? If not, you can create an account there and submit report this bug. Or if you want, I can help you submit this bug too.

No, I have not account in the bug report forum, please help me to submit it, my English is not good, and I don't know how to report bug. Thak you very much!
« Last Edit: October 20, 2017, 07:44:10 am by tomitomy »

Handoko

  • Hero Member
  • *****
  • Posts: 5149
  • My goal: build my own game engine using Lazarus
I have submitted the issue to the bug tracker forum:
https://bugs.freepascal.org/view.php?id=32583

tomitomy

  • Sr. Member
  • ****
  • Posts: 251
I have submitted the issue to the bug tracker forum:
https://bugs.freepascal.org/view.php?id=32583

Thank you very much!

tomitomy

  • Sr. Member
  • ****
  • Posts: 251
https://bugs.freepascal.org/view.php?id=32583

This BUG has been repaired, but there is still a problem, and the following code doesn't get the right result:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   Memo1.Text := #10'abc';
  4.   Memo1.SelStart := 0;
  5.   Memo1.SelLength := 1;
  6.   Memo1.SelText := 'a';
  7. end;

The result should be 'aabc', but it's #10'abca'.

@Handoko, Can you help me to submit it again? Thank you!
« Last Edit: October 23, 2017, 06:02:01 pm by tomitomy »

Handoko

  • Hero Member
  • *****
  • Posts: 5149
  • My goal: build my own game engine using Lazarus
Have you applied the patch? Or tried the revision r56138 or above?

tomitomy

  • Sr. Member
  • ****
  • Posts: 251
Have you applied the patch? Or tried the revision r56138 or above?

I have applied the patch. and This code works normally:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   i: Integer;
  4. begin
  5.   Memo1.Text := 'abcdefg';
  6.   for i := 1 to 5 do begin
  7.     Memo1.SelStart := 1;
  8.     Memo1.SelLength := 2;
  9.     Memo1.SelText := 'a';
  10.   end;  // Result is 'aa'
  11. end;

But this code is not normal:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   Memo1.Text := 'abc';
  4.   Memo1.SelStart := 0;
  5.   Memo1.SelLength := 1;
  6.   Memo1.SelText := 'd';   // Result should be 'dbc', but is 'abcd'
  7. end;

Handoko

  • Hero Member
  • *****
  • Posts: 5149
  • My goal: build my own game engine using Lazarus
I have submitted the information to the bug tracker forum.

tomitomy

  • Sr. Member
  • ****
  • Posts: 251
Re: I implemented the undo/redo method, but it doesn't work properly at Linux
« Reply #10 on: October 23, 2017, 06:51:55 pm »
I have submitted the information to the bug tracker forum.

Thank you very much!

tomitomy

  • Sr. Member
  • ****
  • Posts: 251
Re: I implemented the undo/redo method, but it doesn't work properly at Linux
« Reply #11 on: October 24, 2017, 08:00:11 am »
I have applied the attached patch, and there is still a problem:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   Memo1.Text := 'abcd';
  4.   Memo1.SelStart := 1;
  5.   Memo1.SelLength := 1;
  6.   Memo1.SelText := 'x';
  7.   Memo1.SelText := 'x'; // should be 'axxcd', but is 'axxd'
  8.   Memo1.SetFocus;
  9.   // Memo1.SelLegth was not updated after Memo1.SelText:=something.
  10.   // Memo1.SelLegth should be zero after Memo1.SelText:=something.
  11.   writeln(Memo1.SelStart, ' ', Memo1.SelLength);
  12. end;

And I have a new problem about SelText:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   Memo1.SelStart := 0;
  4.   Memo1.SelLength := 0;
  5.   Memo1.SelText := 'xxx';
  6.   Memo1.SetFocus;
  7.   writeln('Button1: ', Memo1.SelStart, ' ', Memo1.SelLength);
  8. end;
  9.  
  10. procedure TForm1.Memo1Change(Sender: TObject);
  11. begin
  12.   // After Click Button1, I want get Memo1.SelStart here, but the Result is wrong.
  13.   // If I type text in Memo, the Result is right.
  14.   writeln('OnChange: ', Memo1.SelStart, ' ', Memo1.SelLength);
  15. end;

The new problem is also in windows system, is it a bug or a feature? If it‘s a feature, how to achieve my needs.



tomitomy

  • Sr. Member
  • ****
  • Posts: 251
Re: I implemented the undo/redo method, but it doesn't work properly at Linux
« Reply #12 on: October 24, 2017, 08:42:15 am »
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   Memo1.SelStart := 0;
  4.   Memo1.SelLength := 3;
  5.   Memo1.SelText := 'abc';
  6. end;

This code does not mean selecting three characters, and then pasting 'abc', They trigger different events.

I'm afraid that I can't go through this path to implement Undo and Redo.

The demo in the attachment almost works normally, but I still have problems when I use it, and I can't find the problem.

The following code has different results in Windows and Linux, when using Ctrl+A, then Ctrl+C, and then Ctrl+V.
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Memo1Change(Sender: TObject);
  2. begin
  3.   Writeln(Memo1.Text);
  4. end;
« Last Edit: October 24, 2017, 10:13:53 am by tomitomy »

tomitomy

  • Sr. Member
  • ****
  • Posts: 251
Re: I implemented the undo/redo method, but it doesn't work properly at Linux
« Reply #13 on: October 24, 2017, 03:48:32 pm »
I registered an account in the bug report forum, And added a note about SelLength in the bug report. thank you, Handoko, you're a kind man!

I can't implement the Undo and Redo functions through the OnChange event, because the OnChange event has different performance under Windows and Linux, and I couldn't get the Text and SelStart I needed in the Onchange event, and my ability is limited. I hope the official can implement TMemo's Undo and Redo functions, because it is the most basic function, without this function, the content of TMemo is like losing protection, it is very uneasy to use.

Thank you for the efforts made by community members for Lazarus, and hope Lazarus is getting better and better.

Handoko

  • Hero Member
  • *****
  • Posts: 5149
  • My goal: build my own game engine using Lazarus
Re: I implemented the undo/redo method, but it doesn't work properly at Linux
« Reply #14 on: October 24, 2017, 04:32:09 pm »
Sorry, I'm late. Yesterday I was busy trying to upgrade my Ubuntu 17.04.
I saw you already added the note at the bug report.

Have you tried TSynEdit? I wrote myself a small programs to help me organize my notes. I got several problems with TMemo, one of the issue was undo/redo. So I used TSynEdit. You can think TSynEdit is a more powerful version of TMemo, the syntax-highlighting can be disabled so it will give the result as a TMemo. Maybe you can try it.
http://wiki.freepascal.org/TSynEdit

 

TinyPortal © 2005-2018