Reposition Annotation
Code:
-- Reposition Annotation OmniGraffle objects by Dan Thomsen
-- parameters that the user specifies
-- parameters that the user specifies
global horizontal_margin
global vertical_margin
global horizontal_position
global vertical_position
global annotation_position
set horizontal_margin to 20
set vertical_margin to 20
-- valid values are left, center right
set horizontal_position to "left"
-- valid values are top, middle, bottom
set vertical_position to "top"
-- constants
-- these are used to create magnets on the two ends and the middle of the edge
set left_edge to {{-0.5, -0.5}, {-0.5, 0}, {-0.5, 0.5}}
set right_edge to {{0.5, -0.5}, {0.5, 0}, {0.5, 0.5}}
set bottom_edge to {{-0.5, 0.5}, {0, 0.5}, {0.5, 0.5}}
set top_edge to {{-0.5, -0.5}, {0, -0.5}, {0.5, -0.5}}
set text_alignment to left -- default value
-- Prompt the user as to where to place annotation
try
tell front window of application "OmniGraffle Professional"
activate
set objects to selection
if (length of objects < 1) then
error "No annotations selected. Select annotations created with Annotation script, non-annotation objects are ignored."
end if
if not my prompt_user() then
error "user abort"
end if
set object_count to 0
repeat with obj in objects
set obj_data to user data of obj
-- note if the object is not an annotation there is an odd error that is caught by this try statement.
try
-- this statement fails if the object is not an annotation
if (annotation of obj_data is true) then
set current_position to position of obj_data
if annotation_position is "no change" then
set horizontal_position to my get_horizontal_position(current_position)
set vertical_position to my get_vertical_position(current_position)
else
set current_position to annotation_position
end if
set annotation_tag to {annotation:true, position:current_position}
set annotation to obj
set annotation_size to size of annotation -- used to store the size of the annotated text
set user data of annotation to annotation_tag
set incoming_lines to incoming line of annotation
set connector_line to (item 1 of incoming_lines)
set obj to source of connector_line
set obj_size to size of obj
set obj_orig to origin of obj
if horizontal_position = "left" then
set x_pos to (item 1 of obj_orig) - horizontal_margin - (item 1 of annotation_size)
set text_alignment to right
set magnet_list to right_edge
else if horizontal_position = "center" then
set x_pos to (item 1 of obj_orig) + ((item 1 of obj_size) - (item 1 of annotation_size)) / 2
set text_alignment to center
if vertical_position = "top" then
set magnet_list to bottom_edge
else -- vertical_position ="bottom"
set magnet_list to top_edge
end if
else
set x_pos to (item 1 of obj_orig) + (item 1 of obj_size) + horizontal_margin
set text_alignment to left
set magnet_list to left_edge
end if
if vertical_position = "top" then
set y_pos to (item 2 of obj_orig) - vertical_margin - (item 2 of annotation_size)
else if vertical_position = "middle" then
set y_pos to (item 2 of obj_orig) + ((item 2 of obj_size) - (item 2 of annotation_size)) / 2
if horizontal_position = "left" then
set magnet_list to right_edge
else -- horizontal_position = right
set magnet_list to left_edge
end if
else -- bottom
set y_pos to (item 2 of obj_orig) + (item 2 of obj_size) + vertical_margin
end if
set origin of annotation to {x_pos, y_pos}
-- just moving the magnets moves the header line
set magnets of annotation to magnet_list
end if -- an annotation
end try
end repeat
set selection to objects as list
end tell
on error error_message
if error_message is not "user abort" then
display alert error_message buttons {"OK"}
end if
end try
-- Ask the user to fill in the four global variables
on prompt_user()
tell front window of application "OmniGraffle Professional"
-- Prompt the user as to where to place annotation
try
set answer to choose from list {"no change", "NW", "N", "NE", "W", "E", "SW", "S", "SE"} with prompt "Placement:"
if answer is false then return false
set annotation_position to (item 1 of answer)
set horizontal_position to my get_horizontal_position(annotation_position)
set vertical_position to my get_vertical_position(annotation_position)
on error error_message
display alert error_message
return false
end try
try
set answer to display dialog "Enter horizontal margin" default answer "20"
if answer is false then return false
set horizontal_margin to text returned of answer as number
set answer to display dialog "Enter vertical margin" default answer "20"
if answer is false then return false
set vertical_margin to text returned of answer as number
on error error_message
if error_message is "OmniGraffle Professional got an error: User canceled." then return false
display alert error_message buttons {"OK"} default button 1
return false
end try
return true
end tell
end prompt_user
on get_horizontal_position(position)
if {"NW", "W", "SW"} contains position then
return ("left")
else if {"N", "S"} contains position then
return "center"
else if {"NE", "E", "SE"} contains position then
return "right"
else
return ("left")
end if
end get_horizontal_position
on get_vertical_position(position)
if {"NW", "N", "NE"} contains position then
return ("top")
else if {"W", "E"} contains position then
return "middle"
else if {"SW", "S", "SE"} contains position then
return "bottom"
else
return ("top")
end if
end get_vertical_position