View Issue Details

IDProjectCategoryView StatusLast Update
0010852ScribusStory Editor / Text Framespublic2012-08-02 19:49
Reporterale Assigned Tocezaryece  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version1.5.0svn 
Fixed in Version1.5.0svn 
Summary0010852: unlink with cut should keep the overflow in the cut frame
Description- i have two frames linked and the text is overflowing
- if i unlink with cut, the overflow is attached to the first frame
- the overflow should stay with the second frame.
TagsNo tags attached.
Patch

Activities

cezaryece

2012-07-10 08:44

updater  

unlinkcut.diff (10,050 bytes)   
diff --git a/Scribus/scribus/actionmanager.cpp b/Scribus/scribus/actionmanager.cpp
index bca307f..449e605 100644
--- a/Scribus/scribus/actionmanager.cpp
+++ b/Scribus/scribus/actionmanager.cpp
@@ -829,7 +829,7 @@ void ActionManager::initToolsMenuActions()
 	*modeActionNames << "toolsSelect" << "toolsInsertTextFrame" << "toolsInsertImageFrame" << "toolsInsertTable";
 	*modeActionNames << "toolsInsertShape" << "toolsInsertPolygon" << "toolsInsertArc" << "toolsInsertSpiral" << "toolsInsertLine" << "toolsInsertBezier";
 	*modeActionNames << "toolsInsertFreehandLine" << "toolsInsertCalligraphicLine" << "toolsInsertRenderFrame" << "toolsRotate" << "toolsZoom" << "toolsEditContents";
-	*modeActionNames << "toolsEditWithStoryEditor" << "toolsLinkTextFrame" << "toolsUnlinkTextFrame" << "toolsUnlinkTextFrameWithTextCopy" << "toolsUnlinkTextFrameWithTextCut";
+	*modeActionNames << "toolsEditWithStoryEditor" << "toolsLinkTextFrame" << "toolsUnlinkTextFrame"; //<< "toolsUnlinkTextFrameWithTextCopy" << "toolsUnlinkTextFrameWithTextCut";
 	*modeActionNames << "toolsEyeDropper" << "toolsCopyProperties";
 	*modeActionNames << "toolsPDFPushButton" << "toolsPDFTextField" << "toolsPDFCheckBox" << "toolsPDFComboBox" << "toolsPDFListBox" << "toolsPDFAnnotText" << "toolsPDFAnnotLink";
 #ifdef HAVE_OSG
@@ -1975,7 +1975,10 @@ void ActionManager::createDefaultMenus()
 		<< "itemSplitPolygons"
 		<< "itemsUnWeld"
 		<< "itemWeld"
-		<< "itemEditWeld";
+		<< "itemEditWeld"
+		<< "toolsUnlinkTextFrameWithTextCopy"
+		<< "toolsUnlinkTextFrameWithTextCut";
+	
 	//Insert
 	++itmenu;
 	itmenu->second
@@ -2199,8 +2202,8 @@ void ActionManager::createDefaultNonMenuActions()
 	itnmenua->second << "toolsEditContents";
 	itnmenua->second << "toolsLinkTextFrame";
 	itnmenua->second << "toolsUnlinkTextFrame";
-	itnmenua->second << "toolsUnlinkTextFrameWithTextCopy";
-	itnmenua->second << "toolsUnlinkTextFrameWithTextCut";
+//	itnmenua->second << "toolsUnlinkTextFrameWithTextCopy";
+//	itnmenua->second << "toolsUnlinkTextFrameWithTextCut";
 	itnmenua->second << "toolsEyeDropper";
 	itnmenua->second << "toolsCopyProperties";
 	itnmenua->second << "toolsPDFPushButton";
diff --git a/Scribus/scribus/pageitem.cpp b/Scribus/scribus/pageitem.cpp
index a232b08..6ea359e 100644
--- a/Scribus/scribus/pageitem.cpp
+++ b/Scribus/scribus/pageitem.cpp
@@ -1165,7 +1165,7 @@ bool PageItem::testLinkCandidate(PageItem* nxt)
 	return true;
 }
 
-void PageItem::link(PageItem* nxt)
+void PageItem::link(PageItem* nxt, bool addPARSEP)
 {
 	assert( !nextInChain() );
 	assert( !nxt->prevInChain() );
@@ -1175,8 +1175,21 @@ void PageItem::link(PageItem* nxt)
 	}
 	// Append only if necessary to avoid the
 	// charstyle: access at end of text warning
+	bool first = false;
+	bool createUndo = addPARSEP;
+
+	if (nxt->prevInChain() == NULL)
+		first = true;
+	int textLen = itemText.length();
 	if (nxt->itemText.length() > 0)
+	{   //case when text will be joined with next frame text
+		//do not add PARSEP if first frame has no text or text ends already with PARSEP
+		if (addPARSEP && (textLen > 0) && (itemText.text(textLen-1) != SpecialChars::PARSEP))
+			itemText.insertChars(textLen, SpecialChars::PARSEP);
+		else
+			addPARSEP = false;
 		itemText.append(nxt->itemText);
+	}
 	NextBox = nxt;
 	nxt->BackBox = this;
 	// update AutoText
@@ -1208,16 +1221,19 @@ void PageItem::link(PageItem* nxt)
 		nxt->firstChar = 0;
 		nxt = nxt->NextBox;
 	}
-	if (UndoManager::undoEnabled())
+	if (UndoManager::undoEnabled() && createUndo) //addPARESEP is false only if linking is invoked from undo action for unlinkWithText
 	{
 		ScItemState<std::pair<PageItem*, PageItem*> > *is = new ScItemState<std::pair<PageItem*, PageItem*> >(UndoManager::LinkTextFrame);
 		is->set("LINK_TEXT_FRAME", "linkTextFrame");
+		is->set("FIRST", first);
+		is->set("JOIN_POS", textLen);
+		is->set("ADDPARSEP", addPARSEP);
 		is->setItem(std::pair<PageItem*, PageItem*>(this, NextBox));
 		undoManager->action(this, is);
 	}
 }
 
-void PageItem::unlink()
+void PageItem::unlink(bool createUndo)
 {
 	if( NextBox )
 	{
@@ -1259,7 +1275,7 @@ void PageItem::unlink()
 		}
 		// NextBox == NULL now
 		NextBox = NULL;
-		if (UndoManager::undoEnabled())
+		if (UndoManager::undoEnabled() && createUndo)
 		{
 			ScItemState<std::pair<PageItem*, PageItem*> > *is = new ScItemState<std::pair<PageItem*, PageItem*> >(UndoManager::UnlinkTextFrame);
 			is->set("UNLINK_TEXT_FRAME", "unlinkTextFrame");
@@ -1310,17 +1326,52 @@ void PageItem::dropLinks()
 //but copy or cut its content from itemText
 void PageItem::unlinkWithText(bool cutText)
 {
-	// FIX ME - make this operation undoable
 	PageItem * Next = NextBox;
-	itemText.select(firstInFrame(),lastInFrame() - firstInFrame() +1);
-	StoryText content(m_Doc);
-	content.insert(0, itemText, true);
-	if (cutText)
-		itemText.removeSelection();
-	dropLinks();
-	itemText.append(content);
-	if (Next)
-		Next->update();
+	PageItem * Prev = BackBox;
+	int length = itemText.length();
+
+	//unlink first frame in chain
+	if (Prev == NULL)
+	{
+		if (lastInFrame() < length -1)
+		{
+			StoryText content(m_Doc);
+			itemText.select(lastInFrame() +1, length - (lastInFrame() +1));
+			content.insert(0, itemText, cutText);
+			itemText.removeSelection();
+			unlink(false);
+			Next->itemText.insert(0, content);
+			Next->update();
+		}
+		else
+		{
+			unlink(false);
+			if (!cutText)
+			{
+				Next->itemText.insert(0, itemText);
+				Next->update();
+			}
+		}
+	}
+	else
+	{
+		itemText.select(firstInFrame(), length - firstInFrame());
+		StoryText content(m_Doc);
+		content.insert(0, itemText, true);
+		if (cutText)
+			itemText.removeSelection();
+		Prev->unlink(false);
+		itemText.insert(0, content);
+		update();
+	}
+	if (UndoManager::undoEnabled())
+	{
+		ScItemState<std::pair<PageItem*, PageItem*> > *is = new ScItemState<std::pair<PageItem*, PageItem*> >(UndoManager::UnlinkTextFrame);
+		is->set("UNLINK_TEXT_FRAME", "unlinkTextFrame");
+		is->set("CUT_TEXT", cutText);
+		is->setItem(std::pair<PageItem*, PageItem*>(Prev, Next));
+		undoManager->action(this, is);
+	}
 }
 
 /// tests if a character is displayed by this frame
@@ -5227,7 +5278,40 @@ void PageItem::restoreLinkTextFrame(UndoState *state, bool isUndo)
 		return;
 	if (isUndo)
 	{
-		unlink();
+		unlink(false);
+		//restore properly text if frame was linked at beginning of chain
+		ScItemState<std::pair<PageItem*, PageItem*> > *is = dynamic_cast<ScItemState<std::pair<PageItem*, PageItem*> >*>(state);
+		int joinPos = is->getInt("JOIN_POS");
+		int ParSep = is->getBool("ADDPARSEP")?1:0;
+		if (is->getBool("FIRST"))
+		{
+			if (joinPos == 0)
+			{
+				is->getItem().second->itemText.append(itemText);
+				itemText = StoryText(m_Doc);
+			}
+			else
+			{
+				StoryText content(m_Doc);
+				itemText.select(joinPos + ParSep, itemText.length() - (joinPos + ParSep));
+				content.insert(0, itemText, true);
+				if (ParSep)
+					itemText.select(joinPos, itemText.length() - joinPos);
+				itemText.removeSelection();
+				is->getItem().second->itemText.append(content);
+			}
+		}
+		else
+		{
+			StoryText content(m_Doc);
+			PageItem* prev = is->getItem().second;
+			prev->itemText.select(joinPos + ParSep, prev->itemText.length() - (joinPos + ParSep));
+			content.insert(0, prev->itemText, true);
+			if (ParSep)
+				prev->itemText.select(joinPos, prev->itemText.length() - joinPos);
+			prev->itemText.removeSelection();
+			itemText.append(content);
+		}
 	}
 	else
 	{
@@ -5240,14 +5324,38 @@ void PageItem::restoreUnlinkTextFrame(UndoState *state, bool isUndo)
 {
 	if (!isTextFrame())
 		return;
-	if (isUndo)
+	ScItemState<std::pair<PageItem*, PageItem*> > *is = dynamic_cast<ScItemState<std::pair<PageItem*, PageItem*> >*>(state);
+	if (is->contains("CUT_TEXT"))
 	{
-		ScItemState<std::pair<PageItem*, PageItem*> > *is = dynamic_cast<ScItemState<std::pair<PageItem*, PageItem*> >*>(state);
-		asTextFrame()->link(is->getItem().second->asTextFrame());
+		bool cutText = is->getBool("CUT_TEXT");
+		if (isUndo)
+		{
+			PageItem* prev = is->getItem().first;
+			PageItem* next  = is->getItem().second;
+			if (prev != NULL)
+			{
+				if (!cutText)
+					itemText = StoryText(m_Doc);
+				prev->link(this, false);
+			}
+			else if (next != NULL)
+			{
+				if (!cutText)
+					this->itemText = StoryText(m_Doc);
+				this->link(next, false);
+			}
+			else
+				Q_ASSERT(prev || next);
+		}
+		else
+			unlinkWithText(cutText);
 	}
 	else
 	{
-		unlink();
+		if (isUndo)
+			asTextFrame()->link(is->getItem().second->asTextFrame());
+		else
+			unlink();
 	}
 }
 
diff --git a/Scribus/scribus/pageitem.h b/Scribus/scribus/pageitem.h
index 387d3d8..b07a17b 100644
--- a/Scribus/scribus/pageitem.h
+++ b/Scribus/scribus/pageitem.h
@@ -546,8 +546,8 @@ public:
 	PageItem *Parent;
 
 	bool testLinkCandidate(PageItem* nextFrame);
-	void unlink();
-	void link(PageItem* nextFrame);
+	void unlink(bool createUndo = true);
+	void link(PageItem* nextFrame, bool addPARSEP = true);
 	void dropLinks();
 	void unlinkWithText(bool);
 
diff --git a/Scribus/scribus/scribus.cpp b/Scribus/scribus/scribus.cpp
index 9a0cf32..c96b969 100644
--- a/Scribus/scribus/scribus.cpp
+++ b/Scribus/scribus/scribus.cpp
@@ -6440,8 +6440,8 @@ void ScribusMainWindow::setAppMode(int mode)
 	scrActions["toolsEditWithStoryEditor"]->setChecked(mode==modeStoryEditor);
 	scrActions["toolsLinkTextFrame"]->setChecked(mode==modeLinkFrames);
 	scrActions["toolsUnlinkTextFrame"]->setChecked(mode==modeUnlinkFrames);
-	scrActions["toolsUnlinkTextFrameWithTextCopy"]->setChecked(mode==modeUnlinkFrames);
-	scrActions["toolsUnlinkTextFrameWithTextCut"]->setChecked(mode==modeUnlinkFrames);
+//	scrActions["toolsUnlinkTextFrameWithTextCopy"]->setChecked(mode==modeUnlinkFrames);
+//	scrActions["toolsUnlinkTextFrameWithTextCut"]->setChecked(mode==modeUnlinkFrames);
 	scrActions["toolsEyeDropper"]->setChecked(mode==modeEyeDropper);
 	scrActions["toolsMeasurements"]->setChecked(mode==modeMeasurementTool);
 	scrActions["toolsCopyProperties"]->setChecked(mode==modeCopyProperties);
unlinkcut.diff (10,050 bytes)   

cezaryece

2012-07-10 08:50

updater   ~0028412

In attached patch is solution for that, but not only ;-)

- change UnlinkTextFramesWithTextCut/Copy to normal menu entries (not as tools)
- undo for UnlinkTextFramesWithTextCut/Copy comands
- fix for undo linking frames in case when text from frames is joined - add PARSEP char in place where text is joined
- if empty frame is linked at beginning of chain then after undo text go back to proper frame

cezaryece

2012-07-10 10:39

updater   ~0028415

Reminder sent to: ale, cbradney

For review and commit

cbradney

2012-07-11 21:54

administrator   ~0028425

I'll look at this tomorrow night

ale

2012-07-12 19:55

manager   ~0028429

i haven't tested the undo part, but the undo with cut works correctly, now!
thanks cezary!
i've found another (similar) issue, but i'll post it in a separate ticket

Issue History

Date Modified Username Field Change
2012-07-07 21:14 ale New Issue
2012-07-07 21:14 ale Status new => assigned
2012-07-07 21:14 ale Assigned To => cezaryece
2012-07-10 08:44 cezaryece File Added: unlinkcut.diff
2012-07-10 08:50 cezaryece Note Added: 0028412
2012-07-10 08:52 cezaryece Status assigned => resolved
2012-07-10 08:52 cezaryece Fixed in Version => 1.5.0svn
2012-07-10 08:52 cezaryece Resolution open => fixed
2012-07-10 08:52 cezaryece Status resolved => confirmed
2012-07-10 10:39 cezaryece Note Added: 0028415
2012-07-11 21:54 cbradney Note Added: 0028425
2012-07-12 19:12 cbradney Status confirmed => resolved
2012-07-12 19:55 ale Note Added: 0028429
2012-08-02 19:49 cbradney Status resolved => closed
2015-09-17 20:08 Kunda Category Story Editor / Text Frames => Story Ed/Txt Frames
2015-09-17 20:12 Kunda Category Story Ed/Txt Frames => Story Editor / Text Frames