Turning a FURL into text before said file exists

What I’m working on is pretty convoluted. Let me throw it out there quick first:

Any way to turn an Apple Event FURL (ie file URL I think) into just a string, when that file doesn’t exist yet?

OK So now the setup: I have been tasked with making a script for InDesign. This script is an “Event Listener” which fires automatically when certain application events occur, such as opening, saving, closing a document, or placing a graphic etc. The one I am working with is “beforeSave”. I need to watch to see if a user is trying to save a file to their desktop, and if so, then that action will not be allowed.

So far my script can detect the save or save-as event (very important point about save-as soon). If the document was already saved, then it has a location. If it was a new document, then there is no “current location” ie file path of the document yet. Or, if the user is doing a save-as to a new location, then the old location becomes moot. And so I need to some how trap the new location they are going to try to save to.

My script can catch the event that happens between the user pressing “save” button in the save-as dialog, and continuing with the script. I have an Apple Event that I can log, and the event contains the new location they are going to save to: ‘fnam’:‘furl’(“file://localhost/Users/chris.paveglio/Desktop/Untitled-0.indd”)

But, I can’t seem to get this location as a string or something usable after this point. I can log it into the console (using Shane’s ASOCObjCRunner app). But I really really need to get it as a string and then see if “Desktop” is in the location, and if so, then throw up a dialog telling the user the action isn’t allowed (or to continue anyways). It logs as what looks like text but I can’t actually convert it in code. I’ve been trying to use stringValue() and stuff from NSApleEventDescriptors to no luck so far.
It’s also PM on Friday so maybe I’m done for the day.

Here’s what I have so far. It needs to be set up as an Event Listener in ID, you can’t run it by itself.


tell application "Adobe InDesign CS5"
	make event listener with properties {event type:"beforeSave", handler:"PREPCTRL-10:Users:chris.paveglio:Desktop:BeforeSave.scpt"}


--before saving test script

script logStuff
	set AEObject to current application's NSApp's passedValue()
	tell me to log AEObject
	tell me to log AEObject's numberOfItems()
	set OneAEObj to AEObject's descriptorAtIndex_(4)
	tell me to log OneAEObj
	-->logs <NSAppleEventDescriptor: 'furl'("file://localhost/Users/name/Desktop/foobar.indd")>
	tell me to log OneAEObj's stringValue()
	-->logs file path if file exists already, otherwise (null)
	tell application "Finder"
		set finderText to OneAEObj as string
		-->if doing save-as and file doesn't exist:
		-->"can't make <class ocid> id <data kptr0001324541> int type string. etc etc -1700
		-->file doesn't exist, yeah we know, gimme the future location anyways!
	end tell
	tell me to log "finderText= " & finderText
end script

tell application "Adobe InDesign CS5"
	if class of (parent of evt) is document then
		set docName to name of parent of evt
		try
			set docFilePath to ((file path of parent of evt) & docName) as string
		on error
			--can't get, or it's a blank/new document
			return
		end try
		
		--well we can display anything we want
		--but the SAVE STILL HAPPENS NO MATTER WHAT YOU CLICK
		--UNLESS you ***tell the evt to prevent default***
		
		--And this dialog isn't shown until
		--after the Save panel of a Save-As or Save-Copy dialog
		
		set theProps to (get properties of evt)
		tell application "ASObjC Runner" to run the script {logStuff} passing theProps
		
		
		if docFilePath contains "Desktop" then
			beep
			display dialog "Don't save to your Desktop, or the Boogey Man will eat your artist points." with icon 0 with title "Warning" buttons {"Stop", "Save Anyways"} default button 1
			--don't use cancel or the script ends before getting to the next statement, duh
			
			if button returned of result is "Stop" then
				tell evt to prevent default
			end if
		end if
		
	end if
end tell

So at this stage OneAEObj is an NSAppleEventDescriptor for an AS file URL. You have to first coerce it to a file URL, and then coercing it to a string should give you an HFS path. So try this:

set OneAEObj to OneAEObj as «class furl»
set OneAEObj to OneAEObj as text

If that doesn’t work, you could make a list of the properties (in correct order), pass the list, and then use “set AEObject to current application’s NSApp’s passedValue() as list”, which will give you your file URL in the list.

I suppose I should make the converting parameter convert a file URL to an NSURL…

Another option is to try to deal with your NSAppleEventDescriptor, something like:

set posixPath to current application's NSString's alloc()'s initWithData_encoding_(OneAEObj's |data|(), current application's NSUTF8StringEncoding)

Done, version 1.1.1 – files and alias passed via the converting parameter will be converted to NSURLs. Available from www.macosxautomation.com/applescript/apps/runner.html or by choosing Check for Updates…

Shane thanks. I updated the ASObj Runner and used your code suggestion.

Do you think it’s at all possible to get that without using ASObjRunner? To somehow pull that out using straight Applescript?

I tried:


set theProps to (get properties of evt)
		set theCount to count of items of theProps
		display dialog "theCount= " & theCount
		display dialog "1"
		set OneAEObj to (get item 4 of theProps)
		display dialog "2"
		set OneAEObj to OneAEObj as «class furl»
		display dialog "3"
		set OneAEObj to OneAEObj as text

but it’s giving me an error on getting item 4 of theProps. The error says “Can’t get item 4 of {id:36, user interaction level:interact with all…” etc. But it will show “the count = 15” which is correct.

OK let me edit myself here. I got the object by using “set OneAEObj to ( full name of theProps )” because Full Name is the identifier in the list.

Perhaps this was ultimately a little easier than my big gigantic description above. :confused: