QLab Script - update all instances

Contents

Table of Contents

This is an "external script" - see QLab Scripts and Macros

(* Update all instances *)
 
--
 
set theExplanation to "This script will take the last Audio Cue currently selected in QLab, copy all the settings (except Gangs) from the " & ¬
    "Settings & Levels tabs of the Inspector, and then apply them to every Audio Cue in the workspace that references the same file target.
 
For example, say you need to turn all those doorbells down a bit and move them to another speaker: do one and then have this script update all the others..."
 
--
 
(* This script is not designed to be run from within QLab!
 
v1.0: 11/01/10 Rich Walsh
 
<<< Last tested with: QLab 2.2.6; Mac OS 10.5.8 & 10.6.2 >>> *)
 
-- ###FIXME### QLab and/or the "script runner" is, generally, increasingly unresponsive to scripts the more cues there are in a workspace
 
-- Declarations
 
global dialogTitle
set dialogTitle to "Update all instances"
 
-- Preamble
 
display dialog theExplanation & return & return & "Are you sure you wish to proceed?" with title dialogTitle with icon 1 ¬
    buttons {"Cancel", "OK"} default button "OK" cancel button "Cancel"
 
-- Check QLab is running
 
tell application "System Events"
    set qLabIsRunning to count (every process whose name is "QLab")
end tell
if qLabIsRunning is 0 then
    display dialog "QLab is not running." with title dialogTitle with icon 0 buttons {"OK"} default button "OK" giving up after 5
    return
end if
 
tell application "QLab"
 
    activate
 
    -- Test for a workspace and a selection
 
    set noSelection to false
    try
        set theSelection to (selected of front workspace as list)
        set countSelection to count theSelection
        if countSelection is 0 then
            set noSelection to true
        end if
    on error
        set noSelection to true
    end try
    if noSelection is true then
        display dialog "There is no selection in QLab." with title dialogTitle with icon 0 buttons {"OK"} default button "OK" giving up after 5
        return
    end if
 
    -- Find the last Audio Cue in the selection and check it has a valid target, or give up
 
    tell front workspace
 
        set badSelection to true
        set hasTarget to ""
        repeat with i from countSelection to 1 by -1
            if q type of item i of theSelection is "Audio" then
                set badSelection to false
                set theAudioCue to item i of theSelection
                try
                    set targetTest to (file target of theAudioCue) as string
                    if targetTest is "missing value" then
                        set hasTarget to "The last selected Audio Cue has lost its target."
                    end if
                on error
                    set hasTarget to "The last selected Audio Cue does not have a valid target."
                end try
                exit repeat
            end if
        end repeat
        if badSelection is true then
            display dialog "QLab's selection does not contain an Audio Cue." with title dialogTitle with icon 0 buttons {"OK"} default button "OK" giving up after 5
            return
        end if
        if hasTarget is not "" then
            display dialog hasTarget with title dialogTitle with icon 0 buttons {"OK"} default button "OK" giving up after 5
            return
        end if
 
        display dialog "One moment caller..." with title dialogTitle with icon 1 buttons {"OK"} default button "OK" giving up after 1
 
        set startTime to time of (current date)
 
        -- Copy the levels
 
        set theLevels to {}
        set howManyChannels to audio input channels of theAudioCue
        repeat with i from 0 to howManyChannels
            repeat with j from 0 to 48
                copy (getLevel theAudioCue row i column j) to end of theLevels
            end repeat
        end repeat
 
        -- Copy the other properties
 
        set theTarget to file target of theAudioCue
        set theID to uniqueID of theAudioCue
        set thePatch to patch of theAudioCue
        set theStart to start time of theAudioCue
        set theLoopStart to loop start time of theAudioCue
        set theLoopEnd to loop end time of theAudioCue
        set theEnd to end time of theAudioCue
        set theLoopCount to loop count of theAudioCue
        set theInfiniteLoop to infinite loop of theAudioCue
        set theGuarantee to guarantee sync of theAudioCue
 
        -- ### Mac OS X 10.6.2 fix for incorrectly returned items
 
        if theStart is missing value then
            set theStart to 0
        end if
        if theLoopStart is missing value then
            set theLoopStart to 0
        end if
 
        -- Update all instances
 
        set allInstances to every cue whose broken is false and q type is "Audio" and file target is theTarget and uniqueID is not theID
        set allInstancesRef to a reference to allInstances
        set countInstances to count allInstancesRef
 
        repeat with i from 1 to countInstances
 
            set eachCue to item i of allInstancesRef
 
            repeat with j from 0 to howManyChannels
                repeat with k from 0 to 48
                    setLevel eachCue row j column k db (item (1 + j * 49 + k) of theLevels)
                end repeat
            end repeat
 
            set patch of eachCue to thePatch
            set start time of eachCue to theStart
            set loop start time of eachCue to theLoopStart
            set loop end time of eachCue to theLoopEnd
            set end time of eachCue to theEnd
            set loop count of eachCue to theLoopCount
            set infinite loop of eachCue to theInfiniteLoop
            set guarantee sync of eachCue to theGuarantee
 
            if i < countInstances then -- Countdown timer (and opportunity to escape)
                set timeTaken to ((time of (current date)) - startTime) as integer
                set timeString to my makeMMSS(timeTaken)
                if application "QLab" is frontmost then
                    display dialog (("Time elapsed: " & timeString & " - " & i as string) & " of " & countInstances as string) & ¬
                        " instances done..." with title dialogTitle with icon 1 buttons {"Cancel", "OK"} default button "OK" cancel button "Cancel" giving up after 1
                end if
            end if
 
        end repeat
 
    end tell
 
    activate
    set timeTaken to ((time of (current date)) - startTime) as integer
    set timeString to my makeNiceT(timeTaken)
    display dialog "Done. 
 
(That took " & timeString & ".)" with title dialogTitle with icon 1 buttons {"OK"} default button "OK" giving up after 60
 
end tell
 
-- Subroutines
 
on makeMMSS(howLong)
    set howManyMinutes to howLong div 60
    set minuteString to (howManyMinutes as string)
    set howManySeconds to howLong mod 60 as integer
    if howManySeconds > 9 then
        set secondString to (howManySeconds as string)
    else
        set secondString to "0" & (howManySeconds as string)
    end if
    return minuteString & ":" & secondString
end makeMMSS
 
on makeNiceT(howLong)
    if howLong is 0 then
        return "less than a second"
    end if
    set howManyHours to howLong div 3600
    if howManyHours is 0 then
        set hourString to ""
    else if howManyHours is 1 then
        set hourString to "1 hour"
    else
        set hourString to (howManyHours as string) & " hours"
    end if
    set howManyMinutes to (howLong mod 3600) div 60
    if howManyMinutes is 0 then
        set minuteString to ""
    else if howManyMinutes is 1 then
        set minuteString to "1 minute"
    else
        set minuteString to (howManyMinutes as string) & " minutes"
    end if
    set howManySeconds to howLong mod 60 as integer
    if howManySeconds is 0 then
        set secondString to ""
    else if howManySeconds is 1 then
        set secondString to "1 second"
    else
        set secondString to (howManySeconds as string) & " seconds"
    end if
    if hourString is not "" then
        if minuteString is not "" and secondString is not "" then
            set theAmpersand to ", "
        else if minuteString is not "" or secondString is not "" then
            set theAmpersand to " and "
        else
            set theAmpersand to ""
        end if
    else
        set theAmpersand to ""
    end if
    if minuteString is not "" and secondString is not "" then
        set theOtherAmpersand to " and "
    else
        set theOtherAmpersand to ""
    end if
    return hourString & theAmpersand & minuteString & theOtherAmpersand & secondString
end makeNiceT
 
(* END: Update all instances *)