=== modified file 'source/NVDAObjects/IAccessible/sysListView32.py'
--- source/NVDAObjects/IAccessible/sysListView32.py	2010-10-11 06:42:53 +0000
+++ source/NVDAObjects/IAccessible/sysListView32.py	2011-01-05 08:35:10 +0000
@@ -16,6 +16,8 @@
 import winUser
 from . import IAccessible, List
 from ..window import Window 
+import ui
+import scriptHandler
 
 #Window messages
 LVM_FIRST=0x1000
@@ -25,6 +27,10 @@
 LVM_GETITEMCOUNT=LVM_FIRST+4
 LVM_GETITEM=LVM_FIRST+75
 LVN_GETDISPINFO=0xFFFFFF4F
+LVM_GETITEMTEXTW=LVM_FIRST+115
+LVM_GETHEADER=LVM_FIRST+31
+LVM_GETCOLUMNORDERARRAY=LVM_FIRST+59
+LVM_GETCOLUMNW=LVM_FIRST+95
 
 #item mask flags
 LVIF_TEXT=0x01 
@@ -35,6 +41,14 @@
 LVIF_GROUPID=0x100
 LVIF_COLUMNS=0x200
 
+#column mask flags
+LVCF_FMT=1
+LVCF_WIDTH=2
+LVCF_TEXT=4
+LVCF_SUBITEM=8
+LVCF_IMAGE=16
+LVCF_ORDER=32
+
 #group mask flags
 LVGF_HEADER=0x1
 LVGF_FOOTER=0x2
@@ -48,6 +62,11 @@
 LVIS_STATEIMAGEMASK=0xF000
 
 LVS_OWNERDRAWFIXED=0x0400
+CBEMAXSTRLEN=260
+
+# listview header window messages
+HDM_FIRST=0x1200
+HDM_GETITEMCOUNT=HDM_FIRST
 
 class LVGROUP(Structure):
 	_fields_=[
@@ -84,7 +103,7 @@
 		('iSubItem',c_int),
 		('state',c_uint),
 		('stateMask',c_uint),
-		('text',LPWSTR),
+		('pszText',c_void_p),
 		('cchTextMax',c_int),
 		('iImage',c_int),
 		('lParam',LPARAM),
@@ -96,6 +115,21 @@
 		('iGroup',c_int),
 	]
 
+class LVCOLUMN(Structure):
+	_fields_=[
+		('mask',c_uint),
+		('fmt',c_int),
+		('cx',c_int),
+		('pszText',c_void_p),
+		('cchTextMax',c_int),
+		('iSubItem',c_int),
+		('iImage',c_int),
+		('iOrder',c_int),
+		('cxMin',c_int),
+		('cxDefault',c_int),
+		('cxIdeal',c_int),
+	]
+
 class NMLVDispInfoStruct(Structure):
 	_fields_=[
 		('hdr',winUser.NMHdrStruct),
@@ -147,6 +181,22 @@
 					return eventHandler.queueEvent("gainFocus",groupingObj)
 		return super(List,self).event_gainFocus()
 
+	def _get_columnsCount(self):
+		headerHwnd= winUser.sendMessage(self.windowHandle,LVM_GETHEADER,0,0)
+		return winUser.sendMessage(headerHwnd,HDM_GETITEMCOUNT,0,0)
+
+	def _get_columnOrderArray(self):
+		coa=(c_int *self.columnsCount)()
+		(processID,threadID)=winUser.getWindowThreadProcessID(self.windowHandle)
+		processHandle=self.processHandle
+		internalCoa=winKernel.virtualAllocEx(processHandle,None,sizeof(coa),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
+		winKernel.writeProcessMemory(processHandle,internalCoa,byref(coa),sizeof(coa),None)
+		res = winUser.sendMessage(self.windowHandle,LVM_GETCOLUMNORDERARRAY, self.columnsCount, internalCoa)
+		if res:
+			winKernel.readProcessMemory(processHandle,internalCoa,byref(coa),sizeof(coa),None)
+		winKernel.virtualFreeEx(processHandle,internalCoa,0,winKernel.MEM_RELEASE)
+		return coa
+
 class GroupingItem(Window):
 
 	def __init__(self,windowHandle=None,parentNVDAObject=None,groupInfo=None):
@@ -191,10 +241,59 @@
 
 	def initOverlayClass(self):
 		for gesture in ("kb:leftArrow", "kb:rightArrow"):
-			self.bindeGesture(gesture, "collapseOrExpand")
+			self.bindGesture(gesture, "collapseOrExpand")
 
 class ListItem(IAccessible):
 
+	def getSubitemText(self,index):
+		buffer=None
+		(processID,threadID)=winUser.getWindowThreadProcessID(self.windowHandle)
+		processHandle=self.processHandle
+		internalItem=winKernel.virtualAllocEx(processHandle,None,sizeof(LVItemStruct),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
+		internalText=winKernel.virtualAllocEx(processHandle,None,CBEMAXSTRLEN*2,winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
+		item=LVItemStruct(iItem=self.IAccessibleChildID-1,mask=LVIF_TEXT|LVIF_COLUMNS,iSubItem=index,pszText=internalText,cchTextMax=CBEMAXSTRLEN)
+		winKernel.writeProcessMemory(processHandle,internalItem,byref(item),sizeof(LVItemStruct),None)
+		len = winUser.sendMessage(self.windowHandle,LVM_GETITEMTEXTW, (self.IAccessibleChildID-1), internalItem)
+		if len:
+			winKernel.readProcessMemory(processHandle,internalItem,byref(item),sizeof(LVItemStruct),None)
+			buffer=create_unicode_buffer(len)
+			winKernel.readProcessMemory(processHandle,item.pszText,buffer,sizeof(buffer),None)
+		winKernel.virtualFreeEx(processHandle,internalText,0,winKernel.MEM_RELEASE)
+		winKernel.virtualFreeEx(processHandle,internalItem,0,winKernel.MEM_RELEASE)
+		return buffer.value if buffer else None
+
+	def getColumnText(self,index):
+		buffer=None
+		(processID,threadID)=winUser.getWindowThreadProcessID(self.windowHandle)
+		processHandle=self.processHandle
+		internalColumn=winKernel.virtualAllocEx(processHandle,None,sizeof(LVCOLUMN),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
+		internalText=winKernel.virtualAllocEx(processHandle,None,CBEMAXSTRLEN*2,winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
+		column=LVCOLUMN(mask=LVCF_TEXT,iSubItem=index,pszText=internalText,cchTextMax=CBEMAXSTRLEN)
+		winKernel.writeProcessMemory(processHandle,internalColumn,byref(column),sizeof(LVCOLUMN),None)
+		res = winUser.sendMessage(self.windowHandle,LVM_GETCOLUMNW, index, internalColumn)
+		if res:
+			winKernel.readProcessMemory(processHandle,internalColumn,byref(column),sizeof(LVCOLUMN),None)
+			buffer=create_unicode_buffer(column.cchTextMax)
+			winKernel.readProcessMemory(processHandle,column.pszText,buffer,sizeof(buffer),None)
+		winKernel.virtualFreeEx(processHandle,internalText,0,winKernel.MEM_RELEASE)
+		winKernel.virtualFreeEx(processHandle,internalColumn,0,winKernel.MEM_RELEASE)
+		return buffer.value if buffer else None
+
+	def _get_lvValue(self):
+		coa=self.parent.columnOrderArray
+		valueList=[]
+		for c in coa:
+			column=self.getColumnText(c)
+			subItem=self.getSubitemText(c)
+			colList=[]
+			if column:
+				colList.append(column)
+			if subItem:
+				colList.append(subItem)
+			if len(colList):
+				valueList.append(u": ".join(colList))
+		return u"; ".join(valueList)
+
 	def _get_lvAppImageID(self):
 		item=LVItemStruct(iItem=self.IAccessibleChildID-1,mask=LVIF_IMAGE)
 		(processID,threadID)=winUser.getWindowThreadProcessID(self.windowHandle)
@@ -219,7 +318,8 @@
 		return None
 
 	def _get_value(self):
-		value=super(ListItem,self)._get_description()
+		#value=super(ListItem,self)._get_description()
+		value=self.lvValue
 		if (not value or value.isspace()) and self.windowStyle & LVS_OWNERDRAWFIXED:
 			value=self.displayText
 		if not value:
@@ -237,3 +337,33 @@
 	def event_stateChange(self):
 		if self.hasFocus:
 			super(ListItem,self).event_stateChange()
+
+	def _get_name(self):
+		if self.value:
+			return None
+		return super(ListItem,self).name
+
+	def initOverlayClass(self):
+		for n in range(min(self.parent.columnsCount,9)):
+			self.bindGesture("kb:NVDA+control+%d" % (n+1), "readSubItem")
+
+	def script_readSubItem(self,gesture):
+		num=int(gesture.keyName[-1])
+		if num >10 or num >self.parent.columnsCount+1:
+			return
+		coa=self.parent.columnOrderArray
+		column=self.getColumnText(coa[num-1])
+		subItem=self.getSubitemText(coa[num-1])
+		colList=[]
+		if column:
+			colList.append(column)
+		if subItem:
+			colList.append(subItem)
+		if len(colList):
+			text=u": ".join(colList)
+			if scriptHandler.getLastScriptRepeatCount()==1:
+				if api.copyToClip(text):
+					speech.speakMessage(_("%s copied to clipboard")%text)
+			else:
+				ui.message(text)
+	script_readSubItem.__doc__=_("Presents a listview column corresponding to the keypress from left to right starting at 1")

