So this is kind of an old one, but a good one; meant to do it before the list crashes and then didn't have time. But the recent report about a missing TOC update following changes to note types reminded me why we need this. So here it is for any comment. I'll commit shortly if there is no objection. OK, Pavel? We'll want time to test it....

Richard

Index: src/Buffer.cpp
===================================================================
--- src/Buffer.cpp	(revision 34814)
+++ src/Buffer.cpp	(working copy)
@@ -2037,6 +2037,7 @@
 			branch->setSelected(func.action() == LFUN_BRANCH_ACTIVATE);
 			dr.setError(false);
 			dr.update(Update::Force);
+			dr.forceBufferUpdate();
 		}
 		break;
 	}
@@ -2071,8 +2072,10 @@
 			}
 		}
 
-		if (success)
+		if (success) {
 			dr.update(Update::Force);
+			dr.forceBufferUpdate();
+		}
 		break;
 	}
 
@@ -2198,8 +2201,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;
 	}
 
Index: src/BufferView.cpp
===================================================================
--- src/BufferView.cpp	(revision 34814)
+++ src/BufferView.cpp	(working copy)
@@ -413,6 +413,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
@@ -935,7 +937,6 @@
 	setCursor(backcur.asDocIterator(&buffer_));
 
 	buffer_.errors("Class Switch");
-	buffer_.updateBuffer();
 }
 
 /** Return the change status at cursor position, taking in account the
@@ -1203,6 +1204,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;
 	}
 		
@@ -1214,6 +1216,7 @@
 		buffer_.params().makeDocumentClass();
 		updateDocumentClass(oldClass);
 		dr.update(Update::Force | Update::FitCursor);
+		dr.forceBufferUpdate();
 		break;
 	}
 
@@ -1231,6 +1234,7 @@
 		buffer_.params().makeDocumentClass();
 		updateDocumentClass(oldClass);
 		dr.update(Update::Force | Update::FitCursor);
+		dr.forceBufferUpdate();
 		break;
 	}
 
@@ -1254,6 +1258,7 @@
 		buffer_.params().makeDocumentClass();
 		updateDocumentClass(oldDocClass);
 		dr.update(Update::Force | Update::FitCursor);
+		dr.forceBufferUpdate();
 		break;
 	}
 
@@ -1270,6 +1275,7 @@
 		buffer_.params().makeDocumentClass();
 		updateDocumentClass(oldClass);
 		dr.update(Update::Force | Update::FitCursor);
+		dr.forceBufferUpdate();
 		break;
 	}
 
@@ -1280,6 +1286,7 @@
 			dr.setMessage(_("No further undo information"));
 		else
 			dr.update(Update::Force | Update::FitCursor);
+		dr.forceBufferUpdate();
 		break;
 
 	case LFUN_REDO:
@@ -1289,6 +1296,7 @@
 			dr.setMessage(_("No further redo information"));
 		else
 			dr.update(Update::Force | Update::FitCursor);
+		dr.forceBufferUpdate();
 		break;
 
 	case LFUN_FONT_STATE:
@@ -1402,6 +1410,7 @@
 	case LFUN_CHANGES_MERGE:
 		if (findNextChange(this) || findPreviousChange(this)) {
 			dr.update(Update::Force | Update::FitCursor);
+			dr.forceBufferUpdate();
 			showDialog("changes");
 		}
 		break;
@@ -1415,6 +1424,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:
@@ -1427,6 +1437,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:
@@ -1481,6 +1492,7 @@
 			}
 		}
 		replace(this, cmd, has_deleted);
+		dr.forceBufferUpdate();
 		break;
 	}
 
@@ -1625,13 +1637,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: {
@@ -1708,6 +1723,7 @@
 		cur = savecur;
 		cur.fixIfBroken();
 		dr.update(Update::Force);
+		dr.forceBufferUpdate();
 
 		if (iterations >= max_iter) {
 			dr.setError(true);
@@ -1810,6 +1826,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: src/Cursor.cpp
===================================================================
--- src/Cursor.cpp	(revision 34814)
+++ src/Cursor.cpp	(working copy)
@@ -1276,6 +1276,7 @@
 	++pos();
 	inset().setBuffer(bv_->buffer());
 	inset().initView();
+	forceBufferUpdate();
 }
 
 
@@ -1318,6 +1319,8 @@
 		text()->insertInset(*this, inset0);
 		inset0->setBuffer(bv_->buffer());
 		inset0->initView();
+		if (inset0->isLabeled())
+			forceBufferUpdate();
 	}
 }
 
@@ -1359,7 +1362,7 @@
 		cap::eraseSelection(*this);
 	cell().insert(pos(), ar);
 	pos() += ar.size();
-	// FIXME audit setBuffer/updateBuffer calls
+	// FIXME audit setBuffer calls
 	inset().setBuffer(bv_->buffer());
 }
 
@@ -1883,6 +1886,8 @@
 
 			updateNeeded |= bv().checkDepm(dummy, *this);
 			updateTextTargetOffset();
+			if (updateNeeded)
+				forceBufferUpdate();
 		}
 		return false;
 	}
@@ -1907,7 +1912,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 {
@@ -1952,6 +1957,8 @@
 		updateNeeded |= bv().checkDepm(*this, old);
 	}
 
+	if (updateNeeded)
+		forceBufferUpdate();
 	updateTextTargetOffset();
 	return true;
 }	
@@ -2119,6 +2126,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: src/Cursor.h
===================================================================
--- src/Cursor.h	(revision 34814)
+++ src/Cursor.h	(working copy)
@@ -228,8 +228,14 @@
 	void undispatched();
 	/// the event was already dispatched
 	void dispatched();
-	/// Set which update should be done
+	/// Set which screen update should be done
 	void updateFlags(Update::flags f);
+	/// Forces an updateBuffer() call
+	void forceBufferUpdate();
+	/// Removes any pending updateBuffer() call
+	void clearBufferUpdate();
+	/// Do we need to call updateBuffer()?
+	bool needBufferUpdate() const;
 	/**
 	 * don't call update() when done
 	 *
Index: src/CutAndPaste.cpp
===================================================================
--- src/CutAndPaste.cpp	(revision 34814)
+++ src/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;
 		}
 
@@ -777,7 +787,7 @@
 
 		// need a valid cursor. (Lgb)
 		cur.clearSelection();
-		cur.buffer()->updateBuffer();
+		cur.forceBufferUpdate();
 
 		// tell tabular that a recent copy happened
 		dirtyTabularStack(false);
@@ -955,7 +965,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: src/DispatchResult.h
===================================================================
--- src/DispatchResult.h	(revision 34814)
+++ src/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; }
+	/// Does the buffer need updating?
+	bool needBufferUpdate() const { return need_buf_update_; }
+	/// Force the buffer to be updated
+	void forceBufferUpdate() { need_buf_update_ = true; }
+	/// Clear the flag indicating we need an update
+	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: src/frontends/qt4/GuiApplication.cpp
===================================================================
--- src/frontends/qt4/GuiApplication.cpp	(revision 34814)
+++ src/frontends/qt4/GuiApplication.cpp	(working copy)
@@ -1098,6 +1098,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.
@@ -1232,6 +1236,7 @@
 		dr.setError(true);
 		dr.dispatched(false);
 		dr.update(Update::None);
+		dr.clearBufferUpdate();
 		return;
 	};
 
@@ -1344,7 +1349,6 @@
 #ifndef DEVEL_VERSION
 			buf->setReadonly(true);
 #endif
-			buf->updateBuffer();
 			buf->errors("Parse");
 		}
 		break;
@@ -1576,9 +1580,10 @@
 	
 		// Let the current GuiView dispatch its own actions.
 		current_view_->dispatch(cmd, dr);
+
 		if (dr.dispatched())
 			break;
-	
+
 		BufferView * bv = current_view_->currentBufferView();
 		LASSERT(bv, /**/);
 	
Index: src/frontends/qt4/GuiView.cpp
===================================================================
--- src/frontends/qt4/GuiView.cpp	(revision 34814)
+++ src/frontends/qt4/GuiView.cpp	(working copy)
@@ -1804,7 +1804,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);
@@ -1853,7 +1856,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 {
@@ -2729,7 +2735,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");
@@ -2777,7 +2787,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(
@@ -3041,6 +3057,7 @@
 			if (ret == 0) {
 				doc_buffer->markClean();
 				reloadBuffer();
+				dr.forceBufferUpdate();
 			}
 			break;
 		}
Index: src/insets/InsetBibitem.cpp
===================================================================
--- src/insets/InsetBibitem.cpp	(revision 34814)
+++ src/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: src/insets/InsetCommand.cpp
===================================================================
--- src/insets/InsetCommand.cpp	(revision 34814)
+++ src/insets/InsetCommand.cpp	(working copy)
@@ -156,6 +156,10 @@
 			cur.noUpdate();
 		else
 			setParams(p);
+		// FIXME We might also want to check here if this one is in the TOC.
+		// But I think most of those are labeled.
+		if (isLabeled())
+			cur.forceBufferUpdate();
 		break;
 	}
 
Index: src/insets/Inset.cpp
===================================================================
--- src/insets/Inset.cpp	(revision 34814)
+++ src/insets/Inset.cpp	(working copy)
@@ -238,13 +238,7 @@
 	return getLayout().forceLTR();
 }
 
-void Inset::initView()
-{
-	if (isLabeled())
-		buffer().updateBuffer();
-}
 
-
 docstring Inset::toolTip(BufferView const &, int, int) const
 {
 	return docstring();
Index: src/insets/InsetFloat.cpp
===================================================================
--- src/insets/InsetFloat.cpp	(revision 34814)
+++ src/insets/InsetFloat.cpp	(working copy)
@@ -152,8 +152,11 @@
 		setNewLabel();
 		if (params_.type != params.type) {
 			params_.type = params.type;
-			buffer().updateBuffer();
+			cur.forceBufferUpdate();
 		}
+		// what we really want here is a TOC update, but that means
+		// a full buffer update
+		cur.forceBufferUpdate();
 		break;
 	}
 
Index: src/insets/Inset.h
===================================================================
--- src/insets/Inset.h	(revision 34814)
+++ src/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: src/insets/InsetInclude.cpp
===================================================================
--- src/insets/InsetInclude.cpp	(revision 34814)
+++ src/insets/InsetInclude.cpp	(working copy)
@@ -274,6 +274,7 @@
 				}
 			}
 			setParams(p);
+			cur.forceBufferUpdate();
 		} else
 			cur.noUpdate();
 		break;
Index: src/insets/InsetLabel.cpp
===================================================================
--- src/insets/InsetLabel.cpp	(revision 34814)
+++ src/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: src/insets/InsetNote.cpp
===================================================================
--- src/insets/InsetNote.cpp	(revision 34814)
+++ src/insets/InsetNote.cpp	(working copy)
@@ -176,6 +176,9 @@
 	case LFUN_INSET_MODIFY:
 		string2params(to_utf8(cmd.argument()), params_);
 		setButtonLabel();
+		// what we really want here is a TOC update, but that means
+		// a full buffer update
+		cur.forceBufferUpdate();
 		break;
 
 	case LFUN_INSET_DIALOG_UPDATE:
Index: src/insets/InsetBranch.cpp
===================================================================
--- src/insets/InsetBranch.cpp	(revision 34814)
+++ src/insets/InsetBranch.cpp	(working copy)
@@ -119,6 +119,9 @@
 		InsetBranchParams params;
 		InsetBranch::string2params(to_utf8(cmd.argument()), params);
 		params_.branch = params.branch;
+		// what we really want here is a TOC update, but that means
+		// a full buffer update
+		cur.forceBufferUpdate();
 		break;
 	}
 	case LFUN_BRANCH_ACTIVATE:
Index: src/insets/InsetIndex.cpp
===================================================================
--- src/insets/InsetIndex.cpp	(revision 34814)
+++ src/insets/InsetIndex.cpp	(working copy)
@@ -211,6 +211,9 @@
 		InsetIndexParams params;
 		InsetIndex::string2params(to_utf8(cmd.argument()), params);
 		params_.index = params.index;
+		// what we really want here is a TOC update, but that means
+		// a full buffer update
+		cur.forceBufferUpdate();
 		break;
 	}
 
Index: src/lyxfind.cpp
===================================================================
--- src/lyxfind.cpp	(revision 34814)
+++ src/lyxfind.cpp	(working copy)
@@ -196,7 +196,6 @@
 		++num;
 	}
 
-	buf.updateBuffer();
 	bv->putSelectionAt(doc_iterator_begin(&buf), 0, false);
 	if (num)
 		buf.markDirty();
Index: src/mathed/InsetMathGrid.cpp
===================================================================
--- src/mathed/InsetMathGrid.cpp	(revision 34814)
+++ src/mathed/InsetMathGrid.cpp	(working copy)
@@ -1371,10 +1371,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: src/mathed/InsetMathHull.cpp
===================================================================
--- src/mathed/InsetMathHull.cpp	(revision 34814)
+++ src/mathed/InsetMathHull.cpp	(working copy)
@@ -572,10 +572,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);
@@ -598,14 +594,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();
 	}
 }
 
@@ -1275,6 +1263,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();
 		}
@@ -1292,6 +1282,7 @@
 				numbered(row, !old);
 
 		cur.message(old ? _("No number") : _("Number"));
+		cur.forceBufferUpdate();
 		break;
 	}
 
@@ -1301,6 +1292,7 @@
 		bool old = numbered(r);
 		cur.message(old ? _("No number") : _("Number"));
 		numbered(r, !old);
+		cur.forceBufferUpdate();
 		break;
 	}
 
@@ -1363,6 +1355,7 @@
 			} else if (numbered(row(cur.idx()))) {
 				cur.recordUndoInset();
 				numbered(row(cur.idx()), false);
+				cur.forceBufferUpdate();
 			} else {
 				InsetMathGrid::doDispatch(cur, cmd);
 				return;
@@ -1397,6 +1390,7 @@
 					label_[r]->initView();
 				}
 			}
+			cur.forceBufferUpdate();
 			break;
 		}
 		InsetMathGrid::doDispatch(cur, cmd);
@@ -1421,6 +1415,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: src/mathed/InsetMathNest.cpp
===================================================================
--- src/mathed/InsetMathNest.cpp	(revision 34814)
+++ src/mathed/InsetMathNest.cpp	(working copy)
@@ -574,8 +574,7 @@
 		}
 		cur.niceInsert(topaste, parseflg, false);
 		cur.clearSelection(); // bug 393
-		// FIXME audit setBuffer/updateBuffer calls
-		cur.buffer()->updateBuffer();
+		cur.forceBufferUpdate();
 		cur.finishUndo();
 		break;
 	}
@@ -587,8 +586,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:
@@ -998,8 +996,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();
@@ -1229,8 +1226,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: src/mathed/InsetMathRef.cpp
===================================================================
--- src/mathed/InsetMathRef.cpp	(revision 34814)
+++ src/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: src/Text2.cpp
===================================================================
--- src/Text2.cpp	(revision 34814)
+++ src/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: src/Text3.cpp
===================================================================
--- src/Text3.cpp	(revision 34814)
+++ src/Text3.cpp	(working copy)
@@ -486,8 +486,8 @@
 		recUndo(cur, pit, pit + 1);
 		cur.finishUndo();
 		pars_.swap(pit, pit + 1);
-		cur.buffer()->updateBuffer();
 		needsUpdate = true;
+		cur.forceBufferUpdate();
 		++cur.pit();
 		break;
 	}
@@ -497,9 +497,9 @@
 		recUndo(cur, pit - 1, pit);
 		cur.finishUndo();
 		pars_.swap(pit, pit - 1);
-		cur.buffer()->updateBuffer();
 		--cur.pit();
 		needsUpdate = true;
+		cur.forceBufferUpdate();
 		break;
 	}
 
@@ -523,7 +523,7 @@
 		par.params().startOfAppendix(start);
 
 		// we can set the refreshing parameters now
-		cur.buffer()->updateBuffer();
+		cur.forceBufferUpdate();
 		break;
 	}
 
@@ -624,7 +624,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;
@@ -650,7 +651,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;
@@ -971,6 +973,7 @@
 			singleParUpdate = false;
 		}
 		moveCursor(cur, false);
+		cur.forceBufferUpdate();
 		break;
 
 	case LFUN_CHAR_DELETE_BACKWARD:
@@ -988,6 +991,7 @@
 			cutSelection(cur, true, false);
 			singleParUpdate = false;
 		}
+		cur.forceBufferUpdate();
 		break;
 
 	case LFUN_BREAK_PARAGRAPH:
@@ -1046,8 +1050,10 @@
 	}
 
 	case LFUN_INSET_DISSOLVE: {
-		if (dissolveInset(cur))
+		if (dissolveInset(cur)) {
 			needsUpdate = true;
+			cur.forceBufferUpdate();
+		}
 		break;
 	}
 
@@ -1579,7 +1585,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:
@@ -1633,7 +1639,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
@@ -2074,26 +2080,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: src/Text.cpp
===================================================================
--- src/Text.cpp	(revision 34814)
+++ src/Text.cpp	(working copy)
@@ -739,10 +739,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!
@@ -1316,7 +1315,7 @@
 	cur.clearSelection();
 	setCursorIntern(cur, begPit, begPos);
 	cur.updateFlags(Update::Force);
-	cur.buffer()->updateBuffer();
+	cur.forceBufferUpdate();
 }
 
 
@@ -1467,7 +1466,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;
@@ -1495,7 +1494,7 @@
 			cur.top().forwardPos();
 
 		if (was_inset)
-			cur.buffer()->updateBuffer();
+			cur.forceBufferUpdate();
 		else
 			cur.checkBufferStructure();
 		needsUpdate = true;
@@ -1571,7 +1570,7 @@
 	}
 
 	if (needsUpdate) {
-		cur.buffer()->updateBuffer();
+		cur.forceBufferUpdate();
 		setCursorIntern(cur, prevcur.pit(), prevcur.pos());
 	}
 
@@ -1611,7 +1610,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();
 	}
@@ -1667,9 +1666,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: src/TextMetrics.cpp
===================================================================
--- src/TextMetrics.cpp	(revision 34814)
+++ src/TextMetrics.cpp	(working copy)
@@ -401,7 +401,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: src/Undo.cpp
===================================================================
--- src/Undo.cpp	(revision 34814)
+++ src/Undo.cpp	(working copy)
@@ -429,7 +429,6 @@
 
 	// Adapt the new material to current buffer.
 	buffer_.setBuffersForInsets(); // FIXME This shouldn't be here.
-	buffer_.updateBuffer();
 	return true;
 }
 

Reply via email to