Hello.
I hope you like and use this, and posts if there are any problems or questions.
Enjoy!
Introduction
I really find it unnecessary to wade through file or folder choose dialogs, when it should be reasonable to demand from the script to remember the last location. The last location, -is the obvious choice under the rerun of a script in a great many circumstances. instead of having to start all over again.
This is isn’t exactly rocket science, but still useful; so I thought it would be nice to have that functionality provided by a script object once and for all.
Preliminaries
You need to declare an empty property for each path which should be saved in your script.
It demands an initialPath, or starting point in some file structure.
This kind of initial path, is not chosen by the user, but by what the programmer (You) finds to be sensible in context of the purpose of the script.
This is rather in opposite to when you beg a user to set an initial path during first run, because the path is to some dedicated files structure for the script you have no idea about where resides.
(You could still use this package for that purpose if you supplied an initial path of:
(POSIX file "/" as text)
If you need to qualify a path to a subtree and that subtree are guaranteed to contain one known subfolder then see this post.
Overview
The script smartPathParadigm contains all necessary functionality and must be copied into your script.
The handler smartPathParadigm’s initiateSmartPath initiates a script object with necessary functionality.
The resulting script object has three handlers
[b][color=blue]getPrevPath[/color]()[/b] returns the previous path.
[b][color=blue]setPrevPath[/color](hfsNewPrevPathAsText)[/b] sets a path explicitly from a folder.
[b][color=blue]updatePrevPath[/color](hfsNewPrevPathAsText)[/b] sets the previous path regardless if it was given a file or folder.
-it will always use the parent folder from the path it was given.
[b][color=blue]withinRealm[/color][/b]([b][color=red]hfsFilePathAsText[/color][/b]) Returns [b][color=blue]true[/color][/b] if this path is within the realms - subfolder or file the path denotes is within
the [b][color=blue]intitalPath[/color][/b] and [b][color=blue]false [/color][/b] otherwise.
Implementation
I wanted to encapsulate as much as possible of this behaviour in an object,
and let it be transparent to actual choosing of files and such, since this functionality will will vary wildly from context to context and programmer to programmer. This is meant to be a “one size fits all” solution.
The object is created by a handler.
Prerequisites
You need to declare empty properties in you main script, and initiate the properties with your chosen initial with something similar to this:
property scoFirstPathToBeUsed : {} -- say for finding a source folder
smartPathParadigm's initiateSmartPath(scoFirstPathToBeUsed, (path to documents folder as text))
You will need one object for each of the paths in your script or applet.
You need two lines of code per path to initiate a path to be remembered.
Usage Details
The difference of setting a previous path implicitly or explicitly.
You don’t need and you shouldn’t do any “massage” of paths of your own. Use the specialiced call setPrevPath when you know that this is the explicit path you want to set as the previous path, only containing folders, if not; if your path is within a successful result from say a choose file/folder dialog then use updatePreviousPath which extracts the parent folder of whatever.
Important
You must take precautions to get the properties written back to the script.
-You can’t just bail out of your script with error number −128 anymore.
You have to return in order to save the previous path back into the script
The solution can’t be used directly in an applet
In order to use this in an applet, you must save the properties as a script object into the the bundle of the applet in the Quit handler.
Demo Example
-- The Idea and implementation and any faults is totally mine. © McUsr 2010 and put in the Public Domain.
-- The usually guarrantees about nothing what so ever applies, use it at your own risk.
-- Read the documentation.
-- You are not allowed to post this code elsewhere, but may of course refer to the post at macscripter.net.
” macscripter.net/viewtopic.php?id=12895
property scoFirstPathToBeUsed : {} -- say for finding a source folder
property scoSecondPathToBeUsed : {} -- and for a target folder
set scoFirstPathToBeUsed to smartPathParadigm's initiateSmartPath(scoFirstPathToBeUsed, (path to documents folder as text))
set scoSecondPathToBeUsed to smartPathParadigm's initiateSmartPath(scoSecondPathToBeUsed, (path to scripts folder from user domain as text))
scoFirstPathToBeUsed's initialPath --> "Macintosh HD:Users:You:Documents:"
scoSecondPathToBeUsed's initialPath --> "Macintosh HD:Users:You:Library:Scripts:"
scoFirstPathToBeUsed's getPrevPath() --> "Macintosh HD:Users:You:Documents:"
scoSecondPathToBeUsed's getPrevPath() --> "Macintosh HD:Users:You:Library:Scripts:"
” *** Line below sets path explicitly ***
scoFirstPathToBeUsed's setPrevPath((path to documents folder as text))
” *** Observe: the same path is returned ***
scoFirstPathToBeUsed's getPrevPath() --> "Macintosh HD:Users:You:Documents:"
” *** Lines below updates path conditionally ->condition: path is within realm of initial path
local blnIsWithinRealm ” A boolean
set blnIsWithinRealm to scoFirstPathToBeUsed's withinRealm(theScriptLibrary as text)
-- this tells us if the user has surpassed the inital realm of the library path.
if blnIsWithinRealm is true then scoFirstPathToBeUsed's updatePrevPath(theScriptLibrary as text)
-- saves the path for next time
” *** Line below sets path implicitly from the parent path wether it is folder app or file ***
scoFirstPathToBeUsed's updatePrevPath("Macintosh HD:Users:You:Applications:HardwareGrowler.app:")
” *** Observe: the parent path is returned ***
scoFirstPathToBeUsed's getPrevPath() --> "Macintosh HD:Users:You:Applications"
You are supposed to know that the choose file and choose folder returns an alias or raises error −128 if you hit escape or Cancel. But choose from list returns false.
The Code
-- The Idea and implementation and any faults is totally mine. © McUsr 2010 and put in the Public Domain.
-- The usually guarrantees about nothing what so ever applies, use it at your own risk.
-- Read the documentation.
-- You are not allowed to post this code elsewhere, but may of course refer to the post at macscripter.net.
-- macscripter.net/viewtopic.php?id=129895
(*
TERMS OF USE.
This applies only to posting code, as long as you don't post it, you are welcome to do
whatever you want to do with it without any further permission.
Except for the following: Selling the code as is, or removing copyright statmentents and the embedded link in the code (without the http:// part) from the code.
You must also state what you eventually have done with the original source. This obviously doesn't matter if you distribure AppleScript as read only. I do not require you to embed any properties helding copyright notice for the code.
Credit for having contributed to your product would in all cases be nice!
If you use this code as part of script of yours you are of course welcome to post that code with my code in it here at macscripter.net. If you then wish to post your code elsewhere after having uploaded it to MacScripter.net please email me and ask for permission.
The ideal situation is however that you then refer to your code by a link to MacScripter.net
The sole reason for this, is that it is so much better for all of us to have a centralized codebase which are updated, than having to roam the net to find any usable snippets. Which some of us probabaly originated in the first hand.
I'm picky about this. If I find you to have published parts of my code on any other site without previous permission, I'll do what I can to have the site remove the code, ban you, and sue you under the jurisdiction of AGDER LAGMANNSRETT of Norway. Those are the terms you silently agree too by using this code.
The above paragraphs are also valid if you violate any of my terms.
If you use this or have advantage of this code in a professional setting, where professional setting means that you use this code to earn money by keeping yourself more productive. Or if you as an employee share the resulting script with other coworkers, enhancing the productivity of your company, then a modest donation to MacScripter.net would be appreciated.
*)
-- See macscripter.net/viewtopic.php?pid=129895#p129895 For Documentation
-- © McUsr 2010 and put in the public domain.
script smartPathParadigm
property McUsr : "1.2 polymorphic and Debugged"
property initialPath : ""
property prevPath : ""
-- maybe remake the object model a little as well.
on makeSmartPath(hfsInitialPathAsText)
script o
property parent : smartPathParadigm
property initialPath : "" & hfsInitialPathAsText -- doesn't harm
property prevPath : ""
end script
o
end makeSmartPath
on getInitialPath()
-- gets the initial path from the last initialization
my initialPath
end getInitialPath
on getPrevPath()
-- gets the previous path. - there is no current.
if my prevPath is "" then
my initialPath
else
my prevPath
end if
end getPrevPath
on updatePrevPath(hfsReturnedPathAsText)
-- sets the previous path to this parent folder of the path delivered.
local newPath
set hfsReturnedPathAsText to "" & hfsReturnedPathAsText
set newPath to smartPathParadigm's getPathToParentFolder(hfsReturnedPathAsText)
if my prevPath is not newPath then
set my prevPath to newPath
end if
end updatePrevPath
on withinRealm(hfsFilePathAsText)
-- check to see if a path is in within the realm of the initial path.
set hfsFilePathAsText to "" & hfsFilePathAsText
if hfsFilePathAsText contains my initialPath then
return true
else
return false
end if
end withinRealm
on setPrevPath(hfsNewPrevPathAsText)
-- sets a path literally
set hfsNewPrevPathAsText to "" & hfsNewPrevPathAsText -- doesn't harm
set my prevPath to hfsNewPrevPathAsText
end setPrevPath
on initiateSmartPath(scoForPath, hfsIntialPathAsText)
-- constructor which allows reuse.
script o
property pathobj : scoForPath
end script
set hfsIntialPathAsText to "" & hfsIntialPathAsText
if scoForPath is {} then
set o's pathobj to smartPathParadigm's makeSmartPath(hfsIntialPathAsText)
else
set o's pathobj's initialPath to hfsIntialPathAsText
set o's pathobj's prevPath to ""
end if
o's pathobj
end initiateSmartPath
on getPathToParentFolder(hfsFileOrFolderPathAsText)
-- return sparehtn folder.
local tids, theFile
set hfsFileOrFolderPathAsText to "" & hfsFileOrFolderPathAsText -- doesn't harm.
set tids to AppleScript's text item delimiters
set AppleScript's text item delimiters to ":"
if character (length of hfsFileOrFolderPathAsText) of hfsFileOrFolderPathAsText is ":" then
set hfsFileOrFolderPathAsText to text items 1 thru -3 of hfsFileOrFolderPathAsText
else
set hfsFileOrFolderPathAsText to text items 1 thru -2 of hfsFileOrFolderPathAsText
end if
set hfsFileOrFolderPathAsText to "" & hfsFileOrFolderPathAsText -- necessary here.
set AppleScript's text item delimiters to tids
return hfsFileOrFolderPathAsText
end getPathToParentFolder
end script
Best Regards
Mcusr