Fix crash reported by Tommaso:

http://marc.info/?l=lyx-devel&m=133876924408431&w=2
The problem here is that the copy_params() routine in FindAndReplace.cpp
created a new DocumentClass, but it never updated its Buffer to reflect
that new DocumentClass. So its Paragraphs still contained points to the
Layouts in the old DocumentClass which, since ead697d4b6, gets garbage
collected once it is no longer needed. So the Layout doesn't exist, and
we crash.
This commit is contained in:
Richard Heck 2012-06-04 13:39:24 -04:00
parent 1078dba130
commit 7ef8df460a
4 changed files with 20 additions and 13 deletions

View File

@ -124,6 +124,10 @@ public:
bool setBaseClass(std::string const & classname);
/// Adds the module information to the baseClass information to
/// create our local DocumentClass.
/// NOTE: This should NEVER be called externally unless one immediately goes
/// on to class BufferView::updateDocumentClass(). The exception, of course,
/// is in GuiDocument, where we use a BufferParams simply to hold a copy of
/// the parameters from the active Buffer.
void makeDocumentClass();
/// Returns the DocumentClass currently in use: the BaseClass as modified
/// by modules.

View File

@ -941,6 +941,14 @@ bool BufferView::scrollToCursor(DocIterator const & dit, bool recenter)
}
void BufferView::makeDocumentClass()
{
DocumentClassConstPtr olddc = buffer_.params().documentClassPtr();
buffer_.params().makeDocumentClass();
updateDocumentClass(olddc);
}
void BufferView::updateDocumentClass(DocumentClassConstPtr olddc)
{
message(_("Converting document to new document class..."));
@ -956,6 +964,7 @@ void BufferView::updateDocumentClass(DocumentClassConstPtr olddc)
buffer_.errors("Class Switch");
}
/** Return the change status at cursor position, taking in account the
* status at each level of the document iterator (a table in a deleted
* footnote is deleted).
@ -1256,11 +1265,9 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
}
case LFUN_LAYOUT_MODULES_CLEAR: {
DocumentClassConstPtr oldClass = buffer_.params().documentClassPtr();
cur.recordUndoFullDocument();
buffer_.params().clearLayoutModules();
buffer_.params().makeDocumentClass();
updateDocumentClass(oldClass);
makeDocumentClass();
dr.screenUpdate(Update::Force);
dr.forceBufferUpdate();
break;
@ -1274,11 +1281,9 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
"conflicts with installed modules.");
break;
}
DocumentClassConstPtr oldClass = params.documentClassPtr();
cur.recordUndoFullDocument();
buffer_.params().addLayoutModule(argument);
buffer_.params().makeDocumentClass();
updateDocumentClass(oldClass);
makeDocumentClass();
dr.screenUpdate(Update::Force);
dr.forceBufferUpdate();
break;
@ -1305,11 +1310,9 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
break;
// Save the old, possibly modular, layout for use in conversion.
DocumentClassConstPtr oldDocClass = buffer_.params().documentClassPtr();
cur.recordUndoFullDocument();
buffer_.params().setBaseClass(argument);
buffer_.params().makeDocumentClass();
updateDocumentClass(oldDocClass);
makeDocumentClass();
dr.screenUpdate(Update::Force);
dr.forceBufferUpdate();
break;
@ -1330,12 +1333,10 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
}
case LFUN_LAYOUT_RELOAD: {
DocumentClassConstPtr oldClass = buffer_.params().documentClassPtr();
LayoutFileIndex bc = buffer_.params().baseClassID();
LayoutFileList::get().reset(bc);
buffer_.params().setBaseClass(bc);
buffer_.params().makeDocumentClass();
updateDocumentClass(oldClass);
makeDocumentClass();
dr.screenUpdate(Update::Force);
dr.forceBufferUpdate();
break;

View File

@ -318,6 +318,8 @@ public:
void clearLastInset(Inset * inset) const;
/// Is the mouse hovering a clickable inset or element?
bool clickableInset() const;
///
void makeDocumentClass();
private:
/// noncopyable

View File

@ -503,7 +503,7 @@ static void copy_params(BufferView const & bv, BufferView & dest_bv) {
Buffer & dest_buf = dest_bv.buffer();
dest_buf.params().setLanguage(lang);
dest_buf.params().setBaseClass(doc_class);
dest_buf.params().makeDocumentClass();
dest_bv.makeDocumentClass();
dest_bv.cursor().current_font.setLanguage(doc_bp.language);
}