Am Sonntag, 21. Mai 2006 16:14 schrieb Juergen Spitzmueller:
> It might be another consequence of the problematic BufferView cache 
situation 
> in tabulars. Georg, do you have an idea?

I got one after a bit of debugging. The problem is not the BufferView 
cache, but the use of std::swap() instead of the specialized pars.swap() 
in CutAndPaste.C. It invalidates some inset pointers in CursorSlice.
This patch fixes the problem, and avoids at the same time the swap call 
when we call switchBetweenClasses from LyXFunc::dispatch. I am committing 
it now.
Jean-Marc, I guess it should also go to 1.4?


Georg

Log:
Fix crash that occurs if the cursor is in a table cell when the document 
class
is changed
        * src/cursor.C: remove unused 'using std::swap'
        * src/BufferView.C: ditto

        * src/CutAndPaste.[Ch]
        (switchBetweenClasses): replace ParagraphList argument with InsetText
        argument. This avoids an unnecessary swap in lyxfunc.C.

        * src/CutAndPaste.C
        (pasteSelectionHelper): Adjust to the changes above
        (pasteSelectionHelper): Use ParagraphList::swap instead of std::swap.
        This fixes the crash.

        * src/lyxfunc.C
        (LyXFunc::dispatch): Adjust to switchBetweenClasses changes
Index: src/cursor.C
===================================================================
--- src/cursor.C	(Revision 13893)
+++ src/cursor.C	(Arbeitskopie)
@@ -63,7 +63,6 @@ using std::endl;
 using std::isalpha;
 #endif
 using std::min;
-using std::swap;
 
 namespace {
 
Index: src/CutAndPaste.C
===================================================================
--- src/CutAndPaste.C	(Revision 13893)
+++ src/CutAndPaste.C	(Arbeitskopie)
@@ -150,7 +150,14 @@ pasteSelectionHelper(Buffer const & buff
 	}
 
 	// Make sure there is no class difference.
-	lyx::cap::switchBetweenClasses(textclass, tc, insertion, errorlist);
+	InsetText in;
+	// This works without copying any paragraph data because we have
+	// a specialized swap method for ParagraphList. This is important
+	// since we store pointers to insets at some places and we don't
+	// want to invalidate them.
+	insertion.swap(in.paragraphs());
+	lyx::cap::switchBetweenClasses(textclass, tc, in, errorlist);
+	insertion.swap(in.paragraphs());
 
 	ParagraphList::iterator tmpbuf = insertion.begin();
 	int depth_delta = pars[pit].params().depth() - tmpbuf->params().depth();
@@ -200,8 +207,7 @@ pasteSelectionHelper(Buffer const & buff
 
 	// Prepare the paragraphs and insets for insertion.
 	// A couple of insets store buffer references so need updating.
-	InsetText in;
-	std::swap(in.paragraphs(), insertion);
+	insertion.swap(in.paragraphs());
 
 	ParIterator fpit = par_iterator_begin(in);
 	ParIterator fend = par_iterator_end(in);
@@ -223,7 +229,7 @@ pasteSelectionHelper(Buffer const & buff
 			}
 		}
 	}
-	std::swap(in.paragraphs(), insertion);
+	insertion.swap(in.paragraphs());
 
 	// Split the paragraph for inserting the buf if necessary.
 	if (!empty)
@@ -368,18 +374,15 @@ string grabAndEraseSelection(LCursor & c
 
 
 void switchBetweenClasses(textclass_type c1, textclass_type c2,
-	ParagraphList & pars, ErrorList & errorlist)
+	InsetText & in, ErrorList & errorlist)
 {
-	BOOST_ASSERT(!pars.empty());
+	BOOST_ASSERT(!in.paragraphs().empty());
 	if (c1 == c2)
 		return;
 
 	LyXTextClass const & tclass1 = textclasslist[c1];
 	LyXTextClass const & tclass2 = textclasslist[c2];
 
-	InsetText in;
-	std::swap(in.paragraphs(), pars);
-
 	// layouts
 	ParIterator end = par_iterator_end(in);
 	for (ParIterator it = par_iterator_begin(in); it != end; ++it) {
@@ -432,8 +435,6 @@ void switchBetweenClasses(textclass_type
 			}
 		}
 	}
-
-	std::swap(in.paragraphs(), pars);
 }
 
 
Index: src/lyxfunc.C
===================================================================
--- src/lyxfunc.C	(Revision 13893)
+++ src/lyxfunc.C	(Arbeitskopie)
@@ -1563,7 +1563,7 @@ void LyXFunc::dispatch(FuncRequest const
 			ErrorList el;
 			lyx::cap::switchBetweenClasses(
 				old_class, new_class,
-				buffer->paragraphs(), el);
+				static_cast<InsetText &>(buffer->inset()), el);
 
 			view()->setCursor(backcur.asDocIterator(&(buffer->inset())));
 			bufferErrors(*buffer, el);
Index: src/CutAndPaste.h
===================================================================
--- src/CutAndPaste.h	(Revision 13893)
+++ src/CutAndPaste.h	(Arbeitskopie)
@@ -23,6 +23,7 @@
 
 class Buffer;
 class ErrorList;
+class InsetText;
 class LyXTextClass;
 class LCursor;
 
@@ -67,9 +68,8 @@ void pasteParagraphList(LCursor & cur, P
  *  It changes layouts and character styles.
  */
 void switchBetweenClasses(lyx::textclass_type c1,
-				lyx::textclass_type c2,
-				ParagraphList & par,
-				ErrorList &);
+                          lyx::textclass_type c2,
+                          InsetText & in, ErrorList &);
 
 // only used by the spellchecker
 void replaceWord(LCursor & cur, std::string const & replacestring);
Index: src/BufferView.C
===================================================================
--- src/BufferView.C	(Revision 13893)
+++ src/BufferView.C	(Arbeitskopie)
@@ -54,7 +54,6 @@ using lyx::cap::setSelectionRange;
 using std::distance;
 using std::find;
 using std::string;
-using std::swap;
 using std::vector;
 
 

Reply via email to