Jaws scripts to virtualize list view items.

In work at the moment, I spend a huge amount of time in massive list views. These list views could have thousands of items and up to 256 columns. At first, reading them with Jaws was one of the most stressful things I’ve ever done. The customize list view scripts don’t work because of a bug in the user interface of this application. Every time focus changes to or away from the main application, the control that previously had focus will no longer have it when you return to the main window. It is a torturous situation to be in because when I’m in this application, I need information quickly and accurately. Also, most of the columns contain numbers that are very important so for the first week or two of starting in my new job you’d find me with my head down in major concentration mode trying to listen to Jaws fly through all the columns so I could pick out the tiny nugget of information that I needed from column 10 or worse, 210. I’d finish the day completely exhausted from this effort so I badly needed a solution.

Jaws has a script that will allow you to read the first ten columns of a list view but this is stupidly limited when you consider that this only allows a user to intentionally work with ten list view columns. What I needed was a script that would let me walk forward and back through each column from the beginning to the end of that item. If I found something that I needed, I could then listen to it and it would be clear. You would not believe how much easier this made my day. However, it became clear that I couldn’t always trust myself to remember all the information that I was being given by Jaws when working through these list view items so I decided to expand the script a little to add the current column into the virtual viewer. This is handy as I can then examine the text character by character if I need to and I can use the clipboard to store that text if I need to use it in notes or SQL statements that will pull more information from the database again, this minor change made things much easier for me.

However, there was one more thing that I needed. When sighted people were using these lists they could compare two items visually much faster than I could with my scripts. Yes, the column I was on was retained even when I was on different list items so say / virtualize current column worked very well. However, it wasn’t quite what I needed for every situation. The next solution has proven to be even more helpful than the first. Now, when I choose to, I can virtualize the entire list item so using the virtual viewer, I can arrow up and down the list of column headers and the text within each one to get the data in the best format for me to understand quickly. Thanks to some excel queries, I can virtualize two columns then use a dif function to work out the differences much faster than anyone who can see.

These scripts have actually changed the way I work with list views. I really hope they are helpful to you.

Disclaimer: I won’t support these. I’m not a script writer; I sometimes manage to scrape scripts together with the help of others or by taking script chunks from existing scripts written for Jaws. In this instance, I butchered a few other scripts to make these. Moving back and forward through list items works very well but for some reason, the count is slightly off so you may find that you need to move to the next list item twice to make it actually go forward.

I added these to my default scripts because I needed this functionality in a number of applications after a while. Add them where ever you like. At the top of your file in the globals section, you need to declare a variable for holding the current list column number. The line is below:


int CurrentListColumn

Remember to add a comma from the previous variable declaration or your script won’t compile.

Here are the scripts. Add them to the bottom of the default file if you choose to use that. Remember to also assign keyboard commands to each script. I’m sorry, but if you aren’t particularly sure how to do this, you may need to ask the Jaws script mailing list or read the script help topics. I cant promis to help you out as I’m busy enough as it is.


Script ReadNextListviewColumn ()
var
int nCol,
int nMaxCols,
string sHeader,
string sText,
handle hCurrent,
int nCurrent
If (CurrentListColumn<1) then CurrentListColumn = 1 EndIf If !(GetRunningFSProducts() & product_JAWS) then return EndIf let hCurrent=getCurrentWindow() if !IsTrueListView(hCurrent) then sayMessage(OT_ERROR,cmsgNotInAListview_L,cmsgNotInAListview_S) return endIf let nMaxCols=lvGetNumOfColumns(hCurrent) let nCurrent=lvGetFocusItem(hCurrent) let nCol=CurrentListColumn let sHeader=lvGetColumnHeader(hCurrent,nCol) let sText=lvGetItemText(hCurrent,nCurrent,nCol) say(sHeader,OT_NO_DISABLE) say(sText,OT_NO_DISABLE) say(IntToString(CurrentListColumn),OT_NO_DISABLE) if (nCol < nMaxCols) then CurrentListColumn = CurrentListColumn + 1 EndIf if (nCol > nMaxCols) then
SayFormattedMessage(OT_ERROR,formatString(cmsgListviewContainsXColumns_L,intToString(nCol),intToString(nMaxCols)),formatString(cmsgListviewContainsXColumns_S,intToString(nCol)))
return
endIf
EndScript

Script ReadPreviousListviewColumn ()
var
int nCol,
int nMaxCols,
string sHeader,
string sText,
handle hCurrent,
int nCurrent
if (CurrentListColumn > 1) then
CurrentListColumn = CurrentListColumn - 1
EndIf
If !(GetRunningFSProducts() & product_JAWS) then
return
EndIf
let hCurrent=getCurrentWindow()
if !IsTrueListView(hCurrent) then
sayMessage(OT_ERROR,cmsgNotInAListview_L,cmsgNotInAListview_S)
return
endIf
let nMaxCols=lvGetNumOfColumns(hCurrent)
let nCol=CurrentListColumn
let nCurrent=lvGetFocusItem(hCurrent)
if (nCol < 1) then let nCol=1 endIf if (nCol > nMaxCols) then
SayFormattedMessage(OT_ERROR,formatString(cmsgListviewContainsXColumns_L,intToString(nCol),intToString(nMaxCols)),formatString(cmsgListviewContainsXColumns_S,intToString(nCol)))
return
endIf
let sHeader=lvGetColumnHeader(hCurrent,nCol)
let sText=lvGetItemText(hCurrent,nCurrent,nCol)
say(sHeader,OT_NO_DISABLE)
say(sText,OT_NO_DISABLE)
say(IntToString(CurrentListColumn),OT_NO_DISABLE)
EndScript

Script VirtualizeCurrentListColumn ()
var
int nCol,
int nMaxCols,
string sHeader,
string sText,
handle hCurrent,
int nCurrent

If !(GetRunningFSProducts() & product_JAWS) then
return
EndIf
let hCurrent=getCurrentWindow()
if !IsTrueListView(hCurrent) then
sayMessage(OT_ERROR,cmsgNotInAListview_L,cmsgNotInAListview_S)
return
endIf
let nMaxCols=lvGetNumOfColumns(hCurrent)
let nCol=CurrentListColumn
let nCurrent=lvGetFocusItem(hCurrent)
if (nCol < 1) then let nCol=1 endIf if (nCol > nMaxCols) then
SayFormattedMessage(OT_ERROR,formatString(cmsgListviewContainsXColumns_L,intToString(nCol),intToString(nMaxCols)),formatString(cmsgListviewContainsXColumns_S,intToString(nCol)))
return
endIf
let sHeader=lvGetColumnHeader(hCurrent,nCol)
let sText=lvGetItemText(hCurrent,nCurrent,nCol)
say(sHeader,OT_NO_DISABLE)
say(sText,OT_NO_DISABLE)
say(IntToString(CurrentListColumn),OT_NO_DISABLE)
UserBufferClear ()
UserBufferAddText (sHeader)
UserBufferAddText (sText)
UserBufferActivate ()
SayLine ()
EndScript

Script VirtualizeAllListColumns ()
var
int nCol,
int nMaxCols,
string sHeader,
string sText,
handle hCurrent,
int nCurrent

If !(GetRunningFSProducts() & product_JAWS) then
return
EndIf
let hCurrent=getCurrentWindow()
if !IsTrueListView(hCurrent) then
sayMessage(OT_ERROR,cmsgNotInAListview_L,cmsgNotInAListview_S)
return
endIf
let nMaxCols=lvGetNumOfColumns(hCurrent)
let nCol=1
let nCurrent=lvGetFocusItem(hCurrent)
UserBufferClear ()
while nCol<=nMaxCols let sHeader=lvGetColumnHeader(hCurrent,nCol) let sText=lvGetItemText(hCurrent,nCurrent,nCol) UserBufferAddText (sHeader) UserBufferAddText (sText) LET nCol = nCol + 1 EndWhile UserBufferActivate () EndScript