The problem with bug 3903
(http://bugzilla.lyx.org/show_bug.cgi?id=3903) is clear, there is no
notifyCursorLeave when you are not in an InsetMathHull (the outer
level of the inset). Therefore, after you edit in, for example, super
or subscript, math preview is not updated.

There is another problem with the current approach: preview snippet is
always regenerated with notifyCursorLeave. That is to say, output to
latex will happen every time when you enter and leave a mathed. This
is, presumably, inefficient.

My solution is to find a way to know if an inset is modified. If so,
clear snippet_, and when a redraw is *needed*, snippet_ is
regenerated.

The attached pre-patch has already fixed the bug, just that too many
events mark an inset dirty so preview is regenerated way too many
times. Help is needed here.

Index: src/insets/RenderPreview.h
===================================================================
--- src/insets/RenderPreview.h  (revision 18842)
+++ src/insets/RenderPreview.h  (working copy)
@@ -84,6 +84,12 @@
        /// equivalent to dynamic_cast
        virtual RenderPreview * asPreview() { return this; }

+       /// clear preview
+       void clear() { snippet_.clear(); }
+
+       /// is this preview empty?
+       bool empty() { snippet_.empty(); }
+

BO: clear snippet_.

Index: src/insets/Inset.h
===================================================================
--- src/insets/Inset.h  (revision 18842)
+++ src/insets/Inset.h  (working copy)
@@ -433,6 +433,9 @@
        /// Add an entry to the TocList
        /// pit is the ParConstIterator of the paragraph containing the inset
        virtual void addToToc(TocList &, Buffer const &, ParConstIterator &) 
const {}
+       /// mark this inset as dirty, inset can, for example, regenerate
+       /// preview in this function
+       virtual void markDirty() {}

BO: Another virtual function of inset???? This is to mark inset as
dirty so appropriate action can be taken. I add it here because it can
be used to, for example, re-generate TOC.


@@ -276,6 +284,12 @@
 bool InsetMathHull::previewState(BufferView * bv) const
{
        if (!editing(bv) && RenderPreview::status() == LyXRC::PREVIEW_ON) {
+               if (preview_->empty()) {
+                       docstring const snippet = latex_string(*this);
+                       lyxerr << "add preview" << to_utf8(snippet) << 
std::endl;
+                       preview_->addPreview(snippet, *bv->buffer());
+                       preview_->startLoading(*bv->buffer());
+               }
                graphics::PreviewImage const * pimage =
                        preview_->getPreviewImage(*bv->buffer());
                return pimage && pimage->image();
@@ -395,19 +409,6 @@
}

BO: if preview_ is empty, regenerate it.


-bool InsetMathHull::notifyCursorLeaves(Cursor & cur)
-{
-       if (RenderPreview::status() == LyXRC::PREVIEW_ON) {
-               Buffer const & buffer = cur.buffer();
-               docstring const snippet = latex_string(*this);
-               preview_->addPreview(snippet, buffer);
-               preview_->startLoading(buffer);
-               cur.updateFlags(Update::Force);
-       }
-       return false;
-}

BO: Remove notifyCursorLeave.

+void InsetMathHull::markDirty()
+{
+       preview_->clear();
+ }

BO: if the inset is dirty, clear preview.


Index: src/mathed/InsetMathNest.cpp
===================================================================
--- src/mathed/InsetMathNest.cpp        (revision 18842)
+++ src/mathed/InsetMathNest.cpp        (working copy)
@@ -1001,6 +1001,9 @@
                InsetMath::doDispatch(cur, cmd);
                break;
        }
+       // FIXME: Need an efficient way of knowing if the inset has been 
modified.
+       if (cur.result().dispatched())
+               markDirty();
}

 This is the unfinished part. Numerous LFUNC can contaminate an
inset, what is the best way to know if an inset is modified? I am
thinking of doing an markDiry after each recordUndo, but there are too
many recordUndo's. Is there any way to know if recordUndo() is called?

Cheers,
Bo
Index: src/insets/RenderPreview.h
===================================================================
--- src/insets/RenderPreview.h	(revision 18842)
+++ src/insets/RenderPreview.h	(working copy)
@@ -84,6 +84,12 @@
 	/// equivalent to dynamic_cast
 	virtual RenderPreview * asPreview() { return this; }
 
+	/// clear preview
+	void clear() { snippet_.clear(); }
+
+	/// is this preview empty?
+	bool empty() { snippet_.empty(); }
+
 private:
 	/// Not implemented.
 	RenderPreview & operator=(RenderPreview const &);
Index: src/insets/Inset.h
===================================================================
--- src/insets/Inset.h	(revision 18842)
+++ src/insets/Inset.h	(working copy)
@@ -433,6 +433,9 @@
 	/// Add an entry to the TocList
 	/// pit is the ParConstIterator of the paragraph containing the inset
 	virtual void addToToc(TocList &, Buffer const &, ParConstIterator &) const {}
+	/// mark this inset as dirty, inset can, for example, regenerate 
+	/// preview in this function
+	virtual void markDirty() {}
 
 public:
 	/// returns LyX code associated with the inset. Used for TOC, ...)
Index: src/mathed/InsetMathHull.cpp
===================================================================
--- src/mathed/InsetMathHull.cpp	(revision 18842)
+++ src/mathed/InsetMathHull.cpp	(working copy)
@@ -114,7 +114,15 @@
 		return numbered ? "" : "*";
 	}
 
+	docstring const latex_string(InsetMathHull const & inset)
+	{
+		odocstringstream ls;
+		WriteStream wi(ls, false, false);
+		inset.write(wi);
+		return ls.str();
+	}
 
+
 } // end anon namespace
 
 
@@ -276,6 +284,12 @@
 bool InsetMathHull::previewState(BufferView * bv) const
 {
 	if (!editing(bv) && RenderPreview::status() == LyXRC::PREVIEW_ON) {
+		if (preview_->empty()) {
+			docstring const snippet = latex_string(*this);
+			lyxerr << "add preview" << to_utf8(snippet) << std::endl;
+			preview_->addPreview(snippet, *bv->buffer());
+			preview_->startLoading(*bv->buffer());
+		}
 		graphics::PreviewImage const * pimage =
 			preview_->getPreviewImage(*bv->buffer());
 		return pimage && pimage->image();
@@ -395,19 +409,6 @@
 }
 
 
-namespace {
-
-docstring const latex_string(InsetMathHull const & inset)
-{
-	odocstringstream ls;
-	WriteStream wi(ls, false, false);
-	inset.write(wi);
-	return ls.str();
-}
-
-} // namespace anon
-
-
 void InsetMathHull::addPreview(graphics::PreviewLoader & ploader) const
 {
 	if (RenderPreview::status() == LyXRC::PREVIEW_ON) {
@@ -417,16 +418,9 @@
 }
 
 
-bool InsetMathHull::notifyCursorLeaves(Cursor & cur)
+void InsetMathHull::markDirty()
 {
-	if (RenderPreview::status() == LyXRC::PREVIEW_ON) {
-		Buffer const & buffer = cur.buffer();
-		docstring const snippet = latex_string(*this);
-		preview_->addPreview(snippet, buffer);
-		preview_->startLoading(buffer);
-		cur.updateFlags(Update::Force);
-	}
-	return false;
+	preview_->clear();
 }
 
 
Index: src/mathed/InsetMathHull.h
===================================================================
--- src/mathed/InsetMathHull.h	(revision 18842)
+++ src/mathed/InsetMathHull.h	(working copy)
@@ -111,9 +111,9 @@
 	/// the string that is passed to the TOC
 	virtual void textString(Buffer const &, odocstream &) const;
 
-	/// get notification when the cursor leaves this inset
-	bool notifyCursorLeaves(Cursor & cur);
 	///
+	void markDirty();
+	///
 	//bool insetAllowed(Code code) const;
 	///
 	void addPreview(graphics::PreviewLoader &) const;
Index: src/mathed/InsetMathNest.cpp
===================================================================
--- src/mathed/InsetMathNest.cpp	(revision 18842)
+++ src/mathed/InsetMathNest.cpp	(working copy)
@@ -1001,6 +1001,9 @@
 		InsetMath::doDispatch(cur, cmd);
 		break;
 	}
+	// FIXME: Need an efficient way of knowing if the inset has been modified.
+	if (cur.result().dispatched())
+		markDirty();
 }
 
 

Reply via email to