Select files or folders....

Is there a way to be able to select files and folder in ApplescriptObjC? I am creating a program that will upload files to a server but I need to select both files and folders.

any help is much appreciated!

NSOpenPanel has the methods, setCanChooseFiles: and setCanChooseDirectories:, which control what you can select from an open panel.

Ric

OK, well I am to new to this, can you point me to some examples of how this is used. I cannot seem to find any with a web search.

thanks

You could use it like this:

on applicationWillFinishLaunching_(aNotification)
		set cp to current application's NSOpenPanel's openPanel()
		cp's setCanChooseFiles_(1) -- 1 allows choosing files, 0 disallows
		cp's setCanChooseDirectories_(1) -- 1 allows choosing folders, 0 disallows
		cp's setAllowsMultipleSelection_(1) -- 1 allows multiple selection, 0 disallows
		cp's runModal()
		set theChosen to cp's URLs()
		log theChosen
	end applicationWillFinishLaunching_

Ric

that worked great! Here is what I am trying to do…

I have a text field, so that you can enter the name of a folder that you want to create. when you push a button it will get the text fields value and create a new folder. Then I want the user to select files to copy to a specific destination.

I have the all of this working but now I cannot get the duplication to work, here is what I have


	on uploadHTMLads_(sender)
		set textFieldAdValue to (textFieldAd's |stringValue|()) as text --gets textFields string value
		tell application "Finder"
			set inimg02 to "files_2:localadtemplates" --sets the destination folder
		end tell
		tell application "Uploads"
			if textFieldAdValue is "" then error display dialog "You need to put a season code in the box" --checks textField to see if it is empty and display error code
		end tell
		tell application "Finder"
			if not (exists folder textFieldAdValue of folder inimg02) then --creates new folder in destination folder
				make new folder at inimg02 with properties {name:textFieldAdValue}
			end if
		end tell
		set cp to current application's NSOpenPanel's openPanel() --open panel for selecting files and folders
		cp's setCanChooseFiles_(1) -- 1 allows choosing files, 0 disallows
		cp's setCanChooseDirectories_(1) -- 1 allows choosing folders, 0 disallows
		cp's setAllowsMultipleSelection_(1) -- 1 allows multiple selection, 0 disallows
		cp's runModal()
		set theChosen to cp's URLs()
		log theChosen
		tell application "Finder"
			duplicate theChosen to inimg02 & ":" & textFieldAdValue with replacing --copy chosen files and folder to new destination
		end tell
	end uploadHTMLads_

I figure that having the finder do the duplication might be part of the problem. I am not sure…

error I am getting in the log

2011-07-07 15:27:33.309 Uploads[70233:a0f] *** -[UploadsAppDelegate uploadHTMLads:]: Can’t set “files_2:localadtemplates:Scooter2” to «class ocid» id «data kptr00000000000C730002000000». (error -10006)

any ideas?

I’m not sure about the Finder either, since I don’t usually use it. This worked for me using the file manager to copy the items.

on applicationWillFinishLaunching_(aNotification)
		set manager to current application's NSFileManager's defaultManager()
		set cp to current application's NSOpenPanel's openPanel()
		cp's setCanChooseFiles_(1) -- 1 allows choosing files, 0 disallows
		cp's setCanChooseDirectories_(1) -- 1 allows choosing folders, 0 disallows
		cp's setAllowsMultipleSelection_(1) -- 1 allows multiple selection, 0 disallows
		cp's runModal()
		repeat with aURL in cp's URLs()
			set theChosenPath to aURL's |path|()
			set theChosen to aURL's lastPathComponent()
			set dstPath to current application's NSString's stringWithString_(POSIX path of (inimg02 & ":" & textFieldAdValue as string))
			set dstPath to dstPath's stringByAppendingPathComponent_(theChosen)
			log manager's copyItemAtPath_toPath_error_(theChosenPath, dstPath, missing value) -- should log 1 if successful
		end repeat
	end applicationWillFinishLaunching_

Ric

Thanks Ric, that worked. Can you explain what is going on in the code some so I can get a better understanding of how this all works.

Sorry to take up your time, but the more I learn, the better…

Well, I’m not sure what you want me to explain, but I’’ take a stab at it. To work with the file manager you first have to create a file manager object which is what the first line does (you should look at the NSFileManager Class reference to see all the methods that are available to you). I could also have created one by saying “set manager to current application’s NSFileManager’s alloc()'s init()” which is probably preferable as it says inn the overview section at the top of the class reference. I then use the NSString methods to create an NSString for your path name with stringWithString. I put in the “POSIX path of” piece because the paths used by the file manager are POSIX paths (slash delimited as opposed to colon delimited), so that converts your colon delimited path to the correct type. Then I use stringByAppendingPathComponent to add the file name to the end of your folder path – if you look at the documentation for that method, it has a nice little table to show you what you get from this method under various conditions (like it automatically puts the slash in at the end of the folder name). I then use the copyItemAtPath_toPath_error_ method of NSFileManager to copy the items over. This method only copies one file or folder (with all its contents) at a time so I put it in a repeat block to copy all the items that are chosen in the open panel. The method does not automatically assume that the files will have the same name as the source files so that’s why I had to append the file name (set dstPath to dstPath’s stringByAppendingPathComponent_(theChosen)) to the destination folder path. You should read the top section of the class files that I used here for general information and the descriptions of all the methods themselves to familiarize yourself with what these classes and methods can do – that’s how I learned all of this.

Ric

Thanks, your explanation helped. Are all the descriptions of the methods only on apples developer site? Or is there something similar to Applescript editors library?

Just trying to find the best place to look for this and learn more.

Thanks,
Scott

]

I don’t know what the Applescript editors library is. I learned it all from the XCode help menu, this forum and Shane’s book.

Ric

just got the book! This will help a lot.

Thanks for your help…

OK, so I noticed that this script does not copy anything if there is already a folder named the same there. How would I do this if I want it to replace what is already there?

One way to do it would be to add the delegate method, fileManager_shouldCopyItemAtPath_toPath_, which is sent to the delegate each time the file manager tries to copy an item. So, in this delegate method, I check to see if the item exists (with fileExistsAtPath_(toPath)), and if it does, it is removed and the method returns 1, which means that the file manager should go ahead and copy the item. Notice that I add the line “manager’s setDelegate_(me)” which makes the script the delegate for the file manager, so it will be sent any delegate messages. I don’t do any checking to see if the user wants to delete the file (or folder) first, it just goes ahead and does it – if you want to be able to check first whether to go ahead with the deletion, that would require some more code.

on applicationWillFinishLaunching_(aNotification)
		set inimg02 to "MacHD:Users:janicedelmar:Desktop"
		set textFieldAdValue to "New"
		set manager to current application's NSFileManager's defaultManager()
		manager's setDelegate_(me)
		set cp to current application's NSOpenPanel's openPanel()
		cp's setCanChooseFiles_(1) -- 1 allows choosing files, 0 disallows
		cp's setCanChooseDirectories_(1) -- 1 allows choosing folders, 0 disallows
		cp's setAllowsMultipleSelection_(1) -- 1 allows multiple selection, 0 disallows
		cp's runModal()
		repeat with aURL in cp's URLs()
			set theChosenPath to aURL's |path|()
			set theChosen to aURL's lastPathComponent()
			set dstPath to current application's NSString's stringWithString_(POSIX path of (inimg02 & ":" & textFieldAdValue as string))
			set dstPath to dstPath's stringByAppendingPathComponent_(theChosen)
			log dstPath
			log manager's copyItemAtPath_toPath_error_(theChosenPath, dstPath, missing value) -- should log 1 if successful
		end repeat
	end applicationWillFinishLaunching_
	
	on fileManager_shouldCopyItemAtPath_toPath_(man, fromPath, toPath)
		if man's fileExistsAtPath_(toPath) as boolean is true then
			man's removeItemAtPath_error_(toPath, missing value)
		end if
		return 1
	end fileManager_shouldCopyItemAtPath_toPath_

Ric

thanks, got this to work.

Which part lets it know to go to the on fileManager_shouldCopyItemAtPath_toPath_(man, fromPath, toPath)? is it the manager’s setDelegate_(me)?

Also if you have some time could you show me how to check first? If not I understand…

Thanks,
Scott

No, it’s not the setting of the delegate that calls the method – delegate methods are called by the object that set the delegate, so in this case, that’s the file manager. When certain actions happen, like trying to copy an item, the delegate method fileManager_shouldCopyItemAtPath_toPath_ is called automatically by the file manager, and it supplies the arguments (man, fromPath and toPath). Setting the delegate just determines where the message is sent, so if you had a second script in your app, you could set that as the delegate instead of this one, and then you would put the fileManager_shouldCopyItemAtPath_toPath_ method in that script instead.

That’s all I have time for now, I’ll get back to you later

Ric

Thanks for all of your time, I really appreciate your help! You have really helped me to start understanding this…

Thanks,
Scott

Hello. I’m trying to adapt the above method to use it for renaming a file.

I’m trying to get the base path without the file name by using this:

set dstpath to aURL's URLByDeletingLastPathComponent()
            set dstPath to dstPath's stringByAppendingPathComponent_(theNewName)

but it throws this error:
[NSURL stringByAppendingPathComponent:]: unrecognized selector sent to instance 0x2006d9a00

Alternatively, is there a better way to rename a file?

Thanks in advance

Hi,

dstPath is an NSURL object not a string

set destinationURL to aURL's URLByDeletingLastPathComponent()
set destinationURL to destinationURL's URLByAppendingPathComponent_(theNewName)
set destinationPath to destinationURL's |path|

Ah, thank you. I worked around it by using substringTo and From Index. I’ll rework it with this code now.