View Issue Details

IDProjectCategoryView StatusLast Update
0016801ScribusScripterpublic2023-05-29 18:56
ReporterMattMiller Assigned Tojghali  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version1.6.0.svn 
Fixed in Version1.6.0.svn 
Summary0016801: linkTextFrames() documentation vs GUI
DescriptionThe behavior of the scripter function linkTextFrames() is different from the documented behavior, and also different from the behavior of the GUI "Item | Text Frame Links | Link Text Frames" menu option. The attached two patches are two alternative fixes. linkTextFrames_same_as_GUI.txt makes the scripter function behave the same as the GUI, and linkTextFrames_with_force.txt adds an optional flag to give a choice whether the scripter function behaves the same as the GUI.

The problem centers around what checks the scripter function should perform on the target frame. Currently the documented behavior is that scripter will not allow the to target frame to contain any text or to already link to another frame. However, the actual current behavior is that only the second of these checks is performed. In the code the first check is still there, but it's commented. Also, the GUI seems to perform neither of these checks, and allows the target frame have text and to already link to another frame. I think the simplest solution is to remove both of these checks from the scripter code, and update the documentation accordingly. That's the solution of the "linkTextFrames_same_as_GUI.txt" patch file.

The alternative patch file, "linkTextFrames_with_force.txt," adds a new optional "force" flag at the end of the linkTextFrames() argument list. If the new flag is omitted or passed as zero then both checks are applied. In other words, if you don't set the "force" flag then the scripter behaves as it's currently documented, and requires that the target frame be empty and not link to another frame. If you set the new flag then neither check is performed, and the function ends up behaving the same as the GUI.
Tagsscripter
PatchYes

Activities

MattMiller

2022-06-01 21:19

reporter  

linkTextFrames_same_as_GUI.txt (1,842 bytes)   
Index: doc/en/scripterapi-textframes.html
===================================================================
--- doc/en/scripterapi-textframes.html	(revision 25096)
+++ doc/en/scripterapi-textframes.html	(working copy)
@@ -134,7 +134,7 @@
 
 <dt><a name="-linkTextFrames"><strong>linkTextFrames</strong></a>(...)</dt>
 <dd><code>linkTextFrames("fromname", "toname")</code>
-<p>Link two text frames. The frame named "fromname" is linked to the frame named "toname". The target frame must be an empty text frame and must not link to or be linked from any other frames already.</p>
+<p>Link two text frames. The frame named "fromname" is linked to the frame named "toname".</p>
 <p>May throw <a href="#ScribusException">ScribusException</a> if linking rules are violated.</p></dd>
 
 <dt><a name="-selectFrameText"><strong>selectFrameText</strong></a>(...)</dt>
Index: scribus/plugins/scriptplugin/cmdtext.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdtext.cpp	(revision 25096)
+++ scribus/plugins/scriptplugin/cmdtext.cpp	(working copy)
@@ -1297,16 +1297,6 @@
 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Can only link text frames.","python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-/*	if (toitem->itemText.length() > 0)
-	{
-		PyErr_SetString(ScribusException, QObject::tr("Target frame must be empty.","python error").toLocal8Bit().constData());
-		return nullptr;
-	}*/
-	if (toitem->nextInChain() != nullptr)
-	{
-		PyErr_SetString(ScribusException, QObject::tr("Target frame links to another frame.","python error").toLocal8Bit().constData());
-		return nullptr;
-	}
 	if (toitem->prevInChain() != nullptr)
 	{
 		PyErr_SetString(ScribusException, QObject::tr("Target frame is linked to by another frame.","python error").toLocal8Bit().constData());
linkTextFrames_same_as_GUI.txt (1,842 bytes)   
linkTextFrames_with_force.txt (2,786 bytes)   
Index: doc/en/scripterapi-textframes.html
===================================================================
--- doc/en/scripterapi-textframes.html	(revision 25096)
+++ doc/en/scripterapi-textframes.html	(working copy)
@@ -133,8 +133,8 @@
 <p>Relayout the whole text chain whom the text frame "name" belongs. If "name" is not given the currently selected item is used.</p></dd>
 
 <dt><a name="-linkTextFrames"><strong>linkTextFrames</strong></a>(...)</dt>
-<dd><code>linkTextFrames("fromname", "toname")</code>
-<p>Link two text frames. The frame named "fromname" is linked to the frame named "toname". The target frame must be an empty text frame and must not link to or be linked from any other frames already.</p>
+<dd><code>linkTextFrames("fromname", "toname", [force])</code>
+<p>Link two text frames. The frame named "fromname" is linked to the frame named "toname". If "force" is omitted or set to zero then the target frame must be an empty text frame and must not link to or be linked from any other frames already.</p>
 <p>May throw <a href="#ScribusException">ScribusException</a> if linking rules are violated.</p></dd>
 
 <dt><a name="-selectFrameText"><strong>selectFrameText</strong></a>(...)</dt>
Index: scribus/plugins/scriptplugin/cmdtext.cpp
===================================================================
--- scribus/plugins/scriptplugin/cmdtext.cpp	(revision 25096)
+++ scribus/plugins/scriptplugin/cmdtext.cpp	(working copy)
@@ -1281,8 +1281,9 @@
 {
 	char *name1;
 	char *name2;
+        bool force
 
-	if (!PyArg_ParseTuple(args, "eses", "utf-8", &name1, "utf-8", &name2))
+	if (!PyArg_ParseTuple(args, "eses|b", "utf-8", &name1, "utf-8", &name2, &force))
 		return nullptr;
 	if (!checkHaveDocument())
 		return nullptr;
@@ -1297,15 +1298,18 @@
 		PyErr_SetString(WrongFrameTypeError, QObject::tr("Can only link text frames.","python error").toLocal8Bit().constData());
 		return nullptr;
 	}
-/*	if (toitem->itemText.length() > 0)
-	{
-		PyErr_SetString(ScribusException, QObject::tr("Target frame must be empty.","python error").toLocal8Bit().constData());
-		return nullptr;
-	}*/
-	if (toitem->nextInChain() != nullptr)
-	{
-		PyErr_SetString(ScribusException, QObject::tr("Target frame links to another frame.","python error").toLocal8Bit().constData());
-		return nullptr;
+        if (!force)
+        {
+		if (toitem->itemText.length() > 0)
+		{
+			PyErr_SetString(ScribusException, QObject::tr("Target frame must be empty.","python error").toLocal8Bit().constData());
+			return nullptr;
+		}
+		if (toitem->nextInChain() != nullptr)
+		{
+			PyErr_SetString(ScribusException, QObject::tr("Target frame links to another frame.","python error").toLocal8Bit().constData());
+			return nullptr;
+		}
 	}
 	if (toitem->prevInChain() != nullptr)
 	{
linkTextFrames_with_force.txt (2,786 bytes)   

jghali

2022-06-05 17:15

administrator   ~0049684

In fact, following check is wrong: if (toitem->nextInChain() != nullptr). This check should not be performed on toitem but on fromitem. if simply suppressed, an assertion will be triggered in PageItem::link() if fromitem is already linked to another frame.

jghali

2022-06-05 17:27

administrator   ~0049685

So I fixed the wrong check mentioned above + documentation.

Issue History

Date Modified Username Field Change
2022-06-01 21:19 MattMiller New Issue
2022-06-01 21:19 MattMiller Tag Attached: scripter
2022-06-01 21:19 MattMiller File Added: linkTextFrames_same_as_GUI.txt
2022-06-01 21:19 MattMiller File Added: linkTextFrames_with_force.txt
2022-06-05 17:15 jghali Note Added: 0049684
2022-06-05 17:26 jghali Summary linkTextFrames() vs Documentation vs GUI => linkTextFrames() documentation vs GUI
2022-06-05 17:27 jghali Assigned To => jghali
2022-06-05 17:27 jghali Status new => resolved
2022-06-05 17:27 jghali Resolution open => fixed
2022-06-05 17:27 jghali Fixed in Version => 1.6.0.svn
2022-06-05 17:27 jghali Note Added: 0049685
2023-05-29 18:56 cbradney Status resolved => closed