RadMode Tools

Automation scripts and utilities for radiology workflows

RadMode Automation Script

Complete AutoHotkey v2 script for radiology workflow automation including EPIC integration and dictation controls.

Key Features

  • EPIC "break the glass" automation
  • PowerScribe dictation controls
  • Visage viewer shortcuts
  • Trackball scroll emulation (CapsLock)
  • Interactive GUI with help guide
  • Executable runner provided
Full Script & Runner
Download Hammer Icon

Place the icon in the same directory as the script to allow the script to find the "Break the Glass" link and automatically complete it.

Quick Reference
Key shortcuts (full list available in script GUI)

Global Shortcuts

Caps LockTrackball Scroll (Hold)
Alt + zSmart Break Glass
Shift + Alt + zForce Manual Entry
Alt + pLogin site
Alt + dField strength
Alt + fSearch biopsy
Caps + fEnable Rads Mode
Caps + dExit Rads Mode

Rads Mode - Dictation

dToggle dictation
hSave draft
fNext field
gPrevious field
sBackspace
aNew line
qUndo
wRedo

Pick Lists & Visage

e / rPick values
Alt + 1-5Pick values

Visage viewer:

z, x, c, vSend to Visage
Installation & Usage
Step-by-step guide to install and configure the automation scripts
i

Flexibility

You can either run the bundled .exe without installing any software, or you can run the .ahk source script if you already have AutoHotkey v2 installed. Both require downloading all files into the same folder.

Getting Started

  1. 1Download the Script, Runner, and Hammer image above
  2. 2
    Place all three files together into the same folder on your computer
  3. 3Double-click RadMode.exe (or the .ahk script) to run it
  4. 4Use the setup GUI to configure your settings

Usage Tips

  • Use Caps + f to enable Rads Mode for dictation shortcuts
  • Press Caps + d to exit Rads Mode when done
  • Caps Lock toggles trackball scrolling (or Ctrl key if disabled in GUI)
  • The launcher window minimizes after setup - close it to stop the script

Important Security Notes

  • Scripts are designed for specific radiology software (EPIC, PowerScribe, Visage)
  • Test thoroughly in a safe environment before clinical use
  • Keep credentials secure - never share configured script files
  • Customize hotkeys and window titles to match your specific setup
Full RadMode Automation Script
View the complete source code or copy it to your clipboard
1#Requires Autohotkey v2
2#SingleInstance Force
3CoordMode "ToolTip", "Screen"
4CoordMode "Mouse", "Screen" 
5CoordMode "Pixel", "Screen" 
6SetTitleMatchMode 2
7
8; ==============================================================================
9; Version & Configuration Defaults
10; ==============================================================================
11global VERSION := "v22.17" 
12global INI_FILE := "rad_helper_settings.ini"
13
14; --- User Variables (Runtime) ---
15global USER := ""
16global PASS := ""
17global KEEPAWAKE := 0
18global TRACKBALL_SCROLL := 1
19global DEBUG_MODE := 0
20global DETECT_HAMMER := 1 
21
22; --- Advanced Settings (Loaded from INI) ---
23global BTG_TAB_DELAY := 80        
24global BTG_POPUP_DELAY := 500     
25global SCROLL_THRESHOLD := 15     
26global SCROLL_LOCK_RATIO := 2.0   
27
28; --- Marker Customization ---
29global MARKER_SIZE := 5            
30global MARKER_COLOR := "FF0000"    
31global MARKER_ALPHA := 180        
32
33; --- Reliability Settings ---
34SetKeyDelay 10, 10
35global LOGIN_STEP_DELAY := 150    
36
37; --- Window Titles ---
38global EPIC_TITLE := "Prod"
39global PS := "PowerScribe"
40global VISAGE := "Visage"
41global VISAGE_LOGIN := "Client Login ahk_class Qt51510QWindowIcon"
42
43global RADSMODE := false
44global MarkerGui := unset
45
46; ==============================================================================
47; Initialization
48; ==============================================================================
49LoadSettings() 
50CreateCursorMarker()
51
52; ==============================================================================
53; Main GUI
54; ==============================================================================
55myGui := Gui()
56myGui.Title := "Radiology Helper " . VERSION
57myGui.BackColor := "FBFBFB"
58myGui.SetFont("s10", "Segoe UI")
59
60; --- Login Section ---
61myGui.Add("GroupBox", "x20 y10 w460 h80", "Login Credentials")
62myGui.Add("Text", "x40 y40 w70 h25 +0x200", "Username:")
63Edit1 := myGui.Add("Edit", "x115 y40 w130 h25", USER)
64
65myGui.Add("Text", "x255 y40 w70 h25 +0x200", "Password:")
66Edit2 := myGui.Add("Edit", "x330 y40 w110 h25 +Password", PASS)
67
68; --- Action Button ---
69LaunchButton := myGui.Add("Button", "x20 y100 w260 h50 +Default", "Launch Visage System")
70LaunchButton.OnEvent("Click", LaunchButtonHandler)
71LaunchButton.SetFont("s11 bold")
72
73; --- Config Button ---
74ConfigButton := myGui.Add("Button", "x290 y100 w190 h50", "Advanced Config")
75ConfigButton.OnEvent("Click", OpenConfigMenu)
76
77; --- Options Section ---
78CheckBox1 := myGui.Add("CheckBox", "x40 y160 w150 h25 Checked" . KEEPAWAKE, "Prevent Sleep")
79CheckBox2 := myGui.Add("CheckBox", "x220 y160 w240 h25 Checked" . TRACKBALL_SCROLL, "Hold CapsLock to scroll")
80
81; -- Hammer Checkbox Logic --
82hammerFileExists := FileExist("hammer.png")
83hammerState := hammerFileExists ? DETECT_HAMMER : 0
84hammerOpts := hammerFileExists ? "" : "Disabled"
85CheckBoxHammer := myGui.Add("CheckBox", "x40 y185 w200 h25 Checked" . hammerState . " " . hammerOpts, "Detect 'Hammer' Icon")
86
87CheckBox3 := myGui.Add("CheckBox", "x250 y185 w150 h25 Checked" . DEBUG_MODE, "Debug Mode")
88
89; --- Divider ---
90myGui.Add("Text", "x20 y215 w460 h2 0x10")
91
92; --- Reference Guide (Reformatted) ---
93myGui.SetFont("s9", "Segoe UI")
94RefGroup := myGui.Add("GroupBox", "x20 y220 w460 h185", "Quick Reference Guide")
95
96; Column 1: Global
97myGui.SetFont("s9 w700")
98myGui.Add("Text", "x40 y245 w180", "Global Shortcuts")
99myGui.SetFont("s9 w400")
100myGui.Add("Text", "x40 y265 w200", "Caps + f : Rads Mode ON")
101myGui.Add("Text", "x40 y285 w200", "Caps + d : Rads Mode OFF")
102myGui.Add("Text", "x40 y305 w200", "Alt + p : Auto-Login Site")
103myGui.Add("Text", "x40 y325 w200", "Alt + z : Smart Break Glass")
104myGui.Add("Text", "x40 y345 w200", "S+Alt+z : Force Manual Entry")
105
106; Column 2: Rads Mode
107myGui.SetFont("s9 w700")
108myGui.Add("Text", "x260 y245 w180", "Rads Mode (Vim-Style)")
109myGui.SetFont("s9 w400")
110myGui.Add("Text", "x260 y265 w200", "d : Toggle Dictation")
111myGui.Add("Text", "x260 y285 w200", "h : Save Draft (F9)")
112myGui.Add("Text", "x260 y305 w200", "f / g : Next / Prev Field")
113myGui.Add("Text", "x260 y325 w200", "s / a : Backspace / Enter")
114myGui.Add("Text", "x260 y345 w200", "Alt + 1-5 : Pick List Choice")
115
116; Logic Note
117myGui.SetFont("s8 italic c555555")
118myGui.Add("Text", "x40 y370 w420", "Smart Logic: If 'Hammer' setting is ON & icon found, it clicks the hammer. If OFF or NOT found, it runs the 'Provision' entry workflow.")
119
120; Footer
121myGui.SetFont("s8 c777777")
122myGui.Add("Text", "x20 y415 w460 Center", "Note: Red dot indicator appears when Rads Mode is active.")
123
124myGui.Show("w500 h445")
125
126; ==============================================================================
127; Cursor Marker Logic
128; ==============================================================================
129CreateCursorMarker() {
130    global MarkerGui, MARKER_SIZE, MARKER_COLOR, MARKER_ALPHA
131    if IsSet(MarkerGui)
132        MarkerGui.Destroy()
133    MarkerGui := Gui("+AlwaysOnTop -Caption +ToolWindow +E0x20") 
134    MarkerGui.BackColor := MARKER_COLOR
135    D := MARKER_SIZE
136    WinSetRegion("0-0 W" D " H" D " R" D "-" D, MarkerGui.Hwnd)
137    MarkerGui.Opt("+LastFound")
138    WinSetTransparent(MARKER_ALPHA, MarkerGui.Hwnd)
139}
140
141UpdateMarkerPos() {
142    global RADSMODE, MarkerGui, MARKER_SIZE
143    if (RADSMODE) {
144        MouseGetPos(&mX, &mY)
145        MarkerGui.Show("x" (mX + 12) " y" (mY + 12) " w" MARKER_SIZE " h" MARKER_SIZE " NoActivate")
146    } else {
147        MarkerGui.Hide()
148    }
149}
150
151; ==============================================================================
152; Advanced Config Menu
153; ==============================================================================
154OpenConfigMenu(*) {
155    advGui := Gui()
156    advGui.Title := "Advanced Configuration"
157    advGui.SetFont("s9", "Segoe UI")
158
159    advGui.Add("GroupBox", "x10 y10 w380 h100", "Rads Mode Indicator (Dot)")
160    advGui.Add("Text", "x30 y35 w100 h20", "Dot Size (px):")
161    Ctrl_Size := advGui.Add("Edit", "x130 y32 w60 h20 Number", MARKER_SIZE)
162    advGui.Add("Text", "x210 y35 w80 h20", "Hex Color:")
163    Ctrl_Color := advGui.Add("Edit", "x290 y32 w80 h20", MARKER_COLOR)
164    advGui.Add("Text", "x30 y65 w100 h20", "Opacity (0-255):")
165    Ctrl_Alpha := advGui.Add("Edit", "x130 y62 w60 h20 Number", MARKER_ALPHA)
166
167    advGui.Add("GroupBox", "x10 y120 w380 h130", "Workflow Settings")
168    advGui.Add("Text", "x30 y145 w150 h20", "Tab Delay (ms):")
169    Ctrl_TabDelay := advGui.Add("Edit", "x240 y142 w80 h20 Number", BTG_TAB_DELAY)
170    advGui.Add("Text", "x30 y175 w150 h20", "Scroll Sensitivity:")
171    Ctrl_Sens := advGui.Add("Edit", "x240 y172 w80 h20 Number", SCROLL_THRESHOLD)
172    advGui.Add("Text", "x30 y205 w150 h20", "Axis Lock Ratio:")
173    Ctrl_Lock := advGui.Add("Edit", "x240 y202 w80 h20", SCROLL_LOCK_RATIO)
174
175    SaveBtn := advGui.Add("Button", "x90 y270 w100 h30", "Save")
176    CancelBtn := advGui.Add("Button", "x200 y270 w100 h30", "Cancel")
177    SaveBtn.OnEvent("Click", SaveHandler)
178    CancelBtn.OnEvent("Click", (*) => advGui.Destroy())
179    advGui.Show()
180
181    SaveHandler(*) {
182        global BTG_TAB_DELAY, SCROLL_THRESHOLD, SCROLL_LOCK_RATIO
183        global MARKER_SIZE, MARKER_COLOR, MARKER_ALPHA
184        MARKER_SIZE := Ctrl_Size.Value
185        MARKER_COLOR := Ctrl_Color.Value
186        MARKER_ALPHA := Ctrl_Alpha.Value
187        BTG_TAB_DELAY := Ctrl_TabDelay.Value
188        SCROLL_THRESHOLD := Ctrl_Sens.Value
189        SCROLL_LOCK_RATIO := Number(Ctrl_Lock.Value) 
190        SaveSettings() 
191        CreateCursorMarker()
192        advGui.Destroy()
193        MsgBox("Settings Saved!", "Configuration", "Iconi T1")
194    }
195}
196
197; ==============================================================================
198; INI Persistence Functions
199; ==============================================================================
200LoadSettings() {
201    global BTG_TAB_DELAY, SCROLL_THRESHOLD, SCROLL_LOCK_RATIO
202    global MARKER_SIZE, MARKER_COLOR, MARKER_ALPHA, DETECT_HAMMER
203    if FileExist(INI_FILE) {
204        try {
205            BTG_TAB_DELAY := IniRead(INI_FILE, "Citrix", "TabDelay", 80)
206            SCROLL_THRESHOLD := IniRead(INI_FILE, "Physics", "Sensitivity", 15)
207            SCROLL_LOCK_RATIO := IniRead(INI_FILE, "Physics", "AxisLock", 2.0)
208            MARKER_SIZE := IniRead(INI_FILE, "Marker", "Size", 5)
209            MARKER_COLOR := IniRead(INI_FILE, "Marker", "Color", "FF0000")
210            MARKER_ALPHA := IniRead(INI_FILE, "Marker", "Alpha", 180)
211            DETECT_HAMMER := IniRead(INI_FILE, "Workflow", "DetectHammer", 1)
212        }
213    }
214}
215
216SaveSettings() {
217    IniWrite(BTG_TAB_DELAY, INI_FILE, "Citrix", "TabDelay")
218    IniWrite(SCROLL_THRESHOLD, INI_FILE, "Physics", "Sensitivity")
219    IniWrite(SCROLL_LOCK_RATIO, INI_FILE, "Physics", "AxisLock")
220    IniWrite(MARKER_SIZE, INI_FILE, "Marker", "Size")
221    IniWrite(MARKER_COLOR, INI_FILE, "Marker", "Color")
222    IniWrite(MARKER_ALPHA, INI_FILE, "Marker", "Alpha")
223    IniWrite(CheckBoxHammer.Value, INI_FILE, "Workflow", "DetectHammer")
224}
225
226; ==============================================================================
227; GUI Handlers
228; ==============================================================================
229UpdateGlobals(*) {
230    global USER := Edit1.Value, PASS := Edit2.Value, KEEPAWAKE := CheckBox1.Value
231    global TRACKBALL_SCROLL := CheckBox2.Value, DEBUG_MODE := CheckBox3.Value
232    global DETECT_HAMMER := CheckBoxHammer.Value
233}
234LaunchButtonHandler(*) {
235    LaunchVisage()
236    myGui.Minimize()
237}
238CloseHandler(*) => ExitApp()
239
240; ==============================================================================
241; Core Logic
242; ==============================================================================
243SetTimer StopSleep, 100000
244SetTimer UpdateMarkerPos, 15 
245
246LaunchVisage() {
247    if WinExist(VISAGE) {
248        WinActivate(VISAGE)
249        return
250    }
251    if WinExist(VISAGE_LOGIN) {
252        VisageLoginSequence()
253        return
254    }
255    targetLnk := ""
256    loop files A_Desktop "\*Visage*.lnk" {
257        targetLnk := A_LoopFileFullPath
258        break
259    }
260    if (targetLnk == "") {
261        loop files A_DesktopCommon "\*Visage*.lnk" {
262            targetLnk := A_LoopFileFullPath
263            break
264        }
265    }
266    if (targetLnk) {
267        Run(targetLnk)
268    } else {
269        fallbackPath := "C:\Program Files\Visage Imaging\Visage 7.1\bin\arch-Win\vsclient.exe"
270        if FileExist(fallbackPath) {
271            Run(fallbackPath)
272        } else {
273            MsgBox("Could not find Visage executable.", "Error", "Icon!")
274            return
275        }
276    }
277    if WinWait(VISAGE_LOGIN,, 20) {
278        VisageLoginSequence()
279    }
280}
281
282VisageLoginSequence() {
283    global VISAGE_LOGIN, LOGIN_STEP_DELAY
284    global Edit1, Edit2 
285    
286    if !WinExist(VISAGE_LOGIN)
287        return
288    WinActivate(VISAGE_LOGIN)
289    if !WinWaitActive(VISAGE_LOGIN,, 3)
290        return
291    
292    local safeUser := Edit1.Value
293    local safePass := Edit2.Value
294    
295    SetKeyDelay 10, 10
296    
297    WinGetPos(,, &winW, &winH, VISAGE_LOGIN)
298    oldMode := A_CoordModeMouse
299    CoordMode "Mouse", "Window"
300    
301    MouseMove(winW * 0.60, winH * 0.40) 
302    Sleep(LOGIN_STEP_DELAY)
303    Click()
304    Sleep(LOGIN_STEP_DELAY)
305
306    SendEvent("^a{Delete}")
307    Sleep(LOGIN_STEP_DELAY)
308    SendEvent("{Raw}VISAGE.NYUMC.ORG")
309    Sleep(LOGIN_STEP_DELAY)
310    SendEvent("{Tab}")
311    Sleep(LOGIN_STEP_DELAY)
312
313    SendEvent("^a{Delete}")
314    Sleep(LOGIN_STEP_DELAY)
315    SendEvent("{Raw}" safeUser)
316    Sleep(LOGIN_STEP_DELAY)
317    SendEvent("{Tab}")
318    Sleep(LOGIN_STEP_DELAY)
319
320    SendEvent("{Raw}" safePass)
321    Sleep(LOGIN_STEP_DELAY + 200) 
322
323    SendEvent("{Enter}")
324    
325    CoordMode "Mouse", oldMode
326}
327
328breakGlass() {
329    global PASS, BTG_TAB_DELAY, Edit2, DETECT_HAMMER
330    global CheckBoxHammer
331    
332    detectEnabled := CheckBoxHammer.Value 
333    
334    screenLeft := SysGet(76), screenTop := SysGet(77), screenWidth := SysGet(78), screenHeight := SysGet(79)
335    hammerFound := false
336
337    if (detectEnabled && FileExist("hammer.png")) {
338        try {
339            if ImageSearch(&FoundX, &FoundY, screenLeft, screenTop, screenLeft+screenWidth, screenTop+screenHeight, "*75 hammer.png") {
340                hammerFound := true
341                MouseMove(FoundX + 10, FoundY + 10)
342                Click("Down"), Sleep(10), Click("Up"), Sleep(50)
343                Send("{Tab}"), Sleep(50), Send("{Enter}"), Sleep(500)
344            }
345        }
346    }
347
348    if (hammerFound) {
349        ; --- Hammer Found Workflow ---
350        Loop 3 {
351            Send("{Tab}"), Sleep(BTG_TAB_DELAY) 
352        }
353        Send("{Enter}"), Sleep(BTG_TAB_DELAY + 100)
354        Loop 5 {
355            Send("{Tab}"), Sleep(BTG_TAB_DELAY)
356        }
357        SendEvent("{Raw}" Edit2.Value)
358        Sleep(BTG_TAB_DELAY), Send("!a")
359    } else {
360        ; --- Fallback to Manual Workflow ---
361        manualBreakGlass()
362    }
363}
364
365manualBreakGlass(*) {
366    global BTG_TAB_DELAY, Edit2
367    ; Presume popup open, cursor in first field
368    SendEvent("{Raw}Provision")
369    Sleep(BTG_TAB_DELAY)
370    Send("{Tab}")
371    Sleep(BTG_TAB_DELAY)
372    Send("{Tab}")
373    Sleep(BTG_TAB_DELAY)
374    SendEvent("{Raw}" Edit2.Value)
375    Sleep(BTG_TAB_DELAY)
376    Send("!a")
377}
378
379; ==============================================================================
380; CAPSLOCK SCROLL
381; ==============================================================================
382TrackballScroll(*) {
383    global SCROLL_THRESHOLD, SCROLL_LOCK_RATIO
384    oldMode := A_CoordModeMouse
385    CoordMode "Mouse", "Screen"
386    MouseGetPos(&startX, &startY)
387    bankX := 0, bankY := 0
388    Loop {
389        if !GetKeyState("CapsLock", "P")
390            break
391        MouseGetPos(&currentX, &currentY)
392        moveX := currentX - startX, moveY := currentY - startY
393        if (moveX != 0 || moveY != 0) {
394            DllCall("SetCursorPos", "int", startX, "int", startY)
395        }
396        bankX += moveX, bankY += moveY
397        absX := Abs(bankX), absY := Abs(bankY)
398        if (absX > (absY * SCROLL_LOCK_RATIO)) {
399            if (absX >= SCROLL_THRESHOLD) {
400                ticks := Integer(absX / SCROLL_THRESHOLD)
401                direction := (bankX > 0) ? "{WheelRight}" : "{WheelLeft}"
402                Loop ticks
403                    Send(direction)
404                bankX := Mod(bankX, SCROLL_THRESHOLD), bankY := 0
405            }
406        } else if (absY > absX) {
407            if (absY >= SCROLL_THRESHOLD) {
408                ticks := Integer(absY / SCROLL_THRESHOLD)
409                direction := (bankY > 0) ? "{WheelDown}" : "{WheelUp}"
410                Loop ticks
411                    Send(direction)
412                bankY := Mod(bankY, SCROLL_THRESHOLD), bankX := 0
413            }
414        }
415        Sleep(5)
416    }
417    CoordMode "Mouse", oldMode
418}
419
420; ==============================================================================
421; UTILS & HOTKEYS
422; ==============================================================================
423GetTargetControl() {
424    global PS
425    largestArea := 0, bestControl := ""
426    
427    ; STRATEGY: Find the largest visible RichEdit control first.
428    try {
429        ctrlList := WinGetControls(PS)
430        for ctrl in ctrlList {
431            if InStr(ctrl, "RICHEDIT") {
432                try {
433                    if ControlGetVisible(ctrl, PS) {
434                        ControlGetPos(,, &w, &h, ctrl, PS)
435                        if (w * h > largestArea) {
436                            largestArea := w * h, bestControl := ctrl
437                        }
438                    }
439                }
440            }
441        }
442    }
443    
444    if (bestControl != "")
445        return bestControl
446        
447    try {
448        focusedCtrl := ControlGetFocus(PS)
449        if InStr(focusedCtrl, "RICHEDIT")
450            return focusedCtrl
451    }
452    
453    return ""
454}
455
456ActivateAndSend(key, targetSpecificControl := true) {
457    global PS
458    if WinExist(PS) {
459        if !WinActive(PS) {
460            WinActivate(PS), WinWaitActive(PS,, 1), Sleep(50)
461        }
462        target := targetSpecificControl ? GetTargetControl() : ""
463        if (target)
464            ControlSend(key, target, PS)
465        else
466            SendEvent(key)
467    }
468}
469
470StopSleep(*) {
471    if (KEEPAWAKE) {
472        oldMode := A_CoordModeMouse
473        CoordMode("Mouse", "Screen")
474        MouseGetPos(&cX, &cY)
475        MouseMove(cX + 1, cY, 0), MouseMove(cX, cY, 0)
476        CoordMode("Mouse", oldMode)
477    }
478}
479
480loginSite() {
481    global Edit1, Edit2
482    SendEvent("{Raw}" Edit1.Value)
483    Sleep(200)
484    SendEvent("{Tab}")
485    Sleep(200)
486    SendEvent("{Raw}" Edit2.Value)
487    Sleep(200)
488    SendEvent("{Enter}")
489}
490
491pick(num) {
492    global PS
493    MouseGetPos &startX, &startY
494    CoordMode "Mouse", "Client" 
495    heightRow := 17
496    if WinExist(PS) {
497        try {
498            for ctrl in WinGetControls(PS) {
499                try {
500                    txt := ControlGetText(ctrl, PS)
501                } catch {
502                    continue
503                }
504                if (txt == "Pick List Choices") {
505                    ControlGetPos(&x, &y, &w, &h, ctrl, PS)
506                    targetY := y + Integer(heightRow/2) + (heightRow * num)
507                    targetX := x + 20
508                    if !WinActive(PS) {
509                        WinActivate(PS)
510                        WinWaitActive(PS,, 1)
511                    }
512                    Click(targetX, targetY)
513                    Sleep(50)
514                    Click(targetX, targetY)
515                    CoordMode "Mouse", "Screen"
516                    MouseMove(startX, startY)
517                    Sleep(50)
518                    ActivateAndSend("{Tab}", true)
519                    return
520                }
521            }
522        }
523    }
524    CoordMode "Mouse", "Screen"
525}
526
527; -- Common Rads Logic --
528toggleDictation(*) => ActivateAndSend("{F4}", false)
529saveDraft(*)       => ActivateAndSend("{F9}", false)
530nextField(*)       => ActivateAndSend("{Tab}", true)
531prevField(*)       => ActivateAndSend("+{Tab}", true)
532backspace(*)       => ActivateAndSend("{Backspace}", true)
533newLine(*)         => ActivateAndSend("{Enter}", true)
534
535enableRadsMode(*) {
536    global RADSMODE := true
537}
538exitRadsMode(*) {
539    global RADSMODE := false
540}
541
542#HotIf TRACKBALL_SCROLL
543    $CapsLock::TrackballScroll()
544#HotIf
545
546#HotIf GetKeyState("CapsLock", "P")
547    f:: enableRadsMode()
548    d:: exitRadsMode()
549#HotIf
550
551; -- Global Hotkeys --
552!z:: breakGlass()
553+!z:: manualBreakGlass()
554!p:: loginSite()
555
556#HotIf RADSMODE
557    r::LButton
558    e::MButton
559    w::RButton
560    $d:: toggleDictation()
561    $h:: saveDraft()
562    $f:: nextField()
563    $g:: prevField()
564    $s:: backspace()
565    $a:: newLine()
566    $q:: Send("^w")
567    
568    ; -- Pick List Hotkeys --
569    $!1:: pick(1)
570    $!2:: pick(2)
571    $!3:: pick(3)
572    $!4:: pick(4)
573    $!5:: pick(5)
574
575    $z:: (WinActive(PS) ? "" : Send("z"))
576    $x:: (WinActive(PS) ? "" : Send("x"))
577    $c:: (WinActive(PS) ? "" : Send("c"))
578    $v:: (WinActive(PS) ? "" : Send("v"))
579#HotIf

This is the full source code of the RadMode.ahk file. You can copy this into a new .ahk file or download the file directly using the button above.