Am trying to create an AppleScript program that uses a display dialog box that has scrollbars so you can see what is in a very long list of sometimes very wide items? And also is there a way to adjust the size of the display dialog that is created?
A Google search didn’t give much help so thought someone here might have a suggestion.
The AppleScript program I’m trying to write creates a sorted list of all Safari windows and tabs, and now want to display the list of them that would allow me to scroll around in, as well as be able to select a group of them and then copy to copy/paste buffer for pasting into another app as just text later. I can do some of what I want with a “set whichtab to choose from list of sortedlist” statement (it has scrollbars and lets you change window width and height, but only allows selecting of one item in the list – and I want to select any number or even all). If I try using a “display dialog” statement I get a very narrow dialog window (the list of items is typically much wider so one item spans several lines and makes it hard to read) but has no scrollbars and no ability to change window width and height. I’ve read about the trick of making a button name very wide using extra space characters in the name, but hoping that there is a better way.
Ideally, there would be a search button that allows me to find the first/next occurrence of any desired substring within the text items as well, but that’s not critical.
For displaying lists Standard Additions has choose from list.
It will display items of any length, and show a scrollbar when the display gets as tall as your screen.
You cannot copy from the list, so you’ll have to do that in your script.
You can select multiple items in a choose-from-list dialog as follows:
set sortedList to {"a", "b", "c", "d"}
choose from list sortedList with multiple selections allowed
The above script returns a list, so you would need to format this list in some way before copying it to the clipboard. A simple example is:
set sortedList to {"a", "b", "c", "d"}
set selectedItems to choose from list sortedList with multiple selections allowed
set the clipboard to (selectedItems as text)
the clipboard -- to show contents of the clipboard not to include in the final script
peavine’s suggestion about using the “with multiple selections allowed” allows multiple selections as well as the scroll bar feature and the dialog window resizing, but the “Copy” item in the Edit menu is greyed out so can’t do anything with the selection except by writing more AppleScript to parse what is returned I would guess - so this is a possible solution.
maro’s program does not compile for me using either AppleScript Editor or Script Debugger (perhaps it would under Xcode ?), and since I’m just an AppleScript beginner, not sure what to do to even begin right now. Can you give a suggestion/hint on how to compile it? Thanks.
alastor933’s comment is what I had already tried, but thanks for trying to help.
The script written by Takaaki Naganoya contains some errors. So I fixed them. Working script:
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"
property NSAlert : a reference to current application's NSAlert
property NSIndexSet : a reference to current application's NSIndexSet
property NSScrollView : a reference to current application's NSScrollView
property NSTableView : a reference to current application's NSTableView
property NSTableColumn : a reference to current application's NSTableColumn
property NSMutableArray : a reference to current application's NSMutableArray
property NSRunningApplication : a reference to current application's NSRunningApplication
property NSAlertSecondButtonReturn : a reference to current application's NSAlertSecondButtonReturn
property theAlert : missing value
property theResult : 0
property returnCode : 0
property theDataSource : {}
on createAlert()
-- Create an alert
set my theAlert to current application's NSAlert's alloc()'s init()
my performSelectorOnMainThread:"displayAlert:" withObject:theAlert waitUntilDone:true
end createAlert
my performSelectorOnMainThread:"createAlert" withObject:(missing value) waitUntilDone:true
my performSelectorOnMainThread:"displayAlert" withObject:(missing value) waitUntilDone:true
if theResult = (current application's NSAlertSecondButtonReturn) then error number -128
set paramObj to {myMessage:"Item selection", mySubMessage:"Please select the appropriate one from the following", aTableList:{"None", "Apple", "Chick", "Gyouza", "Snagi also", "Alone", "Peaches"}}
set aRes to my chooseItemByTableView:paramObj
on chooseItemByTableView:paramObj
set aMainMes to myMessage of paramObj
set aSubMes to mySubMessage of paramObj
set aTList to (aTableList of paramObj) as list
-- define the matrix size where you’ll put the radio buttons
set aScrollWithTable to makeTableView(aTList, 300, 150) of me
-- set up alert
tell theAlert
its setMessageText:aMainMes
its setInformativeText:aSubMes
its addButtonWithTitle:"OK"
its addButtonWithTitle:"Cancel"
its setAccessoryView:aScrollWithTable
end tell
-- show alert in modal loop
NSRunningApplication's currentApplication()'s activateWithOptions:0
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
if (my returnCode as number) = 1001 then error number -128
return (aScrollWithTable's documentView's selectedRow()) + 1
end chooseItemByTableView:
on doModal:aParam
set (my returnCode) to aParam's runModal()
end doModal:
on makeTableView(aList as list, aWidth as number, aHeight as number)
set aOffset to 40
set sourceList to {}
repeat with i in aList
set the end of sourceList to {dataItem:(contents of i)}
end repeat
set theDataSource to NSMutableArray's alloc()'s init()
theDataSource's addObjectsFromArray:sourceList
set aScroll to NSScrollView's alloc()'s initWithFrame:(current application's NSMakeRect(0, aOffset, aWidth, aHeight))
set aView to NSTableView's alloc()'s initWithFrame:(current application's NSMakeRect(0, aOffset, aWidth, aHeight))
set aColumn to (NSTableColumn's alloc()'s initWithIdentifier:"dataItem")
(aColumn's setWidth:aWidth)
(aColumn's headerCell()'s setStringValue:"dataItem")
(aView's addTableColumn:aColumn)
aView's setDelegate:me
aView's setDataSource:me
aView's reloadData()
aScroll's setDocumentView:aView
aView's enclosingScrollView()'s setHasVerticalScroller:true
-- Select line
set aIndexSet to NSIndexSet's indexSetWithIndex:0
aView's selectRowIndexes:aIndexSet byExtendingSelection:false
-- Force scroll to top
-- set maxHeight to aScroll’s documentView()’s |bounds|()’s |size|()’s height
set aDBounds to aScroll's documentView()'s |bounds|()
if class of aDBounds = list then
-- macOS 10.13 or later
set maxHeight to item 2 of item 1 of aDBounds
else
-- macOS 10.10….10.12
set maxHeight to height of |size| of aDBounds
end if
set aPT to current application's NSMakePoint(0.0, -40.0) -- (aScroll’s documentView()’s |bounds|()’s |size|()’s height))
aScroll's documentView()'s scrollPoint:aPT
return aScroll
end makeTableView
-- TableView Event Handlers
on numberOfRowsInTableView:aView
return my theDataSource's |count|()
end numberOfRowsInTableView:
on tableView:aView objectValueForTableColumn:aColumn row:aRow
set aRec to (my theDataSource)'s objectAtIndex:(aRow as number)
set aTitle to (aColumn's headerCell()'s title()) as string
set aRes to (aRec's valueForKey:aTitle)
return aRes
end tableView:objectValueForTableColumn:row: