View Issue Details

IDProjectCategoryView StatusLast Update
0008907ScribusScripterpublic2010-03-06 11:14
ReporterOssiLehtinen Assigned To 
PrioritynormalSeveritymajorReproducibilityalways
Status newResolutionopen 
PlatformLinuxOSUbuntuOS Version9.10
Product Version1.5.0svn 
Summary0008907: A text frame's line count doesn't seem to be updated while a script is running
DescriptionI'm trying to adjust font size and line spacing of a text frame in a script based on the number of lines in the frame.

It appears that getTextLines returns something incorrect. I think it doesn't keep track of changes that have happened during script execution.
Steps To ReproduceI attached a simple script to demonstrate the problem. You need to have an open (empty) document open when running the script.

The script creates first one text frame and inserts some random text. Next it creates another frame and prints the first frames line count in that one. This results in number 0 in the frame, which is obviously incorrect.

If afterwards one runs in the Scribus console

insertText(str(getTextLines("aa")), -1, "bb")

the correct number is entered.

I would try to fix this myself also, as this seriously hampers the usefulness of getTextLines, but frankly, I can't figure out where to look :)
TagsNo tags attached.
Patch

Activities

OssiLehtinen

2010-03-06 10:13

reporter  

getTextLinesProb.py (1,452 bytes)   
#!/usr/bin/env python
# -*- coding: utf-8 -*-


qfile = "kysymykset/tiede.txt"
frontimg = "kuvat/tiede_etu.jpg"
backimg = "kuvat/tiede_taka.jpg"
savename = "tiede.sla"
fontti = "Station Medium"
fonttinum = "DejaVu Sans Bold"
fonttinum = "Arial Black Regular"
catnum = 100
cw = 4.0167
ch = 2.9933

try:
    # Please do not use 'from scribus import *' . If you must use a 'from import',
    # Do so _after_ the 'import scribus' and only import the names you need, such
    # as commonly used constants.
    import scribus
except ImportError,err:
    print "This Python script is written for the Scribus scripting interface."
    print "It can only be run from within Scribus."
    sys.exit(1)

#def main(argv):
#    """This is a simple way to demonstrate creating a doc on the fly. """

#    pass    # <--- Delete this line
#########################
# YOUR IMPORTS GO HERE  #
#########################

import sys

try:
    from scribus import *
except ImportError:
    print "This script only runs from within Scribus."
    sys.exit(1)



def main():


	# Create a text frame with some text inside it
	createText(100.9019, 100.9190, 100.1549, 100.1549, "aa")
	setText("okwef woif weiofj wefioj weofi jwefio jwf ", "aa")
	
	# Create another text frame and insert the number of lines in the previous one
	createText(250.9019, 100.9190, 100.1549, 100.1549, "bb")
	insertText(str(getTextLines("aa")), -1, "bb")
	

	
		
if __name__ == '__main__':
    main()
getTextLinesProb.py (1,452 bytes)   

OssiLehtinen

2010-03-06 10:20

reporter  

getTextLinesProb2.py (1,475 bytes)   
#!/usr/bin/env python
# -*- coding: utf-8 -*-


qfile = "kysymykset/tiede.txt"
frontimg = "kuvat/tiede_etu.jpg"
backimg = "kuvat/tiede_taka.jpg"
savename = "tiede.sla"
fontti = "Station Medium"
fonttinum = "DejaVu Sans Bold"
fonttinum = "Arial Black Regular"
catnum = 100
cw = 4.0167
ch = 2.9933

try:
    # Please do not use 'from scribus import *' . If you must use a 'from import',
    # Do so _after_ the 'import scribus' and only import the names you need, such
    # as commonly used constants.
    import scribus
except ImportError,err:
    print "This Python script is written for the Scribus scripting interface."
    print "It can only be run from within Scribus."
    sys.exit(1)

#def main(argv):
#    """This is a simple way to demonstrate creating a doc on the fly. """

#    pass    # <--- Delete this line
#########################
# YOUR IMPORTS GO HERE  #
#########################

import sys

try:
    from scribus import *
except ImportError:
    print "This script only runs from within Scribus."
    sys.exit(1)



def main():

	gotoPage(1)
	# Create a text frame with some text inside it
	createText(100.9019, 100.9190, 100.1549, 100.1549, "aa")
	setText("okwef woif weiofj wefioj weofi jwefio jwf ", "aa")
	# Create another text frame and insert the number of lines in the previous one
	createText(250.9019, 100.9190, 100.1549, 100.1549, "bb")
	insertText(str(getTextLines("aa")), -1, "bb")
	gotoPage(2)
	

	
		
if __name__ == '__main__':
    main()
getTextLinesProb2.py (1,475 bytes)   

OssiLehtinen

2010-03-06 10:25

reporter   ~0023463

I noticed something else about this as well. The linecount seems to be updated only if the text frame in question is visible in the ui.

A way to show this is to make a two page document, scroll down so that only the second page is visible, run the script getTextLineProb2.py and then in the console

insertText(str(getTextLines("aa")), -1, "bb")

Now we get only zeros in the second frame as the handled text frames were never visible.

Note: This doesn't seem to have anything to do with the page selection. If I zoom out so that both pages are visible, but keep page 2 selected. The frame gets the correct number after the console command.

p.s. In hindsight, perhaps this isn't a major bug in severity, but it feels major right now :)

OssiLehtinen

2010-03-06 10:51

reporter   ~0023464

Ok after digging around, it seems that one has to call item->layout() in the scripter functions to get things updated.

I tested this with the insertText and setText functions and it appears to work now. This needs to be added to all the text manipulation functions though.

The layout function seems pretty 'big'. I'm worried it might make the scripter a lot slower to call it every time something is done. Perhaps not. An alternative would be to ad another scripter function which would explicitely update the layout info.

OssiLehtinen

2010-03-06 11:13

reporter  

insertTextfix.diff (2,903 bytes)   
Index: Scribus/scribus/plugins/scriptplugin/cmdtext.cpp
===================================================================
--- Scribus/scribus/plugins/scriptplugin/cmdtext.cpp	(revision 14797)
+++ Scribus/scribus/plugins/scriptplugin/cmdtext.cpp	(working copy)
@@ -1121,6 +1121,33 @@
 	return PyBool_FromLong(0);
 }
 
+/*
+ * Updates items layout data.
+ * 6.3.2010: Ossi Lehtinen
+ */
+PyObject *scribus_updatelayoutdata(PyObject* /* self */, PyObject* args)
+{
+	char *Name = const_cast<char*>("");
+	char *Text;
+	if (!PyArg_ParseTuple(args, "|es", "utf-8", &Name))
+		return NULL;
+	if(!checkHaveDocument())
+		return NULL;
+	PageItem *currItem = GetUniqueItem(QString::fromUtf8(Name));
+	if (currItem == NULL)
+		return NULL;
+	if (!(currItem->asTextFrame()) && !(currItem->asPathText()))
+	{
+		PyErr_SetString(WrongFrameTypeError, QObject::tr("Cannot update layout data of non-text frame.","python error").toLocal8Bit().constData());
+		return NULL;
+	}
+
+	currItem->layout();
+	Py_RETURN_NONE;
+}
+
+
+
 /*! HACK: this removes "warning: 'blah' defined but not used" compiler warnings
 with header files structure untouched (docstrings are kept near declarations)
 PV */
Index: Scribus/scribus/plugins/scriptplugin/cmdtext.h
===================================================================
--- Scribus/scribus/plugins/scriptplugin/cmdtext.h	(revision 14797)
+++ Scribus/scribus/plugins/scriptplugin/cmdtext.h	(working copy)
@@ -441,4 +441,14 @@
 /*! Is PDF bookmark? */
 PyObject *scribus_ispdfbookmark(PyObject * /*self*/, PyObject* args);
 
+/*! docstring */
+PyDoc_STRVAR(scribus_updatelayoutdata__doc__,
+QT_TR_NOOP("updateLayoutData( [\"name\"])\n\
+\n\
+Updates the text frame \"name\"'s layout data so that getTextLines and such return up to date values. If \"name\" is\n\
+not given the currently selected Item is used.\n\
+"));
+/*! Insert text */
+PyObject *scribus_updatelayoutdata(PyObject * /*self*/, PyObject* args);
+
 #endif
Index: Scribus/scribus/plugins/scriptplugin/scriptplugin.cpp
===================================================================
--- Scribus/scribus/plugins/scriptplugin/scriptplugin.cpp	(revision 14797)
+++ Scribus/scribus/plugins/scriptplugin/scriptplugin.cpp	(working copy)
@@ -507,6 +507,7 @@
 // 	{const_cast<char*>("getChild"), (PyCFunction)scribus_getchild, METH_KEYWORDS, tr(scribus_getchild__doc__)},
 	// by Christian Hausknecht
 	{const_cast<char*>("duplicateObject"), scribus_duplicateobject, METH_VARARGS, tr(scribus_duplicateobject__doc__)},
+	{const_cast<char*>("updateLayoutData"), scribus_updatelayoutdata, METH_VARARGS, tr(scribus_updatelayoutdata__doc__)},
 	// Internal methods - Not for public use
 	{const_cast<char*>("retval"), (PyCFunction)scribus_retval, METH_VARARGS, const_cast<char*>("Scribus internal.")},
 	{const_cast<char*>("getval"), (PyCFunction)scribus_getval, METH_NOARGS, const_cast<char*>("Scribus internal.")},
insertTextfix.diff (2,903 bytes)   

OssiLehtinen

2010-03-06 11:14

reporter   ~0023465

I uploaded a patch which adds a function updateLayoutData to the scripter, which will do what the name implies. Don't know if this is the right way to go, but at least it works for me :) Cheers.

Issue History

Date Modified Username Field Change
2010-03-06 10:13 OssiLehtinen New Issue
2010-03-06 10:13 OssiLehtinen File Added: getTextLinesProb.py
2010-03-06 10:20 OssiLehtinen File Added: getTextLinesProb2.py
2010-03-06 10:25 OssiLehtinen Note Added: 0023463
2010-03-06 10:51 OssiLehtinen Note Added: 0023464
2010-03-06 11:13 OssiLehtinen File Added: insertTextfix.diff
2010-03-06 11:14 OssiLehtinen Note Added: 0023465