I’ve been mainly programming in Objective-C lately and come across situations where I want to present a TableView to the user to confirm data.
I know how to customize NSAlert and have create an extension on it to provide many option I need… custom text editing, check boxes, buttons etc. But inserting a NSTableView and providing it data has failed.
I want to keep this in a extension and not have to load any nib’s.
I’m thinking I my have to use good old AppleScript via osascript to do this,
Unless someone can provide other suggestions!
Thanks
Here is one example. The script was originally developed by user @Takaaki Naganoya. Slightly modified by me for execution on the main thread.
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"
property |⌘| : a reference to current application
property aList : {3, "None", "Apple", 3, 4, "Chick", "Gyouza", "Snagi also", "Apple", "Peaches"}
property aMainMessage : "IMPROVED CHOOSE FROM LIST DIALOG"
property aSubMessage : "Please select the appropriate one from the following"
property theAlert : missing value
property theResult : 0
property returnCode : 0
property theDataSource : {}
my performSelectorOnMainThread:"createAlert" withObject:(missing value) waitUntilDone:true
my performSelectorOnMainThread:"displayAlert" withObject:(missing value) waitUntilDone:true
if theResult = (|⌘|'s NSAlertSecondButtonReturn) then error number -128
set aResult to my chooseItemByTableView()
on createAlert()
set my theAlert to |⌘|'s NSAlert's alloc()'s init()
my performSelectorOnMainThread:"displayAlert:" withObject:theAlert waitUntilDone:true
end createAlert
on chooseItemByTableView()
-- define the matrix size where you’ll put the radio buttons
set aScrollWithTable to makeTableView(300, 150) of me
-- set up alert
tell theAlert
its setMessageText:aMainMessage
its setInformativeText:aSubMessage
its addButtonWithTitle:"OK"
its addButtonWithTitle:"Cancel"
its setAccessoryView:aScrollWithTable
end tell
-- show alert in modal loop
|⌘|'s 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(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 |⌘|'s NSMutableArray's alloc()'s init()
theDataSource's addObjectsFromArray:sourceList
set aScroll to |⌘|'s NSScrollView's alloc()'s initWithFrame:(|⌘|'s NSMakeRect(0, aOffset, aWidth, aHeight))
set aView to |⌘|'s NSTableView's alloc()'s initWithFrame:(|⌘|'s NSMakeRect(0, aOffset, aWidth, aHeight))
set aColumn to (|⌘|'s 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 |⌘|'s 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 aPoint to |⌘|'s NSMakePoint(0.0, -40.0)
aScroll's documentView()'s scrollPoint:aPoint
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 aRecord to (my theDataSource)'s objectAtIndex:(aRow as number)
set aTitle to (aColumn's headerCell()'s title()) as string
set aResult to (aRecord's valueForKey:aTitle)
return aResult
end tableView:objectValueForTableColumn:row:
Yes but the problem is the delegate methods of supply data or selection. Kinda hard to make the NSAlert class extension the delegate
We can extend NSAlert class by using AppleScriptObjC framework maybe like this.
http://piyocast.com/as/archives/category/custom-class
1 Like
Is think I need to creat my own Class that will — accepted my sourceData.
- follow the NSTableView delegate protocols
- create the Alert with TableView
- run the Alert and return the selected items
I may even create a TableView in InterfaceBuilder and have my custom class load nib file.
Thanks