This is the patch, for if someone wants to test it and tell me how it feels like.
Alfredo
? ChangeLog-old ? PosIterator.C-save ? PosIterator.h-save ? bfri.C ? safe ? textcursor.C-save ? textcursor.h-save ? insets/insetcollapsable-save.C ? insets/insettext-save.C Index: cursor.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/cursor.C,v retrieving revision 1.78 diff -u -p -u -r1.78 cursor.C --- cursor.C 19 Mar 2004 16:36:52 -0000 1.78 +++ cursor.C 22 Mar 2004 12:15:53 -0000 @@ -123,9 +123,10 @@ DispatchResult LCursor::dispatch(FuncReq BOOST_ASSERT(idx() <= lastidx()); BOOST_ASSERT(par() <= lastpar()); - // The common case is 'LFUN handled, need update', so make the - // LFUN handler's life easier by assuming this as default value. - // The handler can reset the update and val flags if necessary. + // The common case is 'LFUN handled, need update', so + // make the LFUN handler's life easier by assuming + // this as default value. The handler can reset the + // update and val flags if necessary. disp_.update(true); disp_.dispatched(true); inset().dispatch(*this, cmd); Index: metricsinfo.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/metricsinfo.C,v retrieving revision 1.12 diff -u -p -u -r1.12 metricsinfo.C --- metricsinfo.C 15 Dec 2003 09:17:04 -0000 1.12 +++ metricsinfo.C 22 Mar 2004 12:15:53 -0000 @@ -21,14 +21,14 @@ using std::string; MetricsBase::MetricsBase() : bv(0), font(), style(LM_ST_TEXT), fontname("mathnormal"), - textwidth(0) + maxwidth(0), remaining_width(0) {} -MetricsBase::MetricsBase(BufferView * b, LyXFont const & f, int w) +MetricsBase::MetricsBase(BufferView * b, LyXFont const & f, int w, int rw) : bv(b), font(f), style(LM_ST_TEXT), fontname("mathnormal"), - textwidth(w) + maxwidth(w), remaining_width(rw) {} @@ -37,8 +37,9 @@ MetricsInfo::MetricsInfo() {} -MetricsInfo::MetricsInfo(BufferView * bv, LyXFont const & font, int textwidth) - : base(bv, font, textwidth) +MetricsInfo::MetricsInfo(BufferView * bv, LyXFont const & font, + int maxwidth, int remaining_width) + : base(bv, font, maxwidth, remaining_width) {} @@ -161,7 +162,7 @@ WidthChanger::WidthChanger(MetricsBase & : Changer<MetricsBase>(mb) { save_ = mb; - mb.textwidth = w; + mb.maxwidth = w; } Index: metricsinfo.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/metricsinfo.h,v retrieving revision 1.10 diff -u -p -u -r1.10 metricsinfo.h --- metricsinfo.h 6 Oct 2003 15:42:29 -0000 1.10 +++ metricsinfo.h 22 Mar 2004 12:15:53 -0000 @@ -40,7 +40,8 @@ struct MetricsBase { /// MetricsBase(); /// - MetricsBase(BufferView * bv, LyXFont const & font, int textwidth); + MetricsBase(BufferView * bv, LyXFont const & font, int maxwidth, + int remaining_width); /// the current view BufferView * bv; @@ -51,7 +52,9 @@ struct MetricsBase { /// name of current font - mathed specific std::string fontname; /// This is the width available in pixels - int textwidth; + int maxwidth; + /// this is the remaining width in the row + int remaining_width; }; @@ -63,8 +66,8 @@ struct MetricsInfo { /// MetricsInfo(); /// - MetricsInfo(BufferView * bv, LyXFont const & font, int textwidth); - + MetricsInfo(BufferView * bv, LyXFont const & font, int maxwidth, + int remaining_width); /// MetricsBase base; }; Index: rowpainter.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/rowpainter.C,v retrieving revision 1.123 diff -u -p -u -r1.123 rowpainter.C --- rowpainter.C 1 Mar 2004 21:10:47 -0000 1.123 +++ rowpainter.C 22 Mar 2004 12:15:54 -0000 @@ -197,6 +197,11 @@ void RowPainter::paintInset(pos_type con BOOST_ASSERT(inset); PainterInfo pi(const_cast<BufferView *>(&bv_)); pi.base.font = getFont(pos); + int const w = text_.width() - text_.rightMargin(*pit_); + + pi.base.maxwidth = w - text_.leftMargin(pit_); + pi.base.remaining_width = w - (x_ - xo_); + inset->drawSelection(pi, int(x_), yo_ + row_.baseline()); inset->draw(pi, int(x_), yo_ + row_.baseline()); x_ += inset->width(); Index: text.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text.C,v retrieving revision 1.553 diff -u -p -u -r1.553 text.C --- text.C 18 Mar 2004 13:28:46 -0000 1.553 +++ text.C 22 Mar 2004 12:15:56 -0000 @@ -493,8 +493,15 @@ void LyXText::rowBreakPoint(ParagraphLis pos_type point = end; pos_type i = pos; for ( ; i < end; ++i, ++fi) { - char const c = pit->getChar(i); + if (pit->isInset(i)) { + Dimension dim; + int const w = width - leftMargin(pit); + MetricsInfo mi(bv(), getFont(pit, i), w, width - x - 1); + pit->getInset(i)->metrics(mi, dim); + } + + char const c = pit->getChar(i); { int thiswidth = singleWidth(pit, i, c, *fi); @@ -512,6 +519,14 @@ void LyXText::rowBreakPoint(ParagraphLis chunkwidth += thiswidth; } + if (!pit->isInset(i) || pit->getInset(i)->isChar()) { + // some insets are line separators too + if (pit->isLineSeparator(i)) { + // register breakpoint: + point = i + 1; + chunkwidth = 0; + } + } // break before a character that will fall off // the right of the row if (x >= width) { @@ -521,7 +536,7 @@ void LyXText::rowBreakPoint(ParagraphLis point = i; else point = i + 1; - + } // exit on last registered breakpoint: break; @@ -538,20 +553,12 @@ void LyXText::rowBreakPoint(ParagraphLis break; } // ...and after. - if (pit->isInset(i) && pit->getInset(i)->display()) { + if (pit->isInset(i) && (pit->getInset(i)->display() || pit->getInset(i)->breakAfter())) { point = i + 1; break; } } - if (!pit->isInset(i) || pit->getInset(i)->isChar()) { - // some insets are line separators too - if (pit->isLineSeparator(i)) { - // register breakpoint: - point = i + 1; - chunkwidth = 0; - } - } } // maybe found one, but the par is short enough. @@ -1068,26 +1075,29 @@ LyXText::computeRowMetrics(ParagraphList if (!pit->empty() && pit->isInset(row.pos()) && pit->getInset(row.pos())->display()) - { align = LYX_ALIGN_CENTER; - } switch (align) { case LYX_ALIGN_BLOCK: { int const ns = numberOfSeparators(*pit, row); - bool disp_inset = false; - if (row.endpos() < pit->size()) { - InsetBase * in = pit->getInset(row.endpos()); - if (in) - disp_inset = in->display(); - } + bool nostretch = false; + if (row.endpos() < pit->size() + && pit->isInset(row.endpos()) + && pit->getInset(row.endpos())->display()) + nostretch = true; + + if (row.pos() != row.endpos() + && pit->isInset(row.endpos() - 1) + && pit->getInset(row.endpos() - 1)->breakAfter()) + nostretch = true; + // If we have separators, this is not the last row of a // par, does not end in newline, and is not row above a // display inset... then stretch it if (ns && row.endpos() < pit->size() && !pit->isNewline(row.endpos() - 1) - && !disp_inset + && !nostretch ) { result.separator = w / ns; } else if (is_rtl) { @@ -1548,16 +1558,6 @@ void LyXText::redoParagraphInternal(Para pit->height = 0; pit->width = 0; - // redo insets - InsetList::iterator ii = pit->insetlist.begin(); - InsetList::iterator iend = pit->insetlist.end(); - for (; ii != iend; ++ii) { - Dimension dim; - int const w = maxwidth_ - leftMargin(pit) - rightMargin(*pit); - MetricsInfo mi(bv(), getFont(pit, ii->pos), w); - ii->inset->metrics(mi, dim); - } - // rebreak the paragraph pit->setBeginOfBody(); pos_type z = 0; @@ -1603,10 +1603,10 @@ void LyXText::fullRebreak() void LyXText::metrics(MetricsInfo & mi, Dimension & dim) { - //BOOST_ASSERT(mi.base.textwidth); - if (mi.base.textwidth) - maxwidth_ = mi.base.textwidth; - //lyxerr << "LyXText::metrics: width: " << mi.base.textwidth + //BOOST_ASSERT(mi.base.maxwidth); + if (mi.base.maxwidth) + maxwidth_ = mi.base.maxwidth; + //lyxerr << "LyXText::metrics: width: " << mi.base.maxwidth //<< " maxWidth: " << maxwidth << "\nfont: " << mi.base.font //<< endl; Index: text2.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text2.C,v retrieving revision 1.561 diff -u -p -u -r1.561 text2.C --- text2.C 18 Mar 2004 13:57:13 -0000 1.561 +++ text2.C 22 Mar 2004 12:15:57 -0000 @@ -1310,25 +1310,29 @@ InsetBase * LyXText::editXY(LCursor & cu Row const & row = *getRowNearY(y - yo_, pit); bool bound = false; - int xx = x; // is modified by getColumnNearX - pos_type const pos = row.pos() + getColumnNearX(pit, row, xx, bound); - cur.par() = parOffset(pit); - cur.pos() = pos; - cur.boundary() = bound; +// int xx = x; // is modified by getColumnNearX +// pos_type const pos = row.pos() + getColumnNearX(pit, row, xx, bound); +// cur.par() = parOffset(pit); +// cur.pos() = pos; +// cur.boundary() = bound; // try to descend into nested insets InsetBase * inset = checkInsetHit(x, y); if (!inset) return 0; + cur.par() = parOffset(pit); + cur.pos() = pit->getPositionOfInset(inset); + cur.boundary() = bound; + // This should be just before or just behind the // cursor position set above. - BOOST_ASSERT((pos != 0 && inset == pit->getInset(pos - 1)) - || inset == pit->getInset(pos)); + //BOOST_ASSERT((pos != 0 && inset == pit->getInset(pos - 1)) + // || inset == pit->getInset(pos)); // Make sure the cursor points to the position before // this inset. - if (inset == pit->getInset(pos - 1)) - --cur.pos(); + //if (inset == pit->getInset(pos - 1)) + // --cur.pos(); return inset->editXY(cur, x, y); } Index: insets/insetbase.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insetbase.h,v retrieving revision 1.33 diff -u -p -u -r1.33 insetbase.h --- insets/insetbase.h 18 Mar 2004 13:57:15 -0000 1.33 +++ insets/insetbase.h 22 Mar 2004 12:16:00 -0000 @@ -325,6 +325,9 @@ public: virtual bool display() const { return false; } // should we break lines after this inset? virtual bool isLineSeparator() const { return false; } + // + virtual bool breakAfter() const { return false; } + /// dumps content to lyxerr virtual void dump() const; /// Index: insets/insetbox.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insetbox.C,v retrieving revision 1.19 diff -u -p -u -r1.19 insetbox.C --- insets/insetbox.C 18 Mar 2004 12:53:38 -0000 1.19 +++ insets/insetbox.C 22 Mar 2004 12:16:00 -0000 @@ -154,7 +154,7 @@ void InsetBox::setButtonLabel() void InsetBox::metrics(MetricsInfo & m, Dimension & dim) const { MetricsInfo mi = m; - mi.base.textwidth = params_.width.inPixels(m.base.textwidth); + mi.base.maxwidth = params_.width.inPixels(m.base.maxwidth); InsetCollapsable::metrics(mi, dim); //if (params_.inner_box && isOpen()) // dim.wid = mi.base.textwidth; Index: insets/insetcollapsable.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insetcollapsable.C,v retrieving revision 1.247 diff -u -p -u -r1.247 insetcollapsable.C --- insets/insetcollapsable.C 18 Mar 2004 13:57:16 -0000 1.247 +++ insets/insetcollapsable.C 22 Mar 2004 12:16:01 -0000 @@ -136,7 +136,9 @@ void InsetCollapsable::metrics(MetricsIn if (status_ == Open) { Dimension insetdim; inset.metrics(mi, insetdim); - openinlined_ = (insetdim.wid + dim.wid <= mi.base.textwidth); + //we prefer inlined also if the inset and + //button wouldn't touch + openinlined_ = (insetdim.wid + dim.wid <= mi.base.remaining_width || insetdim.wid < dim.wid + mi.base.maxwidth - mi.base.remaining_width); if (openinlined_) { dim.wid += insetdim.wid; dim.des = max(dim.des, insetdim.des); @@ -144,7 +146,10 @@ void InsetCollapsable::metrics(MetricsIn } else { dim.des += insetdim.height() + TEXT_TO_BOTTOM_OFFSET; - dim.wid = max(dim.wid, insetdim.wid); + + lyxerr << "rw: " << mi.base.remaining_width << " mw: " << mi.base.maxwidth << " bw: " << dim.wid << endl; + //eat the rest of the row + //dim.wid = max(dim.wid, mi.base.remaining_width); } } } @@ -158,6 +163,13 @@ void InsetCollapsable::draw_collapsed(Pa } +bool InsetCollapsable::covers(int x, int y) const +{ + return (button_dim.contains(x, y) + || (status_ == Open && inset.covers(x, y))); +} + + void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const { setPosCache(pi, x, y); @@ -180,10 +192,16 @@ void InsetCollapsable::draw(PainterInfo if (openinlined_) inset.draw(pi, x + dimc.width(), y - aa + inset.ascent()); - else - inset.draw(pi, x, y - aa + dimc.height() + inset.ascent()); + else + inset.draw(pi, x + pi.base.remaining_width - pi.base.maxwidth, y - aa + dimc.height() + inset.ascent()); } } +} + + +bool InsetCollapsable::breakAfter() const +{ + return status_ == Open && !openinlined_; } Index: insets/insetcollapsable.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insetcollapsable.h,v retrieving revision 1.171 diff -u -p -u -r1.171 insetcollapsable.h --- insets/insetcollapsable.h 18 Mar 2004 13:57:16 -0000 1.171 +++ insets/insetcollapsable.h 22 Mar 2004 12:16:01 -0000 @@ -120,6 +120,10 @@ public: void setStatus(CollapseStatus st); /// bool allowSpellCheck() const { return true; } + /// + bool covers(int x, int y) const; + /// + bool breakAfter() const; protected: /// @@ -162,6 +166,8 @@ private: mutable CollapseStatus status_; /// a substatus of the Open status, determined automatically in metrics mutable bool openinlined_; + /// + mutable int xoffset; }; #endif Index: insets/insetinclude.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insetinclude.C,v retrieving revision 1.185 diff -u -p -u -r1.185 insetinclude.C --- insets/insetinclude.C 18 Mar 2004 12:53:39 -0000 1.185 +++ insets/insetinclude.C 22 Mar 2004 12:16:01 -0000 @@ -535,11 +535,11 @@ void InsetInclude::metrics(MetricsInfo & button_.metrics(mi, dim); } int center_indent = type(params_) == INPUT ? - 0 : (mi.base.textwidth - dim.wid) / 2; + 0 : (mi.base.maxwidth - dim.wid) / 2; Box b(center_indent, center_indent + dim.wid, -dim.asc, dim.des); button_.setBox(b); - dim.wid = mi.base.textwidth; + dim.wid = mi.base.maxwidth; dim_ = dim; } Index: insets/insetline.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insetline.C,v retrieving revision 1.3 diff -u -p -u -r1.3 insetline.C --- insets/insetline.C 5 Nov 2003 12:06:16 -0000 1.3 +++ insets/insetline.C 22 Mar 2004 12:16:01 -0000 @@ -40,7 +40,7 @@ void InsetLine::metrics(MetricsInfo & mi { dim.asc = 3; dim.des = 3; - dim.wid = mi.base.textwidth; + dim.wid = mi.base.maxwidth; dim_ = dim; } Index: insets/insetpagebreak.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insetpagebreak.C,v retrieving revision 1.4 diff -u -p -u -r1.4 insetpagebreak.C --- insets/insetpagebreak.C 5 Nov 2003 12:06:16 -0000 1.4 +++ insets/insetpagebreak.C 22 Mar 2004 12:16:02 -0000 @@ -41,7 +41,7 @@ void InsetPagebreak::metrics(MetricsInfo { dim.asc = defaultRowHeight(); dim.des = defaultRowHeight(); - dim.wid = mi.base.textwidth; + dim.wid = mi.base.maxwidth; dim_ = dim; } Index: insets/insettabular.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insettabular.C,v retrieving revision 1.412 diff -u -p -u -r1.412 insettabular.C --- insets/insettabular.C 18 Mar 2004 13:57:16 -0000 1.412 +++ insets/insettabular.C 22 Mar 2004 12:16:04 -0000 @@ -225,7 +225,7 @@ void InsetTabular::read(Buffer const & b void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const { //lyxerr << "InsetTabular::metrics: " << mi.base.bv << " width: " << - // mi.base.textwidth << "\n"; + // mi.base.maxwidth << "\n"; if (!mi.base.bv) { lyxerr << "InsetTabular::metrics: need bv" << endl; BOOST_ASSERT(false); @@ -240,8 +240,8 @@ void InsetTabular::metrics(MetricsInfo & ++cell; Dimension dim; MetricsInfo m = mi; - m.base.textwidth = - tabular.column_info[j].p_width.inPixels(mi.base.textwidth); + m.base.maxwidth = + tabular.column_info[j].p_width.inPixels(mi.base.maxwidth); tabular.getCellInset(cell).metrics(m, dim); maxAsc = max(maxAsc, dim.asc); maxDesc = max(maxDesc, dim.des); Index: insets/insettext.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insettext.C,v retrieving revision 1.585 diff -u -p -u -r1.585 insettext.C --- insets/insettext.C 18 Mar 2004 13:57:18 -0000 1.585 +++ insets/insettext.C 22 Mar 2004 12:16:04 -0000 @@ -173,14 +173,14 @@ void InsetText::read(Buffer const & buf, void InsetText::metrics(MetricsInfo & mi, Dimension & dim) const { - //lyxerr << "InsetText::metrics: width: " << mi.base.textwidth << endl; + //lyxerr << "InsetText::metrics: width: " << mi.base.maxwidth << endl; setViewCache(mi.base.bv); - mi.base.textwidth -= 2 * TEXT_TO_INSET_OFFSET; + mi.base.maxwidth -= 2 * TEXT_TO_INSET_OFFSET; text_.metrics(mi, dim); dim.asc += TEXT_TO_INSET_OFFSET; dim.des += TEXT_TO_INSET_OFFSET; dim.wid += 2 * TEXT_TO_INSET_OFFSET; - mi.base.textwidth += 2 * TEXT_TO_INSET_OFFSET; + mi.base.maxwidth += 2 * TEXT_TO_INSET_OFFSET; dim_ = dim; font_ = mi.base.font; text_.font_ = mi.base.font; Index: insets/insettheorem.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insettheorem.C,v retrieving revision 1.25 diff -u -p -u -r1.25 insettheorem.C --- insets/insettheorem.C 5 Nov 2003 12:06:18 -0000 1.25 +++ insets/insettheorem.C 22 Mar 2004 12:16:04 -0000 @@ -70,8 +70,8 @@ auto_ptr<InsetBase> InsetTheorem::clone( void InsetTheorem::metrics(MetricsInfo & mi, Dimension & dim) const { InsetCollapsable::metrics(mi, dim); - center_indent_ = (mi.base.textwidth - dim.wid) / 2; - dim.wid = mi.base.textwidth; + center_indent_ = (mi.base.maxwidth - dim.wid) / 2; + dim.wid = mi.base.maxwidth; dim_ = dim; } Index: mathed/math_textinset.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_textinset.C,v retrieving revision 1.22 diff -u -p -u -r1.22 math_textinset.C --- mathed/math_textinset.C 2 Feb 2004 17:32:56 -0000 1.22 +++ mathed/math_textinset.C 22 Mar 2004 12:16:05 -0000 @@ -122,7 +122,7 @@ void MathTextInset::metrics(MetricsInfo // This is a regular char. Go on if we either don't care for // the width limit or have not reached that limit. curr += cell(0)[i]->width(); - if (curr + safe <= mi.base.textwidth) + if (curr + safe <= mi.base.maxwidth) continue; }