def onCaretMoved(self, event): """Called whenever the caret moves. Arguments: - event: the Event """ details = debug.getAccessibleDetails(self.debugLevel, event.source) debug.printObjectEvent(self.debugLevel, event, details) # self.printAncestry(event.source) # If we've received a text caret moved event and the current locus # of focus is on the Find button on the Find dialog or the combo # box in the Find dialog and the last input event was a Return, # and if the current line contains the phrase we were looking for, # then speak the current text line, to give an indication of what # we've just found. # lastKey, mods = self.utilities.lastKeyAndModifiers() if self.isFocusOnFindDialog() and lastKey == "Return": debug.println(self.debugLevel, "gedit.onCaretMoved - find dialog.") allComboBoxes = self.utilities.descendantsWithRole( orca_state.locusOfFocus.getApplication(), pyatspi.ROLE_COMBO_BOX) phrase = self.utilities.displayedText(allComboBoxes[0]) [text, caretOffset, startOffset] = \ self.getTextLineAtCaret(event.source) if text.lower().find(phrase) != -1: # Translators: this indicates a find command succeeded in # finding something. # self.presentMessage(_("Phrase found.")) utterances = self.speechGenerator.generateSpeech( event.source, alreadyFocused=True) speech.speak(utterances) # If Ctrl+G was used to repeat a find command, speak the line that # the caret moved to. # if lastKey == 'G' and mods & settings.CTRL_MODIFIER_MASK: self.sayLine(event.source) # For everything else, pass the caret moved event onto the parent # class to be handled in the default way. default.Script.onCaretMoved(self, event)
def onCaretMoved(self, event): """Called whenever the caret moves. Arguments: - event: the Event """ debug.printObjectEvent(self.debugLevel, event, event.source.toString()) # self.printAncestry(event.source) # If we've received a text caret moved event and the current locus # of focus is on the Find button on the Find dialog or the combo # box in the Find dialog and the last input event was a Return, # and if the current line contains the phrase we were looking for, # then speak the current text line, to give an indication of what # we've just found. # if self.isFocusOnFindDialog() \ and orca_state.lastNonModifierKeyEvent.event_string == "Return": debug.println(self.debugLevel, "gedit.onCaretMoved - find dialog.") allComboBoxes = self.findByRole(orca_state.locusOfFocus.app, rolenames.ROLE_COMBO_BOX) phrase = self.getDisplayedText(allComboBoxes[0]) [text, caretOffset, startOffset] = \ self.getTextLineAtCaret(event.source) if text.lower().find(phrase) != -1: # Translators: this indicates a find command succeeded in # finding something. # speech.speak(_("Phrase found.")) utterances = self.speechGenerator.getSpeech(event.source, True) speech.speakUtterances(utterances) # For everything else, pass the caret moved event onto the parent # class to be handled in the default way. default.Script.onCaretMoved(self, event)
def onNameChanged(self, event): """Called whenever a property on an object changes. Arguments: - event: the Event """ brailleGen = self.brailleGenerator speechGen = self.speechGenerator debug.printObjectEvent(self.debugLevel, event, event.source.toString()) # self.printAncestry(event.source) # 1) check spelling dialog. # # Check to see if if we've had a property-change event for the # accessible name for the label containing the current misspelt # word in the check spelling dialog. # This (hopefully) means that the user has just corrected a # spelling mistake, in which case, speak/braille the current # misspelt word plus its context. # # Note that in order to make sure that this event is for the # check spelling dialog, a check is made of the localized name of the # frame. Translators for other locales will need to ensure that # their translation of this string matches what gedit uses in # that locale. rolesList = [ rolenames.ROLE_LABEL, rolenames.ROLE_PANEL, rolenames.ROLE_FILLER, rolenames.ROLE_FRAME ] if self.isDesiredFocusedItem(event.source, rolesList): frame = event.source.parent.parent.parent # Translators: this is the name of the "Check Spelling" window # in gedit and must be the same as what gedit uses. We hate # keying off stuff like this, but we're forced to do so in this # case. # if frame.name.startswith(_("Check Spelling")): debug.println(self.debugLevel, "gedit.onNameChanged - check spelling dialog.") self.readMisspeltWord(event, event.source.parent) # Fall-thru to process the event with the default handler. # 2) find dialog - phrase not found. # # If we've received an "object:property-change:accessible-name" for # the status bar and the current locus of focus is on the Find # button on the Find dialog or the combo box in the Find dialog # and the last input event was a Return and the name for the current # event source is "Phrase not found", then speak it. # # [[[TODO: richb - "Phrase not found" is spoken twice because we # apparently get two identical "object:property-change:accessible-name" # events.]]] # Translators: the "Phrase not found" is the result of a failed # find command. It must be the same as what gedit uses. We hate # keying off stuff like this, but we're forced to do so in this # case. # if event.source.role == rolenames.ROLE_STATUSBAR \ and self.isFocusOnFindDialog() \ and orca_state.lastNonModifierKeyEvent.event_string == "Return" \ and event.source.name == _("Phrase not found"): debug.println(self.debugLevel, "gedit.onNameChanged - phrase not found.") speech.speak(event.source.name) # Pass the event onto the parent class to be handled in the default way. default.Script.onNameChanged(self, event)
def locusOfFocusChanged(self, event, oldLocusOfFocus, newLocusOfFocus): """Called when the visual object with focus changes. Arguments: - event: if not None, the Event that caused the change - oldLocusOfFocus: Accessible that is the old locus of focus - newLocusOfFocus: Accessible that is the new locus of focus """ brailleGen = self.brailleGenerator speechGen = self.speechGenerator debug.printObjectEvent(self.debugLevel, event, event.source.toString()) # self.printAncestry(event.source) # 1) Text area (for caching handle for spell checking purposes). # # This works in conjunction with code in section 2). Check to see if # focus is currently in the gedit text area. If it is, then, if this # is the first time, save a pointer to the scroll pane which contains # the text being editted. # # Note that this drops through to then use the default event # processing in the parent class for this "focus:" event. rolesList = [ rolenames.ROLE_TEXT, rolenames.ROLE_SCROLL_PANE, rolenames.ROLE_FILLER, rolenames.ROLE_PAGE_TAB, rolenames.ROLE_PAGE_TAB_LIST, rolenames.ROLE_SPLIT_PANE ] if self.isDesiredFocusedItem(event.source, rolesList): debug.println(self.debugLevel, "gedit.locusOfFocusChanged - text area.") self.textArea = event.source.parent # Fall-thru to process the event with the default handler. # 2) check spelling dialog. # # Check to see if the Spell Check dialog has just appeared and got # focus. If it has, then speak/braille the current misspelt word # plus its context. # # Note that in order to make sure that this focus event is for the # check spelling dialog, a check is made of the localized name of the # option pane. Translators for other locales will need to ensure that # their translation of this string matches what gedit uses in # that locale. rolesList = [ rolenames.ROLE_TEXT, rolenames.ROLE_FILLER, rolenames.ROLE_PANEL, rolenames.ROLE_FILLER, rolenames.ROLE_FRAME ] if self.isDesiredFocusedItem(event.source, rolesList): frame = event.source.parent.parent.parent.parent # Translators: this is the name of the "Check Spelling" window # in gedit and must be the same as what gedit uses. We hate # keying off stuff like this, but we're forced to do so in this # case. # if frame.name.startswith(_("Check Spelling")): debug.println( self.debugLevel, "gedit.locusOfFocusChanged - check spelling dialog.") self.readMisspeltWord(event, event.source.parent.parent) # Fall-thru to process the event with the default handler. # For everything else, pass the focus event onto the parent class # to be handled in the default way. default.Script.locusOfFocusChanged(self, event, oldLocusOfFocus, newLocusOfFocus)
def onStateChanged(self, event): """Called whenever an object's state changes. Arguments: - event: the Event """ details = debug.getAccessibleDetails(self.debugLevel, event.source) debug.printObjectEvent(self.debugLevel, event, details) # self.printAncestry(event.source) rolesList = [pyatspi.ROLE_PUSH_BUTTON, \ pyatspi.ROLE_FILLER, \ pyatspi.ROLE_FILLER, \ pyatspi.ROLE_FILLER, \ pyatspi.ROLE_FRAME, \ pyatspi.ROLE_APPLICATION] visible = event.source.getState().contains(pyatspi.STATE_VISIBLE) # Check to see if we have just had an "object:state-changed:showing" # event for the Stop button. If the name is "Stop", and one of its # states is VISIBLE, that means we have started a search. As the # search progresses, regularly inform the user of this by speaking # "Searching" (assuming the search tool has focus). # # Translators: the "Stop" string must match what gnome-search-tool # is using. We hate keying off stuff like this, but we're forced # to do so in this case. # if self.utilities.hasMatchingHierarchy(event.source, rolesList) and \ event.source.name == _("Stop") and visible: debug.println(self.debugLevel, "gnome-search-tool.onNameChanged - " \ + "search started.") self.searching = True # If we don't already have a handle to the table containing the # list of files found, then get it now. # if not self.fileTable: frame = self.utilities.topLevelObject(event.source) allTables = self.utilities.descendantsWithRole( frame, pyatspi.ROLE_TABLE) self.fileTable = allTables[0] GObject.idle_add(self._speakSearching) # Check to see if we have just had an "object:state-changed:showing" # event for the Find button. If the name is "Find", and one of its # states is VISIBLE and we are currently searching, that means we # have just stopped a search. Inform the user that the search is # complete and tell them how many files were found. # # Translators: the "Find" string must match what gnome-search-tool # is using. We hate keying off stuff like this, but we're forced # to do so in this case. # if self.utilities.hasMatchingHierarchy(event.source, rolesList) \ and event.source.name == _("Find") and visible and self.searching: debug.println(self.debugLevel, "gnome-search-tool.onNameChanged - " \ + "search completed.") self.searching = False self.presentMessage(_("Search complete.")) sensitive = self.fileTable.getState().contains( \ pyatspi.STATE_SENSITIVE) if sensitive: try: fileCount = self.fileTable.queryTable().nRows except NotImplementedError: fileCount = 0 noFilesString = ngettext("%d file found", "%d files found", fileCount) % fileCount self.presentMessage(noFilesString) else: self.presentMessage(_("No files found.")) # Pass the event onto the parent class to be handled in the default way. # default.Script.onStateChanged(self, event)
def locusOfFocusChanged(self, event, oldLocusOfFocus, newLocusOfFocus): """Called when the visual object with focus changes. Arguments: - event: if not None, the Event that caused the change - oldLocusOfFocus: Accessible that is the old locus of focus - newLocusOfFocus: Accessible that is the new locus of focus """ brailleGen = self.brailleGenerator speechGen = self.speechGenerator debug.printObjectEvent(self.debugLevel, event, event.source.toString()) # Here we handle the case when focus is in the "Work online/offline" # button near the status bar that has an image without a description. # We speak and braille "Online/Offline button" here, until the # developer of the application adds a description to the images # associated with the button, which shows the online or offline # work mode. # rolesList = [rolenames.ROLE_PUSH_BUTTON, rolenames.ROLE_FILLER, rolenames.ROLE_FILLER, rolenames.ROLE_FRAME] # We are checking if the button with the focus is the button to # turn on/off the work mode in liferea. This push button is # hierarchically located in the main window of the application # (frame), inside a filler and inside another filler. # if self.isDesiredFocusedItem(event.source, rolesList): # If we are focusing this button we construct a utterance and # a braille region to speak/braille "online/offline button". # Here we declare utterances and add the localized string # "online/offline". # utterances = [] utterances.append(_("Work online / offline")) # Here we extend the utterances with the speech generator for # the object with focus (the push button). # utterances.extend(speechGen.getSpeech(event.source,False)) # Finally we speak/braille the utterances/regions. # speech.speakUtterances(utterances) regions = brailleGen.getBrailleRegions(event.source) regions[0].insert(0, braille.Region(utterances[0] + " ")) braille.displayRegions(regions) return # Here we handle the case when the focus is in the headlines table. # See comment #3 of bug #350233. # http://bugzilla.gnome.org/show_bug.cgi?id=350233 # if orca_state.locusOfFocus.role == rolenames.ROLE_TABLE_COLUMN_HEADER: table = event.source.parent cells = self.findByRole(table, rolenames.ROLE_TABLE_CELL) eventsynthesizer.clickObject(cells[1], 1) default.Script.locusOfFocusChanged(self, event, oldLocusOfFocus, newLocusOfFocus)
def locusOfFocusChanged(self, event, oldLocusOfFocus, newLocusOfFocus): """Called when the visual object with focus changes. Arguments: - event: if not None, the Event that caused the change - oldLocusOfFocus: Accessible that is the old locus of focus - newLocusOfFocus: Accessible that is the new locus of focus """ brailleGen = self.brailleGenerator speechGen = self.speechGenerator details = debug.getAccessibleDetails(self.debugLevel, event.source) debug.printObjectEvent(self.debugLevel, event, details) # [[[TODO - JD: what follows here should be replaced with methods # in this script's speech and braille generators. That will require # making each generator, moving this script into a new directory, # etc.]]] # # Here we handle the case when focus is in the "Work online/offline" # button near the status bar that has an image without a description. # We speak and braille "Online/Offline button" here, until the # developer of the application adds a description to the images # associated with the button, which shows the online or offline # work mode. # rolesList = [pyatspi.ROLE_PUSH_BUTTON, pyatspi.ROLE_FILLER, pyatspi.ROLE_FILLER, pyatspi.ROLE_FRAME] # We are checking if the button with the focus is the button to # turn on/off the work mode in liferea. This push button is # hierarchically located in the main window of the application # (frame), inside a filler and inside another filler. # if self.utilities.hasMatchingHierarchy(event.source, rolesList): # If we are focusing this button we construct a utterance and # a braille region to speak/braille "online/offline button". # Here we declare utterances and add the localized string # "online/offline". # utterances = [] utterances.append(_("Work online / offline")) # Here we extend the utterances with the speech generator for # the object with focus (the push button). # utterances.extend(speechGen.generateSpeech(event.source)) # Finally we speak/braille the utterances/regions. # speech.speak(utterances) regions = brailleGen.generateBraille(event.source) regions[0].insert(0, self.getNewBrailleRegion(utterances[0] + " ")) self.displayBrailleRegions(regions) return # Here we handle the case when the focus is in the headlines table. # See comment #3 of bug #350233. # http://bugzilla.gnome.org/show_bug.cgi?id=350233 # if orca_state.locusOfFocus.getRole() == \ pyatspi.ROLE_TABLE_COLUMN_HEADER: table = event.source.parent cells = self.utilities.descendantsWithRole( table, pyatspi.ROLE_TABLE_CELL) eventsynthesizer.clickObject(cells[1], 1) default.Script.locusOfFocusChanged(self, event, oldLocusOfFocus, newLocusOfFocus)
def onNameChanged(self, event): """Called whenever a property on an object changes. Arguments: - event: the Event """ debug.printObjectEvent(self.debugLevel, event, event.source.toString()) if event.source.role == rolenames.ROLE_FRAME: # If we've changed folders, announce the new folder name and # the number of items in it (see bug #350674). # # Unfortunately we get two of what appear to be idential events # when the accessible name of the frame changes. We only want to # speak/braille the new folder name if its different then last # time, so, if the Location bar is showing, look to see if the # same toggle button (with the same name) in the "path view" is # checked. If it isn't, then this is a new folder, so announce it. # # If the Location bar isn't showing, then just do a comparison of # the new folder name with the old folder name and if they are # different, announce it. Note that this doesn't do the right # thing when navigating directory hierarchies such as # /path/to/same/same/same. # allTokens = event.source.name.split(" - ") newFolderName = allTokens[0] allPanels = self.findByRole(event.source, rolenames.ROLE_PANEL) rolesList = [rolenames.ROLE_PANEL, \ rolenames.ROLE_FILLER, \ rolenames.ROLE_PANEL, \ rolenames.ROLE_TOOL_BAR, \ rolenames.ROLE_PANEL, \ rolenames.ROLE_FRAME, \ rolenames.ROLE_APPLICATION] locationBarFound = False for panel in allPanels: if self.isDesiredFocusedItem(panel, rolesList): locationBarFound = True break shouldAnnounce = False if locationBarFound: for i in range(0, panel.childCount): child = panel.child(i) if child.role == rolenames.ROLE_TOGGLE_BUTTON and \ child.state.count(atspi.Accessibility.STATE_CHECKED): if not self.isSameObject(child, self.pathChild): self.pathChild = child shouldAnnounce = True break else: if self.oldFolderName != newFolderName: shouldAnnounce = True if shouldAnnounce: string = newFolderName string += self.getItemCount(event.source) debug.println(debug.LEVEL_INFO, string) speech.speak(string) braille.displayMessage(string) self.oldFolderName = newFolderName return # Pass the event onto the parent class to be handled in the default way. # default.Script.onNameChanged(self, event)
def onNameChanged(self, event): """Called whenever a property on an object changes. Arguments: - event: the Event """ brailleGen = self.brailleGenerator speechGen = self.speechGenerator debug.printObjectEvent(self.debugLevel, event, event.source.toString()) # self.printAncestry(event.source) # 1) check spelling dialog. # # Check to see if if we've had a property-change event for the # accessible name for the label containing the current misspelt # word in the check spelling dialog. # This (hopefully) means that the user has just corrected a # spelling mistake, in which case, speak/braille the current # misspelt word plus its context. # # Note that in order to make sure that this event is for the # check spelling dialog, a check is made of the localized name of the # frame. Translators for other locales will need to ensure that # their translation of this string matches what gedit uses in # that locale. rolesList = [rolenames.ROLE_LABEL, rolenames.ROLE_PANEL, rolenames.ROLE_FILLER, rolenames.ROLE_FRAME] if self.isDesiredFocusedItem(event.source, rolesList): frame = event.source.parent.parent.parent # Translators: this is the name of the "Check Spelling" window # in gedit and must be the same as what gedit uses. We hate # keying off stuff like this, but we're forced to do so in this # case. # if frame.name.startswith(_("Check Spelling")): debug.println(self.debugLevel, "gedit.onNameChanged - check spelling dialog.") self.readMisspeltWord(event, event.source.parent) # Fall-thru to process the event with the default handler. # 2) find dialog - phrase not found. # # If we've received an "object:property-change:accessible-name" for # the status bar and the current locus of focus is on the Find # button on the Find dialog or the combo box in the Find dialog # and the last input event was a Return and the name for the current # event source is "Phrase not found", then speak it. # # [[[TODO: richb - "Phrase not found" is spoken twice because we # apparently get two identical "object:property-change:accessible-name" # events.]]] # Translators: the "Phrase not found" is the result of a failed # find command. It must be the same as what gedit uses. We hate # keying off stuff like this, but we're forced to do so in this # case. # if event.source.role == rolenames.ROLE_STATUSBAR \ and self.isFocusOnFindDialog() \ and orca_state.lastNonModifierKeyEvent.event_string == "Return" \ and event.source.name == _("Phrase not found"): debug.println(self.debugLevel, "gedit.onNameChanged - phrase not found.") speech.speak(event.source.name) # Pass the event onto the parent class to be handled in the default way. default.Script.onNameChanged(self, event)
def locusOfFocusChanged(self, event, oldLocusOfFocus, newLocusOfFocus): """Called when the visual object with focus changes. Arguments: - event: if not None, the Event that caused the change - oldLocusOfFocus: Accessible that is the old locus of focus - newLocusOfFocus: Accessible that is the new locus of focus """ brailleGen = self.brailleGenerator speechGen = self.speechGenerator debug.printObjectEvent(self.debugLevel, event, event.source.toString()) # self.printAncestry(event.source) # 1) Text area (for caching handle for spell checking purposes). # # This works in conjunction with code in section 2). Check to see if # focus is currently in the gedit text area. If it is, then, if this # is the first time, save a pointer to the scroll pane which contains # the text being editted. # # Note that this drops through to then use the default event # processing in the parent class for this "focus:" event. rolesList = [rolenames.ROLE_TEXT, rolenames.ROLE_SCROLL_PANE, rolenames.ROLE_FILLER, rolenames.ROLE_PAGE_TAB, rolenames.ROLE_PAGE_TAB_LIST, rolenames.ROLE_SPLIT_PANE] if self.isDesiredFocusedItem(event.source, rolesList): debug.println(self.debugLevel, "gedit.locusOfFocusChanged - text area.") self.textArea = event.source.parent # Fall-thru to process the event with the default handler. # 2) check spelling dialog. # # Check to see if the Spell Check dialog has just appeared and got # focus. If it has, then speak/braille the current misspelt word # plus its context. # # Note that in order to make sure that this focus event is for the # check spelling dialog, a check is made of the localized name of the # option pane. Translators for other locales will need to ensure that # their translation of this string matches what gedit uses in # that locale. rolesList = [rolenames.ROLE_TEXT, rolenames.ROLE_FILLER, rolenames.ROLE_PANEL, rolenames.ROLE_FILLER, rolenames.ROLE_FRAME] if self.isDesiredFocusedItem(event.source, rolesList): frame = event.source.parent.parent.parent.parent # Translators: this is the name of the "Check Spelling" window # in gedit and must be the same as what gedit uses. We hate # keying off stuff like this, but we're forced to do so in this # case. # if frame.name.startswith(_("Check Spelling")): debug.println(self.debugLevel, "gedit.locusOfFocusChanged - check spelling dialog.") self.readMisspeltWord(event, event.source.parent.parent) # Fall-thru to process the event with the default handler. # For everything else, pass the focus event onto the parent class # to be handled in the default way. default.Script.locusOfFocusChanged(self, event, oldLocusOfFocus, newLocusOfFocus)
def onNameChanged(self, event): """Called whenever a property on an object changes. Arguments: - event: the Event """ details = debug.getAccessibleDetails(self.debugLevel, event.source) debug.printObjectEvent(self.debugLevel, event, details) if event.source.getRole() == pyatspi.ROLE_FRAME: # If we've changed folders, announce the new folder name and # the number of items in it (see bug #350674). # # Unfortunately we get two of what appear to be idential events # when the accessible name of the frame changes. We only want to # speak/braille the new folder name if its different then last # time, so, if the Location bar is showing, look to see if the # same toggle button (with the same name) in the "path view" is # checked. If it isn't, then this is a new folder, so announce it. # # If the Location bar isn't showing, then just do a comparison of # the new folder name with the old folder name and if they are # different, announce it. Note that this doesn't do the right # thing when navigating directory hierarchies such as # /path/to/same/same/same. # allTokens = event.source.name.split(" - ") newFolderName = allTokens[0] allPanels = self.utilities.descendantsWithRole( event.source, pyatspi.ROLE_PANEL) rolesList = [pyatspi.ROLE_PANEL, pyatspi.ROLE_FILLER, pyatspi.ROLE_PANEL, pyatspi.ROLE_TOOL_BAR, pyatspi.ROLE_PANEL, pyatspi.ROLE_FRAME, pyatspi.ROLE_APPLICATION] locationBarFound = False for panel in allPanels: if self.utilities.hasMatchingHierarchy(panel, rolesList): locationBarFound = True desiredPanel = panel break shouldAnnounce = False if locationBarFound: for i in range(0, desiredPanel.childCount): child = desiredPanel.getChildAtIndex(i) if child.getRole() == pyatspi.ROLE_TOGGLE_BUTTON and \ child.getState().contains(pyatspi.STATE_CHECKED): if not self.utilities.isSameObject( child, self.pathChild): self.pathChild = child shouldAnnounce = True break else: if self.oldFolderName != newFolderName: shouldAnnounce = True if shouldAnnounce: string = newFolderName string += self.getItemCount(event.source) debug.println(debug.LEVEL_INFO, string) speech.speak(string) self.displayBrailleMessage(string) self.oldFolderName = newFolderName return # Pass the event onto the parent class to be handled in the default way. # default.Script.onNameChanged(self, event)
def locusOfFocusChanged(self, event, oldLocusOfFocus, newLocusOfFocus): """Called when the visual object with focus changes. Arguments: - event: if not None, the Event that caused the change - oldLocusOfFocus: Accessible that is the old locus of focus - newLocusOfFocus: Accessible that is the new locus of focus """ details = debug.getAccessibleDetails(self.debugLevel, event.source) debug.printObjectEvent(self.debugLevel, event, details) # 1) Text area (for caching handle for spell checking purposes). # # This works in conjunction with code in section 2). Check to see if # focus is currently in the gedit text area. If it is, then, if this # is the first time, save a pointer to the scroll pane which contains # the text being editted. # # Note that this drops through to then use the default event # processing in the parent class for this "focus:" event. rolesList = [pyatspi.ROLE_TEXT, pyatspi.ROLE_SCROLL_PANE, pyatspi.ROLE_FILLER, pyatspi.ROLE_PAGE_TAB, pyatspi.ROLE_PAGE_TAB_LIST, pyatspi.ROLE_SPLIT_PANE] if self.utilities.hasMatchingHierarchy(event.source, rolesList): debug.println(self.debugLevel, "gedit.locusOfFocusChanged - text area.") self.textArea = event.source.parent # Fall-thru to process the event with the default handler. # 2) check spelling dialog. # # Check to see if the Spell Check dialog has just appeared and got # focus. If it has, then speak/braille the current misspelt word # plus its context. # # Note that in order to make sure that this focus event is for the # check spelling dialog, a check is made of the localized name of the # option pane. Translators for other locales will need to ensure that # their translation of this string matches what gedit uses in # that locale. rolesList = [pyatspi.ROLE_TEXT, pyatspi.ROLE_FILLER, pyatspi.ROLE_PANEL, pyatspi.ROLE_FILLER, pyatspi.ROLE_FRAME] if self.utilities.hasMatchingHierarchy(event.source, rolesList): tmp = event.source.parent.parent frame = tmp.parent.parent # Translators: this is the name of the "Check Spelling" window # in gedit and must be the same as what gedit uses. We hate # keying off stuff like this, but we're forced to do so in this # case. # if frame.name.startswith(_("Check Spelling")): debug.println(self.debugLevel, "gedit.locusOfFocusChanged - check spelling dialog.") self.readMisspeltWord(event, event.source.parent.parent) # Fall-thru to process the event with the default handler. # For everything else, pass the focus event onto the parent class # to be handled in the default way. gtk.Script.locusOfFocusChanged(self, event, oldLocusOfFocus, newLocusOfFocus) # If we are doing a Print Preview and we are focused on the # page number text area, also speak the "of n" labels to the # right of this area. See bug #133275 for more details. # rolesList = [pyatspi.ROLE_TEXT, pyatspi.ROLE_FILLER, pyatspi.ROLE_PANEL, pyatspi.ROLE_TOOL_BAR, pyatspi.ROLE_FILLER, pyatspi.ROLE_FILLER, pyatspi.ROLE_PAGE_TAB, pyatspi.ROLE_PAGE_TAB_LIST] if self.utilities.hasMatchingHierarchy(event.source, rolesList): parent = event.source.parent label1 = self.utilities.displayedText(parent[1]) label2 = self.utilities.displayedText(parent[2]) items = [label1, label2] self.presentItemsInSpeech(items) self.presentItemsInBraille(items)
def locusOfFocusChanged(self, event, oldLocusOfFocus, newLocusOfFocus): """Called when the visual object with focus changes. Arguments: - event: if not None, the Event that caused the change - oldLocusOfFocus: Accessible that is the old locus of focus - newLocusOfFocus: Accessible that is the new locus of focus """ brailleGen = self.brailleGenerator speechGen = self.speechGenerator details = debug.getAccessibleDetails(self.debugLevel, event.source) debug.printObjectEvent(self.debugLevel, event, details) # [[[TODO - JD: what follows here should be replaced with methods # in this script's speech and braille generators. That will require # making each generator, moving this script into a new directory, # etc.]]] # # Here we handle the case when focus is in the "Work online/offline" # button near the status bar that has an image without a description. # We speak and braille "Online/Offline button" here, until the # developer of the application adds a description to the images # associated with the button, which shows the online or offline # work mode. # rolesList = [ pyatspi.ROLE_PUSH_BUTTON, pyatspi.ROLE_FILLER, pyatspi.ROLE_FILLER, pyatspi.ROLE_FRAME ] # We are checking if the button with the focus is the button to # turn on/off the work mode in liferea. This push button is # hierarchically located in the main window of the application # (frame), inside a filler and inside another filler. # if self.utilities.hasMatchingHierarchy(event.source, rolesList): # If we are focusing this button we construct a utterance and # a braille region to speak/braille "online/offline button". # Here we declare utterances and add the localized string # "online/offline". # utterances = [] utterances.append(_("Work online / offline")) # Here we extend the utterances with the speech generator for # the object with focus (the push button). # utterances.extend(speechGen.generateSpeech(event.source)) # Finally we speak/braille the utterances/regions. # speech.speak(utterances) regions = brailleGen.generateBraille(event.source) regions[0].insert(0, self.getNewBrailleRegion(utterances[0] + " ")) self.displayBrailleRegions(regions) return # Here we handle the case when the focus is in the headlines table. # See comment #3 of bug #350233. # http://bugzilla.gnome.org/show_bug.cgi?id=350233 # if orca_state.locusOfFocus.getRole() == \ pyatspi.ROLE_TABLE_COLUMN_HEADER: table = event.source.parent hasRole = lambda x: x and x.getRole() == pyatspi.ROLE_TABLE_CELL cells = pyatspi.findAllDescendants(event.source, hasRole) eventsynthesizer.clickObject(cells[1], 1) default.Script.locusOfFocusChanged(self, event, oldLocusOfFocus, newLocusOfFocus)
def onStateChanged(self, event): """Called whenever an object's state changes. Arguments: - event: the Event """ debug.printObjectEvent(self.debugLevel, event, event.source.toString()) # self.printAncestry(event.source) rolesList = [rolenames.ROLE_PUSH_BUTTON, \ rolenames.ROLE_FILLER, \ rolenames.ROLE_FILLER, \ rolenames.ROLE_FILLER, \ rolenames.ROLE_FRAME, \ rolenames.ROLE_APPLICATION] visible = event.source.state.count( \ atspi.Accessibility.STATE_VISIBLE) # Check to see if we have just had an "object:state-changed:showing" # event for the Stop button. If the name is "Stop", and one of its # states is VISIBLE, that means we have started a search. As the # search progresses, regularly inform the user of this by speaking # "Searching" (assuming the search tool has focus). # # Translators: the "Stop" string must match what gnome-search-tool # is using. We hate keying off stuff like this, but we're forced # to do so in this case. # if self.isDesiredFocusedItem(event.source, rolesList) and \ event.source.name == _("Stop") and visible: debug.println(self.debugLevel, "gnome-search-tool.onNameChanged - " \ + "search started.") self.searching = True # If we don't already have a handle to the table containing the # list of files found, then get it now. # if not self.fileTable: frame = self.getTopLevel(event.source) allTables = self.findByRole(frame, rolenames.ROLE_TABLE) self.fileTable = allTables[0] gobject.idle_add(self._speakSearching) # Check to see if we have just had an "object:state-changed:showing" # event for the Find button. If the name is "Find", and one of its # states is VISIBLE and we are currently searching, that means we # have just stopped a search. Inform the user that the search is # complete and tell them how many files were found. # # Translators: the "Find" string must match what gnome-search-tool # is using. We hate keying off stuff like this, but we're forced # to do so in this case. # if self.isDesiredFocusedItem(event.source, rolesList) and \ event.source.name == _("Find") and visible and self.searching: debug.println(self.debugLevel, "gnome-search-tool.onNameChanged - " \ + "search completed.") self.searching = False speech.speak(_("Search complete.")) sensitive = self.fileTable.state.count( \ atspi.Accessibility.STATE_SENSITIVE) if sensitive: fileCount = self.fileTable.table.nRows noFilesString = ngettext("%d file found", "%d files found", fileCount) % fileCount speech.speak(noFilesString) else: speech.speak(_("No files found.")) # Pass the event onto the parent class to be handled in the default way. # default.Script.onStateChanged(self, event)
def locusOfFocusChanged(self, event, oldLocusOfFocus, newLocusOfFocus): """Called when the visual object with focus changes. Arguments: - event: if not None, the Event that caused the change - oldLocusOfFocus: Accessible that is the old locus of focus - newLocusOfFocus: Accessible that is the new locus of focus """ brailleGen = self.brailleGenerator speechGen = self.speechGenerator debug.printObjectEvent(self.debugLevel, event, event.source.toString()) # Here we handle the case when focus is in the "Work online/offline" # button near the status bar that has an image without a description. # We speak and braille "Online/Offline button" here, until the # developer of the application adds a description to the images # associated with the button, which shows the online or offline # work mode. # rolesList = [ rolenames.ROLE_PUSH_BUTTON, rolenames.ROLE_FILLER, rolenames.ROLE_FILLER, rolenames.ROLE_FRAME ] # We are checking if the button with the focus is the button to # turn on/off the work mode in liferea. This push button is # hierarchically located in the main window of the application # (frame), inside a filler and inside another filler. # if self.isDesiredFocusedItem(event.source, rolesList): # If we are focusing this button we construct a utterance and # a braille region to speak/braille "online/offline button". # Here we declare utterances and add the localized string # "online/offline". # utterances = [] utterances.append(_("Work online / offline")) # Here we extend the utterances with the speech generator for # the object with focus (the push button). # utterances.extend(speechGen.getSpeech(event.source, False)) # Finally we speak/braille the utterances/regions. # speech.speakUtterances(utterances) regions = brailleGen.getBrailleRegions(event.source) regions[0].insert(0, braille.Region(utterances[0] + " ")) braille.displayRegions(regions) return # Here we handle the case when the focus is in the headlines table. # See comment #3 of bug #350233. # http://bugzilla.gnome.org/show_bug.cgi?id=350233 # if orca_state.locusOfFocus.role == rolenames.ROLE_TABLE_COLUMN_HEADER: table = event.source.parent cells = self.findByRole(table, rolenames.ROLE_TABLE_CELL) eventsynthesizer.clickObject(cells[1], 1) default.Script.locusOfFocusChanged(self, event, oldLocusOfFocus, newLocusOfFocus)