Shifting All Page Objects

From Scribus Wiki
Jump to navigation Jump to search
This article is part of the Scripts series.

The genesis of this script came from a question about what to do in a situation where one has a Double-Sided layout, with right and left pages, you have already made several, but then you need to add a page somewhere in the middle. The side effect of this is to completely throw off your entire scheme if the lateral page margins are not equal. It's easy enough of course to fix the assignment of Right and Left Master Pages, but what about the main content?

shift_objects.py

What this script does is relatively simple. It makes a list of the items on your selected page, asks you how much you would like to shift, using a default of 40 points (adjusted according to your page units of points, mm, or inches). This somewhat arbitrary amount came from looking at a Gutenberg layout, where inside margins are 40 points and outside are 80 points (at least for US Letter paper).

The next question is which direction to shift. I thought this would be better than specifying, for example, 40 or -40 for the value. I've made it easy by making Left the default, and if you change to anything else, or even just delete the default, then items will shift Right. Note – this isn't quite true, since putting in left will also shift to the left.

Then it loops through the item list and moves all objects on the page – it doesn't matter whether they are selected or not.

If you consistently use some other sort of margins, then you can change the default values, but note that you need to consider the page units.

The action of the script seems to be Undo-able, but since it's really a series of actions, you will need to click Undo as many times as there are objects on the page. Looking at the Action Manager shows this in a listing.

The script

#!/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.
# 
# ****************************************************************************


"""

© 2012 by Gregory Pittman

shift_objects.py


USAGE

Select a page where you need to shift all objects, run script.

The first dialog asks how much to shift, using a distance of 40 points

as the default, but modified to your units.

The second dialog asks whether to shift objects Left (the default), or Right.

Simply enter anything other than Left to shift right.

"""

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)

pageitems = scribus.getAllObjects()
scribus.setRedraw(False)
units = scribus.getUnit()
if units == 0:
    shift = 40
elif units == 1:
    shift = 14.111   # millimeters = points/2.8346
elif units == 2:
    shift = 0.5556   # inches = points/72.0

shiftamount = scribus.valueDialog('Amount of shift?','Enter the amount to shift',str(shift))
shiftamount = float(shiftamount)

shiftdir = scribus.valueDialog('Direction to shift?','Which direction to shift...\nAny change from default shifts to Right','Left')
if ((shiftdir == 'Left') or (shiftdir == 'left')):
    shiftamount = -shiftamount

for item in pageitems:
    scribus.moveObject(shiftamount, 0, item)

scribus.setRedraw(True)


The script, v2

In the second version, you can now specify a list of pages to perform the shift on. Since I had to move around some commands, I decided to add this script rather than modify the one above.

You are presented with the default current page, so simply pressing RETURN when the page list dialog shows up will function like the upper script. Make sure you only have whitespace in between the numbers for the pages, so the Python split() function can work properly.

#!/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.
# 
# ****************************************************************************


"""

© 2012 by Gregory Pittman

shift_objects.py


USAGE

Select a page where you need to shift all objects, run script.

The first dialog asks how much to shift, using a distance of 40 points

as the default, but modified to your units.

The second dialog asks whether to shift objects Left (the default), or Right.

Simply enter anything other than Left to shift right.

This version allows for a series of pages to be shifted at once.

"""

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)
page = scribus.currentPage()
scribus.setRedraw(False)
units = scribus.getUnit()
if units == 0:
    shift = 40
elif units == 1:
    shift = 14.111   # millimeters = points/2.8346
elif units == 2:
    shift = 0.5556   # inches = points/72.0

shiftamount = scribus.valueDialog('Amount of shift?','Enter the amount to shift',str(shift))
shiftamount = float(shiftamount)

shiftdir = scribus.valueDialog('Direction to shift?','Which direction to shift...\nAny change from default shifts to Right','Left')
if ((shiftdir == 'Left') or (shiftdir == 'left')):
    shiftamount = -shiftamount

pages = scribus.valueDialog('Pages to Alter','List pages to shift, separated by white space\n(no commas)',str(page))
pagelist = pages.split()

for pg in pagelist:
    scribus.gotoPage(int(pg))
    pageitems = scribus.getAllObjects()
    for item in pageitems:
        scribus.moveObject(shiftamount, 0, item)

scribus.setRedraw(True)


The script, v2.1, for Dummies (and typos)

What I've added here is some protection from entering page numbers that don't exist. Presumably the former script would crash as soon as it got to scribus.gotoPage() with an erroneous page number, so here we detect this, count the errors, skip over these mistakes, then tell you about it at the end.

#!/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.
# 
# ****************************************************************************


"""

© 2012 by Gregory Pittman

shift_objects.py


USAGE

Select a page where you need to shift all objects, run script.

The first dialog asks how much to shift, using a distance of 40 points

as the default, but modified to your units.

The second dialog asks whether to shift objects Left (the default), or Right.

Simply enter anything other than Left to shift right.

This version allows for a series of pages to be shifted at once.

"""

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)
pgerr = 0
pgcount = scribus.pageCount()
page = scribus.currentPage()
scribus.setRedraw(False)
units = scribus.getUnit()
if units == 0:
    shift = 40
elif units == 1:
    shift = 14.111   # millimeters = points/2.8346
elif units == 2:
    shift = 0.5556   # inches = points/72.0

shiftamount = scribus.valueDialog('Amount of shift?','Enter the amount to shift',str(shift))
shiftamount = float(shiftamount)

shiftdir = scribus.valueDialog('Direction to shift?','Which direction to shift...\nAny change from default shifts to Right','Left')
if ((shiftdir == 'Left') or (shiftdir == 'left')):
    shiftamount = -shiftamount

pages = scribus.valueDialog('Pages to Alter','List pages to shift, separated by white space\n(no commas)',str(page))
pagelist = pages.split()

for pg in pagelist:
    if ((int(pg) < 1) or (int(pg) > pgcount)):
        pgerr += 1
    else:
        scribus.gotoPage(int(pg))
        pageitems = scribus.getAllObjects()
        for item in pageitems:
            scribus.moveObject(shiftamount, 0, item)
scribus.setRedraw(True)

if pgerr == 1:
    scribus.messageBox('OOPS!',str(pgerr)+' of the pages you entered was\n outside the range of the document\n and therefore ignored.',scribus.ICON_WARNING, scribus.BUTTON_OK)
if pgerr > 1:
    scribus.messageBox('OOPS!',str(pgerr)+' of the pages you entered were\n outside the range of the document\n and therefore ignored.',scribus.ICON_WARNING, scribus.BUTTON_OK)

The script, v3

You can always make scripts better as long as you don't break them. This version presumes that you may need to shift every other page in your document, starting at the point where you inserted a new page.

To make use of the feature, when you get to the dialog to enter a list of pages, enter either odd or even (it actually doesn't matter which you choose), then you get a new dialog asking where to start, the default being the currently selected page. Then the script makes a list of every other page from that point to the end of the document, and the shifting begins. If the starting page is odd, you will shift odd pages, and likewise for an even numbered starting page. The script simply takes your starting number, then adds 2 for each page number afterward.

#!/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.
# 
# ****************************************************************************


"""

© 2012 by Gregory Pittman

shift_obj3.py


USAGE

Select a page where you need to shift all objects, run script.

The first dialog asks how much to shift, using a distance of 40 points

as the default, but modified to your units.

The second dialog asks whether to shift objects Left (the default), or Right.

Simply enter anything other than Left to shift right.

This version allows for a series of pages to be shifted at once.

Enter odd or even to shift every other page to the end.

"""

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)
pgerr = 0
pgcount = scribus.pageCount()
page = scribus.currentPage()
scribus.setRedraw(False)
units = scribus.getUnit()
if units == 0:
    shift = 40
elif units == 1:
    shift = 14.111   # millimeters = points/2.8346
elif units == 2:
    shift = 0.5556   # inches = points/72.0

shiftamount = scribus.valueDialog('Amount of shift?','Enter the amount to shift',str(shift))
shiftamount = float(shiftamount)

shiftdir = scribus.valueDialog('Direction to shift?','Which direction to shift...\nAny change from default shifts to Right','Left')
if ((shiftdir == 'Left') or (shiftdir == 'left')):
    shiftamount = -shiftamount

pages = scribus.valueDialog('Pages to Alter','List pages to shift, separated by white space\n(no commas)\nEnter odd or even for every other page',str(page))

if (pages == 'odd') or (pages == 'even'):
    startpage = scribus.valueDialog('Odd/Even','Where to start?\n(Just a single page number)',str(page))
    pgadd = int(startpage)
    pagelist = []
    while pgadd <= pgcount:
        pagelist.append(str(pgadd))
        pgadd += 2
else:
    pagelist = pages.split()

for pg in pagelist:
    if ((int(pg) < 1) or (int(pg) > pgcount)):
        pgerr += 1
    else:
        scribus.gotoPage(int(pg))
        pageitems = scribus.getAllObjects()
        for item in pageitems:
            scribus.moveObject(shiftamount, 0, item)
scribus.setRedraw(True)

if pgerr == 1:
    scribus.messageBox('OOPS!',str(pgerr)+' of the pages you entered was\n outside the range of the document\n and therefore ignored.',scribus.ICON_WARNING, scribus.BUTTON_OK)
if pgerr > 1:
    scribus.messageBox('OOPS!',str(pgerr)+' of the pages you entered were\n outside the range of the document\n and therefore ignored.',scribus.ICON_WARNING, scribus.BUTTON_OK)

The script, v3.1

I guess it's hard to know if I'll ever make a final version of this script.

Here we add a new tweak – let's imagine you have a series of pages to shift, starting somewhere in the middle, but you don't need to go all the way to the end. Maybe you have added some blank pages which you are going to delete, which will fix the shifting from some point onward. For example, you have a 100 page document and added a page after page 9, but with the deletion of page 80, you don't want to go beyond that point. So what you want to do is specify a range, but only indicate the start and end.

Here are your options:

  • Specify the amount of shift.
  • Next the direction, Left or Right.
  • Now, when asked for a page list, enter odd or even.
  • You are now shown a default of your currently selected page, let's say it was 11, then white space, then the last page: 11 100.
    Type in 11 79 – just white space, no comma in between.
  • That's it. Now repeat for your range of even pages, 12 to 79 (12 to 78 should produce the same result). Remember, the starting page number determines whether you will be shifting odd or even pages.

I think it's a good idea to select the page where you want to start before starting the the script, so that it helps you with the default values.

Something to notice is that even though the script has gotten more complex, it will still operate in a simple way if you only want to shift the currently selected page – when you get to the page list, just press RETURN, and you're finished. Also note that our usage would have been the same if we had moved page 80 to become the new page 11, except our ranges would have needed to be 11 to 79 and 12 to 80.

#!/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.
# 
# ****************************************************************************


"""

© 2012 by Gregory Pittman

shift_obj3.py


USAGE

Select a page where you need to shift all objects, run script.

The first dialog asks how much to shift, using a distance of 40 points

as the default, but modified to your units.

The second dialog asks whether to shift objects Left (the default), or Right.

Simply enter anything other than Left to shift right.

This version allows for a series of pages to be shifted at once.

Enter odd or even to shift every other page to the end.

In this version, you can specify a range of even or odd pages, with beginning and end of that range.

"""

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)
pgerr = 0
pgcount = scribus.pageCount()
page = scribus.currentPage()
scribus.setRedraw(False)
units = scribus.getUnit()
if units == 0:
    shift = 40
elif units == 1:
    shift = 14.111   # millimeters = points/2.8346
elif units == 2:
    shift = 0.5556   # inches = points/72.0

shiftamount = scribus.valueDialog('Amount of shift?','Enter the amount to shift',str(shift))
shiftamount = float(shiftamount)

shiftdir = scribus.valueDialog('Direction to shift?','Which direction to shift...\nAny change from default shifts to Right','Left')
if ((shiftdir == 'Left') or (shiftdir == 'left')):
    shiftamount = -shiftamount

pages = scribus.valueDialog('Pages to Alter','List pages to shift, separated by white space\n(no commas)\nEnter odd or even for every other page',str(page))

if (pages == 'odd') or (pages == 'even'):
    startendpages = scribus.valueDialog('Odd/Even','Where to start (and end)?\n(One or 2 page numbers, separated by white space)',str(page) + ' ' +str(pgcount))
    startend = startendpages.split()
    pgadd = int(startend[0])
    if (startend[1] != ""):
        pgcount = int(startend[1])
    pagelist = []
    while pgadd <= pgcount:
        pagelist.append(str(pgadd))
        pgadd += 2
else:
    pagelist = pages.split()

for pg in pagelist:
    if ((int(pg) < 1) or (int(pg) > pgcount)):
        pgerr += 1
    else:
        scribus.gotoPage(int(pg))
        pageitems = scribus.getAllObjects()
        for item in pageitems:
            scribus.moveObject(shiftamount, 0, item)
scribus.setRedraw(True)

if pgerr == 1:
    scribus.messageBox('OOPS!',str(pgerr)+' of the pages you entered was\n outside the range of the document\n and therefore ignored.',scribus.ICON_WARNING, scribus.BUTTON_OK)
if pgerr > 1:
    scribus.messageBox('OOPS!',str(pgerr)+' of the pages you entered were\n outside the range of the document\n and therefore ignored.',scribus.ICON_WARNING, scribus.BUTTON_OK)