View Single Post
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