mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-05 13:26:21 +00:00
Handle the new LFUN_WORD_FIND and LFUN_WORD_REPLACE.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8323 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
de9240227b
commit
5f96595b44
@ -1230,6 +1230,14 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev_in)
|
||||
break;
|
||||
}
|
||||
|
||||
case LFUN_WORD_FIND:
|
||||
lyx::find::find(ev);
|
||||
break;
|
||||
|
||||
case LFUN_WORD_REPLACE:
|
||||
lyx::find::replace(ev);
|
||||
break;
|
||||
|
||||
case LFUN_UNKNOWN_ACTION:
|
||||
ev.errorMessage(N_("Unknown function!"));
|
||||
break;
|
||||
|
@ -3,6 +3,14 @@
|
||||
* LyXAction.C:
|
||||
* lfuns.h: add LFUN_WORD_FIND and LFUN_WORD_REPLACE.
|
||||
|
||||
* BufferView_pimpl.C (dispatch): act on these LFUNs.
|
||||
|
||||
* lyxfind.[Ch] (find2string, replace2string, find, replace): new
|
||||
functions replacing find, replace and replaceAll.
|
||||
|
||||
* lyxfunc.C (dispatch): invoke LFUN_WORD_FIND from a call to
|
||||
LFUN_WORDFIND(FORWARD|BACKWARD).
|
||||
|
||||
2004-01-07 Alfredo Braunstein <abraunst@lyx.org>
|
||||
|
||||
* text.C (breakParagraph): remove an outdated #warning
|
||||
|
@ -1,3 +1,9 @@
|
||||
2004-01-07 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* ControlSearch.C:
|
||||
* ControlThesaurus.C (replace):
|
||||
rewrite to use LFUN_WORD_(FIND|REPLACE).
|
||||
|
||||
2003-12-14 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* ControlBranch.[Ch] (branchlist): new member function.
|
||||
@ -469,7 +475,7 @@
|
||||
|
||||
* ControlErrorList.C (goTo): use lyxerr not cout.
|
||||
|
||||
2003-05-13 Alfredo Braunstein: <abraunst@libero.it>
|
||||
2003-05-13 Alfredo Braunstein <abraunst@libero.it>
|
||||
|
||||
* ControlErrorList.[Ch]: added
|
||||
* Makefile.am: the above adittion
|
||||
|
@ -12,17 +12,17 @@
|
||||
|
||||
#include "ControlSearch.h"
|
||||
|
||||
#include "gettext.h"
|
||||
#include "funcrequest.h"
|
||||
#include "lyxfind.h"
|
||||
|
||||
#include "frontends/LyXView.h"
|
||||
|
||||
#include "support/tostr.h"
|
||||
|
||||
|
||||
using std::string;
|
||||
|
||||
|
||||
/* The ControlSeach class is now in a fit state to derive from
|
||||
Dialog::Controller
|
||||
*/
|
||||
ControlSearch::ControlSearch(LyXView & lv, Dialogs & d)
|
||||
: ControlDialogBD(lv, d)
|
||||
{}
|
||||
@ -31,12 +31,11 @@ ControlSearch::ControlSearch(LyXView & lv, Dialogs & d)
|
||||
void ControlSearch::find(string const & search,
|
||||
bool casesensitive, bool matchword, bool forward)
|
||||
{
|
||||
bool const found = lyx::find::find(bufferview(), search,
|
||||
casesensitive, matchword,
|
||||
forward);
|
||||
|
||||
if (!found)
|
||||
lv_.message(_("String not found!"));
|
||||
string const data =
|
||||
lyx::find::find2string(search,
|
||||
casesensitive, matchword, forward);
|
||||
FuncRequest const fr(bufferview(), LFUN_WORD_FIND, data);
|
||||
lv_.dispatch(fr);
|
||||
}
|
||||
|
||||
|
||||
@ -44,24 +43,10 @@ void ControlSearch::replace(string const & search, string const & replace,
|
||||
bool casesensitive, bool matchword,
|
||||
bool forward, bool all)
|
||||
{
|
||||
// If not replacing all instances of the word, then do not
|
||||
// move on to the next instance once the present instance has been
|
||||
// changed
|
||||
int const replace_count = all ?
|
||||
lyx::find::replaceAll(bufferview(), search, replace,
|
||||
casesensitive, matchword)
|
||||
: lyx::find::replace(bufferview(), search, replace,
|
||||
casesensitive, matchword, forward);
|
||||
|
||||
if (replace_count == 0) {
|
||||
lv_.message(_("String not found!"));
|
||||
} else {
|
||||
if (replace_count == 1) {
|
||||
lv_.message(_("String has been replaced."));
|
||||
} else {
|
||||
string str = tostr(replace_count);
|
||||
str += _(" strings have been replaced.");
|
||||
lv_.message(str);
|
||||
}
|
||||
}
|
||||
string const data =
|
||||
lyx::find::replace2string(search, replace,
|
||||
casesensitive, matchword,
|
||||
all, forward);
|
||||
FuncRequest const fr(bufferview(), LFUN_WORD_REPLACE, data);
|
||||
lv_.dispatch(fr);
|
||||
}
|
||||
|
@ -10,14 +10,10 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
#include "ControlThesaurus.h"
|
||||
|
||||
#include "gettext.h"
|
||||
#include "lyxfind.h"
|
||||
|
||||
#include "frontends/LyXView.h"
|
||||
|
||||
#include "funcrequest.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
@ -46,16 +42,14 @@ void ControlThesaurus::replace(string const & newstr)
|
||||
* on a particular charpos in a paragraph that is broken on
|
||||
* deletion/change !
|
||||
*/
|
||||
int const replace_count =
|
||||
lyx::find::replace(kernel().bufferview(), oldstr_, newstr,
|
||||
true /*cs*/, true /*mw*/, true /*fw*/);
|
||||
|
||||
oldstr_ = newstr;
|
||||
|
||||
if (replace_count == 0)
|
||||
kernel().lyxview().message(_("String not found!"));
|
||||
else
|
||||
kernel().lyxview().message(_("String has been replaced."));
|
||||
string const data =
|
||||
lyx::find::replace2string(oldstr_, newstr,
|
||||
true, // case sensitive
|
||||
true, // match word
|
||||
false, // all words
|
||||
true); // forward
|
||||
FuncRequest const fr(kernel().bufferview(), LFUN_WORD_REPLACE, data);
|
||||
kernel().dispatch(fr);
|
||||
}
|
||||
|
||||
|
||||
|
229
src/lyxfind.C
229
src/lyxfind.C
@ -19,6 +19,7 @@
|
||||
#include "BufferView.h"
|
||||
#include "debug.h"
|
||||
#include "iterators.h"
|
||||
#include "funcrequest.h"
|
||||
#include "gettext.h"
|
||||
#include "lyxtext.h"
|
||||
#include "paragraph.h"
|
||||
@ -26,19 +27,189 @@
|
||||
#include "undo.h"
|
||||
|
||||
#include "frontends/Alert.h"
|
||||
#include "frontends/LyXView.h"
|
||||
|
||||
#include "support/textutils.h"
|
||||
#include "support/tostr.h"
|
||||
|
||||
#include "support/std_sstream.h"
|
||||
|
||||
using lyx::support::lowercase;
|
||||
using lyx::support::uppercase;
|
||||
using lyx::support::split;
|
||||
|
||||
using bv_funcs::put_selection_at;
|
||||
|
||||
using std::ostringstream;
|
||||
using std::string;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
bool parse_bool(string & howto)
|
||||
{
|
||||
if (howto.empty())
|
||||
return false;
|
||||
string var;
|
||||
howto = split(howto, var, ' ');
|
||||
return (var == "1");
|
||||
}
|
||||
|
||||
|
||||
bool find(BufferView * bv,
|
||||
string const & searchstr, bool cs, bool mw, bool fw);
|
||||
|
||||
|
||||
int replace(BufferView * bv,
|
||||
string const & searchstr, string const & replacestr,
|
||||
bool cs, bool mw, bool fw);
|
||||
|
||||
|
||||
int replaceAll(BufferView * bv,
|
||||
string const & searchstr, string const & replacestr,
|
||||
bool cs, bool mw);
|
||||
|
||||
|
||||
bool findChange(PosIterator & cur, PosIterator const & end);
|
||||
|
||||
} // namespace anon
|
||||
|
||||
|
||||
namespace lyx {
|
||||
namespace find {
|
||||
|
||||
string const find2string(string const & search,
|
||||
bool casesensitive, bool matchword, bool forward)
|
||||
{
|
||||
ostringstream ss;
|
||||
ss << search << '\n'
|
||||
<< int(casesensitive) << ' '
|
||||
<< int(matchword) << ' '
|
||||
<< int(forward);
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
string const replace2string(string const & search, string const & replace,
|
||||
bool casesensitive, bool matchword,
|
||||
bool all, bool forward)
|
||||
{
|
||||
ostringstream ss;
|
||||
ss << search << '\n'
|
||||
<< replace << '\n'
|
||||
<< int(casesensitive) << ' '
|
||||
<< int(matchword) << ' '
|
||||
<< int(all) << ' '
|
||||
<< int(forward);
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
void find(FuncRequest const & ev)
|
||||
{
|
||||
if (!ev.view() || ev.action != LFUN_WORD_FIND)
|
||||
return;
|
||||
|
||||
// data is of the form
|
||||
// "<search>
|
||||
// <casesensitive> <matchword> <forward>"
|
||||
string search;
|
||||
string howto = split(ev.argument, search, '\n');
|
||||
|
||||
bool casesensitive = parse_bool(howto);
|
||||
bool matchword = parse_bool(howto);
|
||||
bool forward = parse_bool(howto);
|
||||
|
||||
BufferView * bv = ev.view();
|
||||
bool const found = ::find(bv, search,
|
||||
forward, casesensitive, matchword);
|
||||
|
||||
if (!found)
|
||||
bv->owner()->message(_("String not found!"));
|
||||
}
|
||||
|
||||
|
||||
void replace(FuncRequest const & ev)
|
||||
{
|
||||
if (!ev.view() || ev.action != LFUN_WORD_REPLACE)
|
||||
return;
|
||||
|
||||
// data is of the form
|
||||
// "<search>
|
||||
// <replace>
|
||||
// <casesensitive> <matchword> <all> <forward>"
|
||||
string search;
|
||||
string replace;
|
||||
string howto = split(ev.argument, search, '\n');
|
||||
howto = split(howto, replace, '\n');
|
||||
|
||||
bool casesensitive = parse_bool(howto);
|
||||
bool matchword = parse_bool(howto);
|
||||
bool all = parse_bool(howto);
|
||||
bool forward = parse_bool(howto);
|
||||
|
||||
BufferView * bv = ev.view();
|
||||
LyXView * lv = bv->owner();
|
||||
|
||||
int const replace_count = all ?
|
||||
::replaceAll(bv, search, replace,
|
||||
casesensitive, matchword) :
|
||||
::replace(bv, search, replace,
|
||||
casesensitive, matchword, forward);
|
||||
|
||||
if (replace_count == 0) {
|
||||
lv->message(_("String not found!"));
|
||||
} else {
|
||||
if (replace_count == 1) {
|
||||
lv->message(_("String has been replaced."));
|
||||
} else {
|
||||
string str = tostr(replace_count);
|
||||
str += _(" strings have been replaced.");
|
||||
lv->message(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool findNextChange(BufferView * bv)
|
||||
{
|
||||
if (!bv->available())
|
||||
return false;
|
||||
|
||||
PosIterator cur = PosIterator(*bv);
|
||||
PosIterator const endit = bv->buffer()->pos_iterator_end();
|
||||
|
||||
if (!findChange(cur, endit))
|
||||
return false;
|
||||
|
||||
ParagraphList::iterator pit = cur.pit();
|
||||
pos_type pos = cur.pos();
|
||||
|
||||
Change orig_change = pit->lookupChangeFull(pos);
|
||||
pos_type parsize = pit->size();
|
||||
pos_type end = pos;
|
||||
|
||||
for (; end != parsize; ++end) {
|
||||
Change change = pit->lookupChangeFull(end);
|
||||
if (change != orig_change) {
|
||||
// slight UI optimisation: for replacements, we get
|
||||
// text like : _old_new. Consider that as one change.
|
||||
if (!(orig_change.type == Change::DELETED &&
|
||||
change.type == Change::INSERTED))
|
||||
break;
|
||||
}
|
||||
}
|
||||
pos_type length = end - pos;
|
||||
put_selection_at(bv, cur, length, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // find namespace
|
||||
} // lyx namespace
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class MatchString
|
||||
@ -49,11 +220,11 @@ public:
|
||||
{}
|
||||
|
||||
// returns true if the specified string is at the specified position
|
||||
bool operator()(Paragraph const & par, pos_type pos) const
|
||||
{
|
||||
string::size_type size = str.length();
|
||||
pos_type i = 0;
|
||||
pos_type const parsize = par.size();
|
||||
bool operator()(Paragraph const & par, lyx::pos_type pos) const
|
||||
{
|
||||
string::size_type const size = str.length();
|
||||
lyx::pos_type i = 0;
|
||||
lyx::pos_type const parsize = par.size();
|
||||
while ((pos + i < parsize)
|
||||
&& (string::size_type(i) < size)
|
||||
&& (cs ? (str[i] == par.getChar(pos + i))
|
||||
@ -68,7 +239,7 @@ public:
|
||||
if (mw) {
|
||||
if (pos > 0 && IsLetterCharOrDigit(par.getChar(pos - 1)))
|
||||
return false;
|
||||
if (pos + pos_type(size) < parsize
|
||||
if (pos + lyx::pos_type(size) < parsize
|
||||
&& IsLetterCharOrDigit(par.getChar(pos + size)));
|
||||
return false;
|
||||
}
|
||||
@ -129,9 +300,6 @@ bool searchAllowed(BufferView * bv, string const & str)
|
||||
return bv->available();
|
||||
}
|
||||
|
||||
} // namespace anon
|
||||
|
||||
|
||||
|
||||
bool find(BufferView * bv, string const & searchstr, bool cs, bool mw, bool fw)
|
||||
{
|
||||
@ -175,7 +343,7 @@ int replaceAll(BufferView * bv,
|
||||
int const ssize = searchstr.size();
|
||||
|
||||
while (findForward(cur, end, match)) {
|
||||
pos_type pos = cur.pos();
|
||||
lyx::pos_type pos = cur.pos();
|
||||
LyXFont const font
|
||||
= cur.pit()->getFontSettings(buf.params(), pos);
|
||||
int striked = ssize - cur.pit()->erase(pos, pos + ssize);
|
||||
@ -193,8 +361,6 @@ int replaceAll(BufferView * bv,
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
bool stringSelected(BufferView * bv,
|
||||
string const & searchstr,
|
||||
bool cs, bool mw, bool fw)
|
||||
@ -213,8 +379,6 @@ bool stringSelected(BufferView * bv,
|
||||
return true;
|
||||
}
|
||||
|
||||
} //namespace anon
|
||||
|
||||
|
||||
int replace(BufferView * bv,
|
||||
string const & searchstr, string const & replacestr,
|
||||
@ -239,39 +403,4 @@ int replace(BufferView * bv,
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
bool findNextChange(BufferView * bv)
|
||||
{
|
||||
if (!bv->available())
|
||||
return false;
|
||||
|
||||
PosIterator cur = PosIterator(*bv);
|
||||
PosIterator const endit = bv->buffer()->pos_iterator_end();
|
||||
|
||||
if (!findChange(cur, endit))
|
||||
return false;
|
||||
|
||||
ParagraphList::iterator pit = cur.pit();
|
||||
pos_type pos = cur.pos();
|
||||
|
||||
Change orig_change = pit->lookupChangeFull(pos);
|
||||
pos_type parsize = pit->size();
|
||||
pos_type end = pos;
|
||||
|
||||
for (; end != parsize; ++end) {
|
||||
Change change = pit->lookupChangeFull(end);
|
||||
if (change != orig_change) {
|
||||
// slight UI optimisation: for replacements, we get
|
||||
// text like : _old_new. Consider that as one change.
|
||||
if (!(orig_change.type == Change::DELETED &&
|
||||
change.type == Change::INSERTED))
|
||||
break;
|
||||
}
|
||||
}
|
||||
pos_type length = end - pos;
|
||||
put_selection_at(bv, cur, length, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // find namespace
|
||||
} // lyx namespace
|
||||
} //namespace anon
|
||||
|
@ -20,51 +20,42 @@
|
||||
#include <string>
|
||||
|
||||
class BufferView;
|
||||
class FuncRequest;
|
||||
class LyXText;
|
||||
|
||||
namespace lyx {
|
||||
namespace find {
|
||||
|
||||
/**
|
||||
* This function replaces an ocurrence of \param search with the
|
||||
* string \param replace
|
||||
*
|
||||
* \param bv the BufferView in which the search is to be performed,
|
||||
* starting at the current cursor position.
|
||||
* \param search the string we're looking for.
|
||||
* \param replace if \c search is found, replace it with this.
|
||||
* \param cs perform a case-sensitive search for \c search.
|
||||
* \param mw match whole words only.
|
||||
* \param fw search forward from the current cursor position.
|
||||
/** Encode the parameters needed to find \c search as a string
|
||||
* that can be dispatched to the LyX core in a FuncRequest wrapper.
|
||||
*/
|
||||
std::string const find2string(std::string const & search,
|
||||
bool casesensitive,
|
||||
bool matchword,
|
||||
bool forward);
|
||||
|
||||
int replace(BufferView * bv,
|
||||
std::string const & search, std::string const & replace,
|
||||
bool cs, bool mw, bool fw);
|
||||
/**
|
||||
* This function replaces all ocurrences of \param search with
|
||||
* the string \param replace
|
||||
*
|
||||
* \param bv the BufferView in which the search is to be performed,
|
||||
* starting at the current cursor position.
|
||||
* \param search the string we're looking for.
|
||||
* \param replace if \c search is found, replace it with this.
|
||||
* \param cs perform a case-sensitive search for \c search.
|
||||
* \param mw match whole words only.
|
||||
/** 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
|
||||
* wrapper.
|
||||
*/
|
||||
std::string const replace2string(std::string const & search,
|
||||
std::string const & replace,
|
||||
bool casesensitive,
|
||||
bool matchword,
|
||||
bool all,
|
||||
bool forward);
|
||||
|
||||
int replaceAll(BufferView * bv,
|
||||
std::string const & search, std::string const & replace,
|
||||
bool cs, bool mw);
|
||||
|
||||
/**
|
||||
* This function is called as a general interface to find some text
|
||||
* from the actual cursor position in whatever direction we want to
|
||||
* go. This does also update the screen.
|
||||
/** Parse the string encoding of the find request that is found in
|
||||
* \c ev.argument and act on it.
|
||||
* The string is encoded by \c find2string.
|
||||
*/
|
||||
bool find(BufferView *, std::string const & search,
|
||||
bool cs, bool mw, bool fw);
|
||||
void find(FuncRequest const & ev);
|
||||
|
||||
/** Parse the string encoding of the replace request that is found in
|
||||
* \c ev.argument and act on it.
|
||||
* The string is encoded by \c replace2string.
|
||||
*/
|
||||
void replace(FuncRequest const &);
|
||||
|
||||
/// find the next change in the buffer
|
||||
bool findNextChange(BufferView * bv);
|
||||
|
@ -878,13 +878,18 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
|
||||
if (!argument.empty()) {
|
||||
last_search = argument;
|
||||
searched_string = argument;
|
||||
} else {
|
||||
} else
|
||||
searched_string = last_search;
|
||||
}
|
||||
bool fw = (action == LFUN_WORDFINDFORWARD);
|
||||
if (!searched_string.empty())
|
||||
lyx::find::find(view(), searched_string,
|
||||
true, false, fw);
|
||||
|
||||
if (searched_string.empty())
|
||||
break;
|
||||
|
||||
bool const fw = action == LFUN_WORDFINDFORWARD;
|
||||
string const data =
|
||||
lyx::find::find2string(searched_string,
|
||||
true, false, fw);
|
||||
FuncRequest const fr(view(), LFUN_WORD_FIND, data);
|
||||
view()->dispatch(fr);
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user