r19550 by jghali - #12739: Undo/Redo crashes Scribus if a linked Text Frame is edited and deleted

scribus-commit scribus-commit at lists.scribus.net
Sat Oct 4 12:31:45 UTC 2014


Author: jghali
Date: Sat Oct  4 12:31:45 2014
New Revision: 19550

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=19550
Log:
#12739: Undo/Redo crashes Scribus if a linked Text Frame is edited and deleted

Modified:
    branches/Version14x/Scribus/scribus/pageitem.cpp
    branches/Version14x/Scribus/scribus/pageitem.h
    branches/Version14x/Scribus/scribus/scribusdoc.cpp

Modified: branches/Version14x/Scribus/scribus/pageitem.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=19550&path=/branches/Version14x/Scribus/scribus/pageitem.cpp
==============================================================================
--- branches/Version14x/Scribus/scribus/pageitem.cpp (original)
+++ branches/Version14x/Scribus/scribus/pageitem.cpp Sat Oct  4 12:31:45 2014
@@ -908,24 +908,33 @@
 	// leave text in remaining chain
 	PageItem* before = BackBox;
 	PageItem* after = NextBox;
-	if (after != 0 || before != 0)
-	{
-		itemText = StoryText(m_Doc);
-		if (before)
-			before->NextBox = after;
-		if (after) 
-		{
-			after->BackBox = before;
-			while (after)
-			{ 
-				after->invalid = true;
-				after->firstChar = 0;
-				after = after->NextBox;
-			}
-		}
-		// JG we should set BackBox and NextBox to NULL at a point
-		BackBox = NextBox = NULL;
-	}
+	if (after == 0 && before == 0)
+		return;
+
+	itemText = StoryText(m_Doc);
+	if (before)
+		before->NextBox = after;
+	if (after) 
+	{
+		after->BackBox = before;
+		while (after)
+		{ 
+			after->invalid = true;
+			after->firstChar = 0;
+			after = after->NextBox;
+		}
+	}
+
+	if (UndoManager::undoEnabled())
+	{
+		ItemState<QPair<PageItem*, PageItem*> > *is = new ItemState<QPair<PageItem*, PageItem*> >(Um::UnlinkTextFrame);
+		is->set("DROP_LINKS", "dropLinks");
+		is->setItem(qMakePair(BackBox, NextBox));
+		undoManager->action(this, is);
+	}
+
+	// JG we should set BackBox and NextBox to NULL at a point
+	BackBox = NextBox = NULL;
 }
 
 /// tests if a character is displayed by this frame
@@ -3294,6 +3303,8 @@
 			restoreEditText(ss, isUndo);
 		else if (ss->contains("CLEAR_IMAGE"))
 			restoreClearImage(ss,isUndo);
+		else if (ss->contains("DROP_LINKS"))
+			restoreDropLinks(ss, isUndo);
 		else if (ss->contains("LINK_TEXT_FRAME"))
 			restoreLinkTextFrame(ss,isUndo);
 		else if (ss->contains("UNLINK_TEXT_FRAME"))
@@ -3685,6 +3696,60 @@
 	}
 	else
 		asImageFrame()->clearContents();
+}
+
+void PageItem::restoreDropLinks(UndoState *state, bool isUndo)
+{
+	if (!isTextFrame())
+		return;
+	ItemState<QPair<PageItem*, PageItem*> > *is = dynamic_cast<ItemState<QPair<PageItem*, PageItem*> >*>(state);
+	if (isUndo)
+	{
+		PageItem* prev = is->getItem().first;
+		PageItem* next = is->getItem().second;
+
+		BackBox = prev;
+		NextBox = next;
+		invalid = true;
+
+		if (prev)
+		{
+			this->itemText  = prev->itemText;
+			this->isAutoText |= prev->isAutoText;
+			prev->NextBox = this;
+			while (prev)
+			{
+				prev->invalid = true;
+				prev = prev->BackBox;
+			}
+		}
+		if (next)
+		{
+			this->itemText = next->itemText;
+			this->isAutoText |= next->isAutoText;
+
+			next->BackBox = this;
+			while (next)
+			{
+				next->invalid = true;
+				next = next->NextBox;
+			}
+		}
+
+		// update auto pointers
+		if (isAutoText && NextBox == 0)
+		{
+			m_Doc->LastAuto = this;
+		}
+		if (isAutoText && BackBox == 0)
+		{
+			m_Doc->FirstAuto = this;
+		}
+	}
+	else
+	{
+		dropLinks();
+	}
 }
 
 void PageItem::restoreLinkTextFrame(UndoState *state, bool isUndo)

Modified: branches/Version14x/Scribus/scribus/pageitem.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=19550&path=/branches/Version14x/Scribus/scribus/pageitem.h
==============================================================================
--- branches/Version14x/Scribus/scribus/pageitem.h (original)
+++ branches/Version14x/Scribus/scribus/pageitem.h Sat Oct  4 12:31:45 2014
@@ -1095,6 +1095,7 @@
 	void restoreEditText(SimpleState *state, bool isUndo);
 	void restoreLinkTextFrame(UndoState *state, bool isUndo);
 	void restoreUnlinkTextFrame(UndoState *state, bool isUndo);
+	void restoreDropLinks(UndoState *state, bool isUndo);
 	void restoreReverseText(UndoState *state, bool isUndo);
 	void restorePathOperation(UndoState *state, bool isUndo);
 	/*@}*/

Modified: branches/Version14x/Scribus/scribus/scribusdoc.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=19550&path=/branches/Version14x/Scribus/scribus/scribusdoc.cpp
==============================================================================
--- branches/Version14x/Scribus/scribus/scribusdoc.cpp (original)
+++ branches/Version14x/Scribus/scribus/scribusdoc.cpp Sat Oct  4 12:31:45 2014
@@ -7776,8 +7776,12 @@
 	}
 	selectedItemCount = delItems.count();
 
+	bool doCreateTransaction = (selectedItemCount > 1);
+	if (selectedItemCount == 1)
+		doCreateTransaction = delItems.at(0)->isTextFrame();
+
 	UndoTransaction* activeTransaction = NULL;
-	if ((selectedItemCount > 1) && UndoManager::undoEnabled())
+	if (doCreateTransaction && UndoManager::undoEnabled())
 		activeTransaction = new UndoTransaction(undoManager->beginTransaction(Um::Group + "/" + Um::Selection, Um::IGroup,
 																			  Um::Delete, tooltip, Um::IDelete));
 




More information about the scribus-commit mailing list