[audacity4blind] Test script for Silence Preview

  • From: Gary Campbell <campg2003@xxxxxxxxx>
  • To: audacity4blind@xxxxxxxxxxxxx
  • Date: Thu, 27 Nov 2014 18:24:34 -0700

Hi,

Attached is a test version of the JAWS Scripts for Audacity that implements silencing of speech during preview.

The way I'm handling silencing the preview button seems a bit risky to me. I have observed that when the Preview button is activated the dialog is destroyed, focus moves to the Audacity main window, and a dialog for handling the preview is created. In order to detect when the Preview button is activated, I watch for the focus to move to the main window. JAWS DialogActive() function returns false, so I can't even restrict this test to a dialog. When I detect this condition I set some flags that suppress speech during focus changes. I think the next thing that happens is that focus moves to the Stop button. I remember this window handle and terminate Preview processing when this control is destroyed. This means that any time focus moves to the Audacity main window, from anywhere, the Preview functionality is activated. I haven't noticed any problems with this in my usage over the past few months, but my usage patterns tend to be quite repetitive. This is a tricky change, and I'm not quite sure I understand my notes about it, or actually just what the state of my development source is, which is a very good way to introduce major problems into a project! I will release a test version when I figure out just what files have changed, and how to adequately label the version so we'll be able to recognize it easily if someone somehow gets hold of it and reports a problem.

Oh well, attached are the files straight from my JAWS script folder. If you'd like to test them, first back up your current script files. Then save these files in your script folder and compile them with the Script Manager. You might also back up PersonalizedSettings\Audacity.jsi. I don't remember if the settings file has changed or not, or if it would cause problems with the old version if it did.

Here are the additions to What's new.txt since the 2.0 release. Notice that the silence preview hasn't even made it into it yet.

(This file last updated 7/25/2014)

. The URL for the JAWS User's Guide can now be updated via the script (Control+Shift+j).
. Added support for the QuickSettings dialog (JAWS 13 and later).
. Made messages for moving and selecting more consistent.

New in V2.0 (9/15/2013):
....



Thanks.

Gary

[options]
ProgressBarUpdateInterval=5000
.&after.after.*.*.*.1.0.
.&before.before.*.*.*.1.0.
.&Gain.gain.*.*.*.1.0.
.&Length.length.*.*.*.1.0.
.&Location.location.*.*.*.1.0.
.&Range.range.*.*.*.1.0.
.&Sensitivity.Sensitivity.*.*.*.1.0.
.&Short.short.*.*.*.1.0.
.Attac&k.attack.*.*.*.1.0.
.Fr&equency.frequency.*.*.*.1.0.
.g&ain.gain.*.*.*.0.0.
.L&atency.latency.*.*.*.1.0.
.Lo&ng.long.*.*.*.1.0.
.Ma&ximum.maximum.*.*.*.1.0.
.Mi&nimum.minimum.*.*.*.1.0.
.re&duction.reduction.*.*.*.1.0.
.toolbars.tool bars.*.*.*.0.0.
:script for

:function AnnounceOn
:Returns int True if messages should be spoken
:Synopsis Indicate whether messages related to certain Audacity operations 
should be spoken
:Param string/sKey No Description

:function FocusInTrackPanel
:Returns int True if focus is in the track panel
:Description Indicates if the focus is in the track panel.

:function SaySelectionPosition
:Description Says the selection start or end position
:Category Positioning
:Param int/iPosition The ID of the start or end selection position
:Param string/sMessage Spoken message

:function MarkerMovement
:Param string/sScript The script to be performed.
:Param string/sAlert The alert message to be spoken

:function MouseMovement
:Description Used to bypass scripts such as MouseLeft, MouseRight etc. that are 
assigned to Audacity keys while in the main window.
:Param string/sScript The script to perform.

:function AnnounceKeyMessage
:Description Speak a message for an Audacity hotkey if appropriate and send the 
key to Audacity.
:Param string/Message The message to speak

:function SayNotStopped

:function SayNoProject
:Description Speaks a message when no project is open. For example, pressing 
the [ key will speak this message, and the script will exit.
:Category Say

:function NoProject
:Returns int True if no project is open
:Description This function indicates that no project is open (there are no 
tracks in track panel).

:function AutoStartEvent

:function SayNonHighlightedText
:Param handle/hwnd No Description
:Param string/buffer No Description

:function SayFocusedObject

:function IsToolbar
:Returns int True if window hWnd is a toolbar, False otherwise
:Synopsis Return True if hWnd is one of the toolbars.
:Description Return True if hWnd is one of the toolbars. The toolbars are in a 
window named ToolDock under the app window.  It is the second window, the 
selection bar is inside the window following it, which is also named ToolDock. 
Assumes focus is in the main window.
:Param handle/hWnd handle of toolbar

:function GetToolbar
:Returns handle toolbar containing the current control
:Description When focus is on a toolbar control returns the handle of the 
toolbar containing the control

:function FocusInMainWindow
:Returns int No Return Description

:function GetPositionField
:Returns string Value of field
:Description Get the value of one of the selection fields
:Param handle/hWnd Handle of position control

:script SaySelectionStart
:Synopsis Says the value of the Selection Start control
:Description Says the value of the Selection Start control.  If pressed twice 
quickly, moves focus to it.

:script SaySelectionEnd
:Synopsis Say the end position or length of the selection
:Description Say the end position or length of the selection.  Also says 
whether End or Length is selected.  If pressed twice quickly, moves focus to it.

:script SayActiveCursor
:Synopsis Says the Audio Position value
:Description If the PC cursor is active, says the value of the Audio Position 
control.  If the PC cursor is not active or it is pressed twice quickly, says 
the cursor position.

:script ScriptFileName

:script AudacityScriptKeyHelp
:Synopsis Displays Audacity JAWS hot key help in the virtual viewer.
:Description Press twice quickly to display default JAWS hot key help.

:function ShowJawsGuide
:Description Runs the default web browser to display the Audacity Guide for 
JAWS web page.

:function IsWinKeyHelp

:script AudacityKeysHelp
:Synopsis Displays Audacity shortcut keys in the virtual viewer.
:Description Press twice quickly to display Windows shortcut keys

:script MouseUp
:Synopsis Increase track gain or move the mouse pointer/JAWS cursor up
:Description In the Audacity main window you must activate the JAWS cursor to 
perform the default action.  The number of pixels for mouse movement is 
determined by the mouse movement variable.  The value of the mouse movement 
variable is set in default JCF.  It can be modified by using home row utility 
scripts.  This keystroke is useful for accurately positioning the mouse pointer.

:script MouseDown
:Synopsis Decrease track gain or move the mouse pointer/JAWS cursor down
:Description In the Audacity main window you must activate the JAWS cursor to 
perform the default action.  The number of pixels for mouse movement is 
determined by the mouse movement variable.  The value of the mouse movement 
variable is set in default JCF.  It can be modified by using home row utility 
scripts.  This keystroke is useful for accurately positioning the mouse pointer.

:script MouseLeft
:Synopsis Pan left or move the mouse pointer/JAWS cursor to the left
:Description In the Audacity main window you must activate the JAWS cursor to 
perform the default action.  The number of pixels for mouse movement is 
determined by the mouse movement variable.  The value of the mouse movement 
variable is set in default JCF.  It can be modified by using home row utility 
scripts.  This keystroke is useful for accurately positioning the mouse pointer.

:script MouseRight
:Synopsis Pan right or move the mouse pointer/JAWS cursor to the right
:Description In the Audacity main window you must activate the Jaws cursor to 
perform the default action.  The number of pixels for mouse movement is 
determined by the mouse movement variable.  The value of the mouse movement 
variable is set in default JCF.  It can be modified by using home row utility 
scripts.  This keystroke is useful for accurately positioning the mouse pointer.

:script SelectionStart
:Synopsis Says the selection start position
:Description When the [ key is pressed, says the selection start position.
:Category Positioning

:script SelectionEnd
:Synopsis Says the selection end position
:Description When the ] key is pressed, says the selection end position.
:Category Positioning

:script FinishMarkerRight
:Synopsis Moves the end of the selection to the right by a small amount

:script FinishMarkerLeft
:Synopsis Moves the end of the selection to the left by a small amount

:script StartMarkerRight
:Synopsis Moves the start of the selection to the right by a small amount

:script StartMarkerLeft
:Synopsis Moves the start of the selection to the left by a small amount

:script JAWSHome

:script JAWSEnd

:script MoveToStartOfSelectedTracks
:Synopsis Moves cursor to start of audio in selected tracks

:script MoveToEndOfSelectedTracks
:Synopsis Moves cursor to end of audio in selected tracks

:script SelectToBeginning
:Synopsis Moves the selection start to the start of the audio in the selected 
tracks

:script SelectToEnd
:Synopsis Moves the selection end to the end of the audio in the selected tracks

:script SelectFromStartOfLine
:Synopsis Select from current position to the start of file

:script SelectToEndOfLine
:Synopsis Select from current position to the end of file

:script DeleteSelectedAudio
:Synopsis Deletes the selected audio.

:script JAWSDelete
:Synopsis In track panel delete selected audio, otherwise does normal delete.
:Description If focus is in the main window, a project exists, and audio is 
selected, the DEL key will delete it.  In this case we perform the script 
DeleteSelectedAudio.  Otherwise we perform the default script.

:script JAWSBackspace
:Synopsis Similar to JAWSDelete.

:script SayPriorCharacter

:script SayNextCharacter

:script Copy
:Synopsis Copies selected audio to clipboard
:Description Copy the selected audio to the clipboard if focus is in the main 
window.  Otherwise, perform the default script.

:script CutToClipboard
:Synopsis Cuts selected audio to clipboard

:script DeselectAll
:Synopsis Deselects all audio in current open project

:script CloseFocusTrack
:Synopsis Close the currently focused track

:script AnnounceOnOff
:Synopsis Toggle the announcement of Audacity messages on or off

:script NextDocumentWindow
:Synopsis In the toolbars moves to the next toolbar.

:script PreviousDocumentWindow
:Synopsis In the toolbars moves to the previous toolbar.

:function GetAudacityState
:Returns int a bit mask of the ST_ state constants, or 0 if the Transport 
toolbar cannot be found
:Synopsis returns the current program state-- play, record, pause

:script SayAudacityState
:Synopsis Says the current program state-- play, record, pause

:script Enter
:Synopsis In the main window when not stopped, pause/unpause (if "ENTER during 
play/record pauses" option activated).

:script CtrlEnter
:Synopsis In the main window when not stopped, send ENTER (if "ENTER during 
play/record pauses" option activated).

:function GetObjState
:Returns int object state.  Use CTRL constants from hjconst.jsh to interpret, 
not state constants from msaaconst.jsh
:Synopsis Returns the object state of the object in the window
:Description Works for windows whose object name is the same as the window name
:Param handle/hWnd window to inspect

:function IsStopped
:Returns int TRUE if currently stopped or the Transport toolbar cannot be 
found.  Returns False otherwise.
:Synopsis Determines if Audacity is currently stopped
:Description Determines if Audacity is currently stopped.  Returns TRUE if 
stopped or the Transport toolbar cannot be found.  This is used to keep cursor 
position from being spoken unless Audacity is stopped.

:script AdjustJawsVerbosity

:script AdjustJAWSOptions

:function NodeHlp
:Returns string No Return Description
:Param string/sNodeName No Description

:function UOAnnounceMessages
:Returns string No Return Description
:Param int No Description

:function UOAnnounceMessagesHlp
:Returns string No Return Description

:function UOAnnounceToolbars
:Returns string No Return Description
:Param int No Description

:function UOAnnounceToolbarsHlp
:Returns string No Return Description

:function UOEnterPause
:Returns string No Return Description
:Param int No Description

:function UOEnterPauseHlp
:Returns string No Return Description

:function AddDefaultConfig
:Description Sets the JAWS options for Audacity to their default values and 
writes them to the .jsi file.

:script ResetConfig
:Synopsis Reset all audacity JAWS script config options to their default values.

:script SayAppVersion

:script SelectAll

:function ProcessVST
:Description Activates Preset, Load Preset, and Save Preset controls in VST 
plugin dialogs.
:Param int/iControlID control to activate

:script VSTPreset
:Synopsis Set focus to the preset control in VST dialogs.
:Description Adds support for an access key to set focus to the preset control 
in VST dialogs.

:script VSTLoadPreset
:Synopsis Activates the Load button to load a preset in some VST plugin dialogs

:script VSTSavePreset
:Synopsis Activates the Save button to save a preset in some VST dialogs

:script SayJump
:Synopsis Speaks the position after executing a short/long jump key

:function IsTrackSelected
:Returns int True if current track is selected
:Description Indicates whether the track is selected

:function SayNoTrackSelected
:Description Warn when the user performs a script that requires the current 
track to be selected.

:function IsWarningDialog
:Returns int True if focus is in the warning dialog
:Description Verify that focus is in the warning dialog that appears when 
importing uncompressed audio files.

:script SayLine

:script SwitchChainsList
:Synopsis Switch between the Chains and Chain lists in the Edit Chains dialog.

:script PasteFromClipboard

:script ShowCopyright

:function CheckAudacityVersion
:Returns int True if the version of Audacity is <= the specified version.
:Description Varify that current audacity version is equal to or higher than a 
given version.
:Param string/sCheckver the version to compare against  in the form 
"major,minor,build,fix".  Trailing segments may be omitted, in which case they 
are not checked.  Ex: "2,0,3" to verify that the program version is 2.0.3 or 
higher.

:script test

:function loadNonJCFOptions

:script AddAudacityJawsGuide
:Synopsis Allow adding, or changing the Audacity Guide link
:Category Script

:Script Record
:Synopsis Silence key that starts recording functions.
:Description Silence key that starts recording functions.  This script types 
the key to which it is bound.  If it is not in a dialog or menu it does not 
speak the key label.

Attachment: audacity.JSM
Description: JavaScript source

<?xml version="1.0" encoding="utf-8" ?>
<QuickSettings>
        <QuickSettingsDefinitions 
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; >
                <Category ID="Audacity Options">
                        <Setting
 ID="Audacity Options.Announce Audacity messages" Type="Boolean">
                                <SettingsFile Section="NonJCFOptions" 
Name="AnnounceMessage" />
                        </Setting>
                        <Setting ID="Audacity Options.Announce toolbars" 
Type="Boolean">
                                <SettingsFile Section="NonJCFOptions" 
Name="AnnounceToolbars" />
                        </Setting>
                        <Setting ID="Audacity Options.ENTER pauses during 
play/record" Type="Boolean">
                                <SettingsFile Section="NonJCFOptions" 
Name="EnterPause" />
                        </Setting>
                        <Setting
 ID="Audacity Options.Preview Speech Off" Type="Boolean">
                                <SettingsFile Section="NonJCFOptions" 
Name="SpeechOff" />
                        </Setting>
                </Category>
        </QuickSettingsDefinitions>
</QuickSettings>
<?xml version="1.0" encoding="utf-8" ?>
<LocalizableDefinitions File="Audacity.qs">
        <DisplayNameDefinitions>
                <DisplayName ID="audacity Options" Text="Audacity Settings">
                        <HelpMsg>
Audacity specific settings.</HelpMsg>
                </DisplayName>
                <DisplayName ID="Audacity Options.Announce Audacity messages" 
Text="Announce Audacity messages">
                        <HelpMsg>
If on, speaks messages for Audacity audio operations.
                        </HelpMsg>
                </DisplayName>
                <DisplayName ID="Audacity Options.Announce toolbars" 
Text="Announce Audacity toolbars">
                        <HelpMsg>
If on, speaks the toolbar name when focus moves from one toolbar to another.
                        </HelpMsg>
                </DisplayName>
                <DisplayName ID="Audacity Options.ENTER pauses during 
play/record" Text="ENTER pauses during play/record">
                        <HelpMsg>
If on, ENTER executes Pause during playback and record, and Control+ENTER sends 
ENTER.  Otherwise, sends ENTER to Audacity.
                        </HelpMsg>
                </DisplayName>
                <DisplayName ID="Audacity Options.Preview Speech Off" 
Text="Preview Speech Off">
                        <HelpMsg>
If on, Turns speech off when preview an effect.
                        </HelpMsg>
                </DisplayName>
</DisplayNameDefinitions>
</LocalizableDefinitions>
[Common Keys]
JAWSKey+h=AudacityScriptKeyHelp
Insert+h=AudacityScriptKeyHelp
JAWSKey+w=AudacityKeysHelp
Insert+w=AudacityKeysHelp
JAWSKey+delete=SayAudacityState
Insert+delete=SayAudacityState
shift+control+rightarrow=StartMarkerRight
;control+]=
control+k=DeleteSelectedAudio
shift+control+leftarrow=FinishMarkerLeft
shift+j=SelectToBeginning
k=MoveToEndOfSelectedTracks
shift+leftarrow=StartMarkerLeft
shift+k=SelectToEnd
j=MoveToStartOfSelectedTracks
]=SelectionEnd
[=SelectionStart
control+c=Copy
shift+rightarrow=FinishMarkerRight
shift+control+a=DeselectAll
shift+c=CloseFocusTrack
;control+[=
Control+`=AnnounceOnOff
ENTER=Enter
NumPadEnter=Enter
Control+ENTER=CtrlEnter
; Assigning CtrlEnter to NumPadEnter makes %KeyFor return Control+NumPadEnter 
instead of Control+ENTER.
;Control+NumPadEnter=CtrlEnter
Shift+Control+`=ResetConfig
Alt+P=VSTPreset
Alt+L=VSTLoadPreset
Alt+S=VSTSavePreset
,=SayJump
Shift+,=SayJump
.=SayJump
Shift+.=SayJump
F6=SwitchChainsList
;ctrl+JAWSKey+z=test
Alt+[=SaySelectionStart
Alt+]=SaySelectionEnd
Shift+Insert+S=MuteSynthesizer
Shift+Control+J=AddAudacityJawsGuide
r=Record
Shift+r=Record
[Laptop Keys]
; JAWS script for Audacity multitrack sound editor V2.0.1.0 
(http://audacity.sourceforge.net).
;Original author: Gary Campbell
;Modified: Dang Manh Cuong
;Vietnamese README file translation by Nguyen Hoang Giang.

; This constant contains the script version.  The spacing of the following line 
must be preserved exactly so that the installer can read the version from it.  
There is exactly 1 space between const and the name, and 1 space on either side 
of the equals sign.
Const CS_SCRIPT_VERSION = "2.0 11/28/14 00:45UTC debug"

; This puts the copyright in the jsb file.
Messages

@msgCopyright
JAWS script for Audacity multitrack sound editor V2.0 or later 
(http://audacity.sourceforge.net).

    Copyright (C) 2012, 2013  Gary Campbell and Dang Manh Cuong.  All rights 
reserved.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  
USA
    
    See the file copying.txt for details.
@@
EndMessages

;Modifications:
; 11/27/14 Special release to test Silence Preview.
; Commented out calls to debugstring.
;7/26/14 This is V2.0 7/26/14 01:55UTC (rev 160) merged into the version for 
testing the silence preview feature.  (See below for debug mods.)
;7/25/14 Now speaks the field value after the slider percentage in the 
compressor dialog.  May want to include this behavior in SayLine.  SayCharacter?
;7/25/14 Previous saved to HG rev 159.
;7/25/14 Added Record script to silence the key that starts recording.  Should 
this be controlled by a user option?
;7/25/14 Previous saved to HG rev 158.
;7/25/14 Removed HandleCustomWindows entry from audacity.jsd.  It had no 
arguments, whereas the version in JAWS 10 and JAWS 15 has one argument.  It 
appears it has been with us since the beginning.
;Updated messages in jsm file.
;Script AddAudacityJAWSGuide now updates the global containing the URL so its 
effect is immediately available.
;Added .qs and .qsm files to installer.  Updated What's New and English README 
files.
;7/16/14 Previous saved to HG rev 154 (same as 156 except that 156 contains 
correct version of audacity.jsm).
; Silence Preview debug modifications: {
;7/22/14 This worked except that progress bar values were spoken.  We now 
disable preview mode when the stop button is destroyed.  Progress bar 
announcements suppressed in ProgressBarChangedEvent.
    ;7/22/14 Added debugstring for debugging previewing, also in audacity.jkm.
;Added code in SayCustomWindows to suppress speech during previewing.  This 
turns speech off when we encounter focus on the app main window.  This is a 
risky test, since this could potentially happen anywhere.  DialogActive is even 
0 so we can't restrict to being in a dialog.  
;Uses new globals gbAudSuppressedSayFocus and gbAudSuppressNextTutor, used in 
HandleCustomWindows and TutorMessageEvent.  There is a global declaration for 
these before the TutorMessageEvent that should be moved to where the 
declarations are.
;There are also debug versions of FocusChangedEvent, HandleCustomAppWindows, 
and HandleCustomRealWindows.
;Assumes new declaration for @msgJawsGuideDialog is present in audacity.jsm.  
;7/19/14 In audacity.jsd removed entry for HandleCustomWindows which had no 
parameters.
; 7/18/14 Added debugging for preview button.
; end silence preview debug }
;7/16/14 Merged changes from repo audacity_cuong changeset:   51:2fdf46c42638.
;5/15/14 by Dang Manh Cuong:
; Wrote script Preview: turn Jaws speech off when hitting the preview button in 
some effect dialog.
;Issue: cannot turn Jaws speech on when finish previewing
;Updated comments
;3/22/14 by Dang Man Cuong
;Script AddAudacityJawsGuide now returns user doesn't type anything to the box.
;Updated messages and comments.
;3/20/14 by Dang Manh Cuong
;Script AddAudacityJawsGuide now returns if new and current URL are the same.
;Updated message and documentation for the script above.
;3/19/14 by Dang Manh Cuong:
;Added script AddAudacityJawsGuide for changing Jaws guide link.
;3/17/14 by Dang Manh Cuong
;Modified function HandleCustomWindows. Jaws now reads the checkbox and button 
in the quick settings dialog when navigated to these by the tab key.
;Make the settings section in the JSI file at a contans for easier to change if 
needed, and modified all relatest scripts.
;3/16/14 by DangManh Cuong
;Commented out keystroke: Jawskey+V for testing the quick settings script.
;Wrote xml files for the QuickSetting (Similar to script adjust Jaws options). 
This use on Jaws 13 or later.
;Wrote function LoadNonJCF Options to get info from JCF file, and write to 
Audacity>JSI file. This for script QuickSettings
;Modified Hotkey Help message. Now the hotkey Insert+v displays in all Jaws 
version. Although, it removed from JKM file
;3/14/14 by Gary Campbell:
;Merged changes from repo audacity_cuong changeset:   49:b3b6b02544ec.
;And fixed a couple more typos.
;1/27/14 by Dang Manh Cuong: 
;Updated comments.  Corrected some misspellings.
;10/30/13 by Gary Campbell:
;Corrected referenced changeset in modification comments of 148.
;10/30/13 Previous saved to HG rev 148.
;10/30/13 by Gary Campbell:
;Merged changes from repo audacity_cuong changeset:   47:ea1a0a992a00 
(correction: 48:b3ac8e4ba038).
;10/23/13 by Dang Manh Cuong:
;Uncommented script Paste from clipboard. Remove the check for no project in 
this script.
;Updated comment
;Previous saved to HG rev 147.
;10/23/13 by Gary Campbell:
;Merged changes from repo audacity_cuong changeset:   47:ea1a0a992a00, other 
minor comment fix.
;10/16/13 by Dang Manh Cuong:
;Modified the script swichChainsList due to the control ID for swiching to 
Chain CMD changed in Audacity 2.0.4
;Commented out script Paste from clipboard because it does not allow pasting 
into a blank project.
;10/16/13: Modified the script swichChangeList due to the control ID for 
swiching to Change CMD changed in Audacity 2.0.4

;Commented out script Paste from clipboard
;9/27/13 Changed scripts SelectToStart/EndOfLine to use msgSelectedTo so that 
they say "select to start/end of all audio".  This makes msgStartOfFile and 
msgEndOfFile unused.
;Changed JawsHome to say "all audio" instead of "track", making it consistent 
with JawsEnd.
    ;Changed msgSelectedTo to msgSelectTo.
;9/26/13 Changed msgNoTracksSelected to msgNoTrackSelected_L, added 
msgNoTrackSelected_S, changed content of msgNoTrackSelected_L.  Changed Say to 
SayMessage for this message.
;9/15/13 Previous saved to HG rev 142, tagged with rel2.0_0915.

Include "hjconst.jsh"
Include "hjglobal.jsh"
Include "common.jsm"
Include "audacity.jsm"
Include "msaaconst.jsh"

;Include "debugstring.jsh" ; debug
;use "debugstring.jsb" ; debug

;The next line makes the script compiled on Jaws 13.0 to behave the same as it 
does with earlier versions.
;#pragma StringComparison partial

Const
        ID_SELECTION_START = 2705,
        ID_SELECTION_END = 2706,   ; selection end or selection length
        ID_END_RADIO = 2704,
        ID_LENGTH_RADIO = 2703,
        WC_wxWindowClass = "wxWindowClass", ; grabber control on toolbars
        CS_INI_FILE="Audacity.jsi",
Settings="Settings", ;make easier to change the section name in the config file 
if needed
        ;For VST plugins
        ID_Load_Preset=11001,
        ID_Save_Preset=11002,
        ID_Preset=11000,
        ;For user options.
        CI_MESSAGES_OFF = 0,
        CI_MESSAGES_FULL = 1, ; announce all messages
        CI_TOOLBARS_OFF = 0,
        CI_TOOLBARS_ON = 1, ; announce all toolbars
        CI_ENTERPAUSE_OFF = 0, ; ENTER during play/record sent to ap
        CI_ENTERPAUSE_ON = 1, ; ENTER pauses during play and record
        ;For the Edit chains dialog
        ID_Chains_List=7001,
        ID_Chain_Cmds_List=10002,
        ID_Chain_Cmds_List2=7002 ;Audacity 2.0.4 or higher
        
/*
Const
        ;Names of toolbar button images for use when GetObjectInfoByName 
doesn't work.  See GetAudacityState.
        ;Each ends with a trailing space.
        CS_IMGRECORDPRESSED = "graphic 405 ",
        CS_IMGPLAYPRESSED = "graphic 28 ",
        CS_IMGPAUSEPRESSED = "graphic 161 "
*/


Globals
        Int App_FirstTime,
;For adjust Jaws options and quick settings script
        Int gfEnterPause,
        Int announceMessage,
        Int AnnounceToolbars,
Int SpeechOff,
        String gsJawsGuideLink, ;URL of Audacity Guide for JAWS users
        ;Commented this out 9/14/13.
        ;String gsJawsGuideTitle, ;title of Audacity Guide for JAWS users
        
        Handle ghNull, ; to clear a handle
        ;When focus is on a slider with an associated edit, this holds the 
handle of the associated edit so that it will be spoken by 
SayNonHighlightedText.  Be sure to set this to 0 when focus moves away from the 
slider.
        Handle ghSliderEdit
        
Int Function AnnounceOn (String sKey)
;Indicate whether messages related to certain Audacity operations should be 
spoken.  Return True if messages should be spoken.
;This function can be used to check if announce toolbars is on by specifying 
the appropriate value for sKey.
;sKey: key to read in audacity.JSI file
;New method given by Le Van Mai (Cuong's friend)
Return IniReadInteger (Settings, sKey, 0, CS_INI_FILE)
EndFunction ; AnnounceOn

Int Function FocusInTrackPanel ()
;Indicates that the focus is in the track panel.  It is used to prevent JAWS 
from speaking messages such as move to start of track etc. in the selection bar 
or toolbar.
Return (FocusInMainWindow () && GetWindowName(GetFocus()) == WN_TRACKPANEL )
EndFunction ; FocusInTrackPanel

Void Function SaySelectionPosition (Int iPosition, String sMessage)
;say the selection position field and pass the key to the ap.
;iPosition - control ID of the selection position control.
;sMessage - Spoken message
;This function now uses the method of saying selection start and end position, 
from Gary Campbell.
Var
        Handle wnd, ;the window containing the selection bar
        String sValue ;the selection field value 
        
If DialogActive ()||MenusActive () Then
        SayCurrentScriptKeyLabel ()
        TypeCurrentScriptKey () ;allow users to type [, ] if focus in any text 
box
ElIf NoProject () Then
        SayNoProject ()
        Return
ElIf FocusInMainWindow () Then
        TypeCurrentScriptKey ()
        Pause () ;Wait for possible appearance of Boundary Position dialog.
        If !DialogActive () Then
                Pause ()
                Let wnd=FindDescendantWindow (GetRealWindow (GetFocus ()), 
iPosition)
                ;If the Announce Messages option is on, speak the selection 
posision.
                If AnnounceOn ("AnnounceMessage") Then
                        Let sValue=GetPositionField (wnd) ;get value of desired 
control
                        If !sValue Then ;the selection toolbar is turned off
                                Say (MSGNoSelection, OT_Error)
                        Else
                                SayFormattedMessage 
(OT_USER_REQUESTED_INFORMATION, sMessage, sMessage)
                                SayFormattedMessage 
(OT_USER_REQUESTED_INFORMATION, sValue, sValue)
                        EndIf ;say selection position
                EndIf ; AnnounceOn
        EndIf ; if !DialogActive
EndIf ; If FocusInMainWindow
EndFunction ; SaySelectionPosition

Void Function MarkerMovement (String sScript, String sAlert)
;Used for marker scripts, such as move start of selection to the left by a 
small amount
;First, check to make sure we have a project open.
If !UserBufferIsActive ()&&FocusInTrackPanel () && IsStopped () Then
        If NoProject () Then
                SayNoProject ()
                Return
        EndIf
        TypeCurrentScriptKey ()
        If AnnounceOn ("AnnounceMessage") Then
                SayFormattedMessage (OT_Cursor, sAlert) ;The alert specified by 
calling script
        EndIf ; if AnnounceOn
Else
        ;Not main window, perform the specified script, passed as a parameter. 
This method suggested by Doug Lee
        FormatStringWithEmbeddedFunctions("<$" +sScript +">") ;instead of 
PerformScript method. 
EndIf ; else not main window
EndFunction ; MarkerMovement

Void Function MouseMovement (String sScript)
;Used to bypass scripts such as MouseLeft, MouseRight etc. that are assigned to 
Audacity keys while in the main window.
;sScript - name of JAWS script to be executed when not in the Audacity main 
window.
If FocusInMainWindow () 
&& IsPCCursor () && !NoProject () Then ;focus at the main window, there's a 
project open, and the Jaws cursor is not active
        TypeCurrentScriptKey () ;Audacity hotkey for adjusting gain
Else
        ;otherwise, perform the default JAWS script
        formatStringWithEmbeddedFunctions("<$" +sScript +">")
EndIf ; else perform default script
EndFunction ; MouseMovement

Void Function AnnounceKeyMessage (String Message)
;This speaks an alert message when the user presses certain Audacity hotkeys, 
such as j or Shift J when appropriate, and passes the key to Audacity.
; Message - message to be spoken.
If !NoProject ()&&! UserBufferIsActive ()&&FocusInMainWindow () Then
        If AnnounceOn ("AnnounceMessage") Then
                SayUsingVoice (VCTX_Message, Message, OT_status) ;Speak alert 
message.
        EndIf ; if AnnounceOn
        TypeCurrentScriptKey ()
Else
        ;Not main window, etc.
        SayCurrentScriptKeyLabel ()
        TypeCurrentScriptKey ()
EndIf ; else not main window, etc.
EndFunction ; AnnounceKeyMessage

Void Function SayNotStopped ()
If AnnounceOn ("AnnounceMessage") Then
        SayFormattedMessage (ot_Error, msgNotStopped_l, msgNotStopped_s)
EndIf
EndFunction ; SayNotStopped

Void Function SayNoProject ()
;If no project is open, speak an alert message.
SayFormattedMessage (OT_error, msgNoProject_l, msgNoProject_s)
EndFunction ; SayNoProject

Int Function NoProject ()
;Return True if no project is open  (focus in main window and no tracks in 
track panel).
;This is a feature from GoldWave scripts.
Var
        Int iSubtype,
        Handle hTemp,
        Object obj
        
If !UserBufferIsActive () && FocusInMainWindow () Then
        Let hTemp = GetRealWindow(GetFocus())
        Let hTemp = FindWindow (hTemp, "", WN_TRACKPANEL)
        SaveCursor ()
        InvisibleCursor ()
        MoveToWindow(hTemp)
        Pause ()
        Let obj = GetCurrentObject (0)
        RestoreCursor ()
        If obj.AccChildCount == 0 Then
                Return True
        EndIf ; if no tracks
EndIf ; if in main window
Return False
EndFunction ; NoProject

Function AutoStartEvent ()
Var
        String sTemp,
        Int iTemp
        
If !App_FirstTime Then
        Let App_FirstTime=1
        SayFormattedMessage (OT_No_Disable, MSG_App_Start)
        ;write default settings of Audacity script if settings file doesn't 
exist.
        If !FileExists (FindJAWSPersonalizedSettingsFile (CS_INI_FILE, True)) 
Then
                AddDefaultConfig ()
        EndIf
        Let gfEnterPause = IniReadInteger(Settings, "EnterPause", 
CI_ENTERPAUSE_ON, CS_INI_FILE)
        ;Read a value for the JAWS ref guide link, initialize to default.
        ;The disadvantage of storing these in globals is that you have to shut 
down and restart JAWS to make changes to an externally edited config file take 
effect.  This could be avoided by reading from the config file when the values 
are needed.  Because of the complexity of decoding this value, I choose to use 
globals despite this disadvantage.  One could also decrease the complexity by 
using a second key for the title.
        /*
        Commented the title part of this feature out because it could make the 
hot key help claim it is for a different version of the guide than it was taken 
from.
        Let sTemp = StringTrimTrailingBlanks (IniReadString (Settings, 
"JAWSGuideLink", CS_JawsGuide_LINK + cScSpace + CS_JawsGuide_TITLE , 
CS_INI_FILE))
        Let iTemp = StringContains (sTemp, cScSpace)
        If iTemp Then
        ;We found a space and it's not the last character.
        Let gsJawsGuideLink = StringLeft (sTemp, iTemp - 1)
        Let gsJawsGuideTitle = StringRight(sTemp, StringLength (sTemp) - iTemp)
        Else
        Let gsJawsGuideLink = sTemp
        Let gsJawsGuideTitle = CS_JawsGuide_Title
        EndIf ; else no space
        */
        
        Let gsJawsGuideLink = StringTrimTrailingBlanks (IniReadString 
(Settings, "JAWSGuideLink", CS_JawsGuide_LINK, CS_INI_FILE))
EndIf ; if first time
EndFunction ; AutoStartEvent

Void Function SayNonHighlightedText (Handle hwnd, String buffer)
;SayString("Enter NonHighlighted") ; debug
    ;If we are monitoring an edit associated with a slider, speak it.
If ghSliderEdit && hWnd == ghSliderEdit Then
        Say (buffer, OT_NONHIGHLIGHTED_SCREEN_TEXT)
EndIf
SayNonhighlightedText (hWnd, buffer)
;SayString("Exit NonHighlighted") ; debug
EndFunction ; SayNonHighlightedText

/*
Void Function SayHighlightedText (Handle hwnd, String buffer) ; debug
;DebugString("Enter Highlighted") ; debug
SayNonhighlightedText (hWnd, buffer)
;DebugString("Exit Highlighted") ; debug
EndFunction ; SayHighlightedText
*/

Globals Handle ghAudacityLastArea,
        Handle ghAudacityLastToolbar

void function ProcessEventOnFocusChangedEvent(handle AppWindow, handle 
RealWindow, string RealWindowName,
        handle FocusWindow, handle PrevWindow)
if appWindow != globalPrevApp then
        ;we've loaded a new app, and in case no local loadNonJCFOptions gets 
called,
        ;but user has set something in QuickSettings and it is a NonJCF Option:
        loadNonJCFOptions ()
        SetUpStuffForNewPage (TRUE)
endIf
let GlobalRibbonState = RibbonsActive()
if FocusChangedEventShouldProcessAncestors(FocusWindow) then
        FocusChangedEventProcessAncestors(FocusWindow, PrevWindow)
        return
elif IsJavaWindow(FocusWindow) then
        JavaFocusChangedEvent (FocusWindow, PrevWindow)
        return
elif ExplorerPaneFocusChangedEvent(FocusWindow,PrevWindow) then
        return
EndIf
if GlobalRibbonState != GlobalPrevRibbonState then
        SpeakRibbonStatus(true)
EndIf
    ;DebugString("Calling ProcessSayAppWindowOnFocusChange") ; debug
ProcessSayAppWindowOnFocusChange(AppWindow,FocusWindow)
    ;DebugString("back to FocusChanged") ; debug
    ;DebugString("Calling ProcessSayRealWindowOnFocusChange") ; debug
ProcessSayRealWindowOnFocusChange(AppWindow,RealWindow,RealWindowName,FocusWindow)
    ;DebugString("back to FocusChanged") ; debug
    ;DebugString("Calling ProcessSayFocusWindowOnFocusChange") ; debug
ProcessSayFocusWindowOnFocusChange(RealWindowName,FocusWindow)
    ;DebugString("back to FocusChanged") ; debug
EndFunction

void function ProcessSayFocusWindowOnFocusChange(string RealWindowName, handle 
FocusWindow)
If GetWindowSubTypeCode (FocusWindow) == WT_STARTMENU
;Windows XP, the Type code is ListView, so:
||      RealWindowName == cWnStartMenu then
        ;If in Start Menu, and not in Win NT or 95,
        ;Speak Object Name instead of the whole Object Type And Text 
information:
        If GISuppressStartMenu  then
                SayObjectActiveItem()
        EndIf
        ;Solve Japan problem where Exit Documents menus was not reporting 
accurate state.
        Let GISuppressStartMenu = TRUE
        return
EndIf
;Ensure Start Menu flag is off, since we are not in the Start Menu:
Let GISuppressStartMenu = FALSE
If SayFocusedHJDialogWindow(FocusWindow) then
        return
EndIf
If !HandleCustomWindows(FocusWindow) then
    ;DebugString("Calling SayFocusedWindow") ; debug
        SayFocusedWindow()
        ;DebugString("back to ProcessSayFocused") ; debug
EndIf
EndFunction


Int function HandleCustomAppWindows(handle hApp)
    var int iRtn
;SayString("Enter CustomApp") ; debug
    Let iRtn = HandleCustomAppWindows(hApp)
;SayString("Exit CustomApp") ; debug
    Return iRtn
EndFunction ; HandleCustomAppWindows

Int Function HandleCustomRealWindows(Handle hReal)
var int iRtn ; debug
;SayString("Enter HandleReal" + GetWindowName(hReal)) ; debug
    If GetControlId(GetFocus()) == 5100 Then
;SayString("real stop") ; debug
    Return True
    EndIf
    Let iRtn = HandleCustomRealWindows(hReal)
;SayString("Exit HandleReal") ; debug
    return iRtn
EndFunction ; HandleCustomRealWindows

Globals
    Int gbAudSuppressNextTutor,
    Int gbAudSuppressSayFocus,
    Handle ghAudPreviewStop ; handle of stop button in preview dialog

Void Function TutorMessageEvent(Handle hWnd, Int nMenuMode)
; Suppress tutor message while previewing.
If gbAudSuppressSayFocus Then
    Return
    EndIf
    If gbAudSuppressNextTutor Then
    Let gbAudSuppressNextTutor = False
    Return
EndIf
    ;DebugString("Tutor message for " + GetWindowType(hWnd)) ; debug
TutorMessageEvent(hWnd, nMenuMode)    
EndFunction ; TutorMessageEvent

Void Function WindowCreatedEvent (handle hWindow, int nLeft, int nTop, int 
nRight, int nBottom)
; For debug testing.
;DebugString("Window created " + IntToString(hWindow)) ; debug
WindowCreatedEvent (hWindow, nLeft, nTop, nRight, nBottom)
EndFunction ; WindowCreatedEvent

Void Function WindowDestroyedEvent (handle hWindow)
Var Handle hNull
    ; For debug testing.
;DebugString("Window destroyed " + IntToString(hWindow)) ; debug
    If hWindow == ghAudPreviewStop Then
        ; Stop previewing
        Let gbAudSuppressSayFocus = False
        Let ghAudPreviewStop = hNull
EndIf
WindowDestroyedEvent (hWindow)
EndFunction ; WindowDestroyedEvent

void function ProgressBarChangedEvent(handle hProgress, string sName, string 
sValue)
    If gbAudSuppressSayFocus Then
        Return
    EndIf

ProgressBarChangedEvent(hProgress, sName, sValue)
EndFunction ; ProgressBarChangedEvent

Int Function HandleCustomWindows (handle hFocus)
Var
    Handle hParent,
    ;Handle hFocus,
    Handle hOld,
    Handle hToolbar,
    Handle hTemp,
    Handle hTemp2,
    String sName,
    Int iMSAA_JCFOpt,
    Int iRtn

;Make JAWS read the checkbox and button in the quick settings dialog
Let sName=GetWindowName (GetRealWindow (GetCurrentWindow ()))
If DialogActive ()&&sName=="QuickSettings - audacity" then
    Return
EndIf ;quick settings dialog

;Let hFocus = GetFocus ()
;SayString("Enter CustomWindows {" + GetWindowName(hFocus) + "}" + 
IntToString(GetWindowHierarchyX(hFocus)) + "," + 
IntToString(GetWindowHierarchyY(hFocus))) ; debug
;DebugString("Enter SayCustom for " + IntToString(hFocus) + " DialogActive=" + 
IntToString(DialogActive())) ; debug
If DialogActive () && GetWindowSubtypeCode (hFocus) == WT_LEFTRIGHTSLIDER && 
GetWindowSubtypeCode (GetPriorWindow(hFocus)) == WT_EDIT Then
        Let ghSliderEdit = GetPriorWindow (hFocus)
        Let hTemp = GetPriorWindow(ghSliderEdit) ; control name
        SayControlEx(hFocus, 
        GetWindowName(hTemp), "",   ; control name, type
        "",   ; control state
        "", "",   ; Container name, type
        "", "",   ; value, position
        "")   ; dialog text
        Return True
ElIf DialogActive () && GetWindowSubtypeCode (hFocus) == WT_LEFTRIGHTSLIDER && 
GetWindowSubtypeCode (GetPriorWindow(hFocus)) == WT_STATIC && 
GetWindowSubtypeCode (GetNextWindow(hFocus)) == WT_STATIC Then
        Let ghSliderEdit = GetNextWindow (hFocus)
        Let hTemp = GetPriorWindow(hFocus) ; control name
        SayControlEx(hFocus, 
        GetWindowName(hTemp), "",   ; control name, type
        ;"", "", ; name, type
        "",   ; control state
        "", "",   ; Container name, type
        FormatString(msgCompressorSlider, GetObjectValue(hFocus), GetWindowText 
(ghSliderEdit, False)), "",   ; value, position
        "")   ; dialog text
        Return True
Else
    ;this must be executed any time focus moves away from a slider with a 
monitored edit, even when we exit the dialog
    Let ghSliderEdit = ghNull
EndIf ;else not slider

;If DialogActive() && GetControlId(hFocus) == 4998 Then ; debug
    ;SayString("PreviewBtn") ; debug
;EndIf ; debug

;If DialogActive() && GetControlId(hFocus) == 5100 Then ; debug
    ;SayString("StopBtn prev=" + GetWindowName(GlobalPrevFocus)) ; debug
    ;Return True ; debug
;EndIf ; debug

;DebugString("Checking hFocus=" + IntToString(hFocus)) ; debug
If hFocus == GetAppMainWindow(hFocus) Then
    ;DebugString("previewing " + IntToString(hFocus)) ; debug
    Let gbAudSuppressSayFocus = True
    Return True
EndIf

If DialogActive() && GetControlId(hFocus) == 5100 Then
    Let ghAudPreviewStop = hFocus  ; remember thhis window so we can return to 
normal when it is destroyed
    Return True
EndIf

If gbAudSuppressSayFocus Then
    Return True ; we're doing something like previewing and we don't want focus 
change stuff spoken
EndIf

;Announce when focus changes to a different area of the main window.
If !FocusInMainWindow() Then
        If DialogActive () && GetWindowName(GetFocus()) == cscNULL Then
                Let iMSAA_JCFOpt = GetJCFOption (OPT_MSAA_MODE)
                SetJCFOption (OPT_MSAA_MODE, 2)
                Let sName = GetObjectName()
                SetJCFOption (OPT_MSAA_MODE, iMSAA_JCFOpt)
                SayControlEx(GetFocus (), 
                sName, "",   ; control name, type
                "",   ; control state
                "", "",   ; Container name, type
                "", "",   ; value, position
                "")   ; dialog text
                ;SayString("Exit CustomWindow main screen area") ; debug
                Return True
        ElIf IsWarningDialog ()&&!CheckAudacityVersion ("2,0,3") then
                SayWindowTypeAndText (GetFocus ())
                ;SayString("Exit CustomWindows warning dlg") ; debug
                Return true
        EndIf ; no window name
        Let iRtn = HandleCustomWindows (hFocus) ; not main window, continue 
with normal processing
        ;SayString("Exit CustomWindows") ; debug
        return iRtn
EndIf ; if ! focus in main window
Let hParent = GetParent(hFocus)
If GetWindowName(hFocus) != WN_TRACKPANEL Then
        Let hParent = GetParent(hParent)
EndIf ; if not track panel
; If hFocus is the track panel, hParent is its parent.  Otherwise it is the 
grandparent of hFocus.
Let hOld = ghAudacityLastArea
If hParent != hOld Then
        Let ghAudacityLastArea = hParent ; new area.
        ; We could use FocusInTrackPanel here but we've already tested most of 
its conditions.
        If GetWindowName(hFocus) == WN_TRACKPANEL Then
                Say (CS_TrackPanel, OT_Position)
                ;SayString("Exit CustomWindows") ; debug
                Return HandleCustomWindows (hFocus)
        EndIf ; if track panel
        ; We could also identify the selection by testing for WindowHierarchyX 
= 3.
        If GetWindowName(GetFirstChild(hParent)) == WN_SELECTION Then
                Say (CS_SelectionBar, OT_position)
        Else
                Say (CS_ToolBars, OT_position)
        EndIf ; else toolbar
EndIf ; new area

If IsToolbar(GetToolbar ()) Then
        Let hToolbar = GetToolbar ()
        If hToolbar != ghAudacityLastToolbar Then
                Let ghAudacityLastToolbar = hToolbar
                If AnnounceOn ("AnnounceToolbars") Then
                        Say(GetWindowName(hToolbar), OT_CONTROL_GROUP_NAME)
                EndIf
        EndIf ; new toolbar
EndIf ; If IsToolbar
;SayString("Exit CustomWindows") ; debug
Return HandleCustomWindows (hFocus) ; allow others to process
EndFunction ; HandleCustomWindows

Void Function SayFocusedObject ()
;DebugString("Enter SayFocusedObject " + IntToString(GetFocus()) + " last=" + 
IntToString(GlobalPrevFocus) + " app=" + 
IntToString(GetAppMainWindow(GetFocus()))) ; debug
    If FocusInTrackPanel () Then
        ;Suppress speaking of "track table" when moving between tracks.
        SayObjectActiveItem ()
Else
        SayFocusedObject ()
EndIf
;DebugString("Exit SayFocusedObject") ; debug
EndFunction ; SayFocusedObject

Int Function IsToolbar (Handle hWnd)
; Return True if hWnd is one of the toolbars.
; The toolbars are in a window named ToolDock under the app window.  It is the 
second window, the selection bar is inside the window following it, which is 
also named ToolDock.
; Assumes focus is in the main window.
Var
        Handle hParent
        
Let hParent = GetParent(hWnd)
If hParent == 0 Then
        ;Make sure we have a window handle, just to be safe.
        Let hParent = hWnd
EndIf ; no parent
If GetWindowName(hParent) == WN_TOOLDOCK && GetWindowHierarchyX(hParent) == 2 
Then
        Return True
EndIf
Return False
EndFunction ; IsToolbar

Handle Function GetToolbar ()
; When focus is on a toolbar control returns the handle of the toolbar 
containing the control.
Return GetParent(GetFocus())
EndFunction ; GetToolbar

Int Function FocusInMainWindow ()
;Returns True if the focused control is in the main window, False otherwise.
Var
        Handle hFocus,
        Handle hWnd
        
Let hFocus = GetFocus ()
If (GetWindowName(hFocus) == WN_TRACKPANEL || 
GetWindowName(GetParent(GetParent(hFocus))) == WN_TOOLDOCK) Then
        Return True
EndIf
Return False
EndFunction ; FocusInMainWindow

String Function GetPositionField (Handle hWnd)
;Returns the value of the specified audio selection or position field.
;hWnd - the handle of the control.
;Return - the value of the position field suitable for speaking.
;We don't receive a control ID because of Audio Position field.
Var
        String s,
        String s1,
        String s2,
        String s3,
        String s4,
        Int i,
        Int j
        
Let s = GetWindowText(hWnd, 0)

;Remove "uninteresting" stuff from the position, like leading zeros and ".000"
;A position can be in several formats, such as "0 0  h 0 0  m 0 0 .0 0 0  s " 
or "0 0 0 ,0 0 0  seconds ".
;These strings may need to be localized because H, M, ., and comma may be 
different.
Let s2 = StringStripAllBlanks(s)
If StringContains(s2, csGroupSep) Then
        ;SayString("no point") ; debug
        Let s1 = csPositionGroupFmt ;does not include final 0.
Else
        ;Let s1 = "0 0  h 0 0  m 0 0 .0 0" ; we strip as much of this as 
matches off the front, we don't match the last 0 so it will say something.
        ;SayString("decimal") ; debug
        Let s1 = ""
        If StringContains (s2, csDays) Then
                Let s1 = "00" + csDays
        EndIf
        Let s1 = s1 + csPositionHHMMFmt ; we strip as much of this as matches 
off the front up to the decimal point.
        ;SayString("s1 = " + s1) ; debug
        ;S1 contains what needs to be stripped from the staart of s2.
EndIf ; else contains decimal
; Return is in s1 and s2, passed by reference!!!
StringTrimCommon(s1, s2, 1) ; 1=trim from start
Let i = StringContains (s2, csDecimal)
If i > 0 Then
        ;Check all digits immediately following the decimal point for nonzero 
digits.
        Let s3 = StringRight (s2, StringLength (s2) - i)
        ; We want to know if there are nonzero digits between the point and the 
next nondigit.  We change all zeros to blanks and strip the leading blanks.  
The difference in length is the number of leading digits.
        Let s4 = StringTrimLeadingBlanks(StringReplaceChars(s3, "0", " "))
        If !StringContainsChars(Substring(s4, 1, 1), "123456789") Then
                ;No nonzeros, find the number of zeros.
                Let j = StringLength(s3) - StringLength(s4)
                ;SayString("no nonzeros, j = " + IntToString(j)) ; debug
                If i == 1 Then
                        Let s2 = "0" + s2
                        Let i = i + 1
                EndIf ; if decimal is first char
                Let s3 = StringReplaceSubstrings(substring(s2, 1, i - 1), "00", 
"0")
                Let s2 = s3 + Substring (s2, i + 1 + j, StringLength(s2) - j)
        Else
                ; nonzeros after decimal
                Let s3 = StringReplaceSubstrings(substring(s2, 1, i - 1), "00", 
"0")
                Let s2 = s3 + Substring (s2, i, StringLength(s2) - i + 1)
        EndIf ; if no nonzeros after decimal
EndIf ; if decimal
; What we want is in s2.
;Don't say leading parts if they are 0.

Return s2
EndFunction ; GetPositionField

Script SaySelectionStart ()
;Say the value of the Selection Start field.

Var
        Handle hWnd,
        String sName,
        String sValue
        ;I modified this script to make it work on open project only.
If NoProject () Then
        SayNoProject ()
        Return ;exit this script when no project open
ElIf DialogActive ()||MenusActive () Then
        ;Pass key to app.
        SayCurrentScriptKeyLabel ()
        TypeCurrentScriptKey ()
        Return
Else
        Let hWnd = FindDescendantWindow (GetRealWindow (GetFocus ()), 
ID_SELECTION_START)
        If (IsSameScript()) Then
                SetFocus(hWnd)
                Return
        EndIf ;if IsSameScript
EndIf ; Else not NoProject()
Let sValue = GetPositionField(hWnd)
If !sValue Then ;some time user turn off the selection toolbar, so this 
condition varify the selection boolbar is turned on or not
        Say (msgNoSelection, OT_error)
Else
        SayMessage (OT_NO_DISABLE, sValue, sValue)
EndIf
EndScript ; SaySelectionStart

Script SaySelectionEnd ()
;Say the value of the Selection End or Length field.

Var
        Handle hRadio,
        Handle hEnd, ; handle of the edit control
        String sName,
        String sValue,
        Int bIsSelected
        
If NoProject () Then
        SayNoProject ()
        Return
ElIf DialogActive () || MenusActive () Then
        ;Pass key to app.
        SayCurrentScriptKeyLabel ()
        TypeCurrentScriptKey ()
        Return
Else ; project open
        Let hEnd = FindDescendantWindow (GetRealWindow (GetFocus ()), 
ID_SELECTION_END)
        If (IsSameScript()) Then
                SetFocus(hEnd)
                Return
        EndIf ; if IsSameScriqt
        
        Let hRadio = FindDescendantWindow (GetRealWindow (GetFocus ()), 
ID_END_RADIO)
        SaveCursor()
        InvisibleCursor()
        MoveToWindow (hRadio)
        Pause()
        Let bIsSelected = ControlIsChecked ()
        RestoreCursor()
        
        If (Not bIsSelected) Then
                Let hRadio = GetNextWindow (hRadio)
        EndIf
        
        Let sName = GetWindowName (hRadio)
        
        Let sValue = GetPositionField(hEnd)
        If !sValue Then
                Say (msgNoSelection, OT_error)
        Else
                SayMessage (OT_NO_DISABLE, sName + sValue, sValue)
        EndIf
EndIf ; else project open
EndScript ; SaySelectionEnd

Script SayActiveCursor ()
; Say audio position field if PC cursor is on, or perform the normal function 
if pressed twice quickly.
Var
        Handle hWnd,
        String sValue
        
If (Not FocusInMainWindow () || IsSameScript () || Not IsPCCursor () || 
UserBufferIsActive ())||NoProject () Then
        PerformScript SayActiveCursor()
        Return
EndIf
Let hWnd = FindDescendantWindow (GetRealWindow (GetFocus ()), ID_SELECTION_END)
Let hWnd = GetNextWindow(GetNextWindow(hWnd))
;hWnd is Audio Position field.
Let sValue = GetPositionField(hWnd)
If !sValue Then
        Say (msgNoSelection, OT_error)
Else
        SayMessage (OT_NO_DISABLE, sValue, sValue)
EndIf
EndScript ; SayActiveCursor

Script  ScriptFileName ()
ScriptAndAppNames(msgProgName)
EndScript ; ScriptFileName

Script AudacityScriptKeyHelp ()
Var
        String sMessage
        
If UserBufferIsActive () Then
        UserBufferDeactivate ()
EndIf
If !IsSameScript () && FocusInMainWindow () Then
        Let sMessage=FormatString (MSGScript_Ver, CS_SCRIPT_VERSION)
        SayFormattedMessage (OT_User_buffer, sMessage)
        SayFormattedMessage (OT_User_Buffer, msgScriptkeyHelp)
        ;In JAWS 10 the produced link redisplays the Audacity hot keys list 
when activated from the text.  It works correctly from the links list 
(JAWSKey+F7).  This is the same behavior as seen in Outlook for Office 2003.
        AddHotkeyLinks ()
        ;UserBufferAddText (cScBufferNewLine)
        ;UserBufferAddText (cMsgHotKeysLink, cFuncHotKey, cMsgHotKeysFunc)
        ;UserBufferAddText (cScBufferNewLine)
        ;UserBufferAddText (cMsgBuffExit)
Else
        If DialogActive () && FindDescendantWindow (GetRealWindow (GetFocus 
()), ID_Preset) Then
                ;We are in a dialog with a preset.
                sayFormattedMessage (OT_User_Buffer, msgPresetHotkeyHelp)
                ;UserBufferAddText (cScBufferNewLine)
                ;UserBufferAddText(cMsgHotKeysLink, cFuncHotKey, 
cMsgHotKeysFunc)
                ;UserBufferAddText (cScBufferNewLine)
                ;UserBufferAddText (cMsgBuffExit)
                AddHotkeyLinks ()
                Return
        EndIf
        PerformScript HotKeyHelp ()
EndIf ;else not in main window
EndScript ; AudacityScriptKeyHelp

Function ShowJawsGuide()
SayMessage(OT_JAWS_MESSAGE, msgLoadingJawsGuide_L, msgLoadingJawsGuide_S)
run(gsJawsGuideLink)
EndFunction ; ShowJawsGuide

/*
Int Function IsWinKeyHelp()
;This causes Hotkey and window key help to display links to default JAWS and 
Windows hotkeys.  To use it we could make it return a global that we set in 
AudacityHotKeyHelp.
Return True
EndFunction
*/


Script AudacityKeysHelp ()
If !IsSameScript() && FocusInMainWindow() Then
        If UserBufferIsActive () Then
                UserBufferDeactivate ()
        EndIf
        UserBufferClear()
        UserBufferAddText(FormatString(msgAudacityHotKeyHelp1, 
CS_JawsGuide_Title, CS_JawsGuide_Author))
        UserBufferAddText(gsJawsGuideLink, "ShowJawsGuide()", 
CS_JawsGuide_LINK_DISP)
        UserBufferAddText(msgAudacityHotKeyHelp2)
        ;AddHotKeyLinks ()
        UserBufferAddText (cScBufferNewLine)
        UserBufferAddText (cMsgBuffExit)
        UserBufferActivate()
        JAWSTopOfFile()
        SayLine()
Else
        PerformScript WindowKeysHelp()
EndIf
EndScript ; AudacityKeysHelp

;These scripts allow access to Audacity keys assigned to the same keys as JAWS 
scripts such as MouseUp, MouseDown etc.  The user can still perform the JAWS 
functions by turning on the JAWS cursor.
Script MouseUp ()
Var
        String sScriptName
        
Let sScriptName="MouseUp" ;Perform script name for MouseUp in a variable
MouseMovement (sScriptName)
EndScript ; MouseUp

Script MouseDown ()
Var
        String sScriptName
        
Let sScriptName="MouseDown"
MouseMovement (sScriptName)
EndScript ; MouseDown

Script MouseLeft ()
Var
        String sScriptName
        
Let sScriptName="MouseLeft"
MouseMovement (sScriptName)
EndScript ; MouseLeft

Script MouseRight ()
Var
        String sScriptName
        
Let sScriptName="MouseRight"
MouseMovement (sScriptName)
EndScript ; MouseRight

;The scripts below just speak an alert message when user presses certain 
Audacity hotkeys when they are active.
Script SelectionStart ()
;Say selection start position when user presses the left bracket key to set it.
SaySelectionPosition (ID_SELECTION_START, msgSelectionStart)
EndScript ; SelectionStart

Script SelectionEnd ()
;Say selection end position
SaySelectionPosition (ID_SELECTION_END, msgSelectionEnd)
EndScript ; SelectionEnd

Script FinishMarkerRight ()
;move the end of the selection to the right by a small amount.
Var
        Handle hWnd,
        String sScriptName,
        String sMessage
        
If !IsPCCursor () || UserBufferIsActive () Then
        PerformScript SelectNextCharacter ()
        Return
EndIf

If !IsStopped () Then
        ;When playing this does long jump right, in recording I don't think it 
does anything, and it certainly doesn't select.
        TypeCurrentScriptKey ()
        Return
EndIf ; playing/recording

Let sMessage=FormatString (MSGMoveSelection, msgEnd, msgRight)
Let sScriptName="SelectNextCharacter" ;The default script to perform if not in 
main window
MarkerMovement (sScriptName, sMessage)
If AnnounceOn ("AnnounceMessage") && !NoProject () && FocusInTrackPanel () Then
        pause ()
        Let hWnd=FindDescendantWindow (GetRealWindow (GetFocus ()), 
ID_SELECTION_END)
        Say(GetPositionField (hWnd), OT_USER_REQUESTED_INFORMATION)
EndIf
EndScript ; FinishMarkerRight

Script FinishMarkerLeft ()
Var
        Handle hWnd,
        String sScriptName,
        String sMessage
        
If !IsPCCursor () || UserBufferIsActive () || !IsStopped () Then
        PerformScript SelectPriorWord ()
        Return
EndIf

Let sMessage=FormatString (MSGMoveSelection, msgEnd, msgLeft)
Let sScriptName="SelectPriorWord"
MarkerMovement (sScriptName, sMessage)
If AnnounceOn ("AnnounceMessage") && !NoProject () Then
        pause ()
        Let hWnd=FindDescendantWindow (GetRealWindow (GetFocus ()), 
ID_SELECTION_END)
        Say(GetPositionField (hWnd), OT_USER_REQUESTED_INFORMATION)
EndIf
EndScript ; FinishMarkerLeft

Script StartMarkerRight ()
Var
        Handle hWnd,
        String sScriptName,
        String sMessage
        
If !IsPCCursor () || UserBufferIsActive () || !IsStopped () Then
        PerformScript SelectNextWord ()
        Return
EndIf

Let sMessage=FormatString (MSGMoveSelection, msgStart, msgRight)
Let sScriptName="SelectNextWord"
MarkerMovement (sScriptName, sMessage)
If AnnounceOn ("AnnounceMessage") && !NoProject () Then
        pause ()
        Let hWnd=FindDescendantWindow (GetRealWindow (GetFocus ()), 
ID_SELECTION_START)
        Say(GetPositionField (hWnd), OT_USER_REQUESTED_INFORMATION)
EndIf
EndScript ; StartMarkerRight

Script StartMarkerLeft ()
Var
        Handle hWnd,
        String sScriptName,
        String sMessage
        
If !IsPCCursor () || UserBufferIsActive () Then
        PerformScript SelectPriorCharacter ()
        Return
EndIf

If !IsStopped () Then
        ;When playing this does long jump right, in recording I don't think it 
does anything, and it certainly doesn't select.
        TypeCurrentScriptKey ()
        Return
EndIf ; playing/recording

Let sMessage=FormatString (MSGMoveSelection, msgStart, msgLeft)
Let sScriptName="SelectPriorCharacter"
MarkerMovement (sScriptName, sMessage)
If AnnounceOn ("AnnounceMessage") && !NoProject () && FocusInTrackPanel () Then
        pause ()
        Let hWnd=FindDescendantWindow (GetRealWindow (GetFocus ()), 
ID_SELECTION_START)
        Say(GetPositionField (hWnd), OT_USER_REQUESTED_INFORMATION)
EndIf
EndScript ; StartMarkerLeft

Script JawsHome ()
;If we are speaking an Audacity message, don't speak the key name.
If NoProject () && FocusInTrackPanel () &&!UserBufferIsActive () Then
        SayNoProject ()
        Return
EndIf ; if no project
If IsPCCursor () &&FocusInTrackPanel () &&! NoProject () &&!UserBufferIsActive 
()&&AnnounceOn ("AnnounceMessage")Then
        If !IsStopped () Then
                SayNotStopped ()
                Return
        EndIf ;!IsStopped
        JawsHome () ; do Home without speaking key label
        SayFormattedMessage (OT_Position, FormatString (msgMoveTo, msgStart, 
msgAllAudio))
Else
        PerformScript JAWSHome ()
EndIf
EndScript ; JawsHome

Script JawsEnd ()
;If we are speaking an Audacity message, don't speak the key name.
If NoProject () && FocusInTrackPanel () &&!UserBufferIsActive () Then
        SayNoProject ()
        Return
EndIf ; if no project
If IsPCCursor () &&FocusInTrackPanel () && !NoProject () &&!UserBufferIsActive 
()&&AnnounceOn ("AnnounceMessage") Then
        If !IsStopped () Then
                SayNotStopped ()
                Return
        EndIf ;!IsStopped
        JAWSEnd () ; do End without speaking key label
        SayFormattedMessage (OT_Position, FormatString (msgMoveTo, msgEnd, 
msgAllAudio))
Else
        PerformScript JAWSEnd ()
EndIf
EndScript ; JawsEnd

Script MoveToStartOfSelectedTracks ()
If DialogActive () ||MenusActive () Then
        ;A dialog is open, pass key to application and speak its label.
        SayCurrentScriptKeyLabel ()
        TypeCurrentScriptKey ()
ElIf !IsTrackSelected () Then
        SayNoTrackSelected ()
        Return
Else
        AnnounceKeyMessage (FormatString (MSGMoveTo, msgStart, 
msgSelectedTracks))
EndIf
EndScript ; MoveToStartOfSelectedTracks

Script MoveToEndOfSelectedTracks ()
If DialogActive () ||MenusActive () Then
        SayCurrentScriptKeyLabel ()
        TypeCurrentScriptKey ()
ElIf !IsTrackSelected () Then
        SayNoTrackSelected ()
        Return
Else
        AnnounceKeyMessage (FormatString (MSGMoveTo, msgEnd, msgSelectedTracks))
EndIf
EndScript ; MoveToEndOfSelectedTracks

Script SelectToBeginning ()
;Select to start of selected tracks.
If DialogActive () || MenusActive () Then
        SayCurrentScriptKeyLabel ()
        TypeCurrentScriptKey ()
ElIf !IsTrackSelected () Then
        SayNoTrackSelected ()
        Return
Else
        AnnounceKeyMessage (FormatString (msgSelectTo, msgStart, 
msgSelectedTracks))
EndIf
EndScript ; SelectToBeginning

Script SelectToEnd ()
;Select to end of tracks.
If DialogActive () || MenusActive () Then
        SayCurrentScriptKeyLabel ()
        TypeCurrentScriptKey ()
ElIf !IsTrackSelected () Then
        SayNoTrackSelected ()
        Return
Else
        AnnounceKeyMessage (FormatString (msgSelectTo, msgEnd, 
msgSelectedTracks))
EndIf
EndScript ; SelectToEnd

Script SelectFromStartOfLine ()
;Select from current position to the start of all audio.
;We do not use AnnounceKeyMessage so that we can execute the default JAWS 
script instead of just sending the key on.
If NoProject () Then
        SayNoProject ()
        Return
EndIf ;No project
If IsPCCursor ()&&FocusInTrackPanel ()&&!NoProject ()&&!UserBufferIsActive () 
Then
        SelectFromStartOfLine ()
        If AnnounceOn ("AnnounceMessage") Then ;User can turn off this message
                SayFormattedMessage (OT_No_Disable, FormatString (msgSelectTo, 
msgStart, msgAllAudio)) ;alerts when user activates this script at the main 
window, and a project is open
        EndIf
        ;Otherwise, perform default script
Else
        PerformScript SelectFromStartOfLine ()
EndIf
EndScript ; SelectFromStartOfLine

Script SelectToEndOfLine ()
;Select from current position to the end of file
;We do not use AnnounceKeyMessage so that we can execute the default JAWS 
script instead of just sending the key on.
If NoProject () Then
        SayNoProject ()
        Return
EndIf ;No project
If IsPCCursor ()&&FocusInTrackPanel ()&&!UserBufferIsActive ()&&!NoProject () 
Then
        SelectToEndOfLine ()
        If AnnounceOn ("AnnounceMessage") Then
                SayFormattedMessage (OT_No_Disable, FormatString(msgSelectTo, 
msgEnd, msgAllAudio))
        EndIf
Else
        PerformScript SelectToEndOfLine ()
EndIf
EndScript ; SelectToEndOfLine

Script DeleteSelectedAudio ()
;Alerts when user deletes selected sound
If NoProject () Then
        SayNoProject ()
        Return
ElIf DialogActive () || MenusActive () Then
        ;Pass key to app.
        SayCurrentScriptKeyLabel ()
        TypeCurrentScriptKey ()
        Return
ElIf !IsTrackSelected () Then
        SayNoTrackSelected ()
        Return
ElIf FocusInMainWindow () Then
        If !IsStopped () Then
                SayNotStopped ()
                Return
        EndIf ; If not stopped
        TypeCurrentScriptKey ()
        If AnnounceOn ("AnnounceMessage") Then
                SayFormattedMessage (OT_Jaws_Message, MSGDelete_l, MSGDelete_s)
        EndIf ; if AnnounceOn
Else ; not main window, etc.
        ; !NoProject () && !DialogActive () && !MenusActive () && 
IsTrackSelected () && !FocusInTrackPanel () 
        ; Just in case it is used somewhere else (like CTRL+k).  Actually, we 
could do it at the top of the script and eliminate this else.
        SayCurrentScriptKeyLabel ()
        TypeCurrentScriptKey ()
EndIf ; else not main window, etc.
EndScript ; DeleteSelectedAudio

Script JawsDelete ()
;If focus is in the main window, a project exists, and audio is selected, the 
DEL key will delete it.  In this case we perform the script 
DeleteSelectedAudio.  Otherwise we perform the defaault script.

If FocusInMainWindow () Then
        ; (!FocusInMainWindow () || IsTrackSelected ()) && (FocusInTrackPanel 
()&&!NoProject ())
        PerformScript DeleteSelectedAudio()
Else
        ; NoProject() || ((!FocusInMainWindow () || IsTrackSelected ()) && 
!FocusInTrackPanel ()) ; ?? not sure these are the right conditions here
        PerformScript JAWSDelete ()
EndIf
EndScript ; JawsDelete

Script JAWSBackspace ()
;This script is similar to the JawsDelete script.
If FocusInTrackPanel ()&&!NoProject () Then
        PerformScript DeleteSelectedAudio()
Else
        PerformScript JAWSBackspace()
EndIf
EndScript ; JAWSBackspace

Script SayPriorCharacter ()
Var
        Handle hWnd
        
If !userBufferIsActive () && AnnounceOn ("AnnounceMessage") && IsPCCursor () && 
FocusInTrackPanel () && IsStopped () Then
        If NoProject () Then
                SayNoProject ()
                Return
        EndIf ; if no project
        TypeCurrentScriptKey ()
        Pause ()
        Let hWnd=FindDescendantWindow (GetRealWindow (GetFocus ()), 
ID_SELECTION_START)
        Say(GetPositionField (hWnd), OT_USER_REQUESTED_INFORMATION)
Else
        PerformScript SayPriorCharacter ()
EndIf
EndScript ; SayPriorCharacter

Script SayNextCharacter ()
Var
        Handle hWnd
        
If !userBufferIsActive () && AnnounceOn ("AnnounceMessage") && IsPCCursor () && 
FocusInTrackPanel () && IsStopped () Then
        If NoProject () Then
                SayNoProject ()
                Return
        EndIf ; if no project
        TypeCurrentScriptKey ()
        Pause ()
        Let hWnd=FindDescendantWindow (GetRealWindow (GetFocus ()), 
ID_SELECTION_START)
        Say(GetPositionField (hWnd), OT_USER_REQUESTED_INFORMATION)
Else
        PerformScript SayNextCharacter ()
EndIf
EndScript ; SayNextCharacter


Script Copy ()
;Copy selected sound to clipboard in main window.
If !IsTrackSelected () &&!UserBufferIsActive ()&&!DialogActive () && 
!MenusActive () Then
        SayNoTrackSelected ()
        Return
ElIf FocusInMainWindow ()
&&!UserBufferIsActive () Then ;this second condition makes the default script 
active in virtual viewer
        If NoProject () Then
                SayNoProject ()
                Return
        EndIf ; no project
        If !IsStopped () Then
                SayNotStopped ()
                Return
        EndIf
        TypeCurrentScriptKey ()
        If AnnounceOn ("AnnounceMessage") Then
                SayUsingVoice (VCTX_Message, msgCopyAudio, OT_status) ;speak 
alert message
        EndIf ; if AnnounceOn
Else
        ;If no project open, or focus in other windows, perform the default 
script
        PerformScript CopySelectedTextToClipboard ()
EndIf
EndScript ; Copy

Script CutToClipboard ()
If !IsTrackSelected () &&! DialogActive () Then
        SayNoTrackSelected ()
        Return
ElIf FocusInMainWindow ()
&&!UserBufferIsActive () Then ;this second condition makes the default script 
active in virtual viewer
        If NoProject () Then
                SayNoProject ()
                Return
        EndIf ; no project
        If !IsStopped () Then
                SayNotStopped ()
                Return
        EndIf
        TypeCurrentScriptKey ()
        If AnnounceOn ("AnnounceMessage") Then
                SayUsingVoice (VCTX_Message, msgCutAudio, OT_status) ;speak 
alert message
        EndIf ; if AnnounceOn
        ; We've already sent the key.
Else
        PerformScript CutToClipboard ()
EndIf
EndScript ; CutToClipboard

Script DeselectAll ()
;Unselect all audio
If NoProject () Then
        SayNoProject ()
        Return
Else
        AnnounceKeyMessage (msgDeselectAll)
EndIf
EndScript ; DeselectAll

Script CloseFocusTrack ()
;If this key will close the current track, speak a message, otherwise send to 
ap normally.
If NoProject () Then
        SayNoProject ()
        Return
ElIf !UserBufferIsActive ()&&FocusInTrackPanel () Then
        ;!UserBufferIsActive () makes the default script active in virtual 
viewer.
        If !IsStopped () Then
                SayNotStopped ()
                Return
        EndIf ; if not Stopped
        AnnounceKeyMessage (msgCloseFocusedTrack)
Else
        ;Focus not in track panel, send to app.
        SayCurrentScriptKeyLabel ()
        TypeCurrentScriptKey ()
EndIf ;else not in track panel
EndScript ; CloseFocusTrack

Script AnnounceOnOff ()
Var
        String sMessage
        
        ;Let sMessage="Announce messages" + UOAnnounceMessages(0)
        ;We extract the message from the AdjustJawsOptions constant so we don't 
need another message constant.
Let sMessage=StringSegment (UO_ANNOUNCE_MESSAGES, ":", 2) + 
UOAnnounceMessages(0)
Say (sMessage, OT_Status)
EndScript ; AnnounceOnOff

Script NextDocumentWindow ()
;Skip to next toolbar when in the toolbars.
Var
        Handle hToolbar,
        Handle hNext,
        Handle hWnd
        
If !IsToolbar (GetToolbar ()) Then
        PerformScript NextDocumentWindow ()
Else
        ;Is a toolbar.
        Let hToolbar = GetToolbar ()
        Let hNext = GetNextWindow (hToolbar)
        If !hNext Then
                Let hNext = GetFirstWindow (hToolbar)
        EndIf ; last window
        Let hWnd = GetFirstChild (hNext)
        ;Toolbars start with a grabber control, and some of them have static 
controls following the grabber.  We skip these to get to the first control.
        While hWnd && ( (StringCompare(GetWindowClass(hWnd), WC_wxWindowClass) 
== 0) || (GetWindowSubtypeCode (hWnd) == WT_STATIC))
                ;SayString("class=" + GetWindowClass(hWnd) + ", subtype = " + 
IntToString(GetWindowSubtypeCode(hWnd))) ; debug
                Let hWnd = GetNextWindow(hWnd)
        EndWhile
        SetFocus (hWnd)
EndIf ; else is toolbar
EndScript ; NextDocumentWindow

Script PreviousDocumentWindow ()
;Skip to previous toolbar when in the toolbars.
Var
        Handle hToolbar,
        Handle hPrior,
        Handle hWnd
        
If !IsToolbar (GetToolbar ()) Then
        PerformScript PreviousDocumentWindow ()
Else
        ; Is a toolbar.
        Let hToolbar = GetToolbar ()
        Let hPrior = GetPriorWindow (hToolbar)
        If !hPrior Then
                Let hPrior = GetLastWindow (hToolbar)
        EndIf ; first window
        Let hWnd = GetLastWindow(GetFirstChild (hPrior))
        SetFocus (hWnd)
EndIf ; else is toolbar
EndScript ; PreviousDocumentWindow

Const
;Audacity program states returned by GetAudacityState.
        ST_NOTOOLBAR = 0,
        ST_PAUSE = 1,
        ST_PLAY = 2,
        ST_RECORD = 4,
        ST_STOPPED = 8
        
Int Function GetAudacityState ()
;Returns a value indicating the current program state, e.g. play, record, 
stopped, paused.
Var
        Int iPauseState,
        Int iPlayState,
        Int iStopState,
        Int iRecordState,
        Handle hTemp,
        Int iState,
        Int iTemp
        
Let hTemp = GetFirstChild (GetAppMainWindow (GetFocus()))
Let hTemp = GetNextWindow (hTemp) ; parent of toolbars
Let hTemp = FindWindow (hTemp, "", WN_TRANSPORT_TOOLBAR)
If !hTemp Then
        Return ST_NOTOOLBAR
EndIf ; if no transport toolbar

Let hTemp = GetNextWindow (GetFirstChild (hTemp)) ; skip the grabber
Let iPauseState = GetObjState (hTemp)
Let hTemp = GetNextWindow (hTemp)
Let iPlayState = GetObjState (hTemp)
Let hTemp = GetNextWindow (hTemp)
Let iStopState = GetObjState (hTemp)
Let hTemp = GetNextWindow (GetNextWindow (GetNextWindow (hTemp))) ; skip Start 
and End
Let iRecordState = GetObjState (hTemp)
;SayString("Object states: pause = " + DecToHex(iPauseState) + ", play = " + 
DecToHex(iPLayState) + ", stop = " + DecToHex(iStopState) + ", record = " + 
DecToHex(iRecordState)) ; debug
If iPlayState & CTRL_PRESSED Then
        Let iState = ST_PLAY
ElIf iRecordState & CTRL_PRESSED Then
        Let iState = ST_RECORD
Else
        Let iState = ST_STOPPED
EndIf
If iPauseState & CTRL_PRESSED Then
        Let iState = iState | ST_PAUSE
EndIf
Return iState
EndFunction ; GetAudacityState

Script SayAudacityState ()
;Announces whether Audacity is stopped, playing, paused, or recording.
Var
;Int iPauseState,
;Int iPlayState,
;Int iStopState,
;Int iRecordState,
        Handle hTemp,
        Int iState,
        String sMsg
        
Let iState = GetAudacityState ()
If DialogActive () ||MenusActive () Then
        ;Pass key to app.
        SayCurrentScriptKeyLabel ()
        TypeCurrentScriptKey ()
        Return ;dialog active
ElIf iState == ST_NOTOOLBAR Then
        Say(msgNoTransportToolbar, OT_JAWS_MESSAGE)
        Return
ElIf NoProject () Then
        SayNoProject ()
        Return ;No project
EndIf ; no toolbar
If iState & ST_PLAY Then
        Let sMsg = msgPlay
ElIf iState & ST_RECORD Then
        Let sMsg = msgRecord
Else
        Let sMsg = msgStop
EndIf
If iState & ST_PAUSE Then
        Let sMsg = sMsg + cScSpace + msgPause
EndIf
Say(sMsg, OT_JAWS_MESSAGE)
EndScript ; SayAudacityState

;/*
;This script causes ENTER to do pause if not stopped, otherwise does normal 
ENTER.
;If you comment this out you should also comment out entries for keys ENTER and 
NumPadEnter in the jkm file.  Otherwise, if JAWS is set to treat numpad keys 
separately, not commenting out these entries will cause Audacity to see both 
keys as standard ENTER.
Script Enter ()
;SayString (GetCurrentScriptKeyName ()) ; debug
If FocusInMainWindow () && !IsStopped () && gfEnterPause Then
        TypeKey (csPauseKey)
Else
        ;Not pause
        If UserBufferIsActive () Then
                PerformScript Enter ()
        Else
                SayCurrentScriptKeyLabel ()
                TypeCurrentScriptKey ()
        EndIf ; else user buffer not active
EndIf ; else not pause
EndScript ; Enter
Script CtrlEnter ()
;SayString (GetCurrentScriptKeyName ()) ; debug
If FocusInMainWindow () && !IsStopped () && gfEnterPause Then
        TypeKey (cksEnter)
        Say(cksEnter, OT_KEYBOARD)
Else
        ;Not pause
        If UserBufferIsActive () Then
                PerformScript ControlEnter ()
        Else
                SayCurrentScriptKeyLabel ()
                TypeCurrentScriptKey ()
        EndIf ; else user buffer not active
EndIf ; else not pause
EndScript ; CtrlEnter
;*/

Int Function GetObjState (Handle hWnd)
;Gets the object state from an object in a window.  Assumes the object has the 
same name as the window (returned by GetWindowName).  This is used to get the 
Pressed state of toolbar buttons.
;The returned state uses control attribute values from hjconst.jsh, not 
MSAASTATE values from msaaconst.jsh.
;Returns -1 if unable to get the object state.
Var
        Int iState,
        Int iSubtype,
        String sName,
        Int iRtn,
        Int iMSAAMode,
        Object obj,
        Int iTemp
        
Let sName = GetWindowName (hWnd)
Let iMSAAMode = GetJCFOption (OPT_MSAA_MODE)
SetJCFOption (OPT_MSAA_MODE, 1)
Let iRtn = GetObjectInfoByName (hWnd, sName, 1, iSubtype, iState)
;Let iRtn = 0 ; debug
If !iRtn Then
        ;Try GetObjectFromEvent.
        ;SayString ("GetObjState: GetObjectInfoByName failed for " + sName) ; 
debug
        Let obj = getObjectFromEvent(hWnd, -4, 0, iTemp)
        If obj Then
                Let iTemp = obj.accState(1)
                If iTemp & STATE_SYSTEM_PRESSED Then
                        Let iState = CTRL_PRESSED
                Else
                        Let iState = 0
                EndIf
                ;SayString("  obj.accState returned 0x" + DecToHex(iTemp)) ; 
debug
        Else
                ;SayString ("  ObjectFromEvent got no object") ; debug
                Let iState = -1 ; set error
        EndIf ; If obj
EndIf ; If !iRtn
SetJCFOption (OPT_MSAA_MODE, iMSAAMode)
;SayString ("GetObjState: iState=0x" + DecToHex(iState) + " for " + sName) ; 
debug
Return iState
EndFunction ; GetObjState

Int Function IsStopped ()
Return GetAudacityState () & ST_STOPPED
EndFunction ; IsStopped

; *** Adapted from ie.jss
Script AdjustJawsVerbosity ()
;This is to support JAWS versions that do not support tree-style user options.  
This should work but may not look very nice.  Not tested!
Var
        String strListOfOptions
        
Let strListOfOptions = UO_ANNOUNCE_MESSAGES + _DLG_SEPARATOR + 
UO_ANNOUNCE_TOOLBARS
JawsVerbosityCore (strListOfOptions)
EndScript ; AdjustJawsVerbosity

Script AdjustJAWSOptions ()
Var
        String strListOfOptions
If InHJDialog () Then
        SayFormattedMessage (OT_error, cMSG337_L, cMSG337_S)
        Return
EndIf
Let strListOfOptions = UO_ANNOUNCE_MESSAGES + _DLG_SEPARATOR + 
UO_ANNOUNCE_TOOLBARS + _DLG_SEPARATOR + UO_ENTER_PAUSE
If GetJFWVersion () >= 900000 Then
        OptionsTreeCore (strListOfOptions) ;the OptionsTreeCore available in 
JAWS 9.0 or later
Else
        JawsVerbosityCore (strListOfOptions) ;The AdjustJawsVerbosity available 
prior to Jaws 9.0. Not tested
EndIf ; JAWS 9 or >
EndScript ; AdjustJAWSOptions

String Function NodeHlp (String sNodeName)
;This is the easiest way for you to create your callback help,
;for your configuration-specific options,
;if you have not specified a node, we have done so using your configuration's 
name.
;If you don't do this, your top-level or group node will tell your users that 
no help is available, although we try to be nice about it.
If StringContains (sNodeName, GetActiveConfiguration ()) Then
        Return msgUO_AudacityOptionsHlp
Else
        Return NodeHlp (sNodeName);Default for all default and Virtual Cursor 
groups.
EndIf
EndFunction ; NodeHlp

String Function UOAnnounceMessages (Int iRetCurVal)
Var
        Int iVal
Let iVal = IniReadInteger (Settings, "AnnounceMessage", CI_MESSAGES_OFF, 
CS_INI_FILE)
If !iRetCurVal Then
        If iVal == CI_MESSAGES_FULL Then
                Let iVal = CI_MESSAGES_OFF
        Else
                ; This paves the way for multiple values.
                Let iVal = iVal + 1
        EndIf
        IniWriteInteger (Settings, "AnnounceMessage", iVal, CS_INI_FILE)
EndIf ; if !iRetCurVal
If iVal == CI_MESSAGES_OFF Then
        Return cmsg_Off
ElIf iVal == CI_MESSAGES_FULL Then
        Return cmsg_On
EndIf
EndFunction ; UOAnnounceMessages

String Function UOAnnounceMessagesHlp ()
Return msgUO_AnnounceMessagesHlp
EndFunction ; UOAnnounceMessagesHlp

String Function UOAnnounceToolbars (Int iRetCurVal)
Var
        Int iVal
        
Let iVal = IniReadInteger (Settings, "Announcetoolbars", CI_TOOLBARS_OFF, 
CS_INI_FILE)
If !iRetCurVal Then
        If iVal == CI_TOOLBARS_ON Then
                Let iVal = CI_TOOLBARS_OFF
        Else
                ; This paves the way for multiple values.
                Let iVal = iVal + 1
        EndIf
        IniWriteInteger (Settings, "Announcetoolbars", iVal, CS_INI_FILE)
EndIf ; if !iRetCurVal
If iVal == CI_TOOLBARS_OFF Then
        Return cmsg_Off
ElIf iVal == CI_TOOLBARS_ON Then
        Return cmsg_On
EndIf
EndFunction ; UOAnnounceToolbars

String Function UOAnnounceToolbarsHlp ()
Return msgUO_AnnounceToolbarsHlp
EndFunction ; UOAnnounceToolbarsHlp

String Function UOEnterPause (Int iRetCurVal)
Var
        Int iVal
        
Let iVal = IniReadInteger (Settings, "EnterPause", CI_ENTERPAUSE_ON, 
CS_INI_FILE)
If !iRetCurVal Then
        If iVal == CI_ENTERPAUSE_ON Then
                Let iVal = CI_ENTERPAUSE_OFF
                Let gfEnterPause = False
        Else
                Let iVal = iVal + 1
                Let gfEnterPause = True
        EndIf
        IniWriteInteger (Settings, "EnterPause", iVal, CS_INI_FILE)
EndIf ; if !iRetCurVal
If iVal == CI_ENTERPAUSE_OFF Then
        Return cmsg_Off
ElIf iVal == CI_ENTERPAUSE_ON Then
        Return cmsg_On
EndIf
EndFunction ; UOEnterPause

String Function UOEnterPauseHlp ()
Return msgUO_EnterPauseHlp
EndFunction ; UOEnterPauseHlp

Void Function AddDefaultConfig ()
;Adds values of default settings to Audacity.JSI File.
IniWriteInteger (Settings, "AnnounceMessage", CI_MESSAGES_FULL, CS_INI_FILE, 
False) ; don't flush because we're going to write another one
IniWriteInteger (Settings, "EnterPause", CI_ENTERPAUSE_ON, CS_INI_FILE, False) 
; don't flush because we're going to write another one
Let gfEnterPause = CI_ENTERPAUSE_ON
IniWriteInteger (Settings, "AnnounceToolbars", CI_TOOLBARS_ON, CS_INI_FILE, 
False) ; no flush
IniWriteString (Settings, "JAWSGuideLink", CS_JawsGuide_LINK, CS_INI_FILE, True)
Let gsJawsGuidelink = CS_JawsGuide_LINK
;Let gsJawsGuideTitle = CS_JawsGuide_Title
EndFunction ; AddDefaultConfig

Script ResetConfig ()
;Reset all audacity JAWS script options to their default values.
Var
        String sMessage
        
        ;First we remove the old key because of our changes in Audacity.JSI 
file made by script v1.1.
If FileExists (FindJAWSPersonalizedSettingsFile (CS_INI_FILE, True)) Then
        ;Remove obsolete key if it exists.
        Let sMessage=IniReadString (Settings, "announce", "", CS_INI_FILE) ;the 
old key "anounce" has been changed to "AnnounceMessage"
        If sMessage Then
                IniRemoveKey (settings, "announce", CS_INI_FILE, false)
        EndIf ;sMessage
EndIf ;FileExists
AddDefaultConfig ()
Say (msgResetScriptOptions, OT_message)
EndScript ; ResetConfig

Script SayAppVersion ()
;Says current program and script version
Var
        String sMessage
        
PerformScript SayAppVersion () ;Says current program version
Let sMessage=FormatString (msg_Script_Version, CS_SCRIPT_VERSION) ;current 
script version
Say (sMessage, OT_No_Disable) ;says current script version
If IsSameScript () Then
        UserBufferAddText (sMessage)
EndIf
EndScript ; SayAppVersion

Script SelectAll ()
;Announce a message when user selects all tracks in current project, or no 
project open.
PerformScript SelectAll()
If NoProject () Then
        SayNoProject ()
        Return
ElIf FocusInMainWindow () && ! NoProject () && AnnounceOn ("AnnounceMessage") 
Then
        SayUsingVoice (VCTX_Message, MsgSelectAll, OT_String)
EndIf
EndScript ; SelectAll

; Cuong's with modification
Void Function ProcessVST (Int iControlID)
;Activates Preset, Load Preset, and Save Preset controls in VST plugin dialogs.
Var
        Handle hWnd,
        Int bSpeechOff
        
Let hWnd=FindDescendantWindow (GetRealWindow (GetFocus ()), iControlID) ;The 
control ID of the control the focus should be moved to
If DialogActive () && hWnd Then ;make sure user is in a dialog and we found the 
desired control.
        If GetWindowSubtypeCode (hWnd)==WT_BUTTON Then
                Let bSpeechOff = IsSpeechOff ()
                SpeechOff () ;prevent JAWS from speaking while focus moves to 
the button
                SetFocus (hWnd) ;move focus to the button
                Pause () ;so button doesn't speak after speech is turned back on
                EnterKey () ;activate the button
                If !bSpeechOff Then
                        SpeechOn ()
                EndIf
        Else
                ;dest not a button.  Why do we set focus here?
                ;while focus at the preset control, just set focus to it.
                SetFocus (hWnd)
        EndIf ; get window class
Else
        ;Process normal functionalities wile focus stands at main window. This 
mean user can add the same hotkeys of vst for any options they prefer.
        ;SayString("vst") ; debug
        SayCurrentScriptKeyLabel ()
        TypeCurrentScriptKey ()
EndIf ;Dialog active
EndFunction ; ProcessVST

Script VSTPreset ()
;Set focus to the preset control if present
ProcessVST (ID_Preset)
EndScript ; VSTPreset

Script VSTLoadPreset ()
;Activates the load preset button by pressing alt+l
ProcessVST (ID_Load_Preset)
EndScript ; VSTLoadPreset

Script VSTSavePreset ()
;Save current VST settings as a preset
ProcessVST (ID_Save_Preset)
EndScript ; VSTSavePreset

Script SayJump ()
;For use by short/long jumps (,, ., etc.).  sends the key, if in track panel 
and AnnounceOn speaks start position, otherwise speaks the key label.
;If you want a separate script for each key, turn this into a function and call 
it from the scripts.
Var
        Handle hWnd
        
TypeCurrentScriptKey ()
If !UserBufferIsActive ()&&FocusInTrackPanel () && NoProject () Then
        SayNoProject ()
        Return
ElIf !UserBufferIsActive ()&&FocusInTrackPanel ()&&AnnounceOn 
("AnnounceMessage") && IsStopped () Then
        Pause ()
        Let hWnd=FindDescendantWindow (GetRealWindow (GetFocus ()), 
ID_SELECTION_START)
        Say(GetPositionField (hWnd), OT_USER_REQUESTED_INFORMATION)
Else
        SayCurrentScriptKeyLabel ()
EndIf
EndScript ; SayJump

Int Function IsTrackSelected ()
;indicates that there is a selected track.
Var
        Object obj,
        Handle hWnd,
        String sMsg,
        Int i,
        Int iTrackCount,
        Int iState,
        Int iMSAAMode
        
If NoProject () Then
        SayNoProject ()
        Return
Else
        Let hWnd = GetFirstChild (GetLastWindow (GetFirstChild 
(GetAppMainWindow (GetFocus ()))))
        ;SayString ("Window name = " + GetWindowName(hWnd)) ; debug
        Let iMSAAMode = GetJcfOption(OPT_MSAA_MODE)
        SetJcfOption(OPT_MSAA_MODE, 1)
        Let obj = getObjectFromEvent(hWnd, -4, 0, i)
        ; obj is the table.
        Let iTrackCount = obj.accChildCount
        Let i = 1
        While i <= iTrackCount
                Let iState = obj.accState(i)
                ;This is a bitwise and, we are testing the bit for the selected 
state.
                If iState & STATE_SYSTEM_SELECTED Then
                        SetJcfOption(OPT_MSAA_MODE, iMSAAMode)
                        Return True
                EndIf ; selected
                Let i = i + 1
        EndWhile
        ;None selected.
        SetJcfOption(OPT_MSAA_MODE, iMSAAMode)
        Return False
EndIf ;Else project exists
EndFunction ; IsTrackSelected

Void Function SayNoTrackSelected ()
;Announce that the current track is not selected
If !NoProject () &&!MenusActive () Then ;Only announce when a project exists
        SayMessage (OT_error, msgNoTrackSelected_L, msgNoTrackSelected_S)
EndIf ;No project
EndFunction ; SayNoTrackSelected

Int Function IsWarningDialog ()
;Verify that focus is in the warning dialog that appears when importing 
uncompressed audio files.
Var
        String sName
        
Let sName = GetWindowName (GetFocus ())
If DialogActive ()
&& (sName==MsgCopy
||sName==MSGDirectEdit
||sName==MSGDoNotWarn) Then
        Return TRUE
EndIf ;dialog active
EndFunction ; IsWarningDialog

Script SayLine ()
If IsWarningDialog () && IsPCCursor () && Not UserBufferIsActive () && 
!CheckAudacityVersion ("2,0,3") Then ;we are in the warning dialog for 
importing uncompressed audio
        SayWindowTypeAndText (GetFocus ())
Else
        ; Not at this dialog, performs default funtionality
        PerformScript SayLine()
EndIf
EndScript ; SayLine

Script SwitchChainsList ()
;Switch between the Chains and Chain lists in the Edit Chains dialog.
;Feature suggested by Dang Manh Cuong
;Code given by Gary Campbell
Var
        Handle wnd,
        Handle hReal,
        Int iCurId,
        String sMessage
        
Let hReal = GetRealWindow (GetFocus ())
If DialogActive () &&GetWindowName (hReal)==WN_EDIT_CHAINS Then
        Let iCurId = GetControlID (GetFocus ())
        If iCurId == ID_Chains_List Then
If CheckAudacityVersion ("2,0,4") then ;The control ID of Change CMD has 
changed since Audacity 2.0.4. So we add this condition to varify that.
                Let wnd=FindDescendantWindow (GetRealWindow (GetFocus ()), 
ID_Chain_Cmds_List2)
Else
                Let wnd=FindDescendantWindow (GetRealWindow (GetFocus ()), 
ID_Chain_Cmds_List)
EndIf ;Check Audacity version
                Let sMessage=msgChainCommands ;list of commands in the right 
list
        Else
                Let wnd=FindDescendantWindow (hReal, ID_Chains_List)
                Let sMessage=msgChains ;list of chains in the left list
        EndIf ; Else neither list.
        SetFocus (wnd)
        ;speaks a message when switching between the listss
        If AnnounceOn ("AnnounceMessage") Then
                SayUsingVoice (VCTX_message, sMessage, ot_String)
        EndIf
Else
        ;Not Edit Chains dialog
        SayCurrentScriptKeyLabel ()
        TypeCurrentScriptKey ()
EndIf ;Else not Edit Chains dialog
EndScript ; SwitchChainsList

Script PasteFromClipboard ()
;Speaks a warning message when not stopped
If DialogActive () || MenusActive () Then
        ;I don't think we need to worry about menus, but check just in case.
        PerformScript PasteFromClipboard ()
        Return
EndIf
;Not in a dialog or menu.
/*
This should be removed because we can paste audio without opening a project.
If NoProject () Then
        SayNoProject ()
        Return
ElIf !IsStopped () Then
*/
If !IsStopped () then
        SayNotStopped ()
        Return
Else
        PerformScript PasteFromClipboard ()
EndIf 
EndScript ; PasteFromClipboard

Script ShowCopyright()
SayMessage(OT_USER_BUFFER, msgCopyright)
EndScript ; ShowCopyright

Int Function CheckAudacityVersion (String sCheckVer)
;return True if program version in sCheckVer is >= the version of Audacity.  
SCheckver is in the form "major,minor,build,fix".  Trailing segments may be 
omitted, in which case they are not checked.
Var
        String sVersion, ;get the version
        Int iMax,
        Int iCounter,
        Int fRes,
        Int iTemp,
        Int iTemp2
        ;Now check current version number
Let sVersion = GetVersionInfoString (GetAppFilePath (), "FileVersion")
Let iMax = StringSegmentCount (sVersion, ",")
Let iTemp = StringSegmentCount (sCheckVer, ",")
If iTemp < iMax Then
        Let iMax = iTemp
EndIf

Let fRes = True
Let iCounter = 1
While fRes && iCounter <= iMax
        Let fRes = StringToInt(StringSegment(sVersion, ",", iCounter)) >= 
StringToInt(StringSegment(sCheckVer, ",", iCounter))
        Let iCounter = iCounter + 1
EndWhile
Return fRes
EndFunction ; CheckAudacityVersion

Script test ()
;Test CheckAudacityVersion.
Var String s
Let s = "testing 2,0,3, got " + IntToString(CheckAudacityVersion("2,0,3")) + ", 
should get True\n"
Let s = s + "testing 2,0,4, got " + IntToString(CheckAudacityVersion("2,0,4")) 
+ ", should get True\n"
Let s = s + "testing 2,0,5, got " + IntToString(CheckAudacityVersion("2,0,5")) 
+ ", should get False\n"
SayMessage(OT_USER_BUFFER, s)
EndScript ; test

Void Function loadNonJCFOptions ()
;This function is effected by the QuickSettings script, support for Jaws 13 and 
later
Var
String NonJCF ;the section for storing settings within the JCF file
Let NonJCF="NonJCFOptions"
;Now read the info get from Audacity.jcf file
Let AnnounceMessage=IniReadInteger (NonJCF, "AnnounceMessage", 1, 
"Audacity.jcf")
Let AnnounceToolbars=IniReadInteger (NonJCF, "AnnounceToolbars", 1, 
"audacity.jcf")
Let gfEnterPause=IniReadInteger (NonJCF, "EnterPause", 1, "audacity.jcf")
Let SpeechOff=IniReadInteger (NonJCF, "SpeechOff", 1, "audacity.jcf")
;Write the info above to Audacity.JSI file
                IniWriteInteger (Settings, "AnnounceMessage", AnnounceMessage, 
CS_Ini_File, false)
        IniWriteInteger (Settings, "EnterPause", gfEnterPause, CS_Ini_File, 
false)
        IniWriteInteger (Settings, "EnterPause", gfEnterPause, CS_Ini_File, 
false)
IniWriteInteger (Settings, "SpeechOff", SpeechOff, CS_Ini_File, False)
        IniWriteInteger (Settings, "AnnounceToolbars", AnnounceToolbars, 
CS_Ini_File, true)
;The condition below got from JAWS Scripts for Foobar 2000 (written by Andrew 
Hart)
If GetJFWVersion()<1300000 Then
Return ; prevent loadNonJCFOptions from chaining to itself since it doesn't 
exist in JAWS version prior to 13.0
EndIf ;Get JFW
loadNonJCFOptions ()
EndFunction ;LoadNonJCFOptions

Script AddAudacityJawsGuide ()
;Script for adding new Jaws Guide link if present
Var
String sURL, ;The current URL gotten from the JSI file
String sTemp, ;store current URL
String sNewURL ;The New URL added by user
Let sURL=IniReadString (Settings, "JAWSGuideLink", sURL, CS_INI_File) ;get the 
URL from JSI file
Let sTemp=sURL ;store current URL
;Now display the input box wich contains the Current URL, and allows changing it
InputBox (MSGJawsGuideDialog, "Add Audacity Jaws Guide Link", sURL)
Let sNewURL=sURL ;get the URL from the box.
If StringIsBlank (sNewURL) 
|| sNewURL==sTemp then ;user doesn't enter anything, or the URL from the box 
and the original URL are the same.
        SayFormattedMessage (OT_Jaws_Message, MSGNoChange_l, msgNoChange_s)
Return
ElIf sNewURL != sTemp then
    Let gsJawsGuideLink = sNewURL
    IniWriteString (Settings, "JAWSGuideLink", gsJawsGuideLink, CS_Ini_File, 
true)
        SayFormattedMessage (OT_Jaws_message, FormatString (msgNewURL, sNewURL))
EndIf
EndScript ;AddAudacityJawsGuide

Script Record ()
;Don't speak Record or Record-Append keys.
If DialogActive () ||MenusActive () Then
        ;A dialog is open, pass key to application and speak its label.
        SayCurrentScriptKeyLabel ()
        TypeCurrentScriptKey ()
Else
        TypeCurrentScriptKey ()
EndIf
EndScript ; Record

Script Preview ()
;This just turn Jaws speech off because I don't like Jaws saying when preview 
an effect
Var
Int iSpeech ;Variable to get setting from the JSI file. The setting adjusts 
within the quick settings.
Let iSpeech=IniReadInteger (Settings, "SpeechOff", 0, CS_Ini_File)
If DialogActive ()&&iSpeech==1 then
        SpeechOff ()
EndIf ;Dialog active
SayCurrentScriptKeyLabel ()
TypeCurrentScriptKey ()
EndScript ;Preview

Other related posts: