So, here it is. This takes us down to three calls to updateBuffer():

1. The "main" call, and ideally the only one we would need, is in GuiApplication::dispatch(), after the dispatch cycle has completed.

2. A call in Buffer::reload(), before the call to Buffer::changed(). Without this, we can crash, in TextMetrics, since the new file has no label information yet (I think). I wonder myself if the call to changed() is in the wrong place.

3. A call in GuiView::setBuffer(). This could probably go, but I'm not sure exactly how.

Comments welcome, of course.

Since the main Qt 4.6.x crash has been fixed, and because I think there may actually be some crashes here, like the one mentioned at (2), I now think this should probably wait until after alpha.

Richard

Index: Cursor.h
===================================================================
--- Cursor.h	(revision 33709)
+++ Cursor.h	(working copy)
@@ -229,6 +229,12 @@
 	void dispatched();
 	/// Set which update should be done
 	void updateFlags(Update::flags f);
+	///
+	void forceBufferUpdate();
+	///
+	void clearBufferUpdate();
+	///
+	bool needBufferUpdate() const;
 	/**
 	 * don't call update() when done
 	 *
Index: insets/InsetBibitem.cpp
===================================================================
--- insets/InsetBibitem.cpp	(revision 33709)
+++ insets/InsetBibitem.cpp	(working copy)
@@ -93,8 +93,6 @@
 			"it will be changed to %2$s."), new_key, key));
 	}
 	setParam("key", key);
-
-	buffer().updateBuffer();
 }
 
 
@@ -128,8 +126,9 @@
 			updateCommand(p["key"]);
 			cur.bv().buffer().changeRefsIfUnique(old_key,
 				params()["key"], CITE_CODE);
+			cur.forceBufferUpdate();
+			buffer_->invalidateBibinfoCache();
 		}
-		buffer_->invalidateBibinfoCache();
 		break;
 	}
 
Index: insets/Inset.cpp
===================================================================
--- insets/Inset.cpp	(revision 33709)
+++ insets/Inset.cpp	(working copy)
@@ -233,13 +233,7 @@
 	return getLayout().forceLTR();
 }
 
-void Inset::initView()
-{
-	if (isLabeled())
-		buffer().updateBuffer();
-}
 
-
 docstring Inset::toolTip(BufferView const &, int, int) const
 {
 	return docstring();
Index: insets/InsetInclude.cpp
===================================================================
--- insets/InsetInclude.cpp	(revision 33709)
+++ insets/InsetInclude.cpp	(working copy)
@@ -274,6 +274,7 @@
 				}
 			}
 			setParams(p);
+			cur.forceBufferUpdate();
 		} else
 			cur.noUpdate();
 		break;
Index: insets/Inset.h
===================================================================
--- insets/Inset.h	(revision 33709)
+++ insets/Inset.h	(working copy)
@@ -124,7 +124,7 @@
 	  *
 	  * \sa isLabeled()
 	  **/
-	virtual void initView();
+	virtual void initView() {};
 	/// \return true if this inset is labeled.
 	virtual bool isLabeled() const { return false; }
 
Index: insets/InsetFloat.cpp
===================================================================
--- insets/InsetFloat.cpp	(revision 33709)
+++ insets/InsetFloat.cpp	(working copy)
@@ -152,7 +152,7 @@
 		setNewLabel();
 		if (params_.type != params.type) {
 			params_.type = params.type;
-			buffer().updateBuffer();
+			cur.forceBufferUpdate();
 		}
 		break;
 	}
Index: insets/InsetLabel.cpp
===================================================================
--- insets/InsetLabel.cpp	(revision 33709)
+++ insets/InsetLabel.cpp	(working copy)
@@ -97,10 +97,6 @@
 		}
 	}
 	buffer().undo().endUndoGroup();
-
-	// We need an update of the Buffer reference cache. This is achieved by
-	// updateBuffer().
-	buffer().updateBuffer();
 }
 
 
@@ -205,6 +201,7 @@
 		}
 		if (p["name"] != params()["name"])
 			updateCommand(p["name"]);
+		cur.forceBufferUpdate();
 		break;
 	}
 
Index: insets/InsetCommand.cpp
===================================================================
--- insets/InsetCommand.cpp	(revision 33709)
+++ insets/InsetCommand.cpp	(working copy)
@@ -144,6 +144,8 @@
 			cur.noUpdate();
 		else
 			setParams(p);
+		if (isLabeled())
+			cur.forceBufferUpdate();
 		break;
 	}
 
Index: BufferView.cpp
===================================================================
--- BufferView.cpp	(revision 33709)
+++ BufferView.cpp	(working copy)
@@ -408,6 +408,8 @@
 		<< ", singlepar = " << (flags & Update::SinglePar)
 		<< "]  buffer: " << &buffer_);
 
+	// FIXME Does this really need doing here? It's done in updateBuffer, and
+	// if the Buffer doesn't need updating, then do the macros?
 	buffer_.updateMacros();
 
 	// Now do the first drawing step if needed. This consists on updating
@@ -912,7 +914,6 @@
 	setCursor(backcur.asDocIterator(&buffer_));
 
 	buffer_.errors("Class Switch");
-	buffer_.updateBuffer();
 }
 
 /** Return the change status at cursor position, taking in account the
@@ -1185,6 +1186,7 @@
 		// It is then better to make sure that all dialogs are in sync with
 		// current document settings.
 		dr.update(Update::Force | Update::FitCursor);
+		dr.forceBufferUpdate();
 		break;
 	}
 		
@@ -1196,6 +1198,7 @@
 		buffer_.params().makeDocumentClass();
 		updateDocumentClass(oldClass);
 		dr.update(Update::Force | Update::FitCursor);
+		dr.forceBufferUpdate();
 		break;
 	}
 
@@ -1213,6 +1216,7 @@
 		buffer_.params().makeDocumentClass();
 		updateDocumentClass(oldClass);
 		dr.update(Update::Force | Update::FitCursor);
+		dr.forceBufferUpdate();
 		break;
 	}
 
@@ -1236,6 +1240,7 @@
 		buffer_.params().makeDocumentClass();
 		updateDocumentClass(oldDocClass);
 		dr.update(Update::Force | Update::FitCursor);
+		dr.forceBufferUpdate();
 		break;
 	}
 
@@ -1252,6 +1257,7 @@
 		buffer_.params().makeDocumentClass();
 		updateDocumentClass(oldClass);
 		dr.update(Update::Force | Update::FitCursor);
+		dr.forceBufferUpdate();
 		break;
 	}
 
@@ -1262,6 +1268,7 @@
 			dr.setMessage(_("No further undo information"));
 		else
 			dr.update(Update::Force | Update::FitCursor);
+		dr.forceBufferUpdate();
 		break;
 
 	case LFUN_REDO:
@@ -1271,6 +1278,7 @@
 			dr.setMessage(_("No further redo information"));
 		else
 			dr.update(Update::Force | Update::FitCursor);
+		dr.forceBufferUpdate();
 		break;
 
 	case LFUN_FONT_STATE:
@@ -1403,6 +1411,7 @@
 	case LFUN_CHANGES_MERGE:
 		if (findNextChange(this) || findPreviousChange(this)) {
 			dr.update(Update::Force | Update::FitCursor);
+			dr.forceBufferUpdate();
 			showDialog("changes");
 		}
 		break;
@@ -1416,6 +1425,7 @@
 		buffer_.text().acceptOrRejectChanges(cur, Text::ACCEPT);
 		// FIXME: Move this LFUN to Buffer so that we don't have to do this:
 		dr.update(Update::Force | Update::FitCursor);
+		dr.forceBufferUpdate();
 		break;
 
 	case LFUN_ALL_CHANGES_REJECT:
@@ -1428,6 +1438,7 @@
 		buffer_.text().acceptOrRejectChanges(cur, Text::REJECT);
 		// FIXME: Move this LFUN to Buffer so that we don't have to do this:
 		dr.update(Update::Force | Update::FitCursor);
+		dr.forceBufferUpdate();
 		break;
 
 	case LFUN_WORD_FIND_FORWARD:
@@ -1482,6 +1493,7 @@
 			}
 		}
 		replace(this, cmd, has_deleted);
+		dr.forceBufferUpdate();
 		break;
 	}
 
@@ -1637,13 +1649,16 @@
 		//FIXME: what to do with cur.x_target()?
 		bool update = in_texted && cur.bv().checkDepm(cur, old);
 		cur.finishUndo();
-		if (update)
+		if (update) {
 			dr.update(Update::Force | Update::FitCursor);
+			dr.forceBufferUpdate();
+		}
 		break;
 	}
 
 	case LFUN_SCROLL:
 		lfunScroll(cmd);
+		dr.forceBufferUpdate();
 		break;
 
 	case LFUN_SCREEN_UP_SELECT: {
@@ -1720,6 +1735,7 @@
 		cur = savecur;
 		cur.fixIfBroken();
 		dr.update(Update::Force);
+		dr.forceBufferUpdate();
 
 		if (iterations >= max_iter) {
 			dr.setError(true);
@@ -1838,6 +1854,7 @@
 		FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument());
 		inset->dispatch(cur, fr);
 		dr.update(Update::SinglePar | Update::FitCursor);
+		dr.forceBufferUpdate();
 		break;
 	}
 
@@ -2227,7 +2244,7 @@
 
 	d->cursor_ = cur;
 
-	buffer_.updateBuffer();
+	cur.forceBufferUpdate();
 	buffer_.changed(true);
 	return true;
 }
@@ -2271,6 +2288,8 @@
 
 	d->cursor_.finishUndo();
 	d->cursor_.setCurrentFont();
+	if (update)
+		cur.forceBufferUpdate();
 	return update;
 }
 
Index: Text2.cpp
===================================================================
--- Text2.cpp	(revision 33709)
+++ Text2.cpp	(working copy)
@@ -231,7 +231,7 @@
 	pit_type undopit = undoSpan(end - 1);
 	recUndo(cur, start, undopit - 1);
 	setLayout(start, end, layout);
-	cur.buffer()->updateBuffer();
+	cur.forceBufferUpdate();
 }
 
 
@@ -290,7 +290,7 @@
 	}
 	// this handles the counter labels, and also fixes up
 	// depth values for follow-on (child) paragraphs
-	cur.buffer()->updateBuffer();
+	cur.forceBufferUpdate();
 }
 
 
Index: mathed/InsetMathGrid.cpp
===================================================================
--- mathed/InsetMathGrid.cpp	(revision 33709)
+++ mathed/InsetMathGrid.cpp	(working copy)
@@ -1336,10 +1336,9 @@
 					cell(i).append(grid.cell(grid.index(r, c)));
 		}
 		cur.clearSelection(); // bug 393
-		// FIXME audit setBuffer/updateBuffer calls
+		// FIXME audit setBuffer calls
 		cur.inset().setBuffer(*buffer_);
-		// FIXME audit setBuffer/updateBuffer calls
-		cur.buffer()->updateBuffer();
+		cur.forceBufferUpdate();
 		cur.finishUndo();
 		break;
 	}
Index: mathed/InsetMathHull.cpp
===================================================================
--- mathed/InsetMathHull.cpp	(revision 33709)
+++ mathed/InsetMathHull.cpp	(working copy)
@@ -552,10 +552,6 @@
 		if (label.empty()) {
 			delete label_[row];
 			label_[row] = dummy_pointer;
-			// We need an update of the Buffer reference cache.
-			// This is achieved by updateBuffer().
-			if (buffer_)
-				buffer().updateBuffer();
 		} else {
 			if (buffer_)
 				label_[row]->updateCommand(label);
@@ -578,14 +574,6 @@
 	if (nonum_[row] && label_[row]) {
 		delete label_[row];
 		label_[row] = 0;
-		if (!buffer_) {
-			// The buffer is set at the end of readInset.
-			// When parsing the inset, buffer_ is 0.
-			return;
-		}
-		// We need an update of the Buffer reference cache.
-		// This is achieved by updateBuffer().
-		buffer().updateBuffer();
 	}
 }
 
@@ -1242,6 +1230,8 @@
 			bool const align =
 				cur.bv().buffer().params().use_amsmath == BufferParams::package_on;
 			mutate(align ? hullAlign : hullEqnArray);
+			// mutate() may change labels and such.
+			cur.forceBufferUpdate();
 			cur.idx() = nrows() * ncols() - 1;
 			cur.pos() = cur.lastpos();
 		}
@@ -1259,6 +1249,7 @@
 				numbered(row, !old);
 
 		cur.message(old ? _("No number") : _("Number"));
+		cur.forceBufferUpdate();
 		break;
 	}
 
@@ -1268,6 +1259,7 @@
 		bool old = numbered(r);
 		cur.message(old ? _("No number") : _("Number"));
 		numbered(r, !old);
+		cur.forceBufferUpdate();
 		break;
 	}
 
@@ -1329,6 +1321,7 @@
 			} else if (numbered(row(cur.idx()))) {
 				cur.recordUndoInset();
 				numbered(row(cur.idx()), false);
+				cur.forceBufferUpdate();
 			} else {
 				InsetMathGrid::doDispatch(cur, cmd);
 				return;
@@ -1363,6 +1356,7 @@
 					label_[r]->initView();
 				}
 			}
+			cur.forceBufferUpdate();
 			break;
 		}
 		InsetMathGrid::doDispatch(cur, cmd);
@@ -1387,6 +1381,7 @@
 		if (cur.pos() > cur.lastpos())
 			cur.pos() = cur.lastpos();
 
+		cur.forceBufferUpdate();
 		// FIXME: find some more clever handling of the selection,
 		// i.e. preserve it.
 		cur.clearSelection();
Index: mathed/InsetMathRef.cpp
===================================================================
--- mathed/InsetMathRef.cpp	(revision 33709)
+++ mathed/InsetMathRef.cpp	(working copy)
@@ -214,7 +214,7 @@
 	if (createInsetMath_fromDialogStr(
 	    from_utf8(InsetCommand::params2string("ref", icp)), ar)) {
 		*this = *ar[0].nucleus()->asRefInset();
-		// FIXME audit setBuffer/updateBuffer calls
+		// FIXME audit setBuffer calls
 		setBuffer(buf);
 	}
 }
Index: mathed/InsetMathNest.cpp
===================================================================
--- mathed/InsetMathNest.cpp	(revision 33709)
+++ mathed/InsetMathNest.cpp	(working copy)
@@ -564,8 +564,7 @@
 		}
 		cur.niceInsert(topaste, parseflg, false);
 		cur.clearSelection(); // bug 393
-		// FIXME audit setBuffer/updateBuffer calls
-		cur.buffer()->updateBuffer();
+		cur.forceBufferUpdate();
 		cur.finishUndo();
 		break;
 	}
@@ -577,8 +576,7 @@
 		// Prevent stale position >= size crash
 		// Probably not necessary anymore, see eraseSelection (gb 2005-10-09)
 		cur.normalize();
-		// FIXME audit setBuffer/updateBuffer calls
-		cur.buffer()->updateBuffer();
+		cur.forceBufferUpdate();
 		break;
 
 	case LFUN_COPY:
@@ -988,8 +986,7 @@
 		cur.posBackward();
 		cur.pushBackward(*cur.nextInset());
 		cur.niceInsert(save_selection);
-		// FIXME audit setBuffer/updateBuffer calls
-		cur.buffer()->updateBuffer();
+		cur.forceBufferUpdate();
 #else
 		if (currentMode() == Inset::TEXT_MODE) {
 			cur.recordUndoSelection();
@@ -1203,8 +1200,7 @@
 		if (createInsetMath_fromDialogStr(cmd.argument(), ar)) {
 			cur.recordUndoSelection();
 			cur.insert(ar);
-			// FIXME audit setBuffer/updateBuffer calls
-			cur.buffer()->updateBuffer();
+			cur.forceBufferUpdate();			
 		} else
 			cur.undispatched();
 		break;
Index: DispatchResult.h
===================================================================
--- DispatchResult.h	(revision 33709)
+++ DispatchResult.h	(working copy)
@@ -24,7 +24,7 @@
 public:
 	///
 	DispatchResult() : dispatched_(false), error_(false), 
-			   update_(Update::None) {}
+			   update_(Update::None), need_buf_update_(false) {}
 	///
 	DispatchResult(bool disp, Update::flags f) 
 		: dispatched_(disp), error_(false), update_(f) {}
@@ -44,6 +44,12 @@
 	Update::flags update() const { return update_; }
 	///
 	void update(Update::flags f) { update_ = f; }
+	///
+	bool needBufferUpdate() const { return need_buf_update_; }
+	///
+	void forceBufferUpdate() { need_buf_update_ = true; }
+	///
+	void clearBufferUpdate() { need_buf_update_ = false; }
 private:
 	/// was the event fully dispatched?
 	bool dispatched_;
@@ -53,6 +59,8 @@
 	Update::flags update_;
 	///
 	docstring message_;
+	/// 
+	bool need_buf_update_;
 };
 
 
Index: TextMetrics.cpp
===================================================================
--- TextMetrics.cpp	(revision 33709)
+++ TextMetrics.cpp	(working copy)
@@ -414,7 +414,11 @@
 		LYXERR(Debug::INFO, "MacroContext not initialised!"
 			<< " Going through the buffer again and hope"
 			<< " the context is better then.");
-		bv_->buffer().updateBuffer();
+		// FIXME audit updateBuffer calls
+		// This should not be here, but it is not clear yet where else it
+		// should be. I am disabling it because it is likely to cause the
+		// same crashes we are seeing elsewhere in Qt 4.6.x.
+		// bv_->buffer().updateBuffer();
 		parPos = text_->macrocontextPosition();
 		LASSERT(!parPos.empty(), /**/);
 		parPos.pit() = pit;
Index: lyxfind.cpp
===================================================================
--- lyxfind.cpp	(revision 33709)
+++ lyxfind.cpp	(working copy)
@@ -194,7 +194,6 @@
 		++num;
 	}
 
-	buf.updateBuffer();
 	bv->putSelectionAt(doc_iterator_begin(&buf), 0, false);
 	if (num)
 		buf.markDirty();
Index: Text.cpp
===================================================================
--- Text.cpp	(revision 33709)
+++ Text.cpp	(working copy)
@@ -717,10 +717,9 @@
 			break; // the character couldn't be deleted physically due to change tracking
 	}
 
-	cur.buffer()->updateBuffer();
-
 	// A singlePar update is not enough in this case.
 	cur.updateFlags(Update::Force);
+	cur.forceBufferUpdate();
 
 	// This check is necessary. Otherwise the new empty paragraph will
 	// be deleted automatically. And it is more friendly for the user!
@@ -1294,7 +1293,7 @@
 	cur.clearSelection();
 	setCursorIntern(cur, begPit, begPos);
 	cur.updateFlags(Update::Force);
-	cur.buffer()->updateBuffer();
+	cur.forceBufferUpdate();
 }
 
 
@@ -1445,7 +1444,7 @@
 		cur.recordUndo(ATOMIC_UNDO, prevcur.pit());
 		mergeParagraph(bufparams, cur.text()->paragraphs(),
 							prevcur.pit());
-		cur.buffer()->updateBuffer();
+		cur.forceBufferUpdate();
 		setCursorIntern(cur, prevcur.pit(), prevcur.pos());
 		cur.updateFlags(Update::Force);
 		return true;
@@ -1473,7 +1472,7 @@
 			cur.top().forwardPos();
 
 		if (was_inset)
-			cur.buffer()->updateBuffer();
+			cur.forceBufferUpdate();
 		else
 			cur.checkBufferStructure();
 		needsUpdate = true;
@@ -1549,7 +1548,7 @@
 	}
 
 	if (needsUpdate) {
-		cur.buffer()->updateBuffer();
+		cur.forceBufferUpdate();
 		setCursorIntern(cur, prevcur.pit(), prevcur.pos());
 	}
 
@@ -1589,7 +1588,7 @@
 		bool const was_inset = cur.paragraph().isInset(cur.pos());
 		cur.paragraph().eraseChar(cur.pos(), cur.buffer()->params().trackChanges);
 		if (was_inset)
-			cur.buffer()->updateBuffer();
+			cur.forceBufferUpdate();
 		else
 			cur.checkBufferStructure();
 	}
@@ -1645,9 +1644,7 @@
 		cur.pit() = min(cur.lastpit(), spit);
 		cur.pos() = min(cur.lastpos(), spos);
 	} else
-		// this is the least that needs to be done (bug 6003)
-		// in the above case, pasteParagraphList handles this
-		cur.buffer()->updateBuffer();
+		cur.forceBufferUpdate();
 
 	// Ensure the current language is set correctly (bug 6292)
 	cur.text()->setCursor(cur, cur.pit(), cur.pos());
Index: frontends/qt4/GuiView.cpp
===================================================================
--- frontends/qt4/GuiView.cpp	(revision 33709)
+++ frontends/qt4/GuiView.cpp	(working copy)
@@ -1757,7 +1757,10 @@
 	docstring str2;
 	Buffer * buf = loadDocument(fullname);
 	if (buf) {
-		buf->updateBuffer();
+		// FIXME audit updateBuffer calls
+		// I don't think this is needed, since it will be done in setBuffer().
+		// Someone please check.
+		// buf->updateBuffer();
 		setBuffer(buf);
 		buf->errors("Parse");
 		str2 = bformat(_("Document %1$s opened."), disp_fn);
@@ -1806,7 +1809,10 @@
 		Buffer * buf = lv->loadDocument(lyxfile);
 		if (!buf)
 			return false;
-		buf->updateBuffer();
+		// FIXME audit updateBuffer calls
+		// I don't think this is needed, since it will be done in setBuffer().
+		// Someone please check.
+		// buf->updateBuffer();
 		lv->setBuffer(buf);
 		buf->errors("Parse");
 	} else {
@@ -2675,7 +2681,11 @@
 	// This makes insertion of citations and references in the child work,
 	// when the target is in the parent or another child document.
 	child->setParent(&buffer);
-	child->masterBuffer()->updateBuffer();
+
+	// FIXME audit updateBuffer calls
+	// I don't think this is needed, since it will be called in 
+	// setBuffer().
+	//	child->masterBuffer()->updateBuffer();
 	setBuffer(child);
 	if (parsed)
 		child->errors("Parse");
@@ -2723,7 +2733,13 @@
 			buf = theBufferList().getBuffer(s);
 		else if (s.exists()) {
 			buf = loadDocument(s);
-			buf->updateBuffer();
+			if (!buf)
+				return false;
+			// FIXME audit updateBuffer calls
+			// I don't think this is needed. loadDocument() calls
+			// setBuffer(), which calls updateBuffer().
+			// Someone please check.
+			// buf->updateBuffer();
 			buf->errors("Parse");
 		} else {
 			message(bformat(
@@ -2948,6 +2964,7 @@
 			if (ret == 0) {
 				doc_buffer->markClean();
 				reloadBuffer();
+				dr.forceBufferUpdate();
 			}
 			break;
 		}
Index: frontends/qt4/GuiApplication.cpp
===================================================================
--- frontends/qt4/GuiApplication.cpp	(revision 33709)
+++ frontends/qt4/GuiApplication.cpp	(working copy)
@@ -1072,6 +1072,10 @@
 
 	BufferView * bv = current_view_->currentBufferView();
 	if (bv) {
+		if (dr.needBufferUpdate()) {
+			bv->cursor().clearBufferUpdate();
+			bv->buffer().updateBuffer();
+		}
 		// BufferView::update() updates the ViewMetricsInfo and
 		// also initializes the position cache for all insets in
 		// (at least partially) visible top-level paragraphs.
@@ -1209,6 +1213,7 @@
 		dr.setError(true);
 		dr.dispatched(false);
 		dr.update(Update::None);
+		dr.clearBufferUpdate();
 		return;
 	};
 
@@ -1321,7 +1326,6 @@
 #ifndef DEVEL_VERSION
 			buf->setReadonly(true);
 #endif
-			buf->updateBuffer();
 			buf->errors("Parse");
 		}
 		break;
@@ -1565,7 +1569,7 @@
 
 	// Let the current GuiView dispatch its own actions.
 	lv->dispatch(cmd, dr);
-	if (dr.dispatched() && lv )
+	if (dr.dispatched() && lv)
 		return;
 
 	BufferView * bv = lv->currentBufferView();
Index: CutAndPaste.cpp
===================================================================
--- CutAndPaste.cpp	(revision 33709)
+++ CutAndPaste.cpp	(working copy)
@@ -242,6 +242,8 @@
 				InsetLabel * lab = labels[i];
 				docstring const oldname = lab->getParam("name");
 				lab->updateCommand(oldname, false);
+				// We need to update the buffer reference cache.
+				cur.forceBufferUpdate();
 				docstring const newname = lab->getParam("name");
 				if (oldname == newname)
 					continue;
@@ -258,7 +260,7 @@
 							static_cast<InsetMathHull &>(*itt);
 						// this is necessary to prevent an uninitialized
 						// buffer when the RefInset is in a MathBox.
-						// FIXME audit setBuffer/updateBuffer calls
+						// FIXME audit setBuffer calls
 						mi.setBuffer(const_cast<Buffer &>(buffer));
 						if (mi.asRefInset()->getTarget() == oldname)
 							mi.asRefInset()->changeTarget(newname);
@@ -273,6 +275,8 @@
 			InsetCommand & lab = static_cast<InsetCommand &>(*it);
 			docstring const oldname = lab.getParam("name");
 			lab.updateCommand(oldname, false);
+			// We need to update the buffer reference cache.
+			cur.forceBufferUpdate();
 			docstring const newname = lab.getParam("name");
 			if (oldname == newname)
 				break;
@@ -287,7 +291,7 @@
 						static_cast<InsetMathHull &>(*itt);
 					// this is necessary to prevent an uninitialized
 					// buffer when the RefInset is in a MathBox.
-					// FIXME audit setBuffer/updateBuffer calls
+					// FIXME audit setBuffer calls
 					mi.setBuffer(const_cast<Buffer &>(buffer));
 					if (mi.asRefInset()->getTarget() == oldname)
 						mi.asRefInset()->changeTarget(newname);
@@ -299,6 +303,8 @@
 		case INCLUDE_CODE: {
 			InsetInclude & inc = static_cast<InsetInclude &>(*it);
 			inc.updateCommand();
+			// We need to update the list of included files.
+			cur.forceBufferUpdate();
 			break;
 		}
 
@@ -307,6 +313,8 @@
 			InsetCommand & bib = static_cast<InsetCommand &>(*it);
 			docstring const oldkey = bib.getParam("key");
 			bib.updateCommand(oldkey, false);
+			// We need to update the buffer reference cache.
+			cur.forceBufferUpdate();
 			docstring const newkey = bib.getParam("key");
 			if (oldkey == newkey)
 				break;
@@ -345,6 +353,8 @@
 					  text, 0, 1, _("&Add"), _("&Don't Add")) != 0)
 				break;
 			lyx::dispatch(FuncRequest(LFUN_BRANCH_ADD, name));
+			// We need to update the list of branches.
+			cur.forceBufferUpdate();
 			break;
 		}
 
@@ -775,7 +785,7 @@
 
 		// need a valid cursor. (Lgb)
 		cur.clearSelection();
-		cur.buffer()->updateBuffer();
+		cur.forceBufferUpdate();
 
 		// tell tabular that a recent copy happened
 		dirtyTabularStack(false);
@@ -953,7 +963,7 @@
 
 		boost::tie(ppp, endpit) =
 			pasteSelectionHelper(cur, parlist, docclass, errorList);
-		cur.buffer()->updateBuffer();
+		cur.forceBufferUpdate();
 		cur.clearSelection();
 		text->setCursor(cur, ppp.first, ppp.second);
 	}
Index: Text3.cpp
===================================================================
--- Text3.cpp	(revision 33709)
+++ Text3.cpp	(working copy)
@@ -485,8 +485,8 @@
 		recUndo(cur, pit, pit + 1);
 		cur.finishUndo();
 		pars_.swap(pit, pit + 1);
-		cur.buffer()->updateBuffer();
 		needsUpdate = true;
+		cur.forceBufferUpdate();
 		++cur.pit();
 		break;
 	}
@@ -496,9 +496,9 @@
 		recUndo(cur, pit - 1, pit);
 		cur.finishUndo();
 		pars_.swap(pit, pit - 1);
-		cur.buffer()->updateBuffer();
 		--cur.pit();
 		needsUpdate = true;
+		cur.forceBufferUpdate();
 		break;
 	}
 
@@ -522,7 +522,7 @@
 		par.params().startOfAppendix(start);
 
 		// we can set the refreshing parameters now
-		cur.buffer()->updateBuffer();
+		cur.forceBufferUpdate();
 		break;
 	}
 
@@ -623,7 +623,8 @@
 				// provide it with two different cursors.
 				Cursor dummy = cur;
 				dummy.pos() = dummy.pit() = 0;
-				cur.bv().checkDepm(dummy, cur);
+				if (cur.bv().checkDepm(dummy, cur))
+					cur.forceBufferUpdate();;
 			}
 		}
 		break;
@@ -649,7 +650,8 @@
 				Cursor dummy = cur;
 				dummy.pos() = cur.lastpos();
 				dummy.pit() = cur.lastpit();
-				cur.bv().checkDepm(dummy, cur);
+				if (cur.bv().checkDepm(dummy, cur))
+					cur.forceBufferUpdate();
 			}
 		}
 		break;
@@ -970,6 +972,7 @@
 			singleParUpdate = false;
 		}
 		moveCursor(cur, false);
+		cur.forceBufferUpdate();
 		break;
 
 	case LFUN_CHAR_DELETE_BACKWARD:
@@ -987,6 +990,7 @@
 			cutSelection(cur, true, false);
 			singleParUpdate = false;
 		}
+		cur.forceBufferUpdate();
 		break;
 
 	case LFUN_BREAK_PARAGRAPH:
@@ -1045,8 +1049,10 @@
 	}
 
 	case LFUN_INSET_DISSOLVE: {
-		if (dissolveInset(cur))
+		if (dissolveInset(cur)) {
 			needsUpdate = true;
+			cur.forceBufferUpdate();
+		}
 		break;
 	}
 
@@ -1577,7 +1583,7 @@
 		cur.posForward();
 		// Some insets are numbered, others are shown in the outline pane so
 		// let's update the labels and the toc backend.
-		bv->buffer().updateBuffer();
+		cur.forceBufferUpdate();
 		break;
 
 	case LFUN_TABULAR_INSERT:
@@ -1631,7 +1637,7 @@
 		// date metrics.
 		FuncRequest cmd_caption(LFUN_CAPTION_INSERT);
 		doInsertInset(cur, cur.text(), cmd_caption, true, false);
-		bv->buffer().updateBuffer();
+		cur.forceBufferUpdate();
 		cur.updateFlags(Update::Force);
 		// FIXME: When leaving the Float (or Wrap) inset we should
 		// delete any empty paragraph left above or below the
@@ -2072,26 +2078,26 @@
 	case LFUN_OUTLINE_UP:
 		outline(OutlineUp, cur);
 		setCursor(cur, cur.pit(), 0);
-		cur.buffer()->updateBuffer();
+		cur.forceBufferUpdate();
 		needsUpdate = true;
 		break;
 
 	case LFUN_OUTLINE_DOWN:
 		outline(OutlineDown, cur);
 		setCursor(cur, cur.pit(), 0);
-		cur.buffer()->updateBuffer();
+		cur.forceBufferUpdate();
 		needsUpdate = true;
 		break;
 
 	case LFUN_OUTLINE_IN:
 		outline(OutlineIn, cur);
-		cur.buffer()->updateBuffer();
+		cur.forceBufferUpdate();
 		needsUpdate = true;
 		break;
 
 	case LFUN_OUTLINE_OUT:
 		outline(OutlineOut, cur);
-		cur.buffer()->updateBuffer();
+		cur.forceBufferUpdate();
 		needsUpdate = true;
 		break;
 
Index: Cursor.cpp
===================================================================
--- Cursor.cpp	(revision 33709)
+++ Cursor.cpp	(working copy)
@@ -1267,6 +1267,7 @@
 	++pos();
 	inset().setBuffer(bv_->buffer());
 	inset().initView();
+	forceBufferUpdate();
 }
 
 
@@ -1309,6 +1310,8 @@
 		text()->insertInset(*this, inset0);
 		inset0->setBuffer(bv_->buffer());
 		inset0->initView();
+		if (inset0->isLabeled())
+			forceBufferUpdate();
 	}
 }
 
@@ -1350,7 +1353,7 @@
 		cap::eraseSelection(*this);
 	cell().insert(pos(), ar);
 	pos() += ar.size();
-	// FIXME audit setBuffer/updateBuffer calls
+	// FIXME audit setBuffer calls
 	inset().setBuffer(bv_->buffer());
 }
 
@@ -1874,6 +1877,8 @@
 
 			updateNeeded |= bv().checkDepm(dummy, *this);
 			updateTextTargetOffset();
+			if (updateNeeded)
+				forceBufferUpdate();
 		}
 		return false;
 	}
@@ -1898,7 +1903,7 @@
 			++dummy.pos();
 		if (bv().checkDepm(dummy, old)) {
 			updateNeeded = true;
-			// Make sure that cur gets back whatever happened to dummy(Lgb) 
+			// Make sure that cur gets back whatever happened to dummy (Lgb) 
 			operator=(dummy);
 		}
 	} else {
@@ -1943,6 +1948,8 @@
 		updateNeeded |= bv().checkDepm(*this, old);
 	}
 
+	if (updateNeeded)
+		forceBufferUpdate();
 	updateTextTargetOffset();
 	return true;
 }	
@@ -2110,6 +2117,24 @@
 }
 
 
+void Cursor::forceBufferUpdate()
+{
+	disp_.forceBufferUpdate();
+}
+
+
+void Cursor::clearBufferUpdate()
+{
+	disp_.clearBufferUpdate();
+}
+
+
+bool Cursor::needBufferUpdate() const
+{
+	return disp_.needBufferUpdate();
+}
+
+
 void Cursor::noUpdate()
 {
 	disp_.update(Update::None);
Index: Undo.cpp
===================================================================
--- Undo.cpp	(revision 33709)
+++ Undo.cpp	(working copy)
@@ -428,7 +428,6 @@
 
 	// Adapt the new material to current buffer.
 	buffer_.setBuffersForInsets(); // FIXME This shouldn't be here.
-	buffer_.updateBuffer();
 	return true;
 }
 
Index: Buffer.cpp
===================================================================
--- Buffer.cpp	(revision 33709)
+++ Buffer.cpp	(working copy)
@@ -2006,6 +2006,7 @@
 			branch->setSelected(func.action == LFUN_BRANCH_ACTIVATE);
 			dr.setError(false);
 			dr.update(Update::Force);
+			dr.forceBufferUpdate();
 		}
 		break;
 	}
@@ -2040,8 +2041,10 @@
 			}
 		}
 
-		if (success)
+		if (success) {
 			dr.update(Update::Force);
+			dr.forceBufferUpdate();
+		}
 		break;
 	}
 
@@ -2167,8 +2170,10 @@
 		Language const * newL = languages.getLanguage(argument);
 		if (!newL || oldL == newL)
 			break;
-		if (oldL->rightToLeft() == newL->rightToLeft() && !isMultiLingual())
+		if (oldL->rightToLeft() == newL->rightToLeft() && !isMultiLingual()) {
 			changeLanguage(oldL, newL);
+			dr.forceBufferUpdate();
+		}
 		break;
 	}
 

Reply via email to