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_;
 };

Reply via email to