I’m quite new to AppleScript and AppleScriptObjC, but I’ve been learning a lot in the past two weeks. I’m working on a frontend for TemplateToolkit (http://template-toolkit.org/), and I’d like to be able to choose a file and store its path in a pop up cell for later use. I’ve been reading the tutorials, but I’m having trouble with this.
Here’s the relevant code for viewing a file in the application:
property ttreercFileView : missing value
property ttreercFile : missing value
on viewTtreercFile_(sender)
try
set ttreercFile to ((path to home folder) as string) & ".ttreerc"
set ttreercFileContents to read (ttreercFile as alias)
ttreercFileView's setString_(ttreercFileContents)
end try
end viewTtreercFile_
In short, I’d like to be able to set ttreercFile to the result of a “choose file”, and then store that in pop up button. (I’d actually like to do this for .cfg files in another part of the application, so that .ttreerc is invisible isn’t important.)
property button_ : missing value -- the button
property ttreercFileView : missing value
property ttreercFile : missing value
on viewTtreercFile_(sender)
set ttreercFile to ((path to home folder) as string) & "file.ttreerc"
button_'s setStringValue_(ttreercFile)
set ttreercFileContents to read (ttreercFile as alias)
ttreercFileView's setString_(ttreercFileContents)
end viewTtreercFile_
Here is a sample app demonstrating what you are asking. This is just a starting point for you but it adds each selected file path to the popup and then you can open a previous file by choosing from the popup.
Thank-you both for getting back to me so quickly! Allan Craig’s application does does just what I’m looking for. My application reads and writes the files well, but I wasn’t sure how to implement “setTitle_” properly to add files to the pop up. Is there a way to save the contents of that pop up for later sessions?
User Defaults is just what I’m looking for. I’ve looked at the Xcode documentation for it, but I have a difficult time translating the Objective C into AppleScript Objective C (I just started with AppleScript two weeks ago).
Where can I find more information on setting up User Defaults? I’ve tried clicking the pop up button, clicking “Bind to → Shared User Defaults Controller” and then linking the pop up to the Shared User Defaults Controller icon in the IB classes window, but this isn’t doing it for me. I get a “SIGABRT” when building.
Sorry, I’m having a tough time following along. Here’s the code (from Allan Craig’s website–see link above):
script PopupAppDelegate
property parent : class "NSObject"
property filePopup : missing value
property textView : missing value
on readFile(filePath)
tell current application
set fileContents to read filePath
end tell
textView's setString_(fileContents)
end readFile
on chooseFile_(sender)
set filePath to choose file
readFile(filePath)
filePopup's setTitle_(filePath as string)
end chooseFile_
on readFileFromPopupSelection_(sender)
set filePath to filePopup's |title| as string as alias
readFile(filePath)
end readFileFromPopupSelection_
on applicationWillFinishLaunching_(aNotification)
-- Insert code here to initialize your application before any files are opened
end applicationWillFinishLaunching_
on applicationShouldTerminate_(sender)
-- Insert code here to do any housekeeping before your application quits
return current application's NSTerminateNow
end applicationShouldTerminate_
end script
How would I use your shell scripts to save the paths added to “filePopUp” so they appear when the application is relaunched?
I’ve been working away at Craig’s excellent fourth tutorial (http://macscripter.net/viewtopic.php?id=30359), and I’m very close to doing what I set out to do. I’ve opted for a table view instead of a pop up for simplicity’s sake, and I’ve simplified the current application a fair bit before I start with choosing file paths and whatnot. For the current application, I enter text into a text field, click a button, and that text is sent to a table row. It all saves to a file and gets reloaded when the application is relaunched, which is great! I’ve made a mistake somewhere, though, and I can’t figure it out.
The rows are being created and the external .plist file is saving the text I enter, but instead of that text appearing in the table view, a left curly bracket “{” shows up. This leads me to believe that everything in Interface Builder has been done properly, and the code itself is working as planned. I’m just not sure why it passes a bracket instead of theFilepath (the text entered into the text field) to the table view.
If someone can spot where I’ve gone wrong, I’d really appreciate it. I get no errors in the Console, and after a few hours of tweaking, I can’t figure out why it’s doing this.
Here’s the script:
property NSMutableArray : class "NSMutableArray"
script TableTestAppDelegate
property parent : class "NSObject"
-- IBOutlets
property aTableView : missing value
property filepathField : missing value
-- Bindings
property theFilepath : ""
--Other properties
property theDataSource : {}
property FILE_PATH : POSIX path of ((path to desktop as string) & "TableTest.plist")
-- IBActions (button clicks)
on addFilepath_(sender)
tell filepathField to selectText_(me) -- forces all fields to complete editing so that our properties are up to date ( thanks to Shane Stanley )
set newData to {theFilepath:theFilepath}
theDataSource's addObject_(newData)
aTableView's reloadData()
my writeToFile()
end addFilepath_
####
#Methods
on writeToFile()
if not theDataSource's writeToFile_atomically_(FILE_PATH, true) then
set messageText to "There was an error writing to file"
display dialog messageText buttons {"Ok"} default button 1
end if
end writeToFile
###
#TableView
on tableView_objectValueForTableColumn_row_(aTableView, aColumn, aRow)
if theDataSource's |count|() is equal to 0 then return end
set theRecord to theDataSource's objectAtIndex_(aRow)
end tableView_objectValueForTableColumn_row_
on numberOfRowsInTableView_(aTableView)
try
if theDataSource's |count|() is equal to missing value then
return 0
else
return theDataSource's |count|()
end if
on error
return 0
end try
end numberOfRowsInTableView_
on tableView_sortDescriptorsDidChange_(aTableView, oldDescriptors)
set sortDesc to aTableView's sortDescriptors()
theDataSource's sortUsingDescriptors_(sortDesc)
aTableView's reloadData()
end tableView_sortDescriptorsDidChange_
###
#Application
on awakeFromNib()
set theDataSource to NSMutableArray's alloc()'s initWithContentsOfFile_(FILE_PATH)
if theDataSource is equal to missing value then
set theDataSource to NSMutableArray's alloc()'s init()
set theData to {{theFilepath:"John"}, {theFilepath:"Hot chocolate"}}
theDataSource's addObjectsFromArray_(theData)
end if
aTableView's reloadData()
end awakeFromNib
on applicationWillFinishLaunching_(aNotification)
-- Insert code here to initialize your application before any files are opened
end applicationWillFinishLaunching_
on applicationShouldTerminate_(sender)
-- Insert code here to do any housekeeping before your application quits
theDataSource's release()
return true
end applicationShouldTerminate_
end script
For anyone who’s interested, I found a way to do this once I figured out the “defaults write” and “defaults read” shell scripts suggested by Dylan.
To remember opened files:
on getCfgFile_(sender)
set cfgFile to (choose file of type {"txt", "cfg"} with prompt "Select your TT2 project config file")
viewCfgFile(cfgFile)
cfgFilePopUp's setTitle_(cfgFile as string)
do shell script "defaults write ~/Library/Preferences/com.speedofmac.tt2_easy cfgFile -array-add '" & (cfgFile as string) & "'"
end getCfgFile_
To populate the popup:
on applicationWillFinishLaunching_(aNotification)
-- Insert code here to initialize your application before any files are opened
set plistFile to ((path to home folder) as string) & "Library:Preferences:com.speedofmac.tt2_easy.plist"
tell application "System Events"
tell property list file plistFile
tell contents
set eachCfgFile to value of property list item "cfgFile"
end tell
end tell
end tell
repeat with i from 1 to (number of items of eachCfgFile)
cfgFilePopUp's setTitle_(item i of eachCfgFile as string)
end repeat
end applicationWillFinishLaunching_
Thanks everyone for pointing me in some interesting directions!