Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > SynUniHighlighter и SynEdit > Поиск и замена текста в SynEdit


Автор: ActioN 3.5.2005, 15:52
Пытаюсь реализовать поиск и замену информации в SynEdit, но никак неполучается. Подскажите, что нужно добавить или исправить, чтобы этот кусочек кода заработал
Код
TSynSearchOptions *sOpt = new TSynSearchOptions();
sOpt->operator =(ssoWholeWord,ssoMathCase); //как присвоить sOpt параметры ?
SynEdit1->SearchReplace(Edit1->Text,"",*sOpt);

SynEdit версии 1.0. C++ Builder версии 6.0

Автор: ActioN 5.5.2005, 00:29
Кто-нибудь мне поможет с этой проблеммой. Может кто-то уже сталкивался с чем-то похожим. Тут хотябы присвоить параметры переменной.

Автор: ActioN 7.5.2005, 00:50
Проблема решена. В билдере это делается так:
TSynSearchOptions Option;
Option = Option <<ssoWholeWord;

Автор: ActioN 9.5.2005, 22:59
Теперь столкнулся с новой проблемой. Как можно сделать подтверждение при замене. Пробовал использовать ssoPrompt. Если я правильно понял, то она означает, что при замене будет выдаваться сообщение типа "Заменить такой-то текст таким-то". Если все же она выполняет другую функцию, то как можно сделать такое - замену с подтверждением?
И еще заметил такие события в SynEdit OnReplaceText и OnSearchEngineOverride?
Вобщем как можно сделать подтверждение при замене?

Автор: Vit 9.5.2005, 23:16
Кусок из моей программы:

Код

  TGPSearch=record
              FindText:String;
              ReplaceText:String;
              Options:TSynSearchOptions;
            end;

    CurrentSearch:TGPSearch;

...

procedure TForm1.aFindExecute(Sender: TObject);
begin
  Find.FindText.Text:=CurrentSearch.FindText;
  if Find.showmodal=mrOk then
    begin
      DidSearchBackword:=False;
      CurrentSearch.FindText:=Find.FindText.Text;

      if Find.CaseSensitive.Checked then
        CurrentSearch.Options:=CurrentSearch.Options+[ssoMatchCase]
      else
        CurrentSearch.Options:=CurrentSearch.Options-[ssoMatchCase];

      if Find.Wholewords.Checked then
        CurrentSearch.Options:=CurrentSearch.Options+[ssoWholeWord]
      else
        CurrentSearch.Options:=CurrentSearch.Options-[ssoWholeWord];

      if Find.Direction.ItemIndex=1 then
        CurrentSearch.Options:=CurrentSearch.Options+[ssoBackwards]
      else
        CurrentSearch.Options:=CurrentSearch.Options-[ssoBackwards];

      if Find.Scope.ItemIndex=1 then
        CurrentSearch.Options:=CurrentSearch.Options+[ssoSelectedOnly]
      else
        CurrentSearch.Options:=CurrentSearch.Options-[ssoSelectedOnly];

      if Find.Origin.ItemIndex=1 then
        CurrentSearch.Options:=CurrentSearch.Options+[ssoEntireScope]
      else
        CurrentSearch.Options:=CurrentSearch.Options-[ssoEntireScope];

      CurrentSearch.Options:=CurrentSearch.Options-[ssoReplace];
      CurrentSearch.Options:=CurrentSearch.Options-[ssoReplaceAll];
      CurrentSearch.Options:=CurrentSearch.Options-[ssoPrompt];

      if PPageInfo(PageControl.ActivePage.Tag).Edit.SearchReplace(CurrentSearch.FindText, CurrentSearch.ReplaceText, CurrentSearch.Options)=0 then
        Showmessage('No matches found!');
    end;
end;


procedure TForm1.aFindNextExecute(Sender: TObject);
begin
  if DidSearchBackword then CurrentSearch.Options:=CurrentSearch.Options-[ssoBackwards];;
  if CurrentSearch.FindText='' then aFindExecute(nil)
  else
    begin
      CurrentSearch.Options:=CurrentSearch.Options-[ssoEntireScope];
      if PPageInfo(PageControl.ActivePage.Tag).Edit.SearchReplace(CurrentSearch.FindText, CurrentSearch.ReplaceText, CurrentSearch.Options)=0 then
        Showmessage('No matches found!');
    end;
end;

procedure TForm1.aFindPreviousExecute(Sender: TObject);
begin
  DidSearchBackword:=True;
  CurrentSearch.Options:=CurrentSearch.Options+[ssoBackwards];
  if CurrentSearch.FindText='' then aFindExecute(nil)
  else
    begin
      CurrentSearch.Options:=CurrentSearch.Options-[ssoEntireScope]+[ssoBackwards];
      if PPageInfo(PageControl.ActivePage.Tag).Edit.SearchReplace(CurrentSearch.FindText, CurrentSearch.ReplaceText, CurrentSearch.Options)=0 then
        Showmessage('No matches found!');
    end;
end;

procedure TForm1.aReplaceExecute(Sender: TObject);
  var Modal:Integer;
begin
  Replace.FindText.Text:=CurrentSearch.FindText;
  Replace.ReplaceText.Text:=CurrentSearch.ReplaceText;
  Modal:=Replace.showmodal;
  if Modal in [mrOk, mrYesToAll] then
    begin
      DidSearchBackword:=False;
      CurrentSearch.FindText:=Replace.FindText.Text;
      CurrentSearch.ReplaceText:=Replace.ReplaceText.Text;

      if Replace.CaseSensitive.Checked then
        CurrentSearch.Options:=CurrentSearch.Options+[ssoMatchCase]
      else
        CurrentSearch.Options:=CurrentSearch.Options-[ssoMatchCase];

      if Replace.Wholewords.Checked then
        CurrentSearch.Options:=CurrentSearch.Options+[ssoWholeWord]
      else
        CurrentSearch.Options:=CurrentSearch.Options-[ssoWholeWord];

      if Replace.Direction.ItemIndex=1 then
        CurrentSearch.Options:=CurrentSearch.Options+[ssoBackwards]
      else
        CurrentSearch.Options:=CurrentSearch.Options-[ssoBackwards];

      if Replace.Scope.ItemIndex=1 then
        CurrentSearch.Options:=CurrentSearch.Options+[ssoSelectedOnly]
      else
        CurrentSearch.Options:=CurrentSearch.Options-[ssoSelectedOnly];

      if Replace.Origin.ItemIndex=1 then
        CurrentSearch.Options:=CurrentSearch.Options+[ssoEntireScope]
      else
        CurrentSearch.Options:=CurrentSearch.Options-[ssoEntireScope];

      CurrentSearch.Options:=CurrentSearch.Options+[ssoReplace];
      if Modal = mrYesToAll then
        CurrentSearch.Options:=CurrentSearch.Options+[ssoReplaceAll]
      else
        CurrentSearch.Options:=CurrentSearch.Options-[ssoReplaceAll];


      if Replace.Prompt.checked then
        CurrentSearch.Options:=CurrentSearch.Options+[ssoPrompt]
      else
        CurrentSearch.Options:=CurrentSearch.Options-[ssoPrompt];

      if PPageInfo(PageControl.ActivePage.Tag).Edit.SearchReplace(CurrentSearch.FindText, CurrentSearch.ReplaceText, CurrentSearch.Options)=0 then
        Showmessage('No matches found!');
    end;
end;

procedure TForm1.SynEditReplaceText(Sender: TObject; const ASearch,
  AReplace: String; Line, Column: Integer; var Action: TSynReplaceAction);
begin
  case MessageDlg(format('Replace string ''%s'' with ''%s''?',[ASearch, AReplace]),mtWarning,[mbYes, mbNo, mbAll, mbCancel],0) of
    mrYes: Action := raReplace;
    mrNo: Action := raSkip;
    mrAll: Action := raReplaceAll;
    mrCancel: Action := raCancel;
  end;
end;


Автор: ActioN 10.5.2005, 23:45
Vit, Спасибо, буду пробовать.

Автор: ActioN 1.8.2005, 00:35
Для чего нужно свойство SynEdit'a - SearchEngine? И почему он отказывается работать без этого компонента (SynEditSearch или SynEditRegExSearch).
Добавил на форму компонент SynEditSearch, написал поиск, добавил в событие SynEdit'а OnReplaceText подтверждение на замену, а SynEdit даже нехочет реагировать на него.
Почему так и как это исправить?
P.S. использую версию CVS-2004-08-25

Автор: Vitalik 1.8.2005, 10:33
Свойство SearchEngine служит для выбора компонента поиска (TSynEditSearch - обычный поиск или TSynEditRegexSearch - поиск с использованием регулярных выражений).
После выбора компонента для SearchEngine можно использовать метод SynEdit.SeachReplace, который будет искать и если нужно заменять нужный текст.

Очень хорошая демка по поиску находится в %SynEdit%\Demos\SearchReplaceDemo\ http://forum.sources.ru/smiles/Main/wink.gif

Автор: ActioN 2.8.2005, 00:39
Так а что я нетак делаю? Свойство SearchEngine=SynEditSearch, потом где-то при нажатии на кнопку пишу код, который должнен заменять текст (Replace). В версии SynEdit 1.0 было событие такое OnReplace. Во 2-й версии оно тоже есть. Прописал все так же, но при нажатии на кнопку и замене текста это событие почему-то не обрабатывается.


Код

//Это при нажатии на кнопку "Заменить"
//---------------------------------------------------------------
TSynSearchOptions OptionRep;
OptionRep = OptionRep <<ssoPrompt;
if (frmCodeEdit->MainEdit->SearchReplace(frmReplace->ComboBox1->Text,frmReplace->ComboBox2->Text,OptionRep) == 0)
    MessageBox(0,"Искомый текст не найден",0,MB_ICONINFORMATION);
else
    frmReplace->Close();
//---------------------------------------------------------------
//Это при замене (должно вывести подтверждение замены, а его нет)
//---------------------------------------------------------------
void __fastcall TfrmCodeEdit::MainEditReplaceText(TObject *Sender,
      const AnsiString ASearch, const AnsiString AReplace, int Line,
      int Column, TSynReplaceAction &Action)
{
  switch (MessageDlg("Заменить текст '"+ASearch+"' текстом '"+AReplace+"'?",mtInformation,TMsgDlgButtons() <<mbYes <<mbNo <<mbAll <<mbCancel,0))
  {
      case mrYes: Action = raReplace;
          break;
      case mrNo:  Action = raSkip;
          break;
      case mrAll: Action = raReplaceAll;
          break;
      case mrCancel:  Action = raCancel;
  };
} 
//---------------------------------------------------------------

Автор: Vitalik 2.8.2005, 09:47
Всё дело в том, что нужно в OptionRep добавить еще свойства ssoReplace и ssoReplaceAll smile

То есть четвёртая строчка должна быть:
Код
OptionRep = OptionRep <<ssoPrompt <<ssoReplace << ssoReplaceAll;
http://forum.sources.ru/smiles/Main/wink.gif

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)