def script_reportCurrentSelection(self, gesture): # specific implementation, see: # https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/IAccessibleTable2 # try to avoid COM call generates a crash if getLastScriptRepeatCount(): sleep(0.5) table = self.parent.IAccessibleTable2Object selRowArray, selRowNum = table.selectedRows items = [] colNum = table.nColumns for i in rangeFunc(0, selRowNum): row = selRowArray[i] itemCells = [] for col in rangeFunc(0, colNum): cellText = table.cellAt( row, col).QueryInterface(IAccessible2).accName[0] itemCells.append(cellText) item = ' '.join(itemCells) items.append(item) spokenItems = ', '.join(items) ui.message("%d %s: %s" % ( len(items), # translators: message presented when get selected item count and names _("selected items"), spokenItems))
def getFixedNum(self, num): child = self.simpleFirstChild for n in rangeFunc(1, num): child = child.simpleNext if not child: return self.childCount + 1 return child.columnNumber
def __init__(self, port): global mbCellsMap, mbBaud, mbDll super(BrailleDisplayDriver, self).__init__() mbCellsMap = [convertMbCells(x) for x in rangeFunc(256)] if mbBaud: log.info("Try MDV on port %s at saved baud %d" % (port, mbBaud)) else: log.info("Try MDV on port %s at baud 38400 and 19200" % port) mbPort = bytes(port.encode("mbcs")) mbFound = False bauds = (mbBaud, ) if mbBaud else (38400, 19200) if not mbBaud: args = ( _("Please wait"), Spri.NOW, ) if py3 else (_("Please wait"), ) speakMessage(*args) for baud in bauds: log.info("Trying baud %d" % baud) loadDll(baud) if mbDll.BrlInit(mbPort, baud): mbBaud = baud mbFound = True log.info("Found MDV on port %s at baud %d" % (port, baud)) break if not mbFound: resetBaud() loadDll(mbBaud) raise RuntimeError("No MB408 display found") else: self._keyCheckTimer = wx.PyTimer(self._handleKeyPresses) self._keyCheckTimer.Start(KEY_CHECK_INTERVAL) saveBaud()
def getHeaderParent(self): # when thread view is disabled if self.role != ct.ROLE_TREEVIEWITEM: return self.simpleParent.simpleFirstChild # else, we manage the thread grouping case else: # tree-level of current obj level = self._get_IA2Attributes()["level"] # we go up level by level parent = self for n in rangeFunc(0, int(level)): parent = parent.simpleParent return parent.simpleFirstChild
def findInList(self, text, reverse, caseSensitive, stopCheck=lambda: False): """performs search in item list, via object handles.""" # specific implementation fg = api.getForegroundObject() listHandles = findAllDescendantWindows(fg.windowHandle, controlID=self.windowControlID) thisList = None # there may be different lists with same controlID (see eMule) for handle in listHandles: tempList = getNVDAObjectFromEvent(handle, winUser.OBJID_CLIENT, 0) if tempList == self.simpleParent: thisList = tempList break # if handle approach fails, use generic method if not thisList: res = super(ColumnsReview32, self).findInList(text, reverse, caseSensitive) return res listLen = self.positionInfo["similarItemsInGroup"] # 1-based index curIndex = self.positionInfo["indexInGroup"] if reverse: indexes = rangeFunc(curIndex - 1, 0, -1) else: indexes = rangeFunc(curIndex + 1, listLen + 1) for index in indexes: item = getNVDAObjectFromEvent(thisList.windowHandle, winUser.OBJID_CLIENT, index) if ((not caseSensitive and text.lower() in item.name.lower()) or (caseSensitive and text in item.name)): return item if stopCheck(): break
def initOverlayClass(self): """maps the correct gestures""" # obviously, empty lists are not handled if self.childCount < 0: return global useNumpadKeys, switchChar, baseKeys # a string useful for defining gestures nk = "numpad" if useNumpadKeys else "" # bind gestures from 1 to 9 for n in rangeFunc(1, 10): self.bindGesture("kb:%s+%s%d" % (baseKeys, nk, n), "readColumn") if useNumpadKeys: # map numpadMinus for 10th column self.bindGesture("kb:%s+numpadMinus" % baseKeys, "readColumn") # ...numpadPlus to change interval self.bindGesture("kb:%s+numpadPlus" % baseKeys, "changeInterval") # delete for list item info self.bindGesture("kb:%s+numpadDelete" % baseKeys, "itemInfo") # ...and enter to headers manager self.bindGesture("kb:%s+numpadEnter" % baseKeys, "manageHeaders") else: # do same things for no numpad case self.bindGesture("kb:%s+0" % baseKeys, "readColumn") self.bindGesture("kb:%s+%s" % (baseKeys, switchChar), "changeInterval") self.bindGesture("kb:%s+delete" % baseKeys, "itemInfo") self.bindGesture("kb:%s+enter" % baseKeys, "manageHeaders") # find gestures self.bindGesture("kb:NVDA+control+f", "find") self.bindGesture("kb:NVDA+f3", "findNext") self.bindGesture("kb:NVDA+shift+f3", "findPrevious") # for current selection for gesture in getScriptGestures( commands.script_reportCurrentSelection): self.bindGesture(gesture, "reportCurrentSelection") # for say all # (available only after Py3 speech refactoring) if py3: for gesture in getScriptGestures(commands.script_sayAll): self.bindGesture(gesture, "sayAll")
def findInList(self, text, reverse, caseSensitive, stopCheck=lambda: False): """performs search in item list, via shell32 object.""" curFolder = self.curWindow.Document.Folder # names of children objects of current list item, # as "size", "modify date", "duration"... # note that icon has no name detailNames = [c.name for c in self.children if c.name] # corresponding indexes to query info for each file detailIndexes = [] # 500 limit seems reasonable (they are 300+ on my system!) for index in rangeFunc(0, 500): # localized detail name, as "size" detailName = curFolder.GetDetailsOf("", index) # we get index corresponding to name, so update lists if detailName in detailNames: detailNames.remove(detailName) detailIndexes.append(index) # to speed-up process, we want only visible details if not detailNames: break # useful to compute size bytePerSector = ctypes.c_ulonglong(0) # path without leading file:// curPath = self.curWindow.LocationURL.rsplit("/", 1)[0][8:] # we get from current path, to ensure precision # also on external drives or different partitions getBytePerSector( ctypes.c_wchar_p(curPath), None, ctypes.pointer(bytePerSector), None, None, ) listLen = self.positionInfo["similarItemsInGroup"] # 1-based index curIndex = self.positionInfo["indexInGroup"] # pointer to item list items = curFolder.Items() res = None if reverse: # indexes = rangeFunc(curIndex-2,-1,-1) # unfortunately, list pointer seems to change # for each query in reverse order # so, this range indexes = rangeFunc(0, curIndex - 1) else: indexes = rangeFunc(curIndex, listLen) for index in indexes: # pointer to item item = items.Item(index) # detail value list tempItemInfo = [] for index in detailIndexes: # getDetailsOf(item, 1) returns file size in KB, MB, etc, # item.size returns as file size in bytes # but explorer shows file size on disk, in kilobytes... if (index == 1) and not item.IsFolder: # formula below is an optimization of ((item.size-1)/bytePerSector.value+1)*bytePerSector.value diskSizeB = ( (item.size - 1) & ~(bytePerSector.value - 1) ) + bytePerSector.value if item.size > 512 else 1024 diskSizeKB = int(round(diskSizeB / 1024.0)) # to insert thousands separator formattedSize = locale.format_string( '%d', diskSizeKB, True) formattedSize = formattedSize if py3 else formattedSize.decode( 'mbcs') explorerSize = ' '.join([formattedSize, "KB"]) tempItemInfo.append(explorerSize) else: tempItemInfo.append(curFolder.GetDetailsOf(item, index)) # our reconstruction of item as shown in explorer itemInfo = '; '.join(tempItemInfo) # finally, the search if if ((not caseSensitive and text.lower() in itemInfo.lower()) or (caseSensitive and text in itemInfo)): res = item if not reverse: # we can stop; if reverse # we must scroll everything break return res