Hi,

please, find attached a preliminary replace functionality
(just try the "ReplaceNext button"), made while traveling,
as usual :-). Like with find, there are
some stability issues if you search (and replace) backwards,
but hopefully I'll find the time to fix that as well.

Bye,

   T.

Index: src/frontends/qt4/FindAndReplace.cpp
===================================================================
--- src/frontends/qt4/FindAndReplace.cpp	(revisione 28060)
+++ src/frontends/qt4/FindAndReplace.cpp	(copia locale)
@@ -80,30 +80,32 @@
 	return QWidget::eventFilter(obj, event);
 }
 
+static docstring buffer_to_latex(Buffer & buffer) {
+	OutputParams runparams(&buffer.params().encoding());
+	odocstringstream os;
+	runparams.nice = true;
+	runparams.flavor = OutputParams::LATEX;
+	runparams.linelen = 80; //lyxrc.plaintext_linelen;
+	// No side effect of file copying and image conversion
+	runparams.dryrun = true;
+	buffer.texrow().reset();
+	ParagraphList::const_iterator pit = buffer.paragraphs().begin();
+	ParagraphList::const_iterator const end = buffer.paragraphs().end();
+	for (; pit != end; ++pit) {
+		TeXOnePar(buffer, buffer.text(), pit, os, buffer.texrow(), runparams);
+		LYXERR(Debug::DEBUG, "searchString up to here: " << os.str());
+	}
+	return os.str();
+}
 
-void FindAndReplaceWidget::findAdv(bool casesensitive,
-		bool matchword, bool backwards,
-		bool expandmacros, bool ignoreformat)
+void FindAndReplaceWidget::findAndReplace(
+	bool casesensitive, bool matchword, bool backwards,
+	bool expandmacros, bool ignoreformat, bool replace)
 {
 	Buffer & buffer = find_work_area_->bufferView().buffer();
 	docstring searchString;
 	if (!ignoreformat) {
-		OutputParams runparams(&buffer.params().encoding());
-		odocstringstream os;
-		runparams.nice = true;
-		runparams.flavor = OutputParams::LATEX;
-		runparams.linelen = 80; //lyxrc.plaintext_linelen;
-		// No side effect of file copying and image conversion
-		runparams.dryrun = true;
-		buffer.texrow().reset();
-//		latexParagraphs(buffer, buffer.paragraphs(), os, buffer.texrow(), runparams);
-		ParagraphList::const_iterator pit = buffer.paragraphs().begin();
-		ParagraphList::const_iterator const end = buffer.paragraphs().end();
-		for (; pit != end; ++pit) {
-			TeXOnePar(buffer, buffer.text(), pit, os, buffer.texrow(), runparams);
-			LYXERR0("searchString up to here: " << os.str());
-		}
-		searchString = os.str();
+		searchString = buffer_to_latex(buffer);
 	} else {
 		ParIterator it = buffer.par_iterator_begin();
 		ParIterator end = buffer.par_iterator_end();
@@ -124,8 +126,15 @@
 		return;
 	}
 	bool const regexp = to_utf8(searchString).find("\\regexp") != std::string::npos;
-	FindAdvOptions opt(searchString, casesensitive, matchword, ! backwards,
-		expandmacros, ignoreformat, regexp);
+	docstring replaceString;
+	if (replace) {
+		Buffer & replace_buffer = replace_work_area_->bufferView().buffer();
+		replaceString = buffer_to_latex(replace_buffer);
+	} else {
+		replaceString = from_utf8(LYX_FR_NULL_STRING);
+	}
+	FindAndReplaceOptions opt(searchString, casesensitive, matchword, ! backwards,
+		expandmacros, ignoreformat, regexp, replaceString);
 	LYXERR(Debug::DEBUG, "Dispatching LFUN_WORD_FINDADV" << std::endl);
 	std::ostringstream oss;
 	oss << opt;
@@ -137,16 +146,17 @@
 }
 
 
-void FindAndReplaceWidget::find(bool backwards)
+void FindAndReplaceWidget::findAndReplace(bool backwards, bool replace)
 {
 	// FIXME: create a Dialog::returnFocus() or something instead of this:
 	view_.setCurrentWorkArea(view_.currentMainWorkArea());
 	// FIXME: This should be an LFUN.
-	findAdv(caseCB->isChecked(),
-			wordsCB->isChecked(),
-			backwards,
-			expandMacrosCB->isChecked(),
-			ignoreFormatCB->isChecked());
+	findAndReplace(caseCB->isChecked(),
+		wordsCB->isChecked(),
+		backwards,
+		expandMacrosCB->isChecked(),
+		ignoreFormatCB->isChecked(),
+		replace);
 	view_.currentMainWorkArea()->redraw();
 	find_work_area_->setFocus();
 }
@@ -176,20 +186,27 @@
 
 
 void FindAndReplaceWidget::on_findNextPB_clicked() {
-	find(false);
+	findAndReplace(false, false);
 }
 
 
 void FindAndReplaceWidget::on_findPrevPB_clicked() {
-	find(true);
+	findAndReplace(true, false);
 }
 
 
-void FindAndReplaceWidget::on_replacePB_clicked()
+void FindAndReplaceWidget::on_replaceNextPB_clicked()
 {
+	findAndReplace(false, true);
 }
 
 
+void FindAndReplaceWidget::on_replacePrevPB_clicked()
+{
+	findAndReplace(true, true);
+}
+
+
 void FindAndReplaceWidget::on_replaceallPB_clicked()
 {
 }
Index: src/frontends/qt4/FindAndReplace.h
===================================================================
--- src/frontends/qt4/FindAndReplace.h	(revisione 28060)
+++ src/frontends/qt4/FindAndReplace.h	(copia locale)
@@ -44,16 +44,14 @@
 
 	// add a string to the combo if needed
 	void remember(std::string const & find, QComboBox & combo);
-	void findAdv(bool casesensitive,
-			bool matchword, bool backwards,
-			bool expandmacros, bool ignoreformat);
+	void findAndReplace(
+		bool casesensitive, bool matchword, bool backwards,
+		bool expandmacros, bool ignoreformat, bool replace
+	);
 	void find(docstring const & str, int len, bool casesens,
 		  bool words, bool backwards, bool expandmacros);
-	void find(bool backwards);
+	void findAndReplace(bool backwards, bool replace);
 
-	void replace(docstring const & findstr,
-		     docstring const & replacestr,
-		     bool casesens, bool words, bool backwards, bool expandmacros, bool all);
 	bool eventFilter(QObject *obj, QEvent *event);
 
 	void virtual showEvent(QShowEvent *ev);
@@ -62,7 +60,8 @@
 protected Q_SLOTS:
 	void on_findNextPB_clicked();
 	void on_findPrevPB_clicked();
-	void on_replacePB_clicked();
+	void on_replaceNextPB_clicked();
+	void on_replacePrevPB_clicked();
 	void on_replaceallPB_clicked();
 	void on_closePB_clicked();
 	void on_regexpInsertCombo_currentIndexChanged(int index);
Index: src/frontends/qt4/ui/FindAndReplaceUi.ui
===================================================================
--- src/frontends/qt4/ui/FindAndReplaceUi.ui	(revisione 28060)
+++ src/frontends/qt4/ui/FindAndReplaceUi.ui	(copia locale)
@@ -66,7 +66,7 @@
       <rect>
        <x>0</x>
        <y>0</y>
-       <width>227</width>
+       <width>221</width>
        <height>351</height>
       </rect>
      </property>
@@ -90,8 +90,8 @@
           <rect>
            <x>0</x>
            <y>0</y>
-           <width>221</width>
-           <height>85</height>
+           <width>215</width>
+           <height>89</height>
           </rect>
          </property>
         </widget>
@@ -123,7 +123,7 @@
       <item row="5" column="0" >
        <widget class="QPushButton" name="replaceNextPB" >
         <property name="enabled" >
-         <bool>false</bool>
+         <bool>true</bool>
         </property>
         <property name="text" >
          <string>Replace Ne&amp;xt</string>
@@ -163,8 +163,8 @@
           <rect>
            <x>0</x>
            <y>0</y>
-           <width>221</width>
-           <height>85</height>
+           <width>215</width>
+           <height>89</height>
           </rect>
          </property>
         </widget>
@@ -186,7 +186,7 @@
       <item row="5" column="1" >
        <widget class="QPushButton" name="replacePrevPB" >
         <property name="enabled" >
-         <bool>false</bool>
+         <bool>true</bool>
         </property>
         <property name="text" >
          <string>Replace P&amp;rev</string>
Index: src/lyxfind.cpp
===================================================================
--- src/lyxfind.cpp	(revisione 28060)
+++ src/lyxfind.cpp	(copia locale)
@@ -30,6 +30,8 @@
 #include "ParIterator.h"
 #include "TexRow.h"
 #include "Text.h"
+#include "FuncRequest.h"
+#include "LyXFunc.h"
 
 #include "mathed/InsetMath.h"
 #include "mathed/InsetMathGrid.h"
@@ -531,7 +533,7 @@
  **/
 class MatchStringAdv {
 public:
-	MatchStringAdv(lyx::Buffer const & buf, FindAdvOptions const & opt);
+	MatchStringAdv(lyx::Buffer const & buf, FindAndReplaceOptions const & opt);
 
 	/** Tests if text starting at the supplied position matches with the one provided to the MatchStringAdv
 	 ** constructor as opt.search, under the opt.* options settings.
@@ -549,7 +551,7 @@
 	/// buffer
 	lyx::Buffer const & buf;
 	/// options
-	FindAdvOptions const & opt;
+	FindAndReplaceOptions const & opt;
 
 private:
 	/** Normalize a stringified or latexified LyX paragraph.
@@ -580,7 +582,7 @@
 };
 
 
-MatchStringAdv::MatchStringAdv(lyx::Buffer const & buf, FindAdvOptions const & opt)
+MatchStringAdv::MatchStringAdv(lyx::Buffer const & buf, FindAndReplaceOptions const & opt)
   : buf(buf), opt(opt)
 {
 	par_as_string = normalize(opt.search);
@@ -943,7 +945,7 @@
 } // anonym namespace
 
 
-docstring stringifyFromForSearch(FindAdvOptions const & opt,
+docstring stringifyFromForSearch(FindAndReplaceOptions const & opt,
 	DocIterator const & cur, int len)
 {
 	if (!opt.ignoreformat)
@@ -953,17 +955,17 @@
 }
 
 
-lyx::FindAdvOptions::FindAdvOptions(docstring const & search, bool casesensitive,
+lyx::FindAndReplaceOptions::FindAndReplaceOptions(docstring const & search, bool casesensitive,
 	bool matchword, bool forward, bool expandmacros, bool ignoreformat,
-	bool regexp)
+	bool regexp, docstring const & replace)
 	: search(search), casesensitive(casesensitive), matchword(matchword),
 	forward(forward), expandmacros(expandmacros), ignoreformat(ignoreformat),
-	regexp(regexp)
+	regexp(regexp), replace(replace)
 {
 }
 
 /// Perform a FindAdv operation.
-bool findAdv(BufferView * bv, FindAdvOptions const & opt)
+bool findAdv(BufferView * bv, FindAndReplaceOptions const & opt)
 {
 	DocIterator cur = bv->cursor();
 	int match_len = 0;
@@ -997,7 +999,9 @@
 	LYXERR(Debug::DEBUG, "Putting selection at " << cur << " with len: " << match_len);
 	bv->putSelectionAt(cur, match_len, ! opt.forward);
 	bv->message(_("Match found!"));
-	//bv->update();
+	if (opt.replace != docstring(from_utf8(LYX_FR_NULL_STRING))) {
+		dispatch(FuncRequest(LFUN_SELF_INSERT, opt.replace));
+	}
 
 	return true;
 }
@@ -1008,14 +1012,14 @@
 	if (!bv || ev.action != LFUN_WORD_FINDADV)
 		return;
 
-	FindAdvOptions opt;
+	FindAndReplaceOptions opt;
 	istringstream iss(to_utf8(ev.argument()));
 	iss >> opt;
 	findAdv(bv, opt);
 }
 
 
-ostringstream & operator<<(ostringstream & os, lyx::FindAdvOptions const & opt)
+ostringstream & operator<<(ostringstream & os, lyx::FindAndReplaceOptions const & opt)
 {
 	os << to_utf8(opt.search) << "\nEOSS\n"
 	   << opt.casesensitive << ' '
@@ -1023,14 +1027,15 @@
 	   << opt.forward << ' '
 	   << opt.expandmacros << ' '
 	   << opt.ignoreformat << ' '
-	   << opt.regexp;
+	   << opt.regexp << ' '
+	   << to_utf8(opt.replace) << "\nEOSS\n";
 
 	LYXERR(Debug::DEBUG, "built: " << os.str());
 
 	return os;
 }
 
-istringstream & operator>>(istringstream & is, lyx::FindAdvOptions & opt)
+istringstream & operator>>(istringstream & is, lyx::FindAndReplaceOptions & opt)
 {
 	LYXERR(Debug::DEBUG, "parsing");
 	string s;
@@ -1047,8 +1052,21 @@
 	LYXERR(Debug::DEBUG, "searching for: '" << s << "'");
 	opt.search = from_utf8(s);
 	is >> opt.casesensitive >> opt.matchword >> opt.forward >> opt.expandmacros >> opt.ignoreformat >> opt.regexp;
+	is.get();	// Waste space before replace string
+	s = "";
+	getline(is, line);
+	while (line != "EOSS") {
+		if (! s.empty())
+				s = s + "\n";
+		s = s + line;
+		if (is.eof())	// Tolerate malformed request
+				break;
+		getline(is, line);
+	}
 	LYXERR(Debug::DEBUG, "parsed: " << opt.casesensitive << ' ' << opt.matchword << ' ' << opt.forward << ' '
 		   << opt.expandmacros << ' ' << opt.ignoreformat << ' ' << opt.regexp);
+	LYXERR(Debug::DEBUG, "replacing with: '" << s << "'");
+	opt.replace = from_utf8(s);
 	return is;
 }
 
Index: src/lyxfind.h
===================================================================
--- src/lyxfind.h	(revisione 28060)
+++ src/lyxfind.h	(copia locale)
@@ -66,18 +66,22 @@
 /// find the next change in the buffer
 bool findNextChange(BufferView * bv);
 
-class FindAdvOptions {
+// Hopefully, nobody will ever replace with something like this
+#define LYX_FR_NULL_STRING "__LYX__F&R__NULL__STRING__"
+
+class FindAndReplaceOptions {
 public:
-	FindAdvOptions(
+	FindAndReplaceOptions(
 		docstring const & search,
 		bool casesensitive,
 		bool matchword,
 		bool forward,
 		bool expandmacros,
 		bool ignoreformat,
-		bool regexp
+		bool regexp,
+		docstring const & replace
 	);
-	FindAdvOptions() {  }
+	FindAndReplaceOptions() {  }
 	docstring search;
 	bool casesensitive;
 	bool matchword;
@@ -85,19 +89,20 @@
 	bool expandmacros;
 	bool ignoreformat;
 	bool regexp;
+	docstring replace;
 };
 
 /// Write a FindAdvOptions instance to a stringstream
-std::ostringstream & operator<<(std::ostringstream & os, lyx::FindAdvOptions const & opt);
+std::ostringstream & operator<<(std::ostringstream & os, lyx::FindAndReplaceOptions const & opt);
 
 /// Read a FindAdvOptions instance from a stringstream
-std::istringstream & operator>>(std::istringstream & is, lyx::FindAdvOptions & opt);
+std::istringstream & operator>>(std::istringstream & is, lyx::FindAndReplaceOptions & opt);
 
 /// Dispatch a LFUN_WORD_FINDADV command request
 void findAdv(BufferView * bv, FuncRequest const & ev);
 
 /// Perform a FindAdv operation.
-bool findAdv(BufferView * bv, FindAdvOptions const & opt);
+bool findAdv(BufferView * bv, FindAndReplaceOptions const & opt);
 	
 /** Computes the simple-text or LaTeX export (depending on opt) of buf starting
  ** from cur and ending len positions after cur, if len is positive, or at the
@@ -107,7 +112,7 @@
  ** Ideally, this should not be needed, and the opt.search field should become a Text const &.
  **/
 docstring stringifyFromForSearch(
-	FindAdvOptions const & opt,
+	FindAndReplaceOptions const & opt,
 	DocIterator const & cur,
 	int len = -1);
 

Reply via email to