View Issue Details

IDProjectCategoryView StatusLast Update
0002215JEDI VCL00 JVCL Componentspublic2004-10-13 00:56
ReporterSimesAssigned Touser72 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version3.00 BETA 2 
Target VersionFixed in Version3.00 RC 1 
Summary0002215: TJvFindReplaceDialog whole word check is dubious.
DescriptionTJvFindReplaceDialog whole word check fails if find text is present at beginning or end of string.
Additional Informationprocedure TForm1.Button1Click(Sender: TObject);
var
  JvFindReplace: TJvFindReplace;
begin
  Edit1.Text := 'Me ';
  JvFindReplace := TJvFindReplace.Create(Self);
  try
    JvFindReplace.EditControl := Edit1;
    JvFindReplace.ShowDialogs := false;
    JvFindReplace.FindText := 'Me';
    JvFindReplace.Options := [frWholeWord, frDown];
    JvFindReplace.Find;
  finally
    JvFindReplace.Free;
  end;
end;

The text is not found. Similarly if
  Edit1.Text := ' Me';
TagsNo tags attached.

Activities

user72

2004-10-12 13:21

  ~0005362

In FindInText, change:

Result.isWhole := IsValidWholeWord(S) or AnsiSameText(S, Text);

anonymous

2004-10-12 13:30

viewer   ~0005365

Peter, I believe procedure FindInText is incorrect. Run it through the debugger and see the value of S in the section:
  if Found > 0 then
  begin
    Result.StartAt := Found + FromPos - 1;
    Result.EndAt := Length(Search);
    S := Copy(Text, Result.StartAt - 1, Result.EndAt + 2); <-- this line is incorrect
    Result.isWhole := IsValidWholeWord(S);
    S := Copy(S, 1, Length(S) - 1); <-- (ALSO, THIS SHOULD BE -2)
    Result.isSameCase := (AnsiCompareStr(trim(Search), trim(S)) = 0);
  end;

Simes

2004-10-12 15:01

reporter   ~0005368

I believe the code should be:

function FindInText(const Text, Search: string; FromPos, ToPos: Integer; Fast: Boolean): TFoundText;
var
  Found: Integer;
  S: string;
begin
  Result.StartAt := -1; // assume failure
  if Fast then
    Found := BoyerMoore(PChar(AnsiUpperCase(Search)), PChar(AnsiUpperCase(Copy(Text, FromPos + 1, ToPos))))
  else
    Found := Pos(AnsiUpperCase(Search), AnsiUpperCase(Copy(Text, FromPos + 1, ToPos)));
  if Found > 0 then
  begin
    Result.StartAt := Found + FromPos - 1;
    Result.EndAt := Length(Search);
    S := Copy(Text, Result.StartAt - 1, Result.EndAt + 2);
    // check for extremes...
    // is find string the same as the whole string?
    if Length(Search) = Length(Text) then begin
      Result.isWhole := True;
      S := Text;
    end else begin
      // check for match at beginning or end of string
      if Result.StartAt - 1 < 0 then
        S := Copy(' ' + S, 1, Result.EndAt + 2);
      if Result.StartAt - 1 + Result.EndAt + 2 > Length(Text) then
        S := Copy(S + ' ', Length(Text)- Result.EndAt-1, Result.EndAt + 2);
      Result.isWhole := IsValidWholeWord(S);
      S := Copy(S, 2, Length(S) - 2);
    end;
    Result.isSameCase := (AnsiCompareStr(trim(Search), trim(S)) = 0);
  end;
end;

user72

2004-10-12 15:24

  ~0005369

Agree. Comitted to CVS

Issue History

Date Modified Username Field Change
2004-10-12 12:50 Simes New Issue
2004-10-12 13:21 user72 Note Added: 0005362
2004-10-12 13:21 user72 Status new => feedback
2004-10-12 13:30 anonymous Note Added: 0005365
2004-10-12 15:01 Simes Note Added: 0005368
2004-10-12 15:24 user72 Note Added: 0005369
2004-10-13 00:56 user72 Status feedback => resolved
2004-10-13 00:56 user72 Resolution open => fixed
2004-10-13 00:56 user72 Assigned To => user72