Tuesday, May 21, 2013

Changing the canvas size of all canvases with AppleScript

***
Update (07/20/2013): a new version of this script that prompts for the new canvas size (rather than changing the variable in the script) appears after the jump.
***

Here's another useful AppleScript script for changing all canvases in your document to a given size.

First, some important notes about page size vs. canvas size:

Changing your canvas size does not change your page size, which is defined in Page Setup as the paper size you print to. You can have multiple pages on a canvas, and you will if you set the canvas size larger than the paper size from Page Setup

Also, the variables <%#%> (page number) and <%TotalPages%> report their values based on number of pages in the document, not the number canvases. However, if you check the "Print canvas on one printer sheet" checkbox in the Canvas > Size inspector, then these variables consider a multi-page canvas a single page.

So if you are manually setting the canvas size this script does, and you only want one page per canvas, you'll want to do two things:
  1. Make sure that the paper size that you choose in Page Setup is larger than the canvas size you pick. Pick or create a humungous paper size in Page Setup, just to be safe. 
  2. If you plan to print and want the printer to ignore the page size set in Page Setup, export to a PDF document first. Note: do NOT print to PDF, but instead go to File > Export and chose PDF document. All resulting pages in the PDF will be sized to your canvas size (assuming you followed step 1 above). Open the PDF in Preview. Preview will automatically set the zoom to fit the paper size you select in its print dialog,
With those disclaimers out of the way, on to the script:


-- Copyright © 2013, Joseph Brick
-- All rights reserved. 
-- Redistribution, with or without modification, is permitted provided that the copyright notice is retained.

set theSize to {480, 800}
tell application id "OGfl"
    tell the front document
        set allCanvases to canvases
        repeat with currentCanvas in allCanvases
            tell currentCanvas
                set adjusts pages to false --prevents creating a new page in a canvas by accidentally dragging an object beyond the paper size
                set canvasSize to theSize
            end tell
        end repeat
    end tell
end tell

A few notes on this script are below. See the post "Using AppleScript to reposition objects" for more details on using AppleScript.

-----

tell the front document / end tell

Instead of using this tell / end tell structure, we could have done the following:

    set allCanvases to canvases of the front document 

Since each canvas in allCanvases will now include a reference to the document that contains it, we don't need to refer explicitly to the document when looping through the canvases.

set theSize to {480, 800}

This variable contains the size we'll set each canvas to. This is always a pixel size, regardless of which units are set in each canvas. So if you want the size to be in a different unit, you'll have to do the conversion to pixels.

For example, if you want a 10-inch by 10-inch canvas, you could do something like this:

     set conversionMultiplier to 72
     set theSize to {10 * conversionMulitplier, 10 * conversionMultiplier}

To find the conversion multiplier from pixels to any unit, set a canvas to use the desired units in the Canvas > Size Inspector, then set the Major Grid Spacing to 1 (of those units) in the Canvas > Grid Inspector, and then (temporarily) change the canvas units to pixels. The setting in Major Grid Spacing will change to the number of pixels that make up 1 unit of the desired units.

tell currentCanvas / end tell

Instead of using this tell end tell structure, we could have put "of currentCanvas" after the properties in each of the set commands within the repeat loop. E.g.,

     set canvasSize of currentCanvas to theSize

-----

Note: the purple items in the script are class properties.

To get details on all the properties that OmniGraffle classes like document and canvas contain, open AppleScript Editor, choose File > Open Dictionary, and choose "OmniGraffle Professional 5" from the ensuing dialog. This brings up documentation on everything that OmniGraffle's AppleScript implementation supports.



Note: this version of the script prompts you for the size value.


(*
Copyright © 2013, Joseph Brick

All rights reserved. 

Redistribution, with or without modification, is permitted 
provided that the copyright notice is retained.
*)

on run
set theSize to getPointValueFromUser("Enter the new width and height of each canvas in pixels, separated by a comma", "1000,1000", true)
-- if getPointValueFromUser is null, the user either hit cancel or made a invalid entry.
if theSize is null then
return -- bail on script
end if
tell application id "OGfl"
tell front document
set allCanvases to canvases
repeat with currentCanvas in allCanvases
tell currentCanvas
set adjusts pages to false
set canvasSize to theSize
end tell
end repeat
end tell
end tell
end run

on getPointValueFromUser(instructionsToDisplay, defaultValue, valuesMustBePositive)
try
set userReply to display dialog instructionsToDisplay default answer defaultValue with title "Enter a value"
on error errorText number errorNumber
if errorNumber is -128 then -- user canceled
return null
end if
end try
set userText to text returned of userReply
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to {","}
try
set pX to first text item of userText as number
set pY to second text item of userText as number
on error
display dialog "You must enter two numeric values separated by a comma." buttons {"OK"} with title "Error" with icon caution
set AppleScript's text item delimiters to astid
return null
end try
set AppleScript's text item delimiters to astid
if (pX > 0 and pY > 0) or valuesMustBePositive = false then
return {pX, pY}
else
display dialog "Both numbers must be greater than zero." buttons {"OK"} with title "Error" with icon caution
return null
end if
end getPointValueFromUser

5 comments:

  1. You can have multiple pages on a canvas, and you will if you set the canvas size larger than the paper size from Page Setup canvas printing

    ReplyDelete
  2. Photo Canvas Collage prints are the ideal way to display lots of your stunning images without buying masses of bulky picture frames or cluttering up the house. With the use of smartphones and readily available digital cameras, we have become a nation of amateur photographers, using Instagram to capture our favourite moments. Out of this we now have some incredible photographs we are sure to treasure forever; the problem is there are just too many of them, making the task almost impossible when
    choosing images to display in our homes

    ReplyDelete
  3. Photo Canvas Collage prints are the ideal way to display lots of your stunning images without buying masses of bulky picture frames or cluttering up the house. With the use of smartphones and readily available digital cameras, we have become a nation of amateur photographers, using Instagram to capture our favourite moments. Out of this we now have some incredible photographs we are sure to treasure forever; the problem is there are just too many of them, making the task almost impossible when
    choosing images to display in our homes

    ReplyDelete
  4. Photo Canvas Collage prints are the ideal way to display lots of your stunning images without buying masses of bulky picture frames or cluttering up the house. With the use of smartphones and readily available digital cameras, we have become a nation of amateur photographers, using Instagram to capture our favourite moments. Out of this we now have some incredible photographs we are sure to treasure forever; the problem is there are just too many of them, making the task almost impossible when
    choosing images to display in our homes

    ReplyDelete
  5. In my script using OG v7 you also need a line to ensure the canvas size is not measured in pages. My script looks like this:
    set thePageSize to {thePageWidth, thePageHeight}
    tell myCanvas
    set adjusts pages to false
    set canvas size is measured in pages to false
    set canvasSize to thePageSize
    end tell

    ReplyDelete