Below is a proposed change to ControlSearch (which currently does all this 
core stuff itself). It attempts to maintain compatibility with the existing 
LFUN_WORDFINDFORWARD/BACKWARD by placing the qualifying params on a 
separate line. If you're happy with the basic idea, I'll move this code 
into lyxfind of course. (Note that there is no REPLACE lfun at present).

Angus

namespace lyxfind {

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 once)
{
        ostringstream ss;
        ss << search << '\n'
           << replace << '\n'
           << int(casesensitive) << ' '
           << int(matchword) << ' '
           << int(all) << ' '
           << int(once);

        return ss.str();
}

namespace {

bool parse_bool(string & howto)
{
        if (howto.empty())
                return false;
        string var;
        howto = split(howto, var, ' ');
        return (var == "1");
}

} // namespace anon


void LyXFind(FuncRequest const & ev)
{
        if (!ev.view() || ev.action != LFUN_WORD_FIND)
                return;

        // data is of the form
        // <search> + "\n <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 = lyxfind::LyXFind(bv, search,
                                            forward, casesensitive,
                                            matchword);

        if (!found)
                bv->owner()->message(_("String not found!"));
}
 

void LyXReplace(FuncRequest const & ev)
{
        if (!ev.view() || ev.action != LFUN_WORD_REPLACE)
                return;

        // data is of the form
        // <search> + '\n' + <replace> +
        // "\n <casesensitive> <matchword> <all> <once>"
        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 once          = parse_bool(howto);

        BufferView * bv = ev.view();
        LyXView * lv = bv->owner();

        int const replace_count =
                lyxfind::LyXReplace(bv, search, replace, true, casesensitive,
                                    matchword, all, once);

        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);
                }
        }
}

} // namespace lyxfind


namespace {

void test_dispatch(FuncRequest const & ev)
{
        string argument = ev.argument;
        kb_action action = ev.action;

        switch (action) {
        case LFUN_WORD_FIND:
                lyxfind::LyXFind(ev);
                break;
        case LFUN_WORD_REPLACE:
                lyxfind::LyXReplace(ev);
                break;
        }
        default:
                break;
        }
}

} // namespace anon


void ControlSearch::find(string const & search,
                         bool casesensitive, bool matchword, bool forward)
{
        string const data =
                lyxfind::find2string(search,
                                     casesensitive, matchword, forward);
        FuncRequest const fr(bufferview(), LFUN_WORD_FIND, data);
        test_dispatch(fr);
}


void ControlSearch::replace(string const & search, string const & replace,
                            bool casesensitive, bool matchword, 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
        bool const once = !all;

        string const data =
                lyxfind::replace2string(search, replace,
                                        casesensitive, matchword, all, once);
        FuncRequest const fr(bufferview(), LFUN_WORD_REPLACE, data);
        test_dispatch(fr);
}


Reply via email to