Need assistance selecting Disk Icons on desktop

G’day

I’m trying to update a script for organizing icons on the desktop and in windows, to make it compatible with Snow Leopard.

Everything works OK except for re-selecting the original selection after they’ve been moved on the desktop. I can’t work out how to select any chosen Disk icons along with the ordinary icons.

The variable keepSelection stores the original selection, including disk icons, but only restores non-disk icons

if we_are_on_desktop then set the selection to KeepSelection --< is the part I need to change

Any advice appreciated.

Regards

Santa


--  ****************************
--  * Copyright 2011, Brian Christmas  *
--  *                                                    *
--  *   From the Sunny Land of Oz        *
--  *             Version 2.0                      *
--  *             21 Jan 11                        *
--  *                                                    *
--  *        OzSanta@gmail.com             *
--  ****************************

-- AID OR Automatic Icon Distributor

-- Qsort routine from MacScripter
-- http://bbs.applescript.net/viewtopic.php?id=17340

-- Thanks to Yvan Koenig for the routine that traps
-- the Window of the Desktop that holds selected icons

-- This script works best if some approximate 
-- organizing is done first, otherwise extra columns
-- may be added, especially on horizontal single lines,
-- or columns left empty if you've left vertical gaps.

-- Also note that if insufficient side margins are not allowed for when arranging a windows icons,
-- the Finder may 'shake' the window from side to side, thereby altering the icon placement.

-- It's particularly important to have a wide margin on the left when arranging,
-- otherwise the left column may not get arranged correctly, & need a second pass.

-- Feedback appreciated, especially suggestions to speed this up.

global IconList
global IconPositions
global overlapFlag
global we_are_on_desktop
global seedValue
global AlphabetMin
global staggered
global StaggeredCount
global FoundDisk
global thelist
global KeepSelection

set StaggeredCount to 0

-- *******************************
-- **** Set this as minimum amount ****
-- ****   allowed between columns     ****
-- *******************************
set seedValue to 100

-- *******************************
-- **** Set this as minimum amount ****
-- ****          of icons to offer             ****
-- ****          alphabet sorting            ****
-- *******************************
set AlphabetMin to 20

-- *******************************
-- **** Set this to true to vertically    ****
-- **** stagger labels that are closer  ****
-- **** than seedvalue + 40 pixles    ****
-- *******************************
set staggered to false -- set to true or false


my mainCycle()

on mainCycle()
	tell application "Finder"
		set currX to 0
		set LargestY to 0
		set SmallestY to 0
		set SmallestX to 0
		set LargestX to 0
		set overlapFlag to 0
		set Xdifflist to {}
		set ydiffList to {}
		set columnCount to {}
		set XYlist to {}
		try
			
			set thelist to (selection as list)
			set KeepSelection to the selection
			set distribute to count of thelist
			if distribute = 0 then
				display dialog "There are no icons selected." & return & return & "Try selecting some, and running the script again." buttons {"OK"}
				return
			end if
			if distribute = 1 then return -- Only one selected, so leave alone
			set FoundDisk to false
			set xx to distribute
			repeat with x from 1 to distribute
				if kind of item x of thelist as text ≠ "Volume" then
					set xx to x
					if FoundDisk then exit repeat
				else
					set FoundDisk to true
					set KeepDisk to item x of thelist as alias
					if xx < distribute then exit repeat
				end if
			end repeat
			set ThisItem to item xx of thelist
			set ptw to container of (ThisItem)
			if (count of windows) > 0 then
				try
					if name of window 1 = "Desktop" then
						tell application "Finder"
							activate
							set windName to get localized string "N5"
						end tell
						
						tell application "System Events" to tell application process "Finder" to tell menu bar 1 to tell menu bar item 7 to tell menu 1
							set noemi to (name of every menu item)
							if (noemi contains windName) then
								set windStatus to false
								repeat with i from 1 to count of noemi
									try (* to get rid of "missing value" *)
										if (name of menu item i is windName) and (value of attribute "AXMenuItemMarkChar" of menu item i is not "") then
											set windStatus to true
											exit repeat
										end if
									end try
								end repeat
								
							else
								set windStatus to false
							end if
						end tell
						if windStatus then
							tell application "Finder"
								try
									set EnclosingFolder to container of ThisItem as string
									close window "Desktop"
								end try
								display dialog "A Window belonging to the Desktop was frontmost, and you have selected Icons in it, and tried to organize them." & return & return & "Doing so may seriously disrupt your actual Desktop Icon arrangement." & return & return & "If you wish to organize any Desktop icons, please select them on the Desktop itself." buttons {"So, I've stopped it."}
								try
									open EnclosingFolder
								end try
							end tell
							return
						end if
					end if
				end try
			end if
			--- ARE WE ON THE DESKTOP?
			try
				set we_are_on_desktop to ((container of ThisItem as alias) is (path to desktop folder))
			on error
				set we_are_on_desktop to (kind of ThisItem as text = "Volume") --< only Volume icons selected
			end try
			if FoundDisk then --< there is at least one disk in the mix, so restart Finder
				quit
				delay 0.4
				try
					activate
				end try
				select disk KeepDisk
				close window 1
			end if
			-- make array of positions
			repeat with ThisItem in thelist
				if we_are_on_desktop then
					set temp to desktop position of ThisItem
				else
					set temp to position of ThisItem
				end if
				set end of XYlist to temp
				set end of Xdifflist to item 1 of temp
				set end of ydiffList to item 2 of temp
			end repeat
			set IconList to thelist
			--display dialog item 1 of XYlist as text
			set IconPositions to XYlist
			set AlphaFlag to false
			-- Heaps of icons? then ask!
			if length of thelist > (AlphabetMin - 1) then
				display dialog " there are " & length of thelist & " icons selected." & return & return & "Do you want to sort them alphabetically or normally?" & return & return & "(it takes a while with large numbers)" buttons {"Alphabetically please", "Normally thanks", "Cancel"}
				set AlphaFlag to (the button returned of the result is "Alphabetically please")
			end if
			if we_are_on_desktop then
				set theTotal to count of items of desktop
				set IconSize to icon size of icon view options of window of desktop
				set ArrangementValue to arrangement of icon view options of window of desktop
			else
				set TheCurrentView to current view of window 1
				if TheCurrentView ≠ icon view then
					set the current view of window 1 to icon view
					display dialog "I have reset the view of the window to 'icon view'. Do you wish to proceed?" buttons {"No", "Proceed"}
					if the button returned of the result = "No" then
						set the current view of window 1 to TheCurrentView
						return
					end if
				end if
				set theTotal to count of items of window 1
				set IconSize to icon size of icon view options of window 1
				set ArrangementValue to arrangement of icon view options of window 1
			end if
			set AddendumText to ""
			if (count of thelist) < theTotal then set AddendumText to "You have only selected " & (count of thelist) & " of " & theTotal & " items. The new arrangement mightn't look good because the extra icons may end up all over the place." & return & return & "You will however, be given a 'restore' option." & return & return
			if ArrangementValue as text ≠ "not arranged" then
				display dialog "The window of the selection has a current arrangement of '" & ArrangementValue & "'. " & return & return & AddendumText & "Do you want to proceed?" buttons {"Proceed", "No thanks"}
				if button returned of the result = "No thanks" then return
			end if
			if ArrangementValue as text ≠ "not arranged" then
				if we_are_on_desktop then
					set arrangement of icon view options of window of desktop to not arranged
				else
					try
						set (arrangement of icon view options of window 1) to not arranged
					on error errmsg
						display dialog errmsg
					end try
				end if
			end if
			
			my Qsort(Xdifflist, 1, (length of Xdifflist))
			my Qsort(ydiffList, 1, length of ydiffList)
			
			set LargestX to last item of Xdifflist
			set SmallestX to first item of Xdifflist
			set LargestY to last item of ydiffList
			set SmallestY to first item of ydiffList
			
			if we_are_on_desktop then
				set seedValueadd to ((label position of icon view options of window of desktop) = right)
			else
				set seedValueadd to ((label position of icon view options of window 1) = right)
			end if
			
			-- If text is on right, double the minimum spacing
			if seedValueadd = true then
				set seedValue to seedValue * 2
				set staggered to false --<-- no need to stagger them
			end if
			-- Now the guessing part, what to distribute as column spacing?
			if IconSize > seedValue then set seedValue to IconSize
			set setX to seedValue
			repeat with x from ((length of Xdifflist) - 1) to 1 by -1
				set diff to ((item (x + 1) of Xdifflist) - (item x of Xdifflist))
				if (diff > seedValue - 1) then
					set setX to diff
				end if
			end repeat
			--Now, set width between columns
			
			-- SPECIAL CASE : Roughly all on one horizontal line, then spread 'em evenly, else
			if LargestY - SmallestY < 60 and length of Xdifflist > 1 then
				set columnSpaces to (LargestX - SmallestX) div (((LargestX - SmallestX) div ((length of Xdifflist) - 1)))
			else
				set columnSpaces to ((LargestX - SmallestX + (setX / 2)) div setX)
			end if
			--Only 1 column? then set columnSpace to seedvalue
			
			if columnSpaces = 0 then
				set ColumnWidth to seedValue
				set columnSpaces to 1
			else
				if columnSpaces = 1 and (LargestX - SmallestX) < seedValue * 2 then
					set ColumnWidth to (LargestX - SmallestX)
				else
					set ColumnWidth to (LargestX - SmallestX) / columnSpaces
					if ColumnWidth < seedValue then set ColumnWidth to seedValue
					-- Roughly all on one horizontal line, then spread 'em evenly
					if LargestY - SmallestY < 60 then set ColumnWidth to (LargestX - SmallestX) / columnSpaces
				end if
			end if
			if staggered and columnSpaces > 0 then set staggered to ColumnWidth < (seedValue + 40)
			if staggered and columnSpaces > 1 then set LargestY to LargestY - 20
			set columnCount to columnSpaces + 1
			
			set columnCountStore to 0
			set columnXstore to {0, 0}
			repeat with x from 1 to columnSpaces
				set end of columnXstore to {0, 0}
				set columnCountStore to columnCountStore & 0
			end repeat
			repeat with x from 1 to columnCount
				set minX to SmallestX + ((x - 1) * ColumnWidth) - (ColumnWidth / 2)
				set MaxX to SmallestX + ((x - 1) * ColumnWidth) + (ColumnWidth / 2)
				set item x of columnXstore to {minX, MaxX}
			end repeat
			repeat with ThisItem in thelist
				if we_are_on_desktop then
					set temp to desktop position of ThisItem
				else
					set temp to position of ThisItem
				end if
				repeat with x from 1 to columnCount
					set minX to item 1 of item x of columnXstore
					set MaxX to item 2 of item x of columnXstore
					set tempX to item 1 of temp
					-- if icon falls in the range of column, add it up
					if ((tempX = minX) or (tempX > minX)) and (tempX < MaxX) then
						set item x of columnCountStore to ((item x of columnCountStore) + 1)
					end if
				end repeat
			end repeat
			
			if AlphaFlag then --> Alphabet arrange set
				set iconspacing to (LargestY - SmallestY) / ((distribute / columnCount) div 1)
			else
				
				-- Now find Column with largest number of icons
				
				set maxCount to 2 ---> to avoid division by zero if only one row
				repeat with x from 1 to number of items in columnCountStore
					if item x of columnCountStore > maxCount then
						set maxCount to item x of columnCountStore
					end if
				end repeat
				set iconspacing to ((LargestY - SmallestY) / (maxCount - 1))
			end if
			
			if AlphaFlag then
				my SortbyAlphabet(thelist, SmallestX, LargestX, SmallestY, ColumnWidth, iconspacing)
			else
				-- Now place Icons
				-- Loop ColumnCount times....
				repeat with MoveColumns from 1 to columnCount
					set minX to SmallestX + ((MoveColumns - 1) * ColumnWidth) - (ColumnWidth / 2)
					set MaxX to SmallestX + ((MoveColumns - 1) * ColumnWidth) + (ColumnWidth / 2)
					
					set templist to {}
					repeat with ThisItem from 1 to number of items in XYlist
						set temp to item ThisItem of XYlist
						set tempX to item 1 of temp
						if (((tempX = minX) or (tempX > minX)) and ((tempX < MaxX) or (tempX = MaxX))) then
							--Build list of icon XY positions in column
							set end of templist to tempX
							set end of templist to item 2 of temp
						end if
					end repeat
					-- This is the X value of the column
					set columnX to SmallestX + ((MoveColumns - 1) * ColumnWidth)
					--
					-- Now go and shift a column of the little bastards around!
					--
					my ArrangeColumn(thelist, templist, columnX, SmallestY, iconspacing, XYlist)
				end repeat
			end if
			if not we_are_on_desktop then
				close ptw
				open ptw
			end if
			if not we_are_on_desktop then select every item of IconList

			if we_are_on_desktop then set the selection to KeepSelection --< Need to alter this

			display dialog "Restore." & return & return & "Is this arrangement satisfactory?" buttons {"Yes", "No"}
			if button returned of the result = "No" then
				if we_are_on_desktop then
					repeat with x from 1 to count of IconList
						set desktop position of item x of IconList to item x of IconPositions
					end repeat
					if ArrangementValue as text ≠ "not arranged" then set arrangement of icon view options of window of desktop to ArrangementValue
				else
					if ArrangementValue as text ≠ "not arranged" then
						set (arrangement of icon view options of window 1) to ArrangementValue
					else
						repeat with x from 1 to count of IconList
							set position of item x of IconList to item x of IconPositions
						end repeat
					end if
				end if
				if not we_are_on_desktop then
					close ptw
					open ptw
				end if
			end if
		end try
	end tell
end mainCycle

-- =============================================================

on ArrangeColumn(thelist, templist, currX, SmallestY, iconspacing, XYlist)
	tell application "Finder"
		try
			-- Start with a Y seed position, to overcome 
			-- problem with 1 entry not seen as an item
			set ylist to {0}
			--
			-- Now make list of Y positions
			repeat with Cycle from 1 to number of items in XYlist
				set temp to item Cycle of XYlist
				set ThisItem to item Cycle of thelist
				if temp is in templist then
					set ylist to ylist & item 2 of temp
				end if
			end repeat --
			-- Sort Y positions
			my Qsort(ylist, 1, length of ylist)
			--
			-- Now position each
			repeat with Cycle from 1 to number of items in XYlist
				set thisItemTwo to item Cycle in thelist
				set temp to item Cycle of XYlist
				if we_are_on_desktop then
					if temp is in templist then
						set tempY to item 2 of temp
						repeat with countdown from 2 to (number of items in ylist)
							if item countdown of ylist = tempY then
								set currY to SmallestY + ((countdown - 2) * iconspacing)
								set item countdown of ylist to "Done"
								exit repeat
							end if
						end repeat
						set desktop position of thisItemTwo to {currX, currY + StaggeredCount}
					end if
				else
					if temp is in templist then
						set tempY to item 2 of temp
						repeat with countdown from 2 to (number of items in ylist)
							if item countdown of ylist = tempY then
								set currY to SmallestY + ((countdown - 2) * iconspacing)
								set item countdown of ylist to "Done"
								exit repeat
							end if
						end repeat
						set position of thisItemTwo to {currX, currY + StaggeredCount}
					end if
				end if
			end repeat
			if staggered then
				if StaggeredCount = 0 then
					set StaggeredCount to 20
				else
					set StaggeredCount to 0
				end if
			end if
		end try
	end tell
end ArrangeColumn

on SortbyAlphabet(thelist, SmallestX, LargestX, SmallestY, ColumnWidth, iconspacing)
	
	tell application "Finder"
		try
			set templist to {}
			-- First, sort list of icons alphabetically
			set xx to length of thelist
			repeat with x from 1 to xx
				set end of templist to name of item x of thelist
			end repeat
			my Qsort(templist, 1, xx)
			set iconPos to 1
			set Xwidth to LargestX - SmallestX + ColumnWidth
			if staggered then set staggered to ColumnWidth < (seedValue + 40)
			repeat with ThisItem in thelist
				set tempName to name of ThisItem
				repeat with mainCount from 1 to xx
					if tempName = item mainCount of templist then
						set farRightX to ((mainCount - 1) * ColumnWidth)
						set numberofRows to ((farRightX) / (Xwidth)) div 1
						set Xposition to SmallestX + (farRightX - (numberofRows * Xwidth))
						set yposition to SmallestY + ((numberofRows) * iconspacing)
						set columntemp to (((Xposition - SmallestX) / ColumnWidth) + 0.5) div 1
						if staggered then
							set StaggeredCount to 0
							if (columntemp mod 2) = 1 then set StaggeredCount to 20
						end if
						
						if we_are_on_desktop then
							set desktop position of ThisItem to {Xposition, yposition + StaggeredCount}
						else
							set position of ThisItem to {Xposition, yposition + StaggeredCount}
						end if
						exit repeat
					end if
				end repeat
			end repeat
		end try
	end tell
end SortbyAlphabet


to Qsort(array, leftEnd, rightEnd) -- Hoare's QuickSort Algorithm
	script A
		property L : array
	end script
	set {i, j} to {leftEnd, rightEnd}
	set v to item ((leftEnd + rightEnd) div 2) of A's L -- pivot in the middle
	repeat while (j > i)
		repeat while (item i of A's L < v)
			set i to i + 1
		end repeat
		repeat while (item j of A's L > v)
			set j to j - 1
		end repeat
		if (not i > j) then
			tell A's L to set {item i, item j} to {item j, item i} -- swap
			set {i, j} to {i + 1, j - 1}
		end if
	end repeat
	if (leftEnd < j) then Qsort(A's L, leftEnd, j)
	if (rightEnd > i) then Qsort(A's L, i, rightEnd)
end Qsort


Model: 27" iMac
Browser: Safari 533.19.4
Operating System: Mac OS X (10.6)

G’day

Turned out the GUI was the way to go…



if we_are_on_desktop then
			repeat with SelectDisk in KeepSelection
				tell application "System Events" to tell process "Finder"
					try
						select image (name of SelectDisk) of group 1 of scroll area 1
					end try
				end tell
			end repeat
		else
			
			(*with timeout of 600 seconds
				select KeepSelection
			end timeout*)
		end if

Regards

Santa