TCustomSynEdit.SearchReplace function always returns 0, even if it finds (and replaces) text. (Patch proposed)
Original Reporter info from Mantis: Bart @flyingsheep
-
Reporter name: Bart Broersma
Original Reporter info from Mantis: Bart @flyingsheep
- Reporter name: Bart Broersma
Description:
While trying to patch and test the TFindDialog and TReplaceDialog I stumbled on this annoying bug.
The SearchReplace function of TCustomSynEdit should return the number of occasions that the text to be found is actually found.
However it returns 0 (zero) every time, even if it finds (and replaces) the foud text.
in
function TCustomSynEdit.SearchReplace(const ASearch, AReplace: string;
AOptions: TSynSearchOptions): integer;
there seems to be a different search strategy depending on the SYN_LAZARUS conditional define.
If this is set (as I guess it is in Lazarus), then the Result of the function never gets updated.
This makes it impossible to reliably use the function and inform the user wether or not the text he wants to find/replace is actually found.
Steps to reproduce:
On a form place a TSynMemo component and a button.
Fill the SynMemo Lines property at design time like this:
test
test
test
test
In the onclick event of the button do this
procedure TForm1.Button1Click(Sender: TObject);
var sOptions: TSynSearchOptions;
begin
sOptions := [ssoReplaceAll];
with SynMemo1 do
begin
if SearchReplace('test','replaced',sOptions) = 0 then
MessageDlg('Text not found',mtError,[mbOk],0)
else
if (ssoReplace in sOptions) and not (ssoReplaceAll in sOptions) then
begin
sOptions := sOptions - [ssoReplace];
SearchReplace(FindText,'',sOptions); //Search and select next occurence
end;
end;
end;
Build the program, click Button1.
Expected behaviour:
- All occurrences of 'test' are replaced by 'replaced'
- The function SearchReplace returns 4
- No errormessage is shown
Observed behaviour
- All occurrences of 'test' are replaced by 'replaced'
- The function SearchReplace returns 0
- The errormessage "Text not found" is shown, despite the fact it is obviously found.
Additional information:
From TCustomEdit.FindRepace()
...
try
{$IFDEF SYN_LAZARUS}
//DebugLn(['TCustomSynEdit.SearchReplace ptStart=',dbgs(ptStart),' ptEnd=',dbgs(ptEnd),' ASearch="',dbgstr(ASearch),'" AReplace="',dbgstr(AReplace),'"']);
while fTSearch.FindNextOne(Lines,ptStart,ptEnd,ptFoundStart,ptFoundEnd) do
begin
//DebugLn(['TCustomSynEdit.SearchReplace FOUND ptStart=',dbgs(ptStart),' ptEnd=',dbgs(ptEnd),' ptFoundStart=',dbgs(ptFoundStart),' ptFoundEnd=',dbgs(ptFoundEnd)]);
// check if found place is entirely in range
if (fSelectionMode<>smColumn)
or ((ptFoundStart.Y=ptFoundEnd.Y)
and (ptFoundStart.X >= ptStart.X) and (ptFoundEnd.X <= ptEnd.X)) then
begin
// pattern found
// Select the text, so the user can see it in the OnReplaceText event
// handler or as the search result.
//I think this might fix it, not sure
Inc(Result); // <====
BlockBegin := ptFoundStart;
if bBackward then CaretXY := BlockBegin;
BlockEnd := ptFoundEnd;
if not bBackward then CaretXY := ptFoundEnd;
// If it's a 'search' only we can leave the procedure now.
if not (bReplace or bReplaceAll) then exit;
Mantis conversion info:
- Mantis ID: 8470
- OS: WinMe
- OS Build: MS
- Build: 10176
- Platform: i386
- Version: 0.9.20
- Fixed in version: 0.9.24
- Fixed in revision: 10827 (#4652c75b)
- Target version: 0.9.24