I need a choose-from-list dialog with three buttons. My present intent is to use Shane’s Myriad Tables script library, but I wondered if there is an alternative (I need the third button and nothing else). Other options I’ve considered are writing a custom dialog with ASObjC and displaying a display-alert dialog which contains the options after displaying the choose-from-list dialog.
Here is one example written by @Takaaki Naganoya, and adapted by me right now. The script returns false when pressed button “Cancel”, last item of list when pressed button “Select last item”, index of selected item of list when pressed button “OK”. I think, @Peavine can improve this script further:
-- Created 2019-02-21 by Takaaki Naganoya
-- Adapted 2021-07-01 by Kniazidis Robert
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 theResult : 0
property returnCode : 0
property theDataSource : {}
property theAlert : missing value
set paramObj to {myMessage:"項目の選択", mySubMessage:"適切なものを以下からえらんでください", aTableList:{"なし", "りんご", "ひよこ", "ぎょうざ", "すなぎも", "ぼんじり", "もも"}}
my chooseItemByTableView:paramObj
on initAlert:args
set theAlert to NSAlert's alloc()'s init()
end initAlert:
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
if my NSThread's isMainThread() as boolean then
-- if we run in main thread
my initAlert:paramObj
else
my performSelectorOnMainThread:"initAlert:" withObject:(missing value) waitUntilDone:true
end if
tell theAlert
its setMessageText:aMainMes
its setInformativeText:aSubMes
its addButtonWithTitle:"OK"
its addButtonWithTitle:"Cancel"
its addButtonWithTitle:"Select last item"
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
set aRes to false
else if (my returnCode as number) = 1002 then
set aRes to last item of aTList
else
set aRes to (aScrollWithTable's documentView's selectedRow()) + 1
end if
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
--1行目を選択
set aIndexSet to NSIndexSet's indexSetWithIndex:0
aView's selectRowIndexes:aIndexSet byExtendingSelection:false
--強制的にトップにスクロール
--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:
@peavine
I cannot pretend to understand the complexities of the advanced coding I saw here for this problem.
But, once, when I wanted to have more choices from a choose-from-list dialog, I simply added a last item after the list. Choosing that instead of the list items was like having another button - not so elegant as another button but it got it done.
Sort of like this:
set answer to choose from list ((items 1 thru DisplayCount of ScriptFolders) & Reset) with title "Music Folders Information"
The string ‘Reset’ appears at the end of the list and can be used to trigger whatever logic was needed.