View Issue Details

IDProjectCategoryView StatusLast Update
0001559JEDI VCL00 JVCL Componentspublic2004-04-03 00:37
Reporterboerema1Assigned Touser72 
PrioritynormalSeveritymajorReproducibilityalways
Status resolvedResolutionfixed 
Product Version 
Target VersionFixed in Version 
Summary0001559: JvRichEdit replace dialog replaces wrong text
DescriptionWhen using the replace dialog in JvRichEdit it replaces the wrong text when you first press find next to find a first occurence and then press replace to replace that occurence.
Instead it searches for and replaces the occurence after the current one.
Additional InformationAfter replacing one occurence it also doesn't search for and select the next occurence.
TagsNo tags attached.

Activities

user72

2004-04-02 06:42

  ~0003578

I think this should fix it:

procedure TJvCustomRichEdit.ReplaceDialogReplace(Sender: TObject);
var
  Cnt, ASelStart: Integer;
  SaveSelChange: TNotifyEvent;
begin
  with TReplaceDialog(Sender) do
  begin
    if frReplaceAll in Options then
    begin
      Cnt := 0;
      SaveSelChange := FOnSelChange;
      TJvRichEditStrings(Lines).EnableChange(False);
      try
        FOnSelChange := nil;
        while FindEditText(TFindDialog(Sender), False, False) do
        begin
          SelText := ReplaceText;
          Inc(Cnt);
        end;
        if Cnt = 0 then
          TextNotFound(TFindDialog(Sender))
        else
          AdjustFindDialogPosition(TFindDialog(Sender));
      finally
        TJvRichEditStrings(Lines).EnableChange(True);
        FOnSelChange := SaveSelChange;
        if Cnt > 0 then
        begin
          Change;
          SelectionChange;
        end;
      end;
    end
    else
    if frReplace in Options then
    begin
      if SelLength > 0 then
      begin
        SelText := ReplaceText;
        FindEditText(TFindDialog(Sender),True, True);
      end
      else if FindEditText(TFindDialog(Sender), True, True) then
      begin
        ASelStart := SelStart;
        SelText := ReplaceText;
        SelStart := ASelStart;
        SelLength := Length(ReplaceText);
      end;
    end;
  end;
end;

boerema1

2004-04-02 07:12

reporter   ~0003579

This works mostly.
But when directly pressing replace without first pressing find first the first occurence of text is found and replaced but the replaced text stays selected instead of searching for the next occurence.
Also if you had some other text selected before calling the replace dialog and then directly pressing replace that selected text wil be replaced which is not what you want.

user72

2004-04-02 08:08

  ~0003580

Last edited: 2004-04-02 09:16

OK, try replacing the last part with:
...
    else if frReplace in Options then
    begin
      if SelText = ReplaceText then
      begin
        FindEditText(TFindDialog(Sender), True, True);
      end
      else if MatchesText(SelText, FindText, Options) then
      begin
        SelText := ReplaceText;
        FindEditText(TFindDialog(Sender), True, True);
      end
      else if FindEditText(TFindDialog(Sender), True, True) then
      begin
        ASelStart := SelStart;
        SelText := ReplaceText;
        SelStart := ASelStart;
        SelLength := Length(ReplaceText);
      end;

MatchesText looks like this:

  function MatchesText(const FindText, FoundText:string; Options:TFindOptions):boolean;
  begin
    if frMatchCase in Options then
      Result := AnsiSameStr(FindText, FoundText)
    else
      Result := AnsiSameText(FindText, FoundText)
  end;

The only problem with this is when there is no selection and you click "Replace". It then finds, replaces and finds again. I don't know if this is the desired behavior.

BTW, TJvRichEdit.HideSelection must be false to see the selection even when the dialog has focus.

edited on: 04-02-04 09:16

boerema1

2004-04-02 09:53

reporter   ~0003584

When no text is selected pressing Replace does not find, replace and find next. It only replaces and selects the replacement.

I just looked at the way Word and WordPad behave in this situation:
If no text is selected pressing replace acts the same as presing find first, meaning it finds and selects the text but does not replace it. So this should probably also be the way this replace dialog should work. (I previously tested only with MetaPad which apparantly has non standard behaviour in that it directly replaces text and finds and selects next occurence.)

user72

2004-04-02 10:35

  ~0003586

Let's break it down:
1. if no selection, find next occurence and select it (but do not replace)
2. if selection is FindText, replace it and find next and select it (but do not replace)
3. if selection is anything else, find next and select it (but do not replace)

Is that the desired behavior?

user72

2004-04-02 10:46

  ~0003587

Sometimes it's just too simple:
...
    else if frReplace in Options then
    begin
      if MatchesText(SelText, FindText, Options) then
        SelText := ReplaceText;
      FindEditText(TFindDialog(Sender), True, True);
    end;

This felt "natural" when I tested...

boerema1

2004-04-02 11:05

reporter   ~0003601

Very nice.
As far as i can see this works perfect.
Thanks.

user72

2004-04-03 00:37

  ~0003616

Great. Updated in CVS

Issue History

Date Modified Username Field Change
2004-04-01 13:45 boerema1 New Issue
2004-04-02 06:42 user72 Note Added: 0003578
2004-04-02 06:42 user72 Status new => assigned
2004-04-02 06:42 user72 Assigned To => user72
2004-04-02 07:12 boerema1 Note Added: 0003579
2004-04-02 08:08 user72 Note Added: 0003580
2004-04-02 09:16 user72 Note Edited: 0003580
2004-04-02 09:53 boerema1 Note Added: 0003584
2004-04-02 10:35 user72 Note Added: 0003586
2004-04-02 10:46 user72 Note Added: 0003587
2004-04-02 11:05 boerema1 Note Added: 0003601
2004-04-03 00:37 user72 Status assigned => resolved
2004-04-03 00:37 user72 Resolution open => fixed
2004-04-03 00:37 user72 Note Added: 0003616