X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftext2.C;h=97fc51aa5b048f91b88c6b82dfdd8765816c54b7;hb=c96136c04080415efdfb6df9b3d25f9e2e732782;hp=e16a58724e4d687530231931322546893d641545;hpb=0510f56da8d04ffb0e901fc913d254b6ff213048;p=lyx.git diff --git a/src/text2.C b/src/text2.C index e16a58724e..97fc51aa5b 100644 --- a/src/text2.C +++ b/src/text2.C @@ -1,12 +1,21 @@ -/* This file is part of - * ====================================================== +/** + * \file text2.C + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. * - * LyX, The Document Processor + * \author Asger Alstrup + * \author Lars Gullik Bjønnes + * \author Alfredo Braunstein + * \author Jean-Marc Lasgouttes + * \author Angus Leeming + * \author John Levon + * \author André Pönitz + * \author Allan Rae + * \author Dekel Tsur + * \author Jürgen Vigna * - * Copyright 1995 Matthias Ettrich - * Copyright 1995-2001 The LyX Team. - * - * ====================================================== */ + * Full author contact details are available in file CREDITS. + */ #include @@ -273,7 +282,7 @@ void LyXText::toggleInset() else inset->open(bv()); - bv()->updateInset(); + bv()->updateInset(inset); } @@ -535,17 +544,7 @@ void LyXText::setFont(LyXFont const & font, bool toggleall) } -// rebreaks all paragraphs between the specified pars -// This function is needed after SetLayout and SetFont etc. -void LyXText::redoParagraphs(ParagraphList::iterator start, - ParagraphList::iterator end) -{ - for ( ; start != end; ++start) - redoParagraph(start); -} - - -void LyXText::redoParagraph(ParagraphList::iterator pit) +int LyXText::redoParagraphInternal(ParagraphList::iterator pit) { RowList::iterator rit = pit->rows.begin(); RowList::iterator end = pit->rows.end(); @@ -555,6 +554,15 @@ void LyXText::redoParagraph(ParagraphList::iterator pit) height -= rit->height(); pit->rows.clear(); + // redo insets + InsetList::iterator ii = pit->insetlist.begin(); + InsetList::iterator iend = pit->insetlist.end(); + for (; ii != iend; ++ii) { + Dimension dim; + MetricsInfo mi(bv(), getFont(pit, ii->pos), workWidth()); + ii->inset->metrics(mi, dim); + } + // rebreak the paragraph for (pos_type z = 0; z < pit->size() + 1; ) { Row row(z); @@ -563,14 +571,42 @@ void LyXText::redoParagraph(ParagraphList::iterator pit) pit->rows.push_back(row); } - // set height and fill of rows + int par_width = 0; + // set height and fill and width of rows + int const ww = workWidth(); for (rit = pit->rows.begin(); rit != end; ++rit) { - rit->fill(fill(pit, rit, workWidth())); + int const f = fill(pit, rit, ww); + int const w = ww - f; + par_width = std::max(par_width, w); + rit->fill(f); + rit->width(w); prepareToPrint(pit, rit); setHeightOfRow(pit, rit); + height += rit->height(); } //lyxerr << "redoParagraph: " << pit->rows.size() << " rows\n"; + return par_width; +} + + +int LyXText::redoParagraphs(ParagraphList::iterator start, + ParagraphList::iterator end) +{ + int pars_width = 0; + for ( ; start != end; ++start) { + int par_width = redoParagraphInternal(start); + pars_width = std::max(par_width, pars_width); + } + updateRowPositions(); + return pars_width; +} + + +void LyXText::redoParagraph(ParagraphList::iterator pit) +{ + redoParagraphInternal(pit); + updateRowPositions(); } @@ -589,29 +625,11 @@ void LyXText::metrics(MetricsInfo & mi, Dimension & dim) //Assert(mi.base.textwidth); // rebuild row cache - width = 0; - height = 0; + width = 0; + ///height = 0; //anchor_y_ = 0; - - ParagraphList::iterator pit = ownerParagraphs().begin(); - ParagraphList::iterator end = ownerParagraphs().end(); - - for (; pit != end; ++pit) { - pit->rows.clear(); - - InsetList::iterator ii = pit->insetlist.begin(); - InsetList::iterator iend = pit->insetlist.end(); - for (; ii != iend; ++ii) { - Dimension dim; - MetricsInfo m = mi; -#warning FIXME: pos != 0 - m.base.font = getFont(pit, 0); - ii->inset->metrics(m, dim); - } - - redoParagraph(pit); - } + width = redoParagraphs(ownerParagraphs().begin(), ownerParagraphs().end()); // final dimension dim.asc = firstRow()->ascent_of_text(); @@ -657,21 +675,12 @@ void LyXText::cursorEnd() return; RowList::iterator rit = cursorRow(); - RowList::iterator next_rit = boost::next(rit); - RowList::iterator end = boost::next(rit); ParagraphList::iterator pit = cursor.par(); - pos_type last_pos = lastPos(*pit, rit); - - if (next_rit == end) { - ++last_pos; - } else { - if (pit->empty() || - (pit->getChar(last_pos) != ' ' && !pit->isNewline(last_pos))) { - ++last_pos; - } - } - - setCursor(pit, last_pos); + pos_type pos = lastPos(*pit, rit); + /* cursor should be before a hard newline only */ + if (!pit->isNewline(pos)) + ++pos; + setCursor(pit, pos); } @@ -735,7 +744,7 @@ string LyXText::getStringToIndex() else if (selection.start.par() != selection.end.par()) bv()->owner()->message(_("Cannot index more than one paragraph!")); else - idxstring = selectionAsString(bv()->buffer(), false); + idxstring = selectionAsString(*bv()->buffer(), false); // Reset cursors to their original position. cursor = reset_cursor; @@ -830,14 +839,14 @@ void LyXText::setParagraph(bool line_top, bool line_bottom, setSelection(); setCursor(tmpcursor.par(), tmpcursor.pos()); if (inset_owner) - bv()->updateInset(); + bv()->updateInset(inset_owner); } // set the counter of a paragraph. This includes the labels -void LyXText::setCounter(Buffer const * buf, ParagraphList::iterator pit) +void LyXText::setCounter(Buffer const & buf, ParagraphList::iterator pit) { - LyXTextClass const & textclass = buf->params.getLyXTextClass(); + LyXTextClass const & textclass = buf.params.getLyXTextClass(); LyXLayout_ptr const & layout = pit->layout(); if (pit != ownerParagraphs().begin()) { @@ -895,7 +904,7 @@ void LyXText::setCounter(Buffer const * buf, ParagraphList::iterator pit) ostringstream s; - if (i >= 0 && i <= buf->params.secnumdepth) { + if (i >= 0 && i <= buf.params.secnumdepth) { string numbertype; string langtype; @@ -903,9 +912,9 @@ void LyXText::setCounter(Buffer const * buf, ParagraphList::iterator pit) // Is there a label? Useful for Chapter layout if (!pit->params().appendix()) { - s << buf->B_(layout->labelstring()); + s << buf.B_(layout->labelstring()); } else { - s << buf->B_(layout->labelstring_appendix()); + s << buf.B_(layout->labelstring_appendix()); } // Use of an integer is here less than elegant. For now. @@ -914,7 +923,7 @@ void LyXText::setCounter(Buffer const * buf, ParagraphList::iterator pit) numbertype = "sectioning"; } else { numbertype = "appendix"; - if (pit->isRightToLeftPar(buf->params)) + if (pit->isRightToLeftPar(buf.params)) langtype = "hebrew"; else langtype = "latin"; @@ -968,7 +977,7 @@ void LyXText::setCounter(Buffer const * buf, ParagraphList::iterator pit) } // In biblio should't be following counters but... } else { - string s = buf->B_(layout->labelstring()); + string s = buf.B_(layout->labelstring()); // the caption hack: if (layout->labeltype == LABEL_SENSITIVE) { @@ -985,9 +994,10 @@ void LyXText::setCounter(Buffer const * buf, ParagraphList::iterator pit) isOK = true; break; } else { + Paragraph const * owner = &ownerPar(buf, in); tmppit = ownerParagraphs().begin(); for ( ; tmppit != end; ++tmppit) - if (&*tmppit == in->parOwner()) + if (&*tmppit == owner) break; } } @@ -1007,7 +1017,7 @@ void LyXText::setCounter(Buffer const * buf, ParagraphList::iterator pit) textclass.counters().step(fl.type()); // Doesn't work... yet. - s = bformat(_("%1$s #:"), buf->B_(fl.name())); + s = bformat(_("%1$s #:"), buf.B_(fl.name())); } else { // par->SetLayout(0); // s = layout->labelstring; @@ -1053,7 +1063,7 @@ void LyXText::updateCounters() pit->params().depth(maxdepth); // setCounter can potentially change the labelString. - setCounter(bv()->buffer(), pit); + setCounter(*bv()->buffer(), pit); string const & newLabel = pit->params().labelString(); @@ -1074,7 +1084,7 @@ void LyXText::insertInset(InsetOld * inset) // The character will not be inserted a second time insertChar(Paragraph::META_INSET); // If we enter a highly editable inset the cursor should be before - // the inset. After an Undo LyX tries to call inset->edit(...) + // the inset. After an Undo LyX tries to call inset->edit(...) // and fails if the cursor is behind the inset and getInset // does not return the inset! if (isHighlyEditableInset(inset)) @@ -1093,7 +1103,7 @@ void LyXText::cutSelection(bool doclear, bool realcut) // finished. The solution used currently just works, to make it // faster we need to be more clever and probably also have more // calls to stuffClipboard. (Lgb) - bv()->stuffClipboard(selectionAsString(bv()->buffer(), true)); + bv()->stuffClipboard(selectionAsString(*bv()->buffer(), true)); // This doesn't make sense, if there is no selection if (!selection.set()) @@ -1158,7 +1168,7 @@ void LyXText::cutSelection(bool doclear, bool realcut) void LyXText::copySelection() { // stuff the selection onto the X clipboard, from an explicit copy request - bv()->stuffClipboard(selectionAsString(bv()->buffer(), true)); + bv()->stuffClipboard(selectionAsString(*bv()->buffer(), true)); // this doesnt make sense, if there is no selection if (!selection.set()) @@ -1338,23 +1348,15 @@ void LyXText::setCursor(LyXCursor & cur, ParagraphList::iterator pit, return; // get the cursor y position in text - int y = 0; - RowList::iterator row = getRow(pit, pos, y); + + RowList::iterator row = getRow(pit, pos); + int y = row->y(); + RowList::iterator old_row = row; // if we are before the first char of this row and are still in the // same paragraph and there is a previous row then put the cursor on // the end of the previous row cur.iy(y + row->baseline()); - if (row != pit->rows.begin() - && pos - && pos < pit->size() - && pit->getChar(pos) == Paragraph::META_INSET) { - InsetOld * ins = pit->getInset(pos); - if (ins && (ins->needFullRow() || ins->display())) { - --row; - y -= row->height(); - } - } // y is now the beginning of the cursor row y += row->baseline(); @@ -1388,17 +1390,6 @@ void LyXText::setCursor(LyXCursor & cur, ParagraphList::iterator pit, cur.ix(int(x)); } else cur.ix(cur.x()); -/* We take out this for the time being because 1) the redraw code is not - prepared to this yet and 2) because some good policy has yet to be decided - while editting: for instance how to act on rows being created/deleted - because of DEPM. -*/ -#if 0 - //if the cursor is in a visible row, anchor to it - int topy = top_y(); - if (topy < y && y < topy + bv()->workHeight()) - anchor_row(row); -#endif } @@ -1493,7 +1484,7 @@ void LyXText::setCurrentFont() real_current_font = getFont(pit, pos); if (cursor.pos() == pit->size() && - isBoundary(bv()->buffer(), *pit, cursor.pos()) && + isBoundary(*bv()->buffer(), *pit, cursor.pos()) && !cursor.boundary()) { Language const * lang = pit->getParLanguage(bv()->buffer()->params); @@ -1594,7 +1585,7 @@ pos_type LyXText::getColumnNearX(ParagraphList::iterator pit, bool const rtl = (bidi_level(c) % 2 == 1); if (left_side == rtl) { ++c; - boundary = isBoundary(bv()->buffer(), *pit, c); + boundary = isBoundary(*bv()->buffer(), *pit, c); } } @@ -1621,38 +1612,13 @@ void LyXText::setCursorFromCoordinates(int x, int y) } -namespace { - - /** - * return true if the cursor given is at the end of a row, - * and the next row is filled by an inset that spans an entire - * row. - */ - bool beforeFullRowInset(LyXText & lt, LyXCursor const & cur) - { - RowList::iterator row = lt.getRow(cur); - RowList::iterator next = boost::next(row); - - if (next == cur.par()->rows.end() || next->pos() != cur.pos()) - return false; - - if (cur.pos() == cur.par()->size() || !cur.par()->isInset(cur.pos())) - return false; - - InsetOld const * inset = cur.par()->getInset(cur.pos()); - if (inset->needFullRow() || inset->display()) - return true; - - return false; - } -} - - void LyXText::setCursorFromCoordinates(LyXCursor & cur, int x, int y) { // Get the row first. ParagraphList::iterator pit; RowList::iterator rit = getRowNearY(y, pit); + y = rit->y(); + bool bound = false; pos_type const column = getColumnNearX(pit, rit, x, bound); cur.par(pit); @@ -1660,17 +1626,9 @@ void LyXText::setCursorFromCoordinates(LyXCursor & cur, int x, int y) cur.x(x); cur.y(y + rit->baseline()); - if (beforeFullRowInset(*this, cur)) { - pos_type const last = lastPrintablePos(*pit, rit); - RowList::iterator next_rit = rit; - ParagraphList::iterator next_pit = pit; - nextRow(next_pit, next_rit); - cur.ix(int(getCursorX(pit, next_rit, cur.pos(), last, bound))); - cur.iy(y + rit->height() + next_rit->baseline()); - } else { - cur.iy(cur.y()); - cur.ix(cur.x()); - } + cur.iy(cur.y()); + cur.ix(cur.x()); + cur.boundary(bound); } @@ -1681,7 +1639,7 @@ void LyXText::cursorLeft(bool internal) bool boundary = cursor.boundary(); setCursor(cursor.par(), cursor.pos() - 1, true, false); if (!internal && !boundary && - isBoundary(bv()->buffer(), *cursor.par(), cursor.pos() + 1)) + isBoundary(*bv()->buffer(), *cursor.par(), cursor.pos() + 1)) setCursor(cursor.par(), cursor.pos() + 1, true, true); } else if (cursor.par() != ownerParagraphs().begin()) { // steps into the paragraph above @@ -1702,7 +1660,7 @@ void LyXText::cursorRight(bool internal) else if (!at_end) { setCursor(cursor.par(), cursor.pos() + 1, true, false); if (!internal && - isBoundary(bv()->buffer(), *cursor.par(), cursor.pos())) + isBoundary(*bv()->buffer(), *cursor.par(), cursor.pos())) setCursor(cursor.par(), cursor.pos(), true, true); } else if (boost::next(cursor.par()) != ownerParagraphs().end()) setCursor(boost::next(cursor.par()), 0); @@ -1716,7 +1674,7 @@ void LyXText::cursorUp(bool selecting) int y = cursor.y() - cursorRow()->baseline() - 1; setCursorFromCoordinates(x, y); if (!selecting) { - int topy = top_y(); + int topy = bv_owner->top_y(); int y1 = cursor.iy() - topy; int y2 = y1; y -= topy; @@ -1742,7 +1700,7 @@ void LyXText::cursorDown(bool selecting) int y = cursor.y() - cursorRow()->baseline() + cursorRow()->height() + 1; setCursorFromCoordinates(x, y); if (!selecting && cursorRow() == cursorIRow()) { - int topy = top_y(); + int topy = bv_owner->top_y(); int y1 = cursor.iy() - topy; int y2 = y1; y -= topy; @@ -1900,7 +1858,7 @@ bool LyXText::deleteEmptyParagraphMechanism(LyXCursor const & old_cursor) ParagraphList::iterator endpit = boost::next(old_cursor.par()); while (endpit != ownerParagraphs().end() && endpit->getDepth()) ++endpit; - + recordUndo(bv(), Undo::DELETE, old_cursor.par(), boost::prior(endpit)); cursor = tmpcursor;