While thinking about the last (!) remaining critical bug in the 1.4 pipe, I stumbled over an old patch from Alfredo, which was rejected due to the feature freeze (http://marc.theaimsgroup.com/?l=lyx-devel&m=110186623406865&q=p3)
The thing is, now, that this patch fixes the assert in a really elegant way: collapsables are automatically opened when the cursor enters (and closed when it leaves, except status_ is open). Something like this has to be done anyway to cure the bug. I think this is enough judgement to let the minor feature enhancement, which the patch originally aimed at, pass thru. I have adapted the patch to current cvs (see attached). The autoopen feature is not yet used by the spellchecker, though (which would be a oneliner, I guess, but could certainly also wait). Lars, could this get into favour with you? Jürgen
Index: insetcollapsable.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insetcollapsable.C,v retrieving revision 1.278 diff -p -u -r1.278 insetcollapsable.C --- insetcollapsable.C 15 Jul 2005 22:10:21 -0000 1.278 +++ insetcollapsable.C 16 Sep 2005 14:06:55 -0000 @@ -40,9 +40,16 @@ using std::min; using std::ostream; +InsetCollapsable::CollapseStatus InsetCollapsable::status() const +{ + return autoOpen_ ? Open : status_; +} + + InsetCollapsable::InsetCollapsable (BufferParams const & bp, CollapseStatus status) - : InsetText(bp), label("Label"), status_(status), openinlined_(false) + : InsetText(bp), label("Label"), status_(status), + openinlined_(false), autoOpen_(false) { setAutoBreakRows(true); setDrawFrame(true); @@ -122,12 +129,14 @@ Dimension InsetCollapsable::dimensionCol void InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const { + autoOpen_ = mi.base.bv->cursor().isInside(this); mi.base.textwidth -= 2 * TEXT_TO_INSET_OFFSET; - if (status_ == Inlined) { + + if (status() == Inlined) { InsetText::metrics(mi, dim); } else { dim = dimensionCollapsed(); - if (status_ == Open) { + if (status() == Open) { InsetText::metrics(mi, textdim_); openinlined_ = (textdim_.wid + dim.wid <= mi.base.textwidth); if (openinlined_) { @@ -151,7 +160,7 @@ void InsetCollapsable::metrics(MetricsIn void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const { const int xx = x + TEXT_TO_INSET_OFFSET; - if (status_ == Inlined) { + if (status() == Inlined) { InsetText::draw(pi, xx, y); } else { Dimension dimc = dimensionCollapsed(); @@ -162,7 +171,7 @@ void InsetCollapsable::draw(PainterInfo button_dim.y2 = top + dimc.height(); pi.pain.buttonText(xx, top + dimc.asc, label, labelfont_); - if (status_ == Open) { + if (status() == Open) { int textx, texty; if (openinlined_) { textx = xx + dimc.width(); @@ -181,13 +190,13 @@ void InsetCollapsable::draw(PainterInfo void InsetCollapsable::drawSelection(PainterInfo & pi, int x, int y) const { x += TEXT_TO_INSET_OFFSET; - if (status_ == Open) { + if (status() == Open) { if (openinlined_) x += dimensionCollapsed().wid; else y += dimensionCollapsed().des + textdim_.asc; } - if (status_ != Collapsed) + if (status() != Collapsed) InsetText::drawSelection(pi, x, y); } @@ -195,32 +204,30 @@ void InsetCollapsable::drawSelection(Pai void InsetCollapsable::cursorPos (CursorSlice const & sl, bool boundary, int & x, int & y) const { - if (status_ == Collapsed) { - x = xo(); - y = yo(); - } else { - InsetText::cursorPos(sl, boundary, x, y); - if (status_ == Open) { - if (openinlined_) - x += dimensionCollapsed().wid; - else - y += dimensionCollapsed().height() - ascent() - + TEXT_TO_INSET_OFFSET + textdim_.asc; - } - x += TEXT_TO_INSET_OFFSET; + BOOST_ASSERT(status() != Collapsed); + + InsetText::cursorPos(sl, boundary, x, y); + + if (status() == Open) { + if (openinlined_) + x += dimensionCollapsed().wid; + else + y += dimensionCollapsed().height() - ascent() + + TEXT_TO_INSET_OFFSET + textdim_.asc; } + x += TEXT_TO_INSET_OFFSET; } InsetBase::EDITABLE InsetCollapsable::editable() const { - return status_ != Collapsed ? HIGHLY_EDITABLE : IS_EDITABLE; + return status() != Collapsed ? HIGHLY_EDITABLE : IS_EDITABLE; } bool InsetCollapsable::descendable() const { - return status_ != Collapsed; + return status() != Collapsed; } @@ -262,7 +269,7 @@ void InsetCollapsable::edit(LCursor & cu InsetBase * InsetCollapsable::editXY(LCursor & cur, int x, int y) { //lyxerr << "InsetCollapsable: edit xy" << endl; - if (status_ == Collapsed) + if (status() == Collapsed) return this; cur.push(*this); return InsetText::editXY(cur, x, y); @@ -276,9 +283,9 @@ void InsetCollapsable::doDispatch(LCurso switch (cmd.action) { case LFUN_MOUSE_PRESS: - if (status_ == Inlined) + if (status() == Inlined) InsetText::doDispatch(cur, cmd); - else if (status_ == Open && !hitButton(cmd)) + else if (status() == Open && !hitButton(cmd)) InsetText::doDispatch(cur, cmd); else cur.noUpdate(); @@ -289,7 +296,7 @@ void InsetCollapsable::doDispatch(LCurso case LFUN_MOUSE_TRIPLE: if (status_ == Inlined) InsetText::doDispatch(cur, cmd); - else if (status_ == Open && !hitButton(cmd)) + else if (status() && !hitButton(cmd)) InsetText::doDispatch(cur, cmd); else cur.undispatched(); @@ -301,7 +308,7 @@ void InsetCollapsable::doDispatch(LCurso break; } - switch (status_) { + switch (status()) { case Collapsed: //lyxerr << "InsetCollapsable::lfunMouseRelease 1" << endl; Index: insetcollapsable.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insetcollapsable.h,v retrieving revision 1.187 diff -p -u -r1.187 insetcollapsable.h --- insetcollapsable.h 15 Jul 2005 22:10:22 -0000 1.187 +++ insetcollapsable.h 16 Sep 2005 14:06:55 -0000 @@ -69,7 +69,7 @@ public: /// bool inlined() const { return status_ == Inlined; } /// - CollapseStatus status() const { return status_; } + CollapseStatus status() const; /// bool allowSpellCheck() const { return true; } /// @@ -107,6 +107,8 @@ private: mutable CollapseStatus status_; /// a substatus of the Open status, determined automatically in metrics mutable bool openinlined_; + /// the inset will automatically open when the cursor is inside + mutable bool autoOpen_; /// mutable Dimension textdim_; };