[LyX/master] GuiSearch: Add auto-wrap option

Juergen Spitzmueller spitz at lyx.org
Mon Feb 15 10:26:49 UTC 2021


commit f59b8cb6576a4af736fb502f37078d0db35c59ec
Author: Juergen Spitzmueller <spitz at lyx.org>
Date:   Mon Feb 15 11:30:03 2021 +0100

    GuiSearch: Add auto-wrap option
---
 src/BufferView.cpp                   |    5 ++-
 src/frontends/qt/GuiSearch.cpp       |   16 +++++----
 src/frontends/qt/GuiSearch.h         |    4 +-
 src/frontends/qt/GuiSpellchecker.cpp |    8 +++--
 src/frontends/qt/GuiThesaurus.cpp    |    3 +-
 src/frontends/qt/Menus.cpp           |    3 +-
 src/frontends/qt/ui/SearchUi.ui      |   12 ++++++-
 src/lyxfind.cpp                      |   64 +++++++++++++++++++--------------
 src/lyxfind.h                        |   12 ++++--
 9 files changed, 79 insertions(+), 48 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 7087973..81b7691 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -458,7 +458,8 @@ void BufferView::setSearchRequestCache(docstring const & text)
 	bool casesensitive;
 	bool matchword;
 	bool forward;
-	docstring const search = string2find(text, casesensitive, matchword, forward);
+	bool wrap;
+	docstring const search = string2find(text, casesensitive, matchword, forward, wrap);
 	theClipboard().setFindBuffer(search);
 }
 
@@ -1644,7 +1645,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
 			break;
 
 		docstring const data =
-			find2string(searched_string, false, false, act == LFUN_WORD_FIND_FORWARD);
+			find2string(searched_string, false, false, act == LFUN_WORD_FIND_FORWARD, false);
 		bool found = lyxfind(this, FuncRequest(LFUN_WORD_FIND, data));
 		if (found)
 			dr.screenUpdate(Update::Force | Update::FitCursor);
diff --git a/src/frontends/qt/GuiSearch.cpp b/src/frontends/qt/GuiSearch.cpp
index 5f12d0f..6c72ab8 100644
--- a/src/frontends/qt/GuiSearch.cpp
+++ b/src/frontends/qt/GuiSearch.cpp
@@ -189,7 +189,7 @@ void GuiSearchWidget::findClicked(bool const backwards)
 {
 	docstring const needle = qstring_to_ucs4(findCO->currentText());
 	find(needle, caseCB->isChecked(), wordsCB->isChecked(), !backwards,
-	     instantSearchCB->isChecked());
+	     instantSearchCB->isChecked(), wrapCB->isChecked());
 	uniqueInsert(findCO, findCO->currentText());
 	if (!instantSearchCB->isChecked())
 		findCO->lineEdit()->selectAll();
@@ -207,7 +207,7 @@ void GuiSearchWidget::replaceClicked(bool const backwards)
 	docstring const needle = qstring_to_ucs4(findCO->currentText());
 	docstring const repl = qstring_to_ucs4(replaceCO->currentText());
 	replace(needle, repl, caseCB->isChecked(), wordsCB->isChecked(),
-		!backwards, false);
+		!backwards, false, wrapCB->isChecked());
 	uniqueInsert(findCO, findCO->currentText());
 	uniqueInsert(replaceCO, replaceCO->currentText());
 }
@@ -223,17 +223,17 @@ void GuiSearchWidget::replaceallClicked()
 {
 	replace(qstring_to_ucs4(findCO->currentText()),
 		qstring_to_ucs4(replaceCO->currentText()),
-		caseCB->isChecked(), wordsCB->isChecked(), true, true);
+		caseCB->isChecked(), wordsCB->isChecked(), true, true, true);
 	uniqueInsert(findCO, findCO->currentText());
 	uniqueInsert(replaceCO, replaceCO->currentText());
 }
 
 
 void GuiSearchWidget::find(docstring const & search, bool casesensitive,
-			 bool matchword, bool forward, bool instant)
+			 bool matchword, bool forward, bool instant, bool wrap)
 {
 	docstring const sdata =
-		find2string(search, casesensitive, matchword, forward);
+		find2string(search, casesensitive, matchword, forward, wrap);
 	if (instant)
 		// re-query current match
 		dispatch(FuncRequest(LFUN_WORD_BACKWARD));
@@ -244,11 +244,11 @@ void GuiSearchWidget::find(docstring const & search, bool casesensitive,
 
 void GuiSearchWidget::replace(docstring const & search, docstring const & replace,
 			    bool casesensitive, bool matchword,
-			    bool forward, bool all)
+			    bool forward, bool all, bool wrap)
 {
 	docstring const sdata =
 		replace2string(replace, search, casesensitive,
-				     matchword, all, forward);
+				     matchword, all, forward, wrap);
 	dispatch(FuncRequest(LFUN_WORD_REPLACE, sdata));
 }
 
@@ -257,6 +257,7 @@ void GuiSearchWidget::saveSession(QSettings & settings, QString const & session_
 	settings.setValue(session_key + "/casesensitive", caseCB->isChecked());
 	settings.setValue(session_key + "/words", wordsCB->isChecked());
 	settings.setValue(session_key + "/instant", instantSearchCB->isChecked());
+	settings.setValue(session_key + "/wrap", wrapCB->isChecked());
 	settings.setValue(session_key + "/minimized", minimized_);
 }
 
@@ -267,6 +268,7 @@ void GuiSearchWidget::restoreSession(QString const & session_key)
 	caseCB->setChecked(settings.value(session_key + "/casesensitive", false).toBool());
 	wordsCB->setChecked(settings.value(session_key + "/words", false).toBool());
 	instantSearchCB->setChecked(settings.value(session_key + "/instant", false).toBool());
+	wrapCB->setChecked(settings.value(session_key + "/wrap", false).toBool());
 	minimized_ = settings.value(session_key + "/minimized", false).toBool();
 	// initialize hidings
 	minimizeClicked(false);
diff --git a/src/frontends/qt/GuiSearch.h b/src/frontends/qt/GuiSearch.h
index 53d25d6..ad8f9c3 100644
--- a/src/frontends/qt/GuiSearch.h
+++ b/src/frontends/qt/GuiSearch.h
@@ -61,11 +61,11 @@ private:
 	/// Searches occurrence of string
 	void find(docstring const & search,
 		  bool casesensitive, bool matchword,
-		  bool forward, bool instant);
+		  bool forward, bool instant, bool wrap);
 	/// Replaces occurrence of string
 	void replace(docstring const & search, docstring const & replace,
 		     bool casesensitive, bool matchword,
-		     bool forward, bool all);
+		     bool forward, bool all, bool wrap);
 	///
 	BufferView const * bv_ = nullptr;
 	///
diff --git a/src/frontends/qt/GuiSpellchecker.cpp b/src/frontends/qt/GuiSpellchecker.cpp
index de25c7a..40ad72c 100644
--- a/src/frontends/qt/GuiSpellchecker.cpp
+++ b/src/frontends/qt/GuiSpellchecker.cpp
@@ -467,7 +467,7 @@ void SpellcheckerWidget::on_findNextPB_clicked()
 		return;
 	docstring const textfield = qstring_to_ucs4(d->ui.wordED->text());
 	docstring const datastring = find2string(textfield,
-				true, true, true);
+				true, true, true, false);
 	LYXERR(Debug::GUI, "Spellchecker: find next (" << textfield << ")");
 	dispatch(FuncRequest(LFUN_WORD_FIND, datastring));
 	d->canCheck();
@@ -486,7 +486,8 @@ void SpellcheckerWidget::on_replacePB_clicked()
 			true,   // match word
 			false,  // all words
 			true,   // forward
-			false); // find next
+			false,  // find next
+			false); // auto-wrap
 
 	LYXERR(Debug::GUI, "Replace (" << replacement << ")");
 	dispatch(FuncRequest(LFUN_WORD_REPLACE, datastring));
@@ -508,7 +509,8 @@ void SpellcheckerWidget::on_replaceAllPB_clicked()
 			true,   // match word
 			true,   // all words
 			true,   // forward
-			false); // find next
+			false,  // find next
+			false); // auto-wrap
 
 	LYXERR(Debug::GUI, "Replace all (" << replacement << ")");
 	dispatch(FuncRequest(LFUN_WORD_REPLACE, datastring));
diff --git a/src/frontends/qt/GuiThesaurus.cpp b/src/frontends/qt/GuiThesaurus.cpp
index d748d29..d498236 100644
--- a/src/frontends/qt/GuiThesaurus.cpp
+++ b/src/frontends/qt/GuiThesaurus.cpp
@@ -266,7 +266,8 @@ void GuiThesaurus::replace(docstring const & newstr)
 				     true,  // case sensitive
 				     true,  // match word
 				     false, // all words
-				     true); // forward
+				     true,  // forward
+				     false);// auto-wrap
 	dispatch(FuncRequest(LFUN_WORD_REPLACE, sdata));
 }
 
diff --git a/src/frontends/qt/Menus.cpp b/src/frontends/qt/Menus.cpp
index 749d4c4..6d77c2e 100644
--- a/src/frontends/qt/Menus.cpp
+++ b/src/frontends/qt/Menus.cpp
@@ -847,7 +847,8 @@ void MenuDefinition::expandSpellingSuggestions(BufferView const * bv)
 								true,     // match word
 								false,    // all words
 								true,     // forward
-								false))); // find next
+								false,    // find next
+								false))); // auto-wrap
 					if (i < m)
 						add(w);
 					else
diff --git a/src/frontends/qt/ui/SearchUi.ui b/src/frontends/qt/ui/SearchUi.ui
index 29d3f5b..12ba071 100644
--- a/src/frontends/qt/ui/SearchUi.ui
+++ b/src/frontends/qt/ui/SearchUi.ui
@@ -208,7 +208,7 @@
         <item>
          <widget class="QCheckBox" name="wordsCB">
           <property name="text">
-           <string>&Whole words</string>
+           <string>Wh&ole words</string>
           </property>
          </widget>
         </item>
@@ -223,6 +223,16 @@
          </widget>
         </item>
         <item>
+         <widget class="QCheckBox" name="wrapCB">
+          <property name="toolTip">
+           <string>If the beggining/start of the document is reached, automatically wrap around</string>
+          </property>
+          <property name="text">
+           <string>&Wrap</string>
+          </property>
+         </widget>
+        </item>
+        <item>
          <spacer name="horizontalSpacer">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
diff --git a/src/lyxfind.cpp b/src/lyxfind.cpp
index ffbd923..8c67141 100644
--- a/src/lyxfind.cpp
+++ b/src/lyxfind.cpp
@@ -267,7 +267,7 @@ bool searchAllowed(docstring const & str)
 
 bool findOne(BufferView * bv, docstring const & searchstr,
 	     bool case_sens, bool whole, bool forward,
-	     bool find_del, bool check_wrap)
+	     bool find_del, bool check_wrap, bool auto_wrap)
 {
 	if (!searchAllowed(searchstr))
 		return false;
@@ -286,16 +286,19 @@ bool findOne(BufferView * bv, docstring const & searchstr,
 		bv->putSelectionAt(cur, match_len, !forward);
 	else if (check_wrap) {
 		DocIterator cur_orig(bv->cursor());
-		docstring q;
-		if (forward)
-			q = _("End of file reached while searching forward.\n"
-			  "Continue searching from the beginning?");
-		else
-			q = _("Beginning of file reached while searching backward.\n"
-			  "Continue searching from the end?");
-		int wrap_answer = frontend::Alert::prompt(_("Wrap search?"),
-			q, 0, 1, _("&Yes"), _("&No"));
-		if (wrap_answer == 0) {
+		if (!auto_wrap) {
+			docstring q;
+			if (forward)
+				q = _("End of file reached while searching forward.\n"
+				  "Continue searching from the beginning?");
+			else
+				q = _("Beginning of file reached while searching backward.\n"
+				  "Continue searching from the end?");
+			int wrap_answer = frontend::Alert::prompt(_("Wrap search?"),
+				q, 0, 1, _("&Yes"), _("&No"));
+			auto_wrap = wrap_answer == 0;
+		}
+		if (auto_wrap) {
 			if (forward) {
 				bv->cursor().clear();
 				bv->cursor().push_back(CursorSlice(bv->buffer().inset()));
@@ -304,7 +307,7 @@ bool findOne(BufferView * bv, docstring const & searchstr,
 				bv->cursor().backwardPos();
 			}
 			bv->clearSelection();
-			if (findOne(bv, searchstr, case_sens, whole, forward, find_del, false))
+			if (findOne(bv, searchstr, case_sens, whole, forward, find_del, false, false))
 				return true;
 		}
 		bv->cursor().setCursor(cur_orig);
@@ -381,13 +384,13 @@ int replaceAll(BufferView * bv,
 // whether anything at all was done.
 pair<bool, int> replaceOne(BufferView * bv, docstring searchstr,
 			   docstring const & replacestr, bool case_sens,
-			   bool whole, bool forward, bool findnext)
+			   bool whole, bool forward, bool findnext, bool wrap)
 {
 	Cursor & cur = bv->cursor();
 	if (!cur.selection()) {
 		// no selection, non-empty search string: find it
 		if (!searchstr.empty()) {
-			bool const found = findOne(bv, searchstr, case_sens, whole, forward, true, findnext);
+			bool const found = findOne(bv, searchstr, case_sens, whole, forward, true, findnext, wrap);
 			return make_pair(found, 0);
 		}
 		// empty search string
@@ -416,7 +419,7 @@ pair<bool, int> replaceOne(BufferView * bv, docstring searchstr,
 	// no selection or current selection is not search word:
 	// just find the search word
 	if (!have_selection || !match) {
-		bool const found = findOne(bv, searchstr, case_sens, whole, forward, true, findnext);
+		bool const found = findOne(bv, searchstr, case_sens, whole, forward, true, findnext, wrap);
 		return make_pair(found, 0);
 	}
 
@@ -432,7 +435,7 @@ pair<bool, int> replaceOne(BufferView * bv, docstring searchstr,
 		        cur.pos() = cur.lastpos());
 	}
 	if (findnext)
-		findOne(bv, searchstr, case_sens, whole, forward, false, findnext);
+		findOne(bv, searchstr, case_sens, whole, forward, false, findnext, wrap);
 
 	return make_pair(true, 1);
 }
@@ -441,13 +444,15 @@ pair<bool, int> replaceOne(BufferView * bv, docstring searchstr,
 
 
 docstring const find2string(docstring const & search,
-			    bool casesensitive, bool matchword, bool forward)
+			    bool casesensitive, bool matchword,
+			    bool forward, bool wrap)
 {
 	odocstringstream ss;
 	ss << search << '\n'
 	   << int(casesensitive) << ' '
 	   << int(matchword) << ' '
-	   << int(forward);
+	   << int(forward) << ' '
+	   << int(wrap);
 	return ss.str();
 }
 
@@ -455,7 +460,7 @@ docstring const find2string(docstring const & search,
 docstring const replace2string(docstring const & replace,
 			       docstring const & search,
 			       bool casesensitive, bool matchword,
-			       bool all, bool forward, bool findnext)
+			       bool all, bool forward, bool findnext, bool wrap)
 {
 	odocstringstream ss;
 	ss << replace << '\n'
@@ -464,7 +469,8 @@ docstring const replace2string(docstring const & replace,
 	   << int(matchword) << ' '
 	   << int(all) << ' '
 	   << int(forward) << ' '
-	   << int(findnext);
+	   << int(findnext) << ' '
+	   << int(wrap);
 	return ss.str();
 }
 
@@ -472,17 +478,19 @@ docstring const replace2string(docstring const & replace,
 docstring const string2find(docstring const & argument,
 			      bool &casesensitive,
 			      bool &matchword,
-			      bool &forward)
+			      bool &forward,
+			      bool &wrap)
 {
 	// data is of the form
 	// "<search>
-	//  <casesensitive> <matchword> <forward>"
+	//  <casesensitive> <matchword> <forward> <wrap>"
 	docstring search;
 	docstring howto = split(argument, search, '\n');
 
 	casesensitive = parse_bool(howto);
 	matchword     = parse_bool(howto);
 	forward       = parse_bool(howto, true);
+	wrap          = parse_bool(howto, true);
 
 	return search;
 }
@@ -497,9 +505,10 @@ bool lyxfind(BufferView * bv, FuncRequest const & ev)
 	bool casesensitive;
 	bool matchword;
 	bool forward;
-	docstring search = string2find(ev.argument(), casesensitive, matchword, forward);
+	bool wrap;
+	docstring search = string2find(ev.argument(), casesensitive, matchword, forward, wrap);
 
-	return findOne(bv, search, casesensitive, matchword, forward, false, true);
+	return findOne(bv, search, casesensitive, matchword, forward, false, true, wrap);
 }
 
 
@@ -511,7 +520,7 @@ bool lyxreplace(BufferView * bv, FuncRequest const & ev)
 	// data is of the form
 	// "<search>
 	//  <replace>
-	//  <casesensitive> <matchword> <all> <forward> <findnext>"
+	//  <casesensitive> <matchword> <all> <forward> <findnext> <wrap>"
 	docstring search;
 	docstring rplc;
 	docstring howto = split(ev.argument(), rplc, '\n');
@@ -521,7 +530,8 @@ bool lyxreplace(BufferView * bv, FuncRequest const & ev)
 	bool matchword     = parse_bool(howto);
 	bool all           = parse_bool(howto);
 	bool forward       = parse_bool(howto, true);
-	bool findnext      = howto.empty() ? true : parse_bool(howto);
+	bool findnext      = parse_bool(howto, true);
+	bool wrap          = parse_bool(howto);
 
 	bool update = false;
 
@@ -531,7 +541,7 @@ bool lyxreplace(BufferView * bv, FuncRequest const & ev)
 		update = replace_count > 0;
 	} else {
 		pair<bool, int> rv =
-			replaceOne(bv, search, rplc, casesensitive, matchword, forward, findnext);
+			replaceOne(bv, search, rplc, casesensitive, matchword, forward, findnext, wrap);
 		update = rv.first;
 		replace_count = rv.second;
 	}
diff --git a/src/lyxfind.h b/src/lyxfind.h
index 20427e8..b6e9ec9 100644
--- a/src/lyxfind.h
+++ b/src/lyxfind.h
@@ -34,7 +34,8 @@ class FuncRequest;
 docstring const string2find(docstring const & argument,
 			      bool &casesensitive,
 			      bool &matchword,
-			      bool &forward);
+			      bool &forward,
+			      bool &wrap);
 
 /** Encode the parameters needed to find \c search as a string
  *  that can be dispatched to the LyX core in a FuncRequest wrapper.
@@ -42,7 +43,8 @@ docstring const string2find(docstring const & argument,
 docstring const find2string(docstring const & search,
 			      bool casesensitive,
 			      bool matchword,
-			      bool forward);
+			      bool forward,
+			      bool wrap);
 
 /** Encode the parameters needed to replace \c search with \c replace
  *  as a string that can be dispatched to the LyX core in a FuncRequest
@@ -54,7 +56,8 @@ docstring const replace2string(docstring const & replace,
 				 bool matchword,
 				 bool all,
 				 bool forward,
-				 bool findnext = true);
+				 bool findnext = true,
+				 bool wrap = true);
 
 /** Parse the string encoding of the find request that is found in
  *  \c ev.argument and act on it.
@@ -65,7 +68,8 @@ bool lyxfind(BufferView * bv, FuncRequest const & ev);
 
 bool findOne(BufferView * bv, docstring const & searchstr,
 	     bool case_sens, bool whole, bool forward,
-	     bool find_del = true, bool check_wrap = false);
+	     bool find_del = true, bool check_wrap = false,
+	     bool auto_wrap = false);
 
 /** Parse the string encoding of the replace request that is found in
  *  \c ev.argument and act on it.


More information about the lyx-cvs mailing list