Simple progress bar example

Discussion in 'Mac Programming' started by SouthernAtHeart, Feb 3, 2012.

  1. macrumors newbie

    Joined:
    Nov 6, 2011
    #1
    I am dabbling in AppleScript and would like to try adding a progress bar to my script so I downloaded Xcode 4. I found a couple examples That seem real easy to follow, but they must be an old version of Xcode because i can't get anywhere in my Xcode 4. Here's one tutorial that seems real easy to follow:
    http://macscripter.net/viewtopic.php?id=24760

    Is there something like this for the new Xcode? Or should I download an older version of Xcode
    Thanks
     
  2. macrumors 6502

    Joined:
    May 29, 2011
    Location:
    Littleton, Colorado, USA
    #2
    If all you are familiar with is AppleScript Studio (or just regular AppleScript), there isn't a whole lot out there that demonstrates the new AppleScript Objective-C framework - mostly it is a matter of converting from the existing Objective-C documentation.

    There is an example project in Shane Stanley's AppleScriptObjC Explored ebook, which is pretty much the handbook for ASObjC. Lion's AppleScript Editor has the ability to create applications using ASObj-C, so if you are just wanting to put a progress indicator into a regular AppleScript, there are also some Cocoa-AppleScript examples.
     
  3. thread starter macrumors newbie

    Joined:
    Nov 6, 2011
    #3
    I'm looking at these links you mentioned. I think it's a bit over my head though. I have scripts that do things like organize contacts and other things with contacts in the address book, and sometimes it takes it awhile (30 seconds)so I thought a progress bar would let the user know my script didn't crash on them, but it looks loke it's pretty complex to just add a progress bar. Its too bad, because that example of a progressbar in the old Xcode looked sumer enough to follow.
    Thanks for the input
     
  4. macrumors 6502

    Joined:
    May 29, 2011
    Location:
    Littleton, Colorado, USA
    #4
    The Cocoa-AppleScript template isn't too complicated (I have a version that uses a controller script similar to the old BP Progress bar), although you need to be able to break the task up into enough pieces to make the progress bar meaningful. Maybe you could just put up an indeterminate progress indicator (a spinner or barber pole).
     
  5. thread starter macrumors newbie

    Joined:
    Nov 6, 2011
    #5
    ...that would be great. Can you do that will plain old AppleScript? I'll do some research...
     
  6. thread starter macrumors newbie

    Joined:
    Nov 6, 2011
    #6
    Here's one of my scripts that can take long enough that a user might think its not doing anything.

    Is there just a few lines to add that would show some kind of barberpole? I searched for AppleScript barberpole but didn't come up with any examples.

    Code:
    set BadList to {"(", ")", " "}
        set Changes to "Person--Phone--OldNo--NewNo" & return
        tell application "Address Book"
            repeat with Acontact in people in the group named theirGroup
                repeat with APhone in phones of Acontact
                    set newtarget to ""
                    set Target to value of APhone
                    repeat with achar in characters of Target
                        if achar is not in BadList then set newtarget to newtarget & achar
                        if achar is in {" "} then
                            if (count of newtarget) < 12 then set newtarget to newtarget & "-"
                        end if
                    end repeat
                    if not (Target = newtarget) then
                        set theChange to (name of Acontact) & "  --  " & (label of APhone)
                        set theChange to theChange & "  --  " & Target & "  --  " & newtarget
                        set Changes to Changes & theChange & return
                        set value of APhone to newtarget
                        save
                    end if
                end repeat
            end repeat
            
        end tell
        Changes
    
     
  7. macrumors 6502

    Joined:
    May 29, 2011
    Location:
    Littleton, Colorado, USA
    #7
    You wouldn't need to break anything up to use the barberpole. Your script repeats through the people in a group though, so you could count the total, and increment the progress indicator each time through the loop.

    My template is set up right now to process files, but it can be changed easily enough. The Changes/log variable would need to be put in a dialog or something, since the Cocoa-AppleScript can only be run as an application. Is that the compete script? I'm noticing that the theirGroup variable is not set.
     
  8. SouthernAtHeart, Feb 3, 2012
    Last edited: Feb 3, 2012

    thread starter macrumors newbie

    Joined:
    Nov 6, 2011
    #8
    ...sorry I copied this out of a series of steps, so theirgroup was set at the beginning. But basically each step is like this, running through the contacts making a change like this. You mentioned you template? Did you post an example you made, I'm not seeing it I guess...
    I tried looking at the example script folder under help in the Appllescript editor, but didn't see anything there that helped.
    If you have an example similar to what I'm trying to do, I'd like to see it.
    Thanks,
     
  9. macrumors 6502

    Joined:
    May 29, 2011
    Location:
    Littleton, Colorado, USA
    #9
    I didn't post the template, it is an application bundle that I have on my AppleScriptObjectiveC home page - the direct link is here.

    As I mentioned earlier, the template is set up as an example using a progress bar for some files (it doesn't actually do anything with them, though), so the main script would need to be reworked to use the Address Book script. If the script works as posted, you should be able to replace the main script in the template with yours, adding the commands to the progress bar (see the ProgressBarController.scpt in the application bundle). It is getting late here, but I will post a modified script later.
     
  10. thread starter macrumors newbie

    Joined:
    Nov 6, 2011
    #10
    Thanks. I bought that book you mentioned, will give it a reading over the next few days. It may be over my head.
    I've made custom forms with VBA in MS Access. I see in Xcode 4 there are button, text boxes, even a progress bar. It would be great if I could made little AppleScript utilities and turn them into professional looking apps with this stuff. I'm hoping this book is for beginners.
    Getting late here, too
     
  11. macrumors 6502

    Joined:
    May 29, 2011
    Location:
    Littleton, Colorado, USA
    #11
    Give this a try. Using my progress bar template, make a new application and replace the main script with:

    Code:
    property myProgressController : missing value -- the controller script instance
    
    on run
    	set myProgressController to current application's ProgressBarController's alloc's init() -- create instance
    	try
    		doStuff()
    	on error errmess number errnum
    		display alert "error number " & errnum message errmess
    	end try
    	tell me to quit
    end run
    
    on doStuff()
    	set theirGroup to "test" -- fill in the blank
    	set badList to {"(", ")", " "} -- a list of characters to clean
    	set changes to {"Person -- Phone -- Old# -- New#"} -- this will be a list of changes
    	
    	tell application "Address Book"
    		set theContacts to (people in group theirGroup)
    		
    		set theCount to (count theContacts) -- get a maximum count for the progress bar
    		tell myProgressController -- set up and show the progress bar
    			createProgressWindow()
    			setBarberPole_(false)
    			setupProgressWithTopText_bottomText_maxValue_("Fixing phone numbers...", "", theCount)
    			delay 1
    		end tell
    		
    		repeat with this from 1 to theCount
    			set aContact to item this of theContacts
    			
    			set theName to name of aContact
    			tell myProgressController -- increment the progress bar
    				updateProgressByAmount_topText_bottomText_(1, "Processing item " & this & " of " & theCount, theName)
    				doEventFetch() -- keep event queue cleared
    				-- delay 0.25
    			end tell
    			
    			repeat with aPhone in phones of aContact
    				set newTarget to ""
    				set target to (value of aPhone)
    				repeat with aChar in (characters of target)
    					if aChar is not in badList then set newTarget to newTarget & aChar
    					if aChar is in {" "} then
    						if (count of newTarget) < 12 then set newTarget to newTarget & "-"
    					end if
    				end repeat
    				if not (target = newTarget) then
    					set theChange to (name of aContact) & "  --  " & (label of aPhone)
    					set theChange to theChange & "  --  " & target & "  --  " & newTarget
    					set the end of changes to theChange
    					set value of aPhone to (newTarget as text)
    					save
    				end if
    			end repeat
    		end repeat
    		delay 0.5
    	end tell
    	
    	if (count changes) is greater than 1 then (choose from list changes with empty selection allowed) -- show any changes
    end doStuff
     
  12. thread starter macrumors newbie

    Joined:
    Nov 6, 2011
    #12
    Thanks!

    I'll definitely look into this. I've started reading this ebook you mentioned. It's VERY helpful.


     
  13. macrumors regular

    kildjean

    Joined:
    Apr 16, 2005
    Location:
    Useless, TX
    #13
    Here goes nothing...

    Disclosure: I am aware that thing to resuscitate this thread might be fruitless but just in case...

    I made this script to make a backup of a user profile. The script on its own works very well. It asks which profile you want to backup into a filename.dmg and stores it on the desktop... you can run it again to restore said filename.dmg into the profile it goes into.

    Code:
    
    property theTitle : "User Migration Tool for Mac v0.01"
    
    set theDialogResults to display dialog "Do you want to BACKUP or RESTORE a user's profile?" with title theTitle buttons {"Backup", "Restore", "Cancel"}
    if button returned of theDialogResults is "Backup" then
    	backup()
    else
    	restore()
    end if
    
    on backup()
    	--	get the path to the user folder to backup 
    	set theSource to choose folder with prompt "Select a user folder to backup to a disk image." default location path to users folder
    	
    	--	get file name and path where image will be saved
    	set theFile to choose file name with prompt "Select the name and location where you want to save the image file." default name "MyBackup.dmg" default location path to desktop
    	
    	--	warning
    	display dialog "Be patient. The backup may take considerable time. You will be notified upon completion." with title theTitle buttons {"Ok"} default button "Ok" giving up after 5 with icon caution
    
    	--	make disk image
    	set theResult to do shell script ("/usr/bin/hdiutil create -fs HFS+ -srcFolder " & POSIX path of theSource & " " & POSIX path of theFile) with administrator privileges
    	log theResult
    			
    	if theResult contains "created:" then
    		display dialog "The backup is complete." with title theTitle buttons {"Ok"} default button "Ok" giving up after 5
    		say "Backup is complete"
    	end if
    end backup
    
    
    on restore()
    	--	get disk image to mount
    	set theFile to choose file of type "devi" with prompt "Select a disk image file that contains a copy of a user's profile to restore." default location path to desktop
    	
    	--	mount disk image 
    	set theMountPath to do shell script ("/usr/bin/hdiutil mount " & POSIX path of theFile & "| grep '/Volumes' | awk '{ print $3 }'")
    	log theMountPath
    	
    	--	get folder where user's profile will be copied
    	set theDestination to choose folder with prompt "Select the user's home folder where the profile will be retored." default location path to users folder
    	
    	--	warning
    	display dialog "Be patient. The restore may take considerable time. You will be notified upon completion." with title theTitle buttons {"Ok"} default button "Ok" giving up after 5 with icon caution
    	
    	--	copy data to user's folder
    	set theResult to do shell script ("/usr/bin/ditto " & theMountPath & " " & POSIX path of theDestination) with administrator privileges
    	log theResult
    	
    	--	unmount disk image
    	do shell script ("/usr/bin/hdiutil eject " & theMountPath)
    	
    	if theResult is "" then
    		display dialog "The restore is complete." with title theTitle buttons {"Ok"} default button "Ok" giving up after 5
    		say "Restore is complete"
    	end if
    end restore
    
    
    The problem I am having is that during the Backup or the Restore there is not "Progress Bar" Indicator of how far into the backup or the restore it is on... there is no time estimation of when it will complete.

    I wanted some help in adding a barber pole that spins until the backup or the restore is done. The line that tells the script when the backup is done is: if theResult contains "created:" then and for the restore it would be:

    Code:
    if theResult is "" then
    		display dialog "The restore is complete."
    
    Any help or direction would be great. I have tried just about everything I can think off... short of building an app in Xcode which I don't have the time to learn for this particular project... don't know what to do.

    Thanks!

    K
     
  14. macrumors 6502

    Joined:
    May 29, 2011
    Location:
    Littleton, Colorado, USA
    #14
    What OS are you running? Yosemite added some properties to AppleScript for indicating progress (see the 10.10 release notes), otherwise you will need to use some AppleScriptObjC from either a Cocoa-AppleScript applet or Xcode.
     
  15. macrumors regular

    kildjean

    Joined:
    Apr 16, 2005
    Location:
    Useless, TX
    #15
    I am running Yosemite / Mavericks. ASObjC Runner is deprecated in Yosemite and only works in Mavericks. I took a look at the new configs you mentioned earlier but they don't offer me a way to add a progress bar to the script...

    A determinate progress bar would be nice but the main purpose of the script is to backup a user profile and store it on a .dmg file, a process which I think probably has an unguessable / indeterminable duration.


    Most if the options on the Yosemite Updates for progress automation, include step counter in order to show progress, but there is no way to that I have found, to add just a barber pole that spins until the script is done doing the backup or the restore.

    I have been told I should probably go the Xcode way since it has widgets I can use, but I tried to build my script in Xcode and I got lost.
     

Share This Page