X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftext.C;h=8e68a70a32f797702cf157a8266ab2fa36d220dd;hb=fe390e9da1538e20eabbc98977d845295f8e563d;hp=ead3e5231dbcbd196f6c822d0b4eb4be5305f38f;hpb=7ab4b6683f1067ffc9cc3fc1b0c56f3f0c1244a1;p=lyx.git diff --git a/src/text.C b/src/text.C index ead3e5231d..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; } @@ -150,10 +156,10 @@ int LyXText::workWidth(Inset const * inset) const ParagraphList::iterator par = std::find(ownerParagraphs().begin(), ownerParagraphs().end(), *inset->parOwner()); - //lyx::Assert(par); + //Assert(par); pos_type pos = par->getPositionOfInset(inset); - lyx::Assert(pos != -1); + Assert(pos != -1); LyXLayout_ptr const & layout = par->layout(); @@ -971,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. @@ -1011,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; @@ -1323,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; @@ -1353,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; @@ -1406,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; @@ -1503,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()) { @@ -1524,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 @@ -1540,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 @@ -1550,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(); } @@ -1575,8 +1581,8 @@ void LyXText::insertChar(char c) // 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 = "+-/*"; @@ -1670,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 @@ -1705,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)); @@ -1974,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()); } @@ -2003,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) @@ -2290,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()); @@ -2311,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()); @@ -2333,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()); @@ -2359,7 +2257,8 @@ 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); } @@ -2397,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()); } @@ -2480,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; } @@ -2496,7 +2395,7 @@ void LyXText::backspace() } 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 @@ -2538,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 @@ -2549,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. @@ -2577,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 @@ -2756,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