Choose file and add to pop up button for later use

Hello,

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.)

Could anyone point me in the right direction?

Thank-you,

John

Umm… would this help?

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_

That’s how I roll… :cool:

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.

Popuplate NSPopupButton from file selection

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?

Thanks again,

John

raises hand Ooooh! Oooooh! User defaults!
I prefer the “do shell script” way, but do it any way you like.

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.

Can someone let me know what I’m missing?

Here is the do shell script command with user defaults:

Write:

do shell script "defaults write com.whatever.pie mysterykey 'I like turtles.'"

Read:

do shell script "defaults read com.whatever.pie mysterykey"

Those should help you. You should be able to build from there! :stuck_out_tongue:

Where “whatever” is the name of my application and “mysterykey” is a variable? Where would I put the ‘Read’ shell script?

Sorry, I forgot to mention that! :lol:

You can change com.whatever.pie to anything, like “r” (one letter, word, or symbol like ©).
You can also change mysterykey.

Sorry, but I forgot to mention that. :smiley:

Also you should do “set hello to do shell script…” because there would be no point of doing it!

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

Thank-you,

John

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!