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