View Issue Details

IDProjectCategoryView StatusLast Update
0015911ScribusScripterpublic2019-12-08 21:24
Reporterm.uhlenberg Assigned Tojghali  
PrioritynormalSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Product Version1.5.6.svn 
Fixed in Version1.5.6.svn 
Summary0015911: After calling insertText(), getText() does not show all characters
DescriptionI have a textframe with several templates. When the first template is expanded in situ, I can see the following text with getAllText, but most often not with getText. The functions getTextLength, getStyle work as expected and show the correct length and style, but getText normally returns an empty string. I was looking for a flush-function, and it appears that e.g. saveDoc has some effect, but it cannot be relied on.
This bug prevents my program to expand more than one template. I would also appreciate a workaround.
Steps To ReproduceTo see this, open a textframe, insert "abcde" into it, and start scribtest.py. This program inserts "12345" before "abcde". getAllText then shows "12345abcde", but getText only "12345".
TagsNo tags attached.
PatchNo

Activities

m.uhlenberg

2019-11-04 17:25

reporter  

scribtest.py (2,100 bytes)   
import sys

try:
    import scribus
except ModuleNotFoundError:
    raise ImportError

if not scribus.haveDoc():
    scribus.messageBox('Scribus - Script Error', "No document open", scribus.ICON_WARNING, scribus.BUTTON_OK)
    sys.exit(1)

if scribus.selectionCount() == 0:
    scribus.messageBox('Scribus - Script Error',
                       "There is no object selected.\nPlease select a text frame and try again.",
                       scribus.ICON_WARNING, scribus.BUTTON_OK)
    sys.exit(2)
if scribus.selectionCount() > 1:
    scribus.messageBox('Scribus - Script Error',
                       "You have more than one object selected.\nPlease select one text frame and try again.",
                       scribus.ICON_WARNING, scribus.BUTTON_OK)
    sys.exit(2)

textbox = scribus.getSelectedObject()
ftype = scribus.getObjectType(textbox)

if ftype != "TextFrame":
    scribus.messageBox('Scribus - Script Error', "This is not a textframe. Try again.", scribus.ICON_WARNING,
                       scribus.BUTTON_OK)
    sys.exit(2)


len1 = scribus.getTextLength(textbox)
if len1 < 5:
    scribus.messageBox('Scribus - Script Error', "Textframe should contain a few characters already. Try again.", scribus.ICON_WARNING,
                       scribus.BUTTON_OK)
    sys.exit(2)

scribus.insertText("12345", 0, textbox)
# need a "flush" function here? saveDoc has a limited effect in the general case
#scribus.saveDocAs("test1.sla")
#scribus.docChanged(True)

len2 = scribus.getTextLength(textbox)
if len2 != len1 + 5:
    scribus.messageBox('Scribus - Script Error', "Expected textLength to increase by 5.", scribus.ICON_WARNING,
                       scribus.BUTTON_OK)

# this should print 12345xxxxx, where xxxxx are the former first 5 chars
res1 = scribus.getAllText(textbox)
scribus.selectText(0, 10,textbox)
res2 = scribus.getText(textbox)
scribus.messageBox('Scribus - Test Result', "Text length=" + str(len2) + ", getAlltext: " + res1 + ", getText: " + res2, scribus.ICON_WARNING,
                       scribus.BUTTON_OK)
scribtest.py (2,100 bytes)   

jghali

2019-11-05 00:56

administrator   ~0046962

There can be indeed a need to update text layout after specific calls such as insertText(). Scripter's getText() use the layout information to return only text shown in the frame and text layout is normally not updated while a script is running.

I have consequently added a new layoutText() function so as to be able to update layout when needed. That means you will need to call this new function after calling insertText() and before calling getText():
scribus.layoutText(textbox)

m.uhlenberg

2019-11-06 08:59

reporter   ~0046990

layoutText does indeed work for the small testscript. But I produce from the first template some 25000 characters in 8 new pages, in a loop "while textOverflows: createNewPage", where createNewPage calls getMasterPage, newPage, gotoPage, createText, linkTextFrames. The position of the second template thus changes from ca. 300 to 25000. layoutText() has apparently no effect, when I getText the second template. getText still returns only empty strings. There are more templates after the second, and astonishingly getText returns parts of some of them!?
But I have a workaround, where I use getAllText instead of getText, so this has now low priority for me.
As an aside:
I go through the templates one character at a time, collecting all characters with the same paragraph and character style in a "run". Parameters are then expanded and the expanded strings are inserted with insertText, setStyle and setCharacterStyle. This works nicely, but of course only, if the function getCharacterStyle is in scribus. Without getCharacterStyle, I would have to call getFont, getFontSize, getTextColor for each (!) character, and still miss something.

jghali

2019-11-06 11:15

administrator   ~0046994

Last edited: 2019-11-06 11:43

For linked text frames, you have to call layoutText() on all frames of the chain for updating text layout of the whole text chain. layoutText() updates text layout only for a specific box.

jghali

2019-11-06 11:52

administrator   ~0046995

Last edited: 2019-11-06 12:23

I have added a convenience layoutTextChain() function for updating text layout for the whole chain a specific text frame belongs:
scribus.layoutTextChain(textbox)

m.uhlenberg

2019-11-06 12:34

reporter   ~0046997

Thank you. I just added a call to layoutText(newframe) right after linkTextFrames(textbox, newframe). No effect. I found no other script functions to follow frame links. Perhaps I have to go otherwise through all pages, all pageitems, all textframes and call layoutText on each of them.
But now it also occurred to me that a template might cross a page/textframe boundary after expansion of a previous template. Not sure what the ramifications are.
Have to do more thinking.
Anyway, I will try layoutTextChain soon, and I hope, I do not keep you from more important work.

m.uhlenberg

2019-11-06 13:18

reporter   ~0046998

After some thinking: Spreading text across new textframes for overflown textframes while continuing to work on the text causes too many problems. Rather, I stay with one large textframe until all templates are expanded, then create the pages and textframes. As getText does not return text in overflown text, I just cannot use it then. Nevertheless, getStyle/getFont/getFontSize do work fortunately for overflown text. That the one works and the other not, is still a bit surprising for me.

Issue History

Date Modified Username Field Change
2019-11-04 17:25 m.uhlenberg New Issue
2019-11-04 17:25 m.uhlenberg File Added: scribtest.py
2019-11-05 00:49 jghali Summary after insertText getText does not show all characters => After calling insertText(), getText() does not show all characters
2019-11-05 00:49 jghali Description Updated
2019-11-05 00:49 jghali Steps to Reproduce Updated
2019-11-05 00:56 jghali Assigned To => jghali
2019-11-05 00:56 jghali Status new => resolved
2019-11-05 00:56 jghali Resolution open => fixed
2019-11-05 00:56 jghali Fixed in Version => 1.5.6.svn
2019-11-05 00:56 jghali Note Added: 0046962
2019-11-06 08:59 m.uhlenberg Status resolved => feedback
2019-11-06 08:59 m.uhlenberg Resolution fixed => reopened
2019-11-06 08:59 m.uhlenberg Note Added: 0046990
2019-11-06 11:15 jghali Status feedback => resolved
2019-11-06 11:15 jghali Resolution reopened => fixed
2019-11-06 11:15 jghali Note Added: 0046994
2019-11-06 11:43 jghali Note Edited: 0046994
2019-11-06 11:52 jghali Note Added: 0046995
2019-11-06 12:23 jghali Note Edited: 0046995
2019-11-06 12:34 m.uhlenberg Note Added: 0046997
2019-11-06 13:18 m.uhlenberg Note Added: 0046998
2019-12-08 21:24 cbradney Status resolved => closed