First implementation of feature in bug #3696. Needs testing.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@31156 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Tommaso Cucinotta 2009-08-19 22:55:38 +00:00
parent 6ee19b2a54
commit edd8e78612

View File

@ -1051,13 +1051,66 @@ docstring stringifyFromForSearch(FindAndReplaceOptions const & opt,
lyx::FindAndReplaceOptions::FindAndReplaceOptions(docstring const & search, bool casesensitive,
bool matchword, bool forward, bool expandmacros, bool ignoreformat,
bool regexp, docstring const & replace)
bool regexp, docstring const & replace, bool keep_case)
: search(search), casesensitive(casesensitive), matchword(matchword),
forward(forward), expandmacros(expandmacros), ignoreformat(ignoreformat),
regexp(regexp), replace(replace)
regexp(regexp), replace(replace), keep_case(keep_case)
{
}
/** Checks if the supplied character is lower-case */
static bool isLowerCase(char_type ch) {
return lowercase(ch) == ch;
}
/** Checks if the supplied character is upper-case */
static bool isUpperCase(char_type ch) {
return uppercase(ch) == ch;
}
/** Check if 'len' letters following cursor are all non-lowercase */
static bool allNonLowercase(DocIterator const & cur, int len) {
pos_type end_pos = cur.pos() + len;
for (pos_type pos = cur.pos(); pos != end_pos; ++pos)
if (isLowerCase(cur.paragraph().getChar(pos)))
return false;
return true;
}
/** Check if first letter is upper case and second one is lower case */
static bool firstUppercase(DocIterator const & cur) {
char_type ch1, ch2;
if (cur.pos() >= cur.lastpos() - 1) {
LYXERR(Debug::FIND, "No upper-case at cur: " << cur);
return false;
}
ch1 = cur.paragraph().getChar(cur.pos());
ch2 = cur.paragraph().getChar(cur.pos()+1);
bool result = isUpperCase(ch1) && isLowerCase(ch2);
LYXERR(Debug::FIND, "firstUppercase(): "
<< "ch1=" << ch1 << "(" << char(ch1) << "), ch2=" << ch2 << "(" << char(ch2) << ")"
<< ", result=" << result << ", cur=" << cur);
return result;
}
/** Make first letter of supplied buffer upper-case, and the rest lower-case.
**
** \fixme What to do with possible further paragraphs in replace buffer ?
**/
static void changeFirstCase(Buffer & buffer, TextCase first_case, TextCase others_case) {
ParagraphList::iterator pit = buffer.paragraphs().begin();
pos_type right = pos_type(1);
pit->changeCase(buffer.params(), pos_type(0), right, first_case);
right = pit->size() + 1;
pit->changeCase(buffer.params(), right, right, others_case);
}
/// Perform a FindAdv operation.
bool findAdv(BufferView * bv, FindAndReplaceOptions const & opt)
{
@ -1101,7 +1154,15 @@ bool findAdv(BufferView * bv, FindAndReplaceOptions const & opt)
Buffer repl_buffer("", false);
repl_buffer.setUnnamed(true);
if (repl_buffer.readString(lyx)) {
cap::cutSelection(bv->cursor(), true, false);
if (opt.keep_case && match_len >= 2) {
if (cur.inTexted()) {
if (firstUppercase(cur))
changeFirstCase(repl_buffer, text_uppercase, text_lowercase);
else if (allNonLowercase(cur, match_len))
changeFirstCase(repl_buffer, text_uppercase, text_uppercase);
}
}
cap::cutSelection(bv->cursor(), false, false);
if (! cur.inMathed()) {
LYXERR(Debug::FIND, "Replacing by pasteParagraphList()ing repl_buffer");
cap::pasteParagraphList(bv->cursor(), repl_buffer.paragraphs(),
@ -1158,7 +1219,8 @@ ostringstream & operator<<(ostringstream & os, lyx::FindAndReplaceOptions const
<< opt.expandmacros << ' '
<< opt.ignoreformat << ' '
<< opt.regexp << ' '
<< to_utf8(opt.replace) << "\nEOSS\n";
<< to_utf8(opt.replace) << "\nEOSS\n"
<< opt.keep_case;
LYXERR(Debug::FIND, "built: " << os.str());
@ -1193,8 +1255,9 @@ istringstream & operator>>(istringstream & is, lyx::FindAndReplaceOptions & opt)
break;
getline(is, line);
}
is >> opt.keep_case;
LYXERR(Debug::FIND, "parsed: " << opt.casesensitive << ' ' << opt.matchword << ' ' << opt.forward << ' '
<< opt.expandmacros << ' ' << opt.ignoreformat << ' ' << opt.regexp);
<< opt.expandmacros << ' ' << opt.ignoreformat << ' ' << opt.regexp << ' ' << opt.keep_case);
LYXERR(Debug::FIND, "replacing with: '" << s << "'");
opt.replace = from_utf8(s);
return is;