import time import oleacc import queueHandler import eventHandler import controlTypes import characterProcessing import config import api import ui import speech import winUser from . import IAccessible from NVDAObjects.behaviors import CandidateItem as CandidateItemBehavior def reportSelectedCandidate(candidateObject,allowDuplicate=False,newList=False): if not eventHandler.isPendingEvents("gainFocus") and (allowDuplicate or candidateObject!=api.getFocusObject()): if not isinstance(api.getFocusObject(),BaseCandidateItem): oldCandidateItemsText=None candidateObject.container=api.getFocusObject() eventHandler.queueEvent("foreground",candidateObject) else: oldCandidateItemsText=api.getFocusObject().visibleCandidateItemsText candidateObject.container=api.getFocusObject().container if config.conf["inputComposition"]["autoReportAllCandidates"] and (newList or candidateObject.visibleCandidateItemsText!=oldCandidateItemsText): queueHandler.queueFunction(queueHandler.eventQueue,ui.message,candidateObject.visibleCandidateItemsText) eventHandler.queueEvent("gainFocus",candidateObject) class BaseCandidateItem(CandidateItemBehavior,IAccessible): role=controlTypes.ROLE_LISTITEM keyboardShortcut="" def _get_candidateNumber(self): number=super(BaseCandidateItem,self).keyboardShortcut try: number=int(number) except (ValueError,TypeError): pass return number def _get_parent(self): parent=super(BaseCandidateItem,self).parent # Translators: A label for a 'candidate' list which contains symbols the user can choose from when typing east-asian characters into a document. parent.name=_("Candidate") parent.description=None return parent def _get_name(self): try: number=int(self.candidateNumber) except (TypeError,ValueError): return super(BaseCandidateItem,self).name candidate=super(BaseCandidateItem,self).name return self.getFormattedCandidateName(number,candidate) def _get_description(self): candidate=super(BaseCandidateItem,self).name return self.getFormattedCandidateDescription(candidate) def _get_basicText(self): return super(BaseCandidateItem,self).name class MSCandUI_candidateListItem(BaseCandidateItem): def _get_states(self): states=super(MSCandUI_candidateListItem,self).states states.add(controlTypes.STATE_SELECTABLE) return states def event_stateChange(self): if controlTypes.STATE_SELECTED in self.states: reportSelectedCandidate(self) class MSCandUI21_candidateMenuItem(BaseCandidateItem): def _get_previous(self): item=super(MSCandUI21_candidateMenuItem,self).previous if not item or controlTypes.STATE_INVISIBLE in item.states: return return MSCandUI21_candidateMenuItem(IAccessibleObject=item.IAccessibleObject,IAccessibleChildID=item.IAccessibleChildID) def _get_next(self): item=super(MSCandUI21_candidateMenuItem,self).next if not item or controlTypes.STATE_INVISIBLE in item.states: return return MSCandUI21_candidateMenuItem(IAccessibleObject=item.IAccessibleObject,IAccessibleChildID=item.IAccessibleChildID) def doAction(self,index=None): if not index: l=self.location if l: x=l[0] y=l[1] oldX,oldY=winUser.getCursorPos() winUser.setCursorPos(x,y) winUser.mouse_event(winUser.MOUSEEVENTF_LEFTDOWN,0,0,None,None) time.sleep(0.2) winUser.mouse_event(winUser.MOUSEEVENTF_LEFTUP,0,0,None,None) winUser.setCursorPos(oldX,oldY) return raise NotImplementedError def script_nextItem(self,gesture): item=self.next if not item or not isinstance(item.candidateNumber,int): return reportSelectedCandidate(item) def script_previousItem(self,gesture): item=self.previous if not item or not isinstance(item.candidateNumber,int): return reportSelectedCandidate(item) def script_changePage(self,gesture): try: del self.__dict__['visibleCandidateItemsText'] except KeyError: pass gesture.send() api.processPendingEvents() oldItem=item=self while item and isinstance(item.candidateNumber,int): oldItem=item item=item.previous if oldItem and isinstance(oldItem.candidateNumber,int) and oldItem.name: reportSelectedCandidate(oldItem,allowDuplicate=True,newList=True) def script_activate(self,gesture): self.doAction() api.processPendingEvents() oldItem=item=self while item and isinstance(item.candidateNumber,int): oldItem=item item=item.previous if oldItem and isinstance(oldItem.candidateNumber,int) and oldItem.name: reportSelectedCandidate(oldItem,allowDuplicate=True,newList=True) __gestures={ "kb:downArrow":"nextItem", "kb:upArrow":"previousItem", "kb:pageDown":"changePage", "kb:pageUp":"changePage", "kb:leftArrow":"changePage", "kb:rightArrow":"changePage", "kb:space":"activate", "kb:enter":"activate", } class MSCandUI21(IAccessible): def _get_isPresentableFocusAncestor(self): return False def event_show(self): candidateList=self.simpleFirstChild if not candidateList: return role=candidateList.role if role==controlTypes.ROLE_LIST: item=candidateList.firstChild while item and controlTypes.STATE_SELECTED not in item.states: item=item.next if item: reportSelectedCandidate(item) return elif config.conf["reviewCursor"]["followFocus"]: api.setNavigatorObject(candidateList) elif role==controlTypes.ROLE_MENUBUTTON: item=candidateList.firstChild.next.next item=MSCandUI21_candidateMenuItem(IAccessibleObject=item.IAccessibleObject,IAccessibleChildID=item.IAccessibleChildID) if item and isinstance(item.candidateNumber,int) and item.name: reportSelectedCandidate(item) ###IME 2002 class MSCandUIWindow_candidateListItem(MSCandUI_candidateListItem): def _get_isValidCandidate(self): if self.IAccessibleRole!=oleacc.ROLE_SYSTEM_LISTITEM: return False name=super(BaseCandidateItem,self).name if not name: return False return True def _get_candidateNumber(self): index=self.IAccessibleChildID-2 if index>0: return index def _get_next(self): childID=self.IAccessibleChildID+1 item=self.__class__(IAccessibleObject=self.IAccessibleObject,IAccessibleChildID=childID) if item.isValidCandidate: return item def _get_previous(self): childID=self.IAccessibleChildID-1 if childID>=3: item=self.__class__(IAccessibleObject=self.IAccessibleObject,IAccessibleChildID=childID) if item.isValidCandidate: return item class MSCandUIWindow(IAccessible): # Translators: A label for a 'candidate' list which contains symbols the user can choose from when typing east-asian characters into a document. name=_("Candidate") role=controlTypes.ROLE_LIST def _get_states(self): states=super(MSCandUIWindow,self).states states.discard(controlTypes.STATE_UNAVAILABLE) return states def event_show(self): item=MSCandUIWindow_candidateListItem(IAccessibleObject=self.IAccessibleObject,IAccessibleChildID=3) reportSelectedCandidate(item) def findExtraOverlayClasses(obj,clsList): windowClassName=obj.windowClassName role=obj.IAccessibleRole if windowClassName=="MSCandUIWindow_Candidate": if role==oleacc.ROLE_SYSTEM_CLIENT: clsList.append(MSCandUIWindow) elif role==oleacc.ROLE_SYSTEM_LISTITEM: clsList.append(MSCandUIWindow_candidateListItem) elif windowClassName in ("mscandui21.candidate","mscandui40.candidate"): if role==oleacc.ROLE_SYSTEM_LISTITEM: clsList.append(MSCandUI_candidateListItem) elif role==oleacc.ROLE_SYSTEM_CLIENT: clsList.append(MSCandUI21)