I tried recently to get rid og all-insets-toggle in favour of
inset-forall. This works, but I noticed at this occasion that the
performance of inset-forall is horrible, in particular because the
screen is redrawn for each inset. This is definitely wrong.

What seems to be a good solution is to define a new
LyXFunc::dispatch(FuncRequest, DispatchResult) that just returns what
needs to be done, and add change the normal LyXFunc::dispatch to be a
wrapper around it that does the screen updates. This is what I started
in the attached patch.

I have some questions before I proceed:

* is that the right direction? (the next steps to make it useful is of
  course to pass a DispatchResult object to all dispatch routines)

* there are some functions (up, down) that require correct metrics. What
  shall I do if the screen is not updated? Shall we somehow mark that
  these functions rely on metrics and have a mechanism to compute them
  if needed? I would need some help with this, I think.

* in inset-forall, how do I build the final DispatchResult as a function
  of the elementary ones? Some kind of logical or?

* should LyXFunc::dispatch(FuncRequest, DispatchResult) modify the
  existing DispatchResult of reset it to forget old contents?

Questions, questions...

JMarc

svndiff

Index: src/LyXFunc.h
===================================================================
--- src/LyXFunc.h	(révision 33078)
+++ src/LyXFunc.h	(copie de travail)
@@ -24,6 +24,7 @@ namespace lyx {
 
 class Buffer;
 class BufferView;
+class DispatchResult;
 class DocumentClass;
 class FuncRequest;
 class FuncStatus;
@@ -46,7 +47,11 @@ public:
 	///
 	explicit LyXFunc();
 
-	/// LyX dispatcher, executes lyx actions.
+	/// LyX dispatcher: executes lyx actions and returns result.
+	void dispatch(FuncRequest const &, DispatchResult &);
+
+	/// LyX dispatcher: executes lyx actions and does necessary
+	/// screen updates depending on results.
 	void dispatch(FuncRequest const &);
 
 	///
Index: src/LyXFunc.cpp
===================================================================
--- src/LyXFunc.cpp	(révision 33078)
+++ src/LyXFunc.cpp	(copie de travail)
@@ -340,6 +340,32 @@ static docstring sendDispatchMessage(doc
 
 void LyXFunc::dispatch(FuncRequest const & cmd)
 {
+	DispatchResult dr;
+	// redraw the screen at the end (first of the two drawing steps).
+	//This is done unless explicitely requested otherwise
+	dr.update(Update::FitCursor);
+	dispatch(cmd, dr);
+
+	LyXView * lv = theApp()->currentWindow();
+	if (lv && lv->currentBufferView()) {
+		// BufferView::update() updates the ViewMetricsInfo and
+		// also initializes the position cache for all insets in
+		// (at least partially) visible top-level paragraphs.
+		// We will redraw the screen only if needed.
+		lv->currentBufferView()->processUpdateFlags(dr.update());
+		
+		// Do we have a selection?
+		theSelection().haveSelection(
+			lv->currentBufferView()->cursor().selection());
+		
+		// update gui
+			lv->restartCursor();
+	}
+}
+
+
+void LyXFunc::dispatch(FuncRequest const & cmd, DispatchResult & dr)
+{
 	string const argument = to_utf8(cmd.argument());
 	FuncCode const action = cmd.action;
 
@@ -350,10 +376,6 @@ void LyXFunc::dispatch(FuncRequest const
 	errorstat = false;
 	dispatch_buffer.erase();
 
-	// redraw the screen at the end (first of the two drawing steps).
-	//This is done unless explicitely requested otherwise
-	Update::flags updateFlags = Update::FitCursor;
-
 	LyXView * lv = theApp()->currentWindow();
 
 	FuncStatus const flag = getStatus(cmd);
@@ -362,9 +384,12 @@ void LyXFunc::dispatch(FuncRequest const
 		LYXERR(Debug::ACTION, "LyXFunc::dispatch: "
 		       << lyxaction.getActionName(action)
 		       << " [" << action << "] is disabled at this location");
+		//FIXME: pass this using the DispatchResult object
 		setErrorMessage(flag.message());
 		if (lv)
 			lv->restartCursor();
+		dr.dispatched(false);
+		dr.update(Update::None);
 	} else {
 		switch (action) {
 
@@ -481,7 +506,7 @@ void LyXFunc::dispatch(FuncRequest const
 		case LFUN_BOOKMARK_GOTO:
 			// go to bookmark, open unopened file and switch to buffer if necessary
 			gotoBookmark(convert<unsigned int>(to_utf8(cmd.argument())), true, true);
-			updateFlags = Update::FitCursor;
+			dr.update(Update::FitCursor);
 			break;
 
 		case LFUN_BOOKMARK_CLEAR:
@@ -493,8 +518,6 @@ void LyXFunc::dispatch(FuncRequest const
 			break;
 
 		default:
-			DispatchResult dr;
-
 			LASSERT(theApp(), /**/);
 			// Let the frontend dispatch its own actions.
 			theApp()->dispatch(cmd, dr);
@@ -507,10 +530,11 @@ void LyXFunc::dispatch(FuncRequest const
 				break;
 
 			// Let the current LyXView dispatch its own actions.
+			//FIXME: pass dr to LyXView::dispatch
 			if (lv->dispatch(cmd)) {
 				BufferView * bv = lv->currentBufferView();
 				if (bv)
-					updateFlags = bv->cursor().result().update();
+					dr = bv->cursor().result();
 				break;
 			}
 
@@ -520,31 +544,24 @@ void LyXFunc::dispatch(FuncRequest const
 			// Let the current BufferView dispatch its own actions.
 			if (bv->dispatch(cmd)) {
 				// The BufferView took care of its own updates if needed.
-				updateFlags = Update::None;
+				//FIXME: make it pass actions as a DispatchResult instead 
+				dr.update(Update::None);
 				break;
 			}
 
 			BufferView * doc_bv = lv->documentBufferView();
 			// Try with the document BufferView dispatch if any.
 			if (doc_bv && doc_bv->dispatch(cmd)) {
-				updateFlags = Update::None;
+				dr.update(Update::None);
 				break;
 			}
 
 			// OK, so try the current Buffer itself...
 			bv->buffer().dispatch(cmd, dr);
-			if (dr.dispatched()) {
-				updateFlags = dr.update();
-				break;
-			}
+
 			// and with the document Buffer.
-			if (doc_bv) {
+			if (doc_bv)
 				doc_bv->buffer().dispatch(cmd, dr);
-				if (dr.dispatched()) {
-					updateFlags = dr.update();
-					break;
-				}
-			}
 
 			// Let the current Cursor dispatch its own actions.
 			Cursor old = bv->cursor();
@@ -573,7 +590,7 @@ void LyXFunc::dispatch(FuncRequest const
 					lv->updateCompletion(bv->cursor(), false, false);
 			}
 
-			updateFlags = bv->cursor().result().update();
+			dr = bv->cursor().result();
 		}
 
 		// if we executed a mutating lfun, mark the buffer as dirty
@@ -584,21 +601,6 @@ void LyXFunc::dispatch(FuncRequest const
 		    && !lyxaction.funcHasFlag(action, LyXAction::NoBuffer)
 		    && !lyxaction.funcHasFlag(action, LyXAction::ReadOnly))
 			lv->currentBufferView()->buffer().markDirty();			
-
-		if (lv && lv->currentBufferView()) {
-			// BufferView::update() updates the ViewMetricsInfo and
-			// also initializes the position cache for all insets in
-			// (at least partially) visible top-level paragraphs.
-			// We will redraw the screen only if needed.
-			lv->currentBufferView()->processUpdateFlags(updateFlags);
-
-			// Do we have a selection?
-			theSelection().haveSelection(
-				lv->currentBufferView()->cursor().selection());
-			
-			// update gui
-			lv->restartCursor();
-		}
 	}
 	if (lv) {
 		// Some messages may already be translated, so we cannot use _()

Reply via email to