Fix bug 2068 and do some cleanup

* src/CutAndPaste.C (setSelectionRange, replaceWord): remove.
	(replaceSelectionWithString): select the new string after
	replacement; add a bool parameter indicating in which sense the
	selection is made.

	* src/lyxfind.C (replace): adapt to above changes.
	(find): comment out debug message.

	* src/frontends/controllers/ControlSpellchecker.C (isLetter):
	rename parameter.
	(nextWord): take a LCursor as parameter; set the selection over
	the word that has been found.
	(check): adapt to changes above (the length of the word is not
	necessarily the length of the selection -- fixes bug 2068).
	(replace): use cap::replaceSelectionWithString




git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14708 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Jean-Marc Lasgouttes 2006-08-16 21:12:20 +00:00
parent bc6cf52e9f
commit a772437054
4 changed files with 37 additions and 63 deletions

View File

@ -651,33 +651,19 @@ void pasteSelection(LCursor & cur, ErrorList & errorList, size_t sel_index)
} }
void setSelectionRange(LCursor & cur, pos_type length)
{
LyXText * text = cur.text();
BOOST_ASSERT(text);
if (!length)
return;
cur.resetAnchor();
while (length--)
text->cursorRight(cur);
cur.setSelection();
}
// simple replacing. The font of the first selected character is used // simple replacing. The font of the first selected character is used
void replaceSelectionWithString(LCursor & cur, string const & str) void replaceSelectionWithString(LCursor & cur, string const & str, bool backwards)
{ {
LyXText * text = cur.text();
BOOST_ASSERT(text);
recordUndo(cur); recordUndo(cur);
DocIterator selbeg = cur.selectionBegin();
// Get font setting before we cut // Get font setting before we cut
pos_type pos = cur.selEnd().pos();
Paragraph & par = text->getPar(cur.selEnd().pit());
LyXFont const font = LyXFont const font =
par.getFontSettings(cur.buffer().params(), cur.selBegin().pos()); selbeg.paragraph().getFontSettings(cur.buffer().params(), selbeg.pos());
// Insert the new string // Insert the new string
pos_type pos = cur.selEnd().pos();
Paragraph & par = cur.selEnd().paragraph();
string::const_iterator cit = str.begin(); string::const_iterator cit = str.begin();
string::const_iterator end = str.end(); string::const_iterator end = str.end();
for (; cit != end; ++cit, ++pos) for (; cit != end; ++cit, ++pos)
@ -685,6 +671,13 @@ void replaceSelectionWithString(LCursor & cur, string const & str)
// Cut the selection // Cut the selection
cutSelection(cur, true, false); cutSelection(cur, true, false);
// select the replacement
if (backwards) {
selbeg.pos() += str.length();
cur.setSelection(selbeg, -str.length());
} else
cur.setSelection(selbeg, str.length());
} }
@ -695,21 +688,6 @@ void replaceSelection(LCursor & cur)
} }
// only used by the spellchecker
void replaceWord(LCursor & cur, string const & replacestring)
{
LyXText * text = cur.text();
BOOST_ASSERT(text);
replaceSelectionWithString(cur, replacestring);
setSelectionRange(cur, replacestring.length());
// Go back so that replacement string is also spellchecked
for (string::size_type i = 0; i < replacestring.length() + 1; ++i)
text->cursorLeft(cur);
}
void eraseSelection(LCursor & cur) void eraseSelection(LCursor & cur)
{ {
//lyxerr << "LCursor::eraseSelection begin: " << cur << endl; //lyxerr << "LCursor::eraseSelection begin: " << cur << endl;

View File

@ -41,13 +41,12 @@ std::string getSelection(Buffer const & buffer, size_t sel_index);
/// ///
void cutSelection(LCursor & cur, bool doclear, bool realcut); void cutSelection(LCursor & cur, bool doclear, bool realcut);
/** /* Replace using the font of the first selected character and select
* Sets the selection from the current cursor position to length * the new string. When \c backwards == false, set anchor before
* characters to the right. No safety checks. * cursor; otherwise set cursor before anchor.
*/ */
void setSelectionRange(LCursor & cur, lyx::pos_type length); void replaceSelectionWithString(LCursor & cur, std::string const & str,
/// simply replace using the font of the first selected character bool backwards);
void replaceSelectionWithString(LCursor & cur, std::string const & str);
/// replace selection helper /// replace selection helper
void replaceSelection(LCursor & cur); void replaceSelection(LCursor & cur);
@ -71,9 +70,6 @@ void switchBetweenClasses(lyx::textclass_type c1,
lyx::textclass_type c2, lyx::textclass_type c2,
InsetText & in, ErrorList &); InsetText & in, ErrorList &);
// only used by the spellchecker
void replaceWord(LCursor & cur, std::string const & replacestring);
/// ///
std::string grabSelection(LCursor const & cur); std::string grabSelection(LCursor const & cur);
/// ///

View File

@ -127,24 +127,25 @@ void ControlSpellchecker::clearParams()
namespace { namespace {
bool isLetter(DocIterator const & cur) bool isLetter(DocIterator const & dit)
{ {
return cur.inTexted() return dit.inTexted()
&& cur.inset().allowSpellCheck() && dit.inset().allowSpellCheck()
&& cur.pos() != cur.lastpos() && dit.pos() != dit.lastpos()
&& (cur.paragraph().isLetter(cur.pos()) && (dit.paragraph().isLetter(dit.pos())
// We want to pass the ' and escape chars to ispell // We want to pass the ' and escape chars to ispell
|| contains(lyxrc.isp_esc_chars + '\'', || contains(lyxrc.isp_esc_chars + '\'',
cur.paragraph().getChar(cur.pos()))) dit.paragraph().getChar(dit.pos())))
&& !isDeletedText(cur.paragraph(), cur.pos()); && !isDeletedText(dit.paragraph(), dit.pos());
} }
WordLangTuple nextWord(DocIterator & cur, ptrdiff_t & progress, WordLangTuple nextWord(LCursor & cur, ptrdiff_t & progress)
BufferParams & bp)
{ {
BufferParams const & bp = cur.bv().buffer()->params();
bool inword = false; bool inword = false;
bool ignoreword = false; bool ignoreword = false;
cur.resetAnchor();
string word, lang_code; string word, lang_code;
while (cur.depth()) { while (cur.depth()) {
@ -152,6 +153,7 @@ WordLangTuple nextWord(DocIterator & cur, ptrdiff_t & progress,
if (!inword) { if (!inword) {
inword = true; inword = true;
ignoreword = false; ignoreword = false;
cur.resetAnchor();
word.clear(); word.clear();
lang_code = cur.paragraph().getFontSettings(bp, cur.pos()).language()->code(); lang_code = cur.paragraph().getFontSettings(bp, cur.pos()).language()->code();
} }
@ -166,9 +168,10 @@ WordLangTuple nextWord(DocIterator & cur, ptrdiff_t & progress,
} }
} else { // !isLetter(cur) } else { // !isLetter(cur)
if (inword) if (inword)
if (!word.empty() && !ignoreword) if (!word.empty() && !ignoreword) {
cur.setSelection();
return WordLangTuple(word, lang_code); return WordLangTuple(word, lang_code);
else } else
inword = false; inword = false;
} }
@ -189,7 +192,7 @@ void ControlSpellchecker::check()
SpellBase::Result res = SpellBase::OK; SpellBase::Result res = SpellBase::OK;
DocIterator cur = kernel().bufferview()->cursor(); LCursor cur = kernel().bufferview()->cursor();
while (cur && cur.pos() && isLetter(cur)) { while (cur && cur.pos() && isLetter(cur)) {
cur.backwardPos(); cur.backwardPos();
} }
@ -202,11 +205,10 @@ void ControlSpellchecker::check()
for (total = start; it; it.forwardPos()) for (total = start; it; it.forwardPos())
++total; ++total;
BufferParams & bufferparams = kernel().buffer().params();
exitEarly_ = false; exitEarly_ = false;
while (res == SpellBase::OK || res == SpellBase::IGNORED_WORD) { while (res == SpellBase::OK || res == SpellBase::IGNORED_WORD) {
word_ = nextWord(cur, start, bufferparams); word_ = nextWord(cur, start);
// end of document // end of document
if (getWord().empty()) { if (getWord().empty()) {
@ -240,7 +242,7 @@ void ControlSpellchecker::check()
lyxerr[Debug::GUI] << "Found word \"" << getWord() << "\"" << endl; lyxerr[Debug::GUI] << "Found word \"" << getWord() << "\"" << endl;
int const size = getWord().size(); int const size = cur.selEnd().pos() - cur.selBegin().pos();
cur.pos() -= size; cur.pos() -= size;
kernel().bufferview()->putSelectionAt(cur, size, false); kernel().bufferview()->putSelectionAt(cur, size, false);
// if we used a lfun like in find/replace, dispatch would do // if we used a lfun like in find/replace, dispatch would do
@ -298,7 +300,7 @@ void ControlSpellchecker::replace(string const & replacement)
lyxerr[Debug::GUI] << "ControlSpellchecker::replace(" lyxerr[Debug::GUI] << "ControlSpellchecker::replace("
<< replacement << ")" << std::endl; << replacement << ")" << std::endl;
BufferView & bufferview = *kernel().bufferview(); BufferView & bufferview = *kernel().bufferview();
cap::replaceWord(bufferview.cursor(), replacement); cap::replaceSelectionWithString(bufferview.cursor(), replacement, true);
kernel().buffer().markDirty(); kernel().buffer().markDirty();
bufferview.update(); bufferview.update();
// fix up the count // fix up the count

View File

@ -226,9 +226,7 @@ int replace(BufferView * bv, string const & searchstr,
return 0; return 0;
LCursor & cur = bv->cursor(); LCursor & cur = bv->cursor();
lyx::cap::replaceSelectionWithString(cur, replacestr); lyx::cap::replaceSelectionWithString(cur, replacestr, fw);
lyx::cap::setSelectionRange(cur, replacestr.length());
cur.top() = fw ? cur.selEnd() : cur.selBegin();
bv->buffer()->markDirty(); bv->buffer()->markDirty();
find(bv, searchstr, cs, mw, fw); find(bv, searchstr, cs, mw, fw);
bv->update(); bv->update();
@ -274,7 +272,7 @@ void find(BufferView * bv, FuncRequest const & ev)
if (!bv || ev.action != LFUN_WORD_FIND) if (!bv || ev.action != LFUN_WORD_FIND)
return; return;
lyxerr << "find called, cmd: " << ev << std::endl; //lyxerr << "find called, cmd: " << ev << std::endl;
// data is of the form // data is of the form
// "<search> // "<search>