X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftext.C;h=8e68a70a32f797702cf157a8266ab2fa36d220dd;hb=fe390e9da1538e20eabbc98977d845295f8e563d;hp=18c022eca1bab98cca5953cdb2b51279d1717999;hpb=deaad2b833e281cbbaecab0f537b55fe9e320d9f;p=lyx.git diff --git a/src/text.C b/src/text.C index 18c022eca1..8e68a70a32 100644 --- a/src/text.C +++ b/src/text.C @@ -30,6 +30,7 @@ #include "language.h" #include "ParagraphParameters.h" #include "undo_funcs.h" +#include "text_funcs.h" #include "WordLangTuple.h" #include "paragraph_funcs.h" #include "rowpainter.h" @@ -43,11 +44,16 @@ #include +using namespace lyx::support; + using std::max; using std::min; using std::endl; using std::pair; + using lyx::pos_type; +using lyx::word_location; + using namespace bv_funcs; /// top, right, bottom pixel margin @@ -62,14 +68,14 @@ extern int bibitemMaxWidth(BufferView *, LyXFont const &); BufferView * LyXText::bv() { - lyx::Assert(bv_owner != 0); + Assert(bv_owner != 0); return bv_owner; } BufferView * LyXText::bv() const { - lyx::Assert(bv_owner != 0); + Assert(bv_owner != 0); return bv_owner; } @@ -87,16 +93,24 @@ void LyXText::updateRowPositions() int LyXText::top_y() const { - if (isInInset() || anchor_row_ == rowlist_.end() ) + if (anchor_row_ == rowlist_.end()) return 0; + return anchor_row_->y() + anchor_row_offset_; } void LyXText::top_y(int newy) { - if (rows().empty() || isInInset()) + if (rows().empty()) return; + + if (isInInset()) { + anchor_row_ = rows().begin(); + anchor_row_offset_ = newy; + return; + } + lyxerr[Debug::GUI] << "setting top y = " << newy << endl; int y = newy; @@ -137,13 +151,15 @@ int LyXText::workWidth() const } -int LyXText::workWidth(Inset * inset) const +int LyXText::workWidth(Inset const * inset) const { - Paragraph * par = inset->parOwner(); - lyx::Assert(par); + ParagraphList::iterator par = std::find(ownerParagraphs().begin(), + ownerParagraphs().end(), + *inset->parOwner()); + //Assert(par); pos_type pos = par->getPositionOfInset(inset); - lyx::Assert(pos != -1); + Assert(pos != -1); LyXLayout_ptr const & layout = par->layout(); @@ -538,29 +554,33 @@ int LyXText::leftMargin(Row const & row) const if (row.par()->layout() == tclass.defaultLayout()) { // find the previous same level paragraph if (row.par() != ownerParagraphs().begin()) { - Paragraph * newpar = row.par() - ->depthHook(row.par()->getDepth()); - if (newpar && - newpar->layout()->nextnoindent) + ParagraphList::iterator newpit = + depthHook(row.par(), ownerParagraphs(), + row.par()->getDepth()); + if (newpit == row.par() && + newpit->layout()->nextnoindent) parindent.erase(); } } } else { // find the next level paragraph - Paragraph * newpar = row.par()->outerHook(); + ParagraphList::iterator newpar = outerHook(row.par(), + ownerParagraphs()); // make a corresponding row. Needed to call leftMargin() // check wether it is a sufficent paragraph - if (newpar && newpar->layout()->isEnvironment()) { + if (newpar != ownerParagraphs().end() && + newpar->layout()->isEnvironment()) { Row dummyrow; dummyrow.par(newpar); dummyrow.pos(newpar->size()); x = leftMargin(dummyrow); } - if (newpar && row.par()->layout() == tclass.defaultLayout()) { + if (newpar != ownerParagraphs().end() && + row.par()->layout() == tclass.defaultLayout()) { if (newpar->params().noindent()) parindent.erase(); else { @@ -614,7 +634,7 @@ int LyXText::leftMargin(Row const & row) const // theorems (JMarc) || (layout->labeltype == LABEL_STATIC && layout->latextype == LATEX_ENVIRONMENT - && ! row.par()->isFirstInSequence())) { + && !isFirstInSequence(row.par(), ownerParagraphs()))) { x += font_metrics::signedWidth(layout->leftmargin, labelfont); } else if (layout->labeltype != LABEL_TOP_ENVIRONMENT @@ -679,7 +699,7 @@ int LyXText::leftMargin(Row const & row) const || layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT || (layout->labeltype == LABEL_STATIC && layout->latextype == LATEX_ENVIRONMENT - && ! row.par()->isFirstInSequence())) + && !isFirstInSequence(row.par(), ownerParagraphs()))) && align == LYX_ALIGN_BLOCK && !row.par()->params().noindent() // in tabulars and ert paragraphs are never indented! @@ -756,8 +776,7 @@ pos_type addressBreakPoint(pos_type i, Paragraph const & par) }; -pos_type -LyXText::rowBreakPoint(Row const & row) const +pos_type LyXText::rowBreakPoint(Row const & row) const { ParagraphList::iterator pit = row.par(); @@ -786,7 +805,7 @@ LyXText::rowBreakPoint(Row const & row) const // or the end of the par, then choose the possible break // nearest that. - int const left = leftMargin(const_cast(row)); + int const left = leftMargin(row); int x = left; // pixel width since last breakpoint @@ -958,7 +977,7 @@ int LyXText::labelFill(Row const & row) const pos_type last = pit->beginningOfBody(); - lyx::Assert(last > 0); + Assert(last > 0); // -1 because a label ends either with a space that is in the label, // or with the beginning of a footnote that is outside the label. @@ -998,7 +1017,7 @@ LColor::color LyXText::backgroundColor() const void LyXText::setHeightOfRow(RowList::iterator rit) { - lyx::Assert(rit != rows().end()); + Assert(rit != rows().end()); // get the maximum ascent and the maximum descent float layoutasc = 0; @@ -1153,7 +1172,7 @@ void LyXText::setHeightOfRow(RowList::iterator rit) if ((layout->labeltype == LABEL_TOP_ENVIRONMENT || layout->labeltype == LABEL_BIBLIO || layout->labeltype == LABEL_CENTERED_TOP_ENVIRONMENT) - && pit->isFirstInSequence() + && isFirstInSequence(pit, ownerParagraphs()) && !pit->getLabelstring().empty()) { float spacing_val = 1.0; @@ -1174,14 +1193,15 @@ void LyXText::setHeightOfRow(RowList::iterator rit) + layout->labelbottomsep * defaultRowHeight()); } - // and now the layout spaces, for example before and after a section, - // or between the items of a itemize or enumerate environment + // And now the layout spaces, for example before and after + // a section, or between the items of a itemize or enumerate + // environment. if (!pit->params().pagebreakTop()) { - Paragraph * prev = pit->previous(); - if (prev) - prev = pit->depthHook(pit->getDepth()); - if (prev && prev->layout() == layout && + ParagraphList::iterator prev = + depthHook(pit, ownerParagraphs(), + pit->getDepth()); + if (prev != pit && prev->layout() == layout && prev->getDepth() == pit->getDepth() && prev->getLabelWidthString() == pit->getLabelWidthString()) { @@ -1201,8 +1221,8 @@ void LyXText::setHeightOfRow(RowList::iterator rit) layoutasc = (tmptop * defaultRowHeight()); } - prev = pit->outerHook(); - if (prev) { + prev = outerHook(pit, ownerParagraphs()); + if (prev != ownerParagraphs().end()) { maxasc += int(prev->layout()->parsep * defaultRowHeight()); } else if (pit != ownerParagraphs().begin()) { ParagraphList::iterator prior_pit = boost::prior(pit); @@ -1250,7 +1270,7 @@ void LyXText::setHeightOfRow(RowList::iterator rit) if (comparepit->getDepth() > nextpit->getDepth()) { usual = (comparepit->layout()->bottomsep * defaultRowHeight()); - comparepit = comparepit->depthHook(nextpit->getDepth()); + comparepit = depthHook(comparepit, ownerParagraphs(), nextpit->getDepth()); if (comparepit->layout()!= nextpit->layout() || nextpit->getLabelWidthString() != comparepit->getLabelWidthString()) @@ -1309,7 +1329,7 @@ void LyXText::setHeightOfRow(RowList::iterator rit) // start at the implicit given position void LyXText::appendParagraph(RowList::iterator rowit) { - lyx::Assert(rowit != rowlist_.end()); + Assert(rowit != rowlist_.end()); pos_type const last = rowit->par()->size(); bool done = false; @@ -1339,7 +1359,7 @@ void LyXText::appendParagraph(RowList::iterator rowit) void LyXText::breakAgain(RowList::iterator rit) { - lyx::Assert(rit != rows().end()); + Assert(rit != rows().end()); bool not_ready = true; @@ -1392,7 +1412,7 @@ void LyXText::breakAgain(RowList::iterator rit) // this is just a little changed version of break again void LyXText::breakAgainOneRow(RowList::iterator rit) { - lyx::Assert(rit != rows().end()); + Assert(rit != rows().end()); pos_type z = rowBreakPoint(*rit); RowList::iterator tmprit = rit; @@ -1446,13 +1466,12 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout) LyXLayout_ptr const & layout = cursor.par()->layout(); // this is only allowed, if the current paragraph is not empty or caption - // and if it has not the keepempty flag aktive - if (cursor.par()->empty() - && layout->labeltype != LABEL_SENSITIVE - && !layout->keepempty) + // and if it has not the keepempty flag active + if (cursor.par()->empty() && !cursor.par()->allowEmpty() + && layout->labeltype != LABEL_SENSITIVE) return; - setUndo(bv(), Undo::FINISH, &*cursor.par(), &*boost::next(cursor.par())); + setUndo(bv(), Undo::FINISH, cursor.par()); // Always break behind a space // @@ -1472,7 +1491,7 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout) // breakParagraph call should return a bool if it inserts the // paragraph before or behind and we should react on that one // but we can fix this in 1.3.0 (Jug 20020509) - bool const isempty = (layout->keepempty && cursor.par()->empty()); + bool const isempty = (cursor.par()->allowEmpty() && cursor.par()->empty()); ::breakParagraph(bv()->buffer()->params, paragraphs, cursor.par(), cursor.pos(), keep_layout); @@ -1490,17 +1509,17 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout) // move one row up! // This touches only the screen-update. Otherwise we would may have // an empty row on the screen - if (cursor.pos() && cursor.row()->pos() == cursor.pos() - && !cursor.row()->par()->isNewline(cursor.pos() - 1)) + if (cursor.pos() && cursorRow()->pos() == cursor.pos() + && !cursorRow()->par()->isNewline(cursor.pos() - 1)) { cursorLeft(bv()); } - int y = cursor.y() - cursor.row()->baseline(); + int y = cursor.y() - cursorRow()->baseline(); // Do not forget the special right address boxes if (layout->margintype == MARGIN_RIGHT_ADDRESS_BOX) { - RowList::iterator r = cursor.row(); + RowList::iterator r = cursorRow(); RowList::iterator beg = rows().begin(); while (r != beg && boost::prior(r)->par() == r->par()) { @@ -1511,12 +1530,12 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout) postPaint(y); - removeParagraph(cursor.row()); + removeParagraph(cursorRow()); // set the dimensions of the cursor row - cursor.row()->fill(fill(cursor.row(), workWidth())); + cursorRow()->fill(fill(cursorRow(), workWidth())); - setHeightOfRow(cursor.row()); + setHeightOfRow(cursorRow()); #warning Trouble Point! (Lgb) // When ::breakParagraph is called from within an inset we must @@ -1527,7 +1546,7 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout) while (!next_par->empty() && next_par->isNewline(0)) next_par->erase(0); - insertParagraph(next_par, boost::next(cursor.row())); + insertParagraph(next_par, boost::next(cursorRow())); updateCounters(); // This check is necessary. Otherwise the new empty paragraph will @@ -1537,8 +1556,8 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout) else setCursor(cursor.par(), 0); - if (boost::next(cursor.row()) != rows().end()) - breakAgain(boost::next(cursor.row())); + if (boost::next(cursorRow()) != rows().end()) + breakAgain(boost::next(cursorRow())); need_break_row = rows().end(); } @@ -1557,13 +1576,13 @@ void LyXText::redoParagraph() // same Paragraph one to the right and make a rebreak void LyXText::insertChar(char c) { - setUndo(bv(), Undo::INSERT, &*cursor.par(), &*boost::next(cursor.par())); + setUndo(bv(), Undo::INSERT, cursor.par()); // When the free-spacing option is set for the current layout, // disable the double-space checking - bool const freeSpacing = cursor.row()->par()->layout()->free_spacing || - cursor.row()->par()->isFreeSpacing(); + bool const freeSpacing = cursorRow()->par()->layout()->free_spacing || + cursorRow()->par()->isFreeSpacing(); if (lyxrc.auto_number) { static string const number_operators = "+-/*"; @@ -1657,17 +1676,17 @@ void LyXText::insertChar(char c) } // the display inset stuff - if (cursor.row()->pos() < cursor.row()->par()->size() - && cursor.row()->par()->isInset(cursor.row()->pos())) { - Inset * inset = cursor.row()->par()->getInset(cursor.row()->pos()); + if (cursorRow()->pos() < cursorRow()->par()->size() + && cursorRow()->par()->isInset(cursorRow()->pos())) { + Inset * inset = cursorRow()->par()->getInset(cursorRow()->pos()); if (inset && (inset->display() || inset->needFullRow())) { // force a new break - cursor.row()->fill(-1); // to force a new break + cursorRow()->fill(-1); // to force a new break } } // get the cursor row fist - RowList::iterator row = cursor.row(); + RowList::iterator row = cursorRow(); int y = cursor.y() - row->baseline(); if (c != Paragraph::META_INSET) { // Here case LyXText::InsertInset already insertet the character @@ -1692,7 +1711,7 @@ void LyXText::insertChar(char c) || cursor.par()->isNewline(cursor.pos()) || ((cursor.pos() + 1 < cursor.par()->size()) && cursor.par()->isInset(cursor.pos() + 1)) - || cursor.row()->fill() == -1)) + || cursorRow()->fill() == -1)) { pos_type z = rowBreakPoint(*boost::prior(row)); @@ -1718,9 +1737,10 @@ void LyXText::insertChar(char c) false, cursor.boundary()); // cursor MUST be in row now. - if (boost::next(row) != rows().end() && - boost::next(row)->par() == row->par()) - need_break_row = boost::next(row); + RowList::iterator next_row = boost::next(row); + if (next_row != rows().end() && + next_row->par() == row->par()) + need_break_row = next_row; else need_break_row = rows().end(); @@ -1744,13 +1764,18 @@ void LyXText::insertChar(char c) if (c == Paragraph::META_INSET || row->fill() < 0) { postPaint(y); breakAgainOneRow(row); + + RowList::iterator next_row = boost::next(row); + // will the cursor be in another row now? if (lastPos(*this, row) <= cursor.pos() + 1 && - boost::next(row) != rows().end()) { - if (boost::next(row) != rows().end() && - boost::next(row)->par() == row->par()) + next_row != rows().end()) { + if (next_row != rows().end() && + next_row->par() == row->par()) { // this should always be true ++row; + } + breakAgainOneRow(row); } current_font = rawtmpfont; @@ -1762,9 +1787,12 @@ void LyXText::insertChar(char c) != cursor.boundary()) setCursor(cursor.par(), cursor.pos(), false, !cursor.boundary()); - if (boost::next(row) != rows().end() && - boost::next(row)->par() == row->par()) - need_break_row = boost::next(row); + + next_row = boost::next(row); + + if (next_row != rows().end() && + next_row->par() == row->par()) + need_break_row = next_row; else need_break_row = rows().end(); } else { @@ -1952,27 +1980,8 @@ void LyXText::prepareToPrint(RowList::iterator rit, float & x, void LyXText::cursorRightOneWord() { - // treat floats, HFills and Insets as words - ParagraphList::iterator pit = cursor.par(); - pos_type pos = cursor.pos(); - - // CHECK See comment on top of text.C - - if (pos == pit->size() - && boost::next(pit) != ownerParagraphs().end()) { - ++pit; - pos = 0; - } else { - // Skip through initial nonword stuff. - while (pos < pit->size() && !pit->isWord(pos)) { - ++pos; - } - // Advance through word. - while (pos < pit->size() && pit->isWord(pos)) { - ++pos; - } - } - setCursor(pit, pos); + ::cursorRightOneWord(cursor, ownerParagraphs()); + setCursor(cursor.par(), cursor.pos()); } @@ -1981,102 +1990,16 @@ void LyXText::cursorRightOneWord() void LyXText::cursorLeftOneWord() { LyXCursor tmpcursor = cursor; - cursorLeftOneWord(tmpcursor); + ::cursorLeftOneWord(tmpcursor, ownerParagraphs()); setCursor(tmpcursor.par(), tmpcursor.pos()); } -void LyXText::cursorLeftOneWord(LyXCursor & cur) -{ - // treat HFills, floats and Insets as words - - ParagraphList::iterator pit = cursor.par(); - pos_type pos = cursor.pos(); - - while (pos && - (pit->isSeparator(pos - 1) || - pit->isKomma(pos - 1) || - pit->isNewline(pos - 1)) && - !(pit->isHfill(pos - 1) || - pit->isInset(pos - 1))) - --pos; - - if (pos && - (pit->isInset(pos - 1) || - pit->isHfill(pos - 1))) { - --pos; - } else if (!pos) { - if (pit != ownerParagraphs().begin()) { - --pit; - pos = pit->size(); - } - } else { // Here, cur != 0 - while (pos > 0 && - pit->isWord(pos - 1)) - --pos; - } - - cur.par(pit); - cur.pos(pos); -} - - -// Select current word. This depends on behaviour of -// CursorLeftOneWord(), so it is patched as well. -void LyXText::getWord(LyXCursor & from, LyXCursor & to, - word_location const loc) -{ - // first put the cursor where we wana start to select the word - from = cursor; - switch (loc) { - case WHOLE_WORD_STRICT: - if (cursor.pos() == 0 || cursor.pos() == cursor.par()->size() - || cursor.par()->isSeparator(cursor.pos()) - || cursor.par()->isKomma(cursor.pos()) - || cursor.par()->isNewline(cursor.pos()) - || cursor.par()->isSeparator(cursor.pos() - 1) - || cursor.par()->isKomma(cursor.pos() - 1) - || cursor.par()->isNewline(cursor.pos() - 1)) { - to = from; - return; - } - // no break here, we go to the next - - case WHOLE_WORD: - // Move cursor to the beginning, when not already there. - if (from.pos() && !from.par()->isSeparator(from.pos() - 1) - && !(from.par()->isKomma(from.pos() - 1) - || from.par()->isNewline(from.pos() - 1))) - cursorLeftOneWord(from); - break; - case PREVIOUS_WORD: - // always move the cursor to the beginning of previous word - cursorLeftOneWord(from); - break; - case NEXT_WORD: - lyxerr << "LyXText::getWord: NEXT_WORD not implemented yet\n"; - break; - case PARTIAL_WORD: - break; - } - to = from; - while (to.pos() < to.par()->size() - && !to.par()->isSeparator(to.pos()) - && !to.par()->isKomma(to.pos()) - && !to.par()->isNewline(to.pos()) - && !to.par()->isHfill(to.pos()) - && !to.par()->isInset(to.pos())) - { - to.pos(to.pos() + 1); - } -} - - void LyXText::selectWord(word_location loc) { - LyXCursor from; + LyXCursor from = cursor; LyXCursor to; - getWord(from, to, loc); + ::getWord(from, to, loc, ownerParagraphs()); if (cursor != from) setCursor(from.par(), from.pos()); if (to == from) @@ -2104,12 +2027,10 @@ void LyXText::acceptChange() if (!selection.set() && cursor.par()->size()) return; - bv()->hideCursor(); - if (selection.start.par() == selection.end.par()) { LyXCursor & startc = selection.start; LyXCursor & endc = selection.end; - setUndo(bv(), Undo::INSERT, &*startc.par(), &*boost::next(startc.par())); + setUndo(bv(), Undo::INSERT, startc.par()); startc.par()->acceptChange(startc.pos(), endc.pos()); finishUndo(); clearSelection(); @@ -2125,13 +2046,10 @@ void LyXText::rejectChange() if (!selection.set() && cursor.par()->size()) return; - bv()->hideCursor(); - if (selection.start.par() == selection.end.par()) { LyXCursor & startc = selection.start; LyXCursor & endc = selection.end; - setUndo(bv(), Undo::INSERT, &*startc.par(), - &*boost::next(startc.par())); + setUndo(bv(), Undo::INSERT, startc.par()); startc.par()->rejectChange(startc.pos(), endc.pos()); finishUndo(); clearSelection(); @@ -2202,7 +2120,8 @@ LyXText::selectNextWordToSpellcheck(float & value) if (cursor.pos() < cursor.par()->size() && cursor.par()->isInset(cursor.pos())) { // lock the inset! - cursor.par()->getInset(cursor.pos())->edit(bv()); + FuncRequest cmd(bv(), LFUN_INSET_EDIT, "left"); + cursor.par()->getInset(cursor.pos())->localDispatch(cmd); // now call us again to do the above trick // but obviously we have to start from down below ;) return bv()->text->selectNextWordToSpellcheck(value); @@ -2272,7 +2191,6 @@ void LyXText::deleteWordForward() cursorRight(bv()); else { LyXCursor tmpcursor = cursor; - tmpcursor.row(0); // ?? selection.set(true); // to avoid deletion cursorRightOneWord(); setCursor(tmpcursor, tmpcursor.par(), tmpcursor.pos()); @@ -2293,7 +2211,6 @@ void LyXText::deleteWordBackward() cursorLeft(bv()); else { LyXCursor tmpcursor = cursor; - tmpcursor.row(0); // ?? selection.set(true); // to avoid deletion cursorLeftOneWord(); setCursor(tmpcursor, tmpcursor.par(), tmpcursor.pos()); @@ -2315,7 +2232,6 @@ void LyXText::deleteLineForward() LyXCursor tmpcursor = cursor; // We can't store the row over a regular setCursor // so we set it to 0 and reset it afterwards. - tmpcursor.row(0); // ?? selection.set(true); // to avoid deletion cursorEnd(); setCursor(tmpcursor, tmpcursor.par(), tmpcursor.pos()); @@ -2341,13 +2257,12 @@ void LyXText::changeCase(LyXText::TextCase action) from = selection.start; to = selection.end; } else { - getWord(from, to, PARTIAL_WORD); + from = cursor; + ::getWord(from, to, lyx::PARTIAL_WORD, ownerParagraphs()); setCursor(to.par(), to.pos() + 1); } - lyx::Assert(from <= to); - - setUndo(bv(), Undo::FINISH, &*from.par(), &*boost::next(to.par())); + setUndo(bv(), Undo::FINISH, from.par(), to.par()); pos_type pos = from.pos(); ParagraphList::iterator pit = from.par(); @@ -2381,8 +2296,8 @@ void LyXText::changeCase(LyXText::TextCase action) ++pos; } - if (to.row() != from.row()) - postPaint(from.y() - from.row()->baseline()); + if (getRow(to) != getRow(from)) + postPaint(from.y() - getRow(from)->baseline()); } @@ -2417,8 +2332,7 @@ void LyXText::Delete() LyXCursor tmpcursor = cursor; // to make sure undo gets the right cursor position cursor = old_cursor; - setUndo(bv(), Undo::DELETE, - &*cursor.par(), &*boost::next(cursor.par())); + setUndo(bv(), Undo::DELETE, cursor.par()); cursor = tmpcursor; backspace(); } @@ -2465,10 +2379,10 @@ void LyXText::backspace() cursorLeft(bv()); // the layout things can change the height of a row ! - int const tmpheight = cursor.row()->height(); - setHeightOfRow(cursor.row()); - if (cursor.row()->height() != tmpheight) { - postPaint(cursor.y() - cursor.row()->baseline()); + int const tmpheight = cursorRow()->height(); + setHeightOfRow(cursorRow()); + if (cursorRow()->height() != tmpheight) { + postPaint(cursor.y() - cursorRow()->baseline()); } return; } @@ -2476,12 +2390,12 @@ void LyXText::backspace() if (cursor.par() != ownerParagraphs().begin()) { setUndo(bv(), Undo::DELETE, - &*boost::prior(cursor.par()), - &*boost::next(cursor.par())); + boost::prior(cursor.par()), + cursor.par()); } ParagraphList::iterator tmppit = cursor.par(); - RowList::iterator tmprow = cursor.row(); + RowList::iterator tmprow = cursorRow(); // We used to do cursorLeftIntern() here, but it is // not a good idea since it triggers the auto-delete @@ -2523,7 +2437,7 @@ void LyXText::backspace() if (cursor.pos()) cursor.pos(cursor.pos() - 1); - postPaint(cursor.y() - cursor.row()->baseline()); + postPaint(cursor.y() - cursorRow()->baseline()); // remove the lost paragraph // This one is not safe, since the paragraph that the tmprow and the @@ -2534,7 +2448,7 @@ void LyXText::backspace() //RemoveRow(tmprow); // This rebuilds the rows. - appendParagraph(cursor.row()); + appendParagraph(cursorRow()); updateCounters(); // the row may have changed, block, hfills etc. @@ -2543,8 +2457,7 @@ void LyXText::backspace() } else { // this is the code for a normal backspace, not pasting // any paragraphs - setUndo(bv(), Undo::DELETE, - &*cursor.par(), &*boost::next(cursor.par())); + setUndo(bv(), Undo::DELETE, cursor.par()); // We used to do cursorLeftIntern() here, but it is // not a good idea since it triggers the auto-delete // mechanism. So we do a cursorLeftIntern()-lite, @@ -2563,7 +2476,7 @@ void LyXText::backspace() } } - RowList::iterator row = cursor.row(); + RowList::iterator row = cursorRow(); int y = cursor.y() - row->baseline(); pos_type z; // remember that a space at the end of a row doesnt count @@ -2742,6 +2655,42 @@ void LyXText::backspace() } +RowList::iterator LyXText::cursorRow() const +{ + return getRow(cursor.par(), cursor.pos()); +} + + +RowList::iterator LyXText::getRow(LyXCursor const & cur) const +{ + return getRow(cur.par(), cur.pos()); +} + + +RowList::iterator +LyXText::getRow(ParagraphList::iterator pit, pos_type pos) const +{ + if (rows().empty()) + return rowlist_.end(); + + // find the first row of the specified paragraph + RowList::iterator rit = rowlist_.begin(); + RowList::iterator end = rowlist_.end(); + while (boost::next(rit) != end && rit->par() != pit) { + ++rit; + } + + // now find the wanted row + while (rit->pos() < pos + && boost::next(rit) != end + && boost::next(rit)->par() == pit + && boost::next(rit)->pos() <= pos) { + ++rit; + } + + return rit; +} + // returns pointer to a specified row RowList::iterator LyXText::getRow(ParagraphList::iterator pit, pos_type pos, int & y) const