[PATCH] bug 1987: Crash when switching to different document class

2005-09-16 Thread Jean-Marc Lasgouttes

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 -	1.2280
+++ src/ChangeLog	16 Sep 2005 10:54:38 -
@@ -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 -	1.667
+++ src/lyxfunc.C	16 Sep 2005 10:54:38 -
@@ -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 -	1.497
+++ src/frontends/controllers/ChangeLog	16 Sep 2005 10:54:38 -
@@ -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  <

Re: [PATCH] bug 1987: Crash when switching to different document class

2005-09-16 Thread Jean-Marc Lasgouttes
> "Jean-Marc" == Jean-Marc Lasgouttes <[EMAIL PROTECTED]> writes:

Jean-Marc> The result is classcrash.diff below, which contains several
Jean-Marc> contents telling where more cleanup can/should be done.

Jean-Marc> Then it occurred to me that it is enough to just set the
Jean-Marc> textclass in LFUN_TEXTCLASS_APPLY.

I sent my message too fast...

So, finally, I came up with the simpler simple-classcrash.diff which
also fixes the bug. Lars, am I right that you prefer this one?

JMarc


Re: [PATCH] bug 1987: Crash when switching to different document class

2005-09-19 Thread Jean-Marc Lasgouttes
> "Jean-Marc" == Jean-Marc Lasgouttes <[EMAIL PROTECTED]> writes:

Jean-Marc> So, finally, I came up with the simpler
Jean-Marc> simple-classcrash.diff which also fixes the bug. Lars, am I
Jean-Marc> right that you prefer this one?

I committed that.

JMarc