Setting Text Distances from a Script

From Scribus Wiki
Jump to navigation Jump to 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.
A dialog asks for the amount of text distance.

"""

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.

I could save some lines by doing this:

scribus.setTextDistances = (float(distance[0]), float(distance[1]), float(distance[2]), float(distance[3]))

but this makes later review, editing, and understanding of the script more difficult.

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, Scribus would redraw and place the text inside the distances, but then I'd have to move it back. So here the script does it, and voilà! It just works.

A new version

Seth Kenlon has contributed a modified version that will set text distances on a number of selected frames. Note that this version does not check to see if all the selected frames are text frames. If they are not, you will get a WrongFrameType error.

#!/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
* 2019 modified by Seth Kenlon <skenlon@redhat.com> 

setmultiframetextdistances.py

Sets the text distances of selected text frames

USAGE

Select one or more text frames, and then run this script.
A dialog asks for the amount of text distance.

"""

import sys

try:
    import scribus
except ImportError:
    print("Unable to import the 'scribus' module. This script only runs within 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', "Select a text frame and try again.", scribus.ICON_WARNING, scribus.BUTTON_OK)
    sys.exit(2)

# use CSS order for values (N E S W)
distances = scribus.valueDialog("Text Distance", 'Enter text padding values (in current page units) delimited by white space.\nTop Right Bottom Left', '0.2  0.2  0.2  0.2')
distance = distances.split()
distancetop = float(distance[0])
distanceright = float(distance[1])
distancebottom = float(distance[2])
distanceleft = float(distance[3])

n = scribus.selectionCount()

for i in range(0, n):
    textbox = scribus.getSelectedObject(i)
    scribus.setRedraw(False)
    scribus.setTextDistances(distanceleft,distanceright,distancetop,distancebottom,textbox)

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

    scribus.setRedraw(True)