Jean-Marc Lasgouttes wrote: > >> Is the thing correct when there is no selection? I would think the > >> replace() then searches for the next hit. Of course, this is > >> difficult to get right, but at least a FIXME would be useful. > > Jürgen> I would think everythink would be OK if the "replace" and > Jürgen> "replace all" buttons would be greyed out if disabled. Why > Jürgen> should "replace" do nothing but search for the next hit? > > My reading of the replace() function in lyxfind.cpp seemed to imply > this. But I may be wrong.
No, you're right. I've missed this. The attached patch proposes a different approach that looks more consistent. > In particular, it seems to me that > stringSelected is eventually invoked and can do an extra search. ??? > >> What happens when there is a multi paragraph selection? Does LyX > >> just crash? > > Jürgen> No. It does nothing (as it should IMHO). > > + DocIterator beg = cur.selectionBegin(); > + DocIterator end = cur.selectionEnd(); > + bool enabled = true; > + for (pos_type p = beg.pos() ; p < end.pos() ; ++p) { > + if (cur.paragraph().isDeleted(p)) > + enabled = false; > + } > > reading the code above, I would say that it crashes if selectionBegin > and selectionEnd are not the same paragraph and the paragraphs have > different number of characters. First, can you even tell me which > paragraph is cur.paragraph()? > > I think a test should be added. I see. Like in the attached? (I don't see the need to do the test for multiple paragraphs) > JMarc Jürgen
Index: src/BufferView.cpp =================================================================== --- src/BufferView.cpp (Revision 18821) +++ src/BufferView.cpp (Arbeitskopie) @@ -693,6 +693,7 @@ case LFUN_NOTE_NEXT: case LFUN_REFERENCE_NEXT: case LFUN_WORD_FIND: + case LFUN_WORD_REPLACE: case LFUN_MARK_OFF: case LFUN_MARK_ON: case LFUN_MARK_TOGGLE: @@ -704,10 +705,6 @@ flag.enabled(true); break; - case LFUN_WORD_REPLACE: - flag.enabled(!cur.paragraph().isDeleted(cur.pos())); - break; - case LFUN_LABEL_GOTO: { flag.enabled(!cmd.argument().empty() || getInsetByCode<InsetRef>(cur, Inset::REF_CODE)); @@ -953,9 +950,21 @@ find(this, cmd); break; - case LFUN_WORD_REPLACE: - replace(this, cmd); + case LFUN_WORD_REPLACE: { + bool has_deleted = false; + if (cur.selection()) { + DocIterator beg = cur.selectionBegin(); + DocIterator end = cur.selectionEnd(); + if (beg.pit() == end.pit()) { + for (pos_type p = beg.pos() ; p < end.pos() ; ++p) { + if (cur.paragraph().isDeleted(p)) + has_deleted = true; + } + } + } + replace(this, cmd, has_deleted); break; + } case LFUN_MARK_OFF: cur.clearSelection(); Index: src/lyxfind.cpp =================================================================== --- src/lyxfind.cpp (Revision 18821) +++ src/lyxfind.cpp (Arbeitskopie) @@ -298,7 +298,7 @@ } -void replace(BufferView * bv, FuncRequest const & ev) +void replace(BufferView * bv, FuncRequest const & ev, bool has_deleted) { if (!bv || ev.action != LFUN_WORD_REPLACE) return; @@ -319,23 +319,34 @@ Buffer * buf = bv->buffer(); - int const replace_count = all - ? replaceAll(bv, search, rplc, casesensitive, matchword) - : replace(bv, search, rplc, casesensitive, matchword, forward); - - if (replace_count == 0) { - // emit message signal. - buf->message(_("String not found!")); - } else { - if (replace_count == 1) { + if (!has_deleted) { + int const replace_count = all + ? replaceAll(bv, search, rplc, casesensitive, matchword) + : replace(bv, search, rplc, casesensitive, matchword, forward); + + if (replace_count == 0) { // emit message signal. - buf->message(_("String has been replaced.")); + buf->message(_("String not found!")); } else { - docstring str = convert<docstring>(replace_count); - str += _(" strings have been replaced."); + if (replace_count == 1) { + // emit message signal. + buf->message(_("String has been replaced.")); + } else { + docstring str = convert<docstring>(replace_count); + str += _(" strings have been replaced."); + // emit message signal. + buf->message(str); + } + } + } else { + // if we have deleted characters, we do not replace at all, but + // rather search for the next occurence + bool const found = find(bv, search, + casesensitive, matchword, forward); + + if (!found) // emit message signal. - buf->message(str); - } + bv->message(_("String not found!")); } } Index: src/lyxfind.h =================================================================== --- src/lyxfind.h (Revision 18821) +++ src/lyxfind.h (Arbeitskopie) @@ -52,7 +52,7 @@ * \c ev.argument and act on it. * The string is encoded by \c replace2string. */ -void replace(BufferView * bv, FuncRequest const &); +void replace(BufferView * bv, FuncRequest const &, bool has_deleted = false); /// find the next change in the buffer bool findNextChange(BufferView * bv);