Setting Text Distances from a Script

From Scribus Wiki
Revision as of 02:41, 10 November 2015 by Gpittman (talk | contribs) (Oh yes, there's some voodoo here too!)
Jump to: navigation, search
This article is part of the Scripts series.

Here is a simple script for setting the text distances for a text frame. In this particular version, we set all the distances the same, so only one value is needed for the value.Dialog().

settextdistance.py

#!/usr/bin/env python
# -*- coding: utf-8  -*-

# ****************************************************************************
#  This program is free software; you can redistribute it and/or modify 
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# 
# ****************************************************************************


"""

© 2015 by Gregory Pittman

settextdistance.py

Sets the text distances of the selected text frame

USAGE

Select a text frame, run script.

"""

try:
    import scribus
except ImportError:
    print "Unable to import the 'scribus' module. This script will only run within"
    print "the Python interpreter embedded in Scribus. Try Script->Execute Script."
    sys.exit(1)

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)
    
distance = scribus.valueDialog("Text Distance", 'Enter your text distance', '10')
distance = float(distance)
distanceleft = distance
distanceright = distance
distancetop = distance
distancebottom = distance

textbox = scribus.getSelectedObject()
pageitems = scribus.getPageItems()
scribus.setRedraw(False)

for item in pageitems:
    if (item[0] == textbox):
        if (item[1] != 4):
            scribus.messageBox('Scribus - Script Error', 
                          "This is not a textframe. Try again.", scribus.ICON_WARNING, scribus.BUTTON_OK)
            sys.exit(2)
            
        scribus.setTextDistances(distanceleft,distanceright,distancetop,distancebottom,textbox)
        scribus.moveObject(-4,0,textbox)
        scribus.moveObject(4,0,textbox)
scribus.setRedraw(True)

More complex but more versatile

What if we didn't want all the distances to be the same? Look at this modification of the distance value.Dialog(), and subsequent lines:

distances = scribus.valueDialog("Text Distance", 'Enter your text distances,\n white space in between.\nLeft Right Top Bottom', '10  10  10  10')
distance = distances.split()
distanceleft = float(distance[0])
distanceright = float(distance[1])
distancetop = float(distance[2])
distancebottom = float(distance[3])

We could use int(distance...), but using float allows for decimals - whatever you enter into the dialog will be a string until converted, and the setTextDistances() command needs number values. In case you haven't used the built-in split function in Python, this breaks a series of values or words into a list, eliminating the white space (which can be of variable length). So here we create the list distance[] from the 4 values. I think this is more efficient than making a series of value.Dialogs.

Oh yes, there's some voodoo here too!

Look at these lines:

        scribus.moveObject(-4,0,textbox)
        scribus.moveObject(4,0,textbox)

I move the text frame, then I move it back! Doesn't make sense, does it? For whatever reason, if I didn't put these in there, Scribus wouldn't redraw the frame, and I don't know why. If you're thinking that it's because I forgot the redrawAll()' command, think again. I tried various combinations of setRedraw(True/False), and nothing worked.

What I found out was that if I moved the frame after the script ran, then moved it back, Scribus would redraw and place the text inside the distances. So here I just tell the script to do it, and voilà! It just works.