This pair of patches is for http://bugzilla.lyx.org/show_bug.cgi?id=1987
Test case: 1. New document 2. Change layout of empty paragraph to "Date" 3. Change document class to "Broadway" => Crash I began by trying to move more code (in particular the LFUN_TEXTCLASS_APPLY) into LFUN_BUFFERPARAMS_APPLY. I think this is sound, and it fixes the bug (what happens is that LFUN_TEXTCLASS_APPLY changes the layouts of the paragraphs when needed, but does not touch the textclass itself; thus, if there is an update before LFUN_BUFFERPARAMS_APPLY is run, the code that sets the layout bar crashes). The result is classcrash.diff below, which contains several contents telling where more cleanup can/should be done. Then it occurred to me that it is enough to just set the textclass in LFUN_TEXTCLASS_APPLY. JMarc
Index: src/ChangeLog =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/ChangeLog,v retrieving revision 1.2280 diff -u -p -r1.2280 ChangeLog --- src/ChangeLog 15 Sep 2005 16:00:27 -0000 1.2280 +++ src/ChangeLog 16 Sep 2005 10:54:38 -0000 @@ -1,3 +1,8 @@ +2005-09-16 Jean-Marc Lasgouttes <[EMAIL PROTECTED]> + + * lyxfunc.C (dispatch): make LFUN_BUFFERPARAMS_APPLY perform the + task previously devoted to LFUN_TEXTCLASS_APPLY (bug 1987). + 2005-09-14 Michael Gerz <[EMAIL PROTECTED]> * lyxfunc.C: update display after LFUN_ALL_INSETS_TOGGLE Index: src/lyxfunc.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lyxfunc.C,v retrieving revision 1.667 diff -u -p -r1.667 lyxfunc.C --- src/lyxfunc.C 15 Sep 2005 16:00:29 -0000 1.667 +++ src/lyxfunc.C 16 Sep 2005 10:54:38 -0000 @@ -1454,14 +1454,16 @@ void LyXFunc::dispatch(FuncRequest const } case LFUN_BUFFERPARAMS_APPLY: { - biblio::CiteEngine const engine = - owner->buffer()->params().cite_engine; + // FIXME: we may want to move this code to + // buffer_funcs.C, especially if it inherits + // some code from ControlDocument. (JMarc) + Buffer & buf = *owner->buffer(); + BufferParams old_params = buf.params(); istringstream ss(argument); LyXLex lex(0,0); lex.setStream(ss); - int const unknown_tokens = - owner->buffer()->readHeader(lex); + int const unknown_tokens = buf.readHeader(lex); if (unknown_tokens != 0) { lyxerr << "Warning in LFUN_BUFFERPARAMS_APPLY!\n" @@ -1469,22 +1471,46 @@ void LyXFunc::dispatch(FuncRequest const << (unknown_tokens == 1 ? "" : "s") << endl; } - if (engine == owner->buffer()->params().cite_engine) - break; - LCursor & cur = view()->cursor(); - FuncRequest fr(LFUN_INSET_REFRESH); + BufferParams const & params = buf.params(); - InsetBase & inset = owner->buffer()->inset(); - InsetIterator it = inset_iterator_begin(inset); - InsetIterator const end = inset_iterator_end(inset); - for (; it != end; ++it) - if (it->lyxCode() == InsetBase::CITE_CODE) - it->dispatch(cur, fr); + if (old_params.cite_engine != params.cite_engine) { + + LCursor & cur = view()->cursor(); + FuncRequest fr(LFUN_INSET_REFRESH); + + InsetBase & inset = buf.inset(); + InsetIterator it = inset_iterator_begin(inset); + InsetIterator const end = inset_iterator_end(inset); + for (; it != end; ++it) + if (it->lyxCode() == InsetBase::CITE_CODE) + it->dispatch(cur, fr); + } + + if (old_params.textclass != params.textclass) { + owner->message(_("Converting document to new document class...")); + textclasslist[params.textclass].load(); + recordUndoFullDocument(view()); + StableDocIterator backcur(view()->cursor()); + ErrorList el; + lyx::cap::SwitchBetweenClasses( + old_params.textclass, + params.textclass, + buf.paragraphs(), el); + + view()->setCursor(backcur.asDocIterator(&(buf.inset()))); + bufferErrors(buf, el); + view()->showErrorList(_("Class switch")); + updateCounters(buf); + update = true; + } break; } case LFUN_TEXTCLASS_APPLY: { + //FIXME: the functionality of this is + //duplicated in LFUN_BUFFERPARAMS_APPLY; it is + //not clear that this LFUN should be kept. (JMarc) recordUndoFullDocument(view()); Buffer * buffer = owner->buffer(); Index: src/frontends/controllers/ChangeLog =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/controllers/ChangeLog,v retrieving revision 1.497 diff -u -p -r1.497 ChangeLog --- src/frontends/controllers/ChangeLog 15 Sep 2005 14:56:27 -0000 1.497 +++ src/frontends/controllers/ChangeLog 16 Sep 2005 10:54:38 -0000 @@ -1,3 +1,9 @@ +2005-09-16 Jean-Marc Lasgouttes <[EMAIL PROTECTED]> + + * ControlDocument.C (dispatchParams): do not invoke + LFUN_TEXTCLASS_APPLY, to avoid a spurious update that can cause a + crash. This job is now done by LFUN_BUFFERPARAMS_APPLY (bug 1987). + 2005-09-15 Jürgen Spitzmüller <[EMAIL PROTECTED]> * ControlDocument.C (dispatchParams): update bufferview at the end Index: src/frontends/controllers/ControlDocument.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/controllers/ControlDocument.C,v retrieving revision 1.56 diff -u -p -r1.56 ControlDocument.C --- src/frontends/controllers/ControlDocument.C 15 Sep 2005 14:56:28 -0000 1.56 +++ src/frontends/controllers/ControlDocument.C 16 Sep 2005 10:54:38 -0000 @@ -87,25 +87,18 @@ void ControlDocument::dispatchParams() // This must come first so that a language change is correctly noticed setLanguage(); - // Set the document class. - textclass_type const old_class = - kernel().buffer().params().textclass; - textclass_type const new_class = bp_->textclass; - if (new_class != old_class) { - string const name = textclasslist[new_class].name(); - kernel().dispatch(FuncRequest(LFUN_TEXTCLASS_APPLY, name)); - } - int const old_secnumdepth = kernel().buffer().params().secnumdepth; int const new_secnumdepth = bp_->secnumdepth; // Apply the BufferParams. dispatch_bufferparams(kernel(), params(), LFUN_BUFFERPARAMS_APPLY); + // FIXME: this should be done by LFUN_BUFFERPARAMS_APPLY (JMarc) // redo the numbering if necessary if (new_secnumdepth != old_secnumdepth) updateCounters(kernel().buffer()); + // FIXME: this should be done by LFUN_BUFFERPARAMS_APPLY (JMarc) // Generate the colours requested by each new branch. BranchList & branchlist = params().branchlist(); if (!branchlist.empty()) {
Index: src/ChangeLog =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/ChangeLog,v retrieving revision 1.2280 diff -u -p -r1.2280 ChangeLog --- src/ChangeLog 15 Sep 2005 16:00:27 -0000 1.2280 +++ src/ChangeLog 16 Sep 2005 11:02:18 -0000 @@ -1,3 +1,8 @@ +2005-09-16 Jean-Marc Lasgouttes <[EMAIL PROTECTED]> + + * lyxfunc.C (dispatch): LFUN_TEXTCLASS_APPLY: actually set the + textclass (bug 1987); do not record undo if nothing is changed. + 2005-09-14 Michael Gerz <[EMAIL PROTECTED]> * lyxfunc.C: update display after LFUN_ALL_INSETS_TOGGLE Index: src/lyxfunc.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lyxfunc.C,v retrieving revision 1.667 diff -u -p -r1.667 lyxfunc.C --- src/lyxfunc.C 15 Sep 2005 16:00:29 -0000 1.667 +++ src/lyxfunc.C 16 Sep 2005 11:02:18 -0000 @@ -1485,7 +1485,6 @@ void LyXFunc::dispatch(FuncRequest const } case LFUN_TEXTCLASS_APPLY: { - recordUndoFullDocument(view()); Buffer * buffer = owner->buffer(); lyx::textclass_type const old_class = @@ -1505,6 +1504,8 @@ void LyXFunc::dispatch(FuncRequest const break; owner->message(_("Converting document to new document class...")); + recordUndoFullDocument(view()); + buffer->params().textclass = new_class; StableDocIterator backcur(view()->cursor()); ErrorList el; lyx::cap::SwitchBetweenClasses(