def processFakeFocusWinEvent(eventID, window, objectID, childID): """Process a fake focus win event. @postcondition: The focus will be found and an event generated for it if appropriate. """ # A suitable event for faking the focus has been received with no focus event, so we probably need to find the focus and fake it. # However, it is possible that the focus event has simply been delayed, so wait a bit and only do it if the focus hasn't changed yet. core.callLater(50, _fakeFocus, api.getFocusObject())
def onOk(self, evt): self.Destroy() if self.addCheckBox.Value or self.searchRadioBox.Selection < 2: # Add or search text = self.searchTextEdit.Value actionToPerform = self.searchRadioBox.Selection if actionToPerform < 2: # Search caseSensitive = self.caseSensitiveCheckBox.Value if actionToPerform == 0: core.callLater(1000, doFindText, text, caseSensitive=caseSensitive) else: core.callLater(1000, doFindTextUp, text, caseSensitive=caseSensitive) if self.addCheckBox.Value or self.removeCheckBox.Value: savedStrings = self.savedTexts if self.removeCheckBox.Value: del savedStrings[self.savedTextsComboBox.Selection] if self.addCheckBox.Value and not "\n" in text and not text in savedStrings: savedStrings.insert(0, text) if len(savedStrings) == 0: os.remove(self.searchFile) return try: with codecs.open(self.searchFile, "w", "utf-8") as f: f.write("\n".join(savedStrings)) except Exception as e: log.debugWarning("Error saving strings of text for specific search", exc_info=True) raise e
def updateStarter(): def update(): if terminating: return if not preparing: updateLocations() callLater(UPDATE_PERIOD, update) callLater(UPDATE_PERIOD, update)
def event_show(self, obj, nextHandler): if obj.role == controlTypes.ROLE_PANE: self.isAutocomplete=True core.callLater(100, self.waitforAndReportDestruction,obj) #get the edit field if the weak reference still has it. edit = self._edit() if not edit: return eventHandler.executeEvent("suggestionsOpened", edit) nextHandler()
def script_close(self,gesture): # #5343: New consoles in Windows 10 close with alt+f4 and take any processes attached with it (including NVDA). # Therefore detach from the console temporarily while sending the gesture. winConsoleHandler.disconnectConsole() gesture.send() def reconnect(): if api.getFocusObject()==self: winConsoleHandler.connectConsole(self) self.startMonitoring() core.callLater(200,reconnect)
def onOk(self, evt): text = self.findTextField.GetValue() # update the list of searched entries so that it can be exibited in the next find dialog call self.updateSearchEntries(self.activeCursorManager._searchEntries, text) caseSensitive = self.caseSensitiveCheckBox.GetValue() # We must use core.callLater rather than wx.CallLater to ensure that the callback runs within NVDA's core pump. # If it didn't, and it directly or indirectly called wx.Yield, it could start executing NVDA's core pump from within the yield, causing recursion. core.callLater(100, self.activeCursorManager.doFindText, text, caseSensitive=caseSensitive) self.Destroy()
def waitforAndReportDestruction(self, obj): if obj.parent: #None when no parent. core.callLater(100, self.waitforAndReportDestruction,obj) return #The object is dead. self.isAutocomplete=False #get the edit field if the weak reference still has it. edit = self._edit() if not edit: return eventHandler.executeEvent("suggestionsClosed", edit)
def processDesktopSwitchWinEvent(window,objectID,childID): hDesk=windll.user32.OpenInputDesktop(0, False, 0) if hDesk!=0: windll.user32.CloseDesktop(hDesk) core.callLater(200, _correctFocus) else: # Switching to a secure desktop. # We don't receive key up events for any keys down before switching to a secure desktop, # so clear our recorded modifiers. keyboardHandler.currentModifiers.clear() obj=SecureDesktopNVDAObject(windowHandle=window) eventHandler.executeEvent("gainFocus",obj)
def _unensureDucked(delay=True): global _duckingRefCount if delay: import core log.debug("Queuing _unensureDucked") core.callLater(1000,_unensureDucked,False) return with _duckingRefCountLock: _duckingRefCount-=1 log.debug("Decreased ref count, _duckingRefCount=%d"%_duckingRefCount) if _duckingRefCount==0 and _audioDuckingMode!=AUDIODUCKINGMODE_NONE: _setDuckingState(False)
def doRestore(restoreDirectory): try: shutil.rmtree(PLACE_MARKERS_PATH, ignore_errors=True) shutil.copytree(restoreDirectory, PLACE_MARKERS_PATH) core.callLater(100, ui.message, # Translators: Message presented when place markers have been restored. _("Place markers restored")) except Exception as e: wx.CallAfter(gui.messageBox, # Translators: label of error dialog shown when cannot copy placeMarkers folder. _("Folder not copied"), # Translators: title of error dialog shown when cannot copy placeMarkers folder. _("Copy Error"), wx.OK|wx.ICON_ERROR) raise e
def changeWatcher(self): self.schedule() edit = self.appModule.edit if None is edit: #The editor gained focus. We're gonna die anyway on the next round. return textInfo = edit.makeTextInfo(textInfos.POSITION_SELECTION) if textInfo.bookmark == IncrementalFind.cacheBookmark: #Nothing has changed. Just go away. return IncrementalFind.cacheBookmark = textInfo.bookmark textInfo.expand(textInfos.UNIT_LINE) #Reporting indentation here is not really necessary. idt = speech.splitTextIndentation(textInfo.text)[0] textInfo.move(textInfos.UNIT_CHARACTER, len(idt), "start") def present(): queueHandler.queueFunction(queueHandler.eventQueue, speech.speakTextInfo, (textInfo)) core.callLater(100, present) #Slightly delay presentation in case the status changes.
def _unensureDucked(delay=True): global _duckingRefCount if delay: import core if _isDebug(): log.debug("Queuing _unensureDucked") try: core.callLater(1000, _unensureDucked, False) return except core.NVDANotInitializedError: # If the wx.App has not been initialized, audio ducking callbacks # will fail as they rely on wx.CallLater/wx.CallAfter log.debugWarning("wx App not initialized, unducking immediately") with _duckingRefCountLock: _duckingRefCount -= 1 if _isDebug(): log.debug("Decreased ref count, _duckingRefCount=%d" % _duckingRefCount) if _duckingRefCount == 0 and _audioDuckingMode != AudioDuckingMode.NONE: _setDuckingState(False)
def speakLater(delay=0, msg=""): global _speakTimer def callback(msg): speech.cancelSpeech() queueHandler.queueFunction(queueHandler.eventQueue, ui.message, msg) if _speakTimer: _speakTimer.Stop() if delay == 0 or msg == "": return _speakTimer = core.callLater(delay, callback, msg)
def checkUpdate(localGestureCounter, attempt, originalTimestamp, gesture=None, spokenAnyway=False): global gestureCounter, storedText if gestureCounter != localGestureCounter: return try: focus = api.getFocusObject() textInfo = focus.makeTextInfo(textInfos.POSITION_CARET) textInfo.expand(textInfos.UNIT_LINE) text = textInfo.text except Exception as e: log.warning( f"Error retrieving text during dynamic keystroke handling: {e}") return if attempt == 0: storedText = text else: if text != storedText: if spokenAnyway: speech.cancelSpeech() speech.speakTextInfo(textInfo, unit=textInfos.UNIT_LINE) return elapsed = time.time() - originalTimestamp if not spokenAnyway and elapsed > speakAnywayAfter: speech.speakTextInfo(textInfo, unit=textInfos.UNIT_LINE) spokenAnyway = True if elapsed < 1.0: sleepTime = 25 # ms elif elapsed < 10: sleepTime = 1000 # ms else: sleepTime = 5000 core.callLater(sleepTime, checkUpdate, localGestureCounter, attempt + 1, originalTimestamp, spokenAnyway=spokenAnyway)
def switchToVoiceProfile(self, selector, silent=False): def finish(synthName, synthspeechConfig, msg): # stop previous synth because oneCore voice switch don't work without it config.conf[SCT_Speech] = synthSpeechConfig.copy() setSynth(synthName) config.conf[SCT_Speech][synthName] = synthSpeechConfig[ synthName].copy() getSynth().loadSettings() # Reinitialize the tones module to update the audio device import tones tones.terminate() tones.initialize() if msg: ui.message(msg) newProfile = self.getVoiceProfile(selector) synthName = None for s, val in getSynthList(): if s == newProfile[KEY_SynthName]: synthName = s break voiceProfileName = newProfile[KEY_VoiceProfileName] if synthName is None: if gui.messageBox( # Translators: the label of a message box dialog. _("Impossible, the synthesizer of voice profile {voiceProfileName} associated to selector {selector} " "is not available. Do you want to free this selector?" ).format(selector=selector, voiceProfileName=voiceProfileName), # Translators: the title of a message box dialog. _("Synthesizer error"), wx.YES | wx.NO | wx.ICON_WARNING) == wx.YES: core.callLater(200, self.freeSelector, selector) return synthSpeechConfig = config.conf[SCT_Speech].dict() synthSpeechConfig.update(newProfile[SCT_Speech].copy()) self.setLastSelector(selector) msg = None if silent else _("Selector {selector}: {name}").format( selector=selector, name=voiceProfileName) queueHandler.queueFunction(queueHandler.eventQueue, finish, synthName, synthSpeechConfig, msg)
def onAction(self, activate): self.Close() # Save off the last selected element type on to the class so its used in initialization next time. self.__class__.lastSelectedElementType = self.lastSelectedElementType item = self.tree.GetSelection() item = self.tree.GetItemData(item).item if activate: item.activate() else: def move(): speech.cancelSpeech() # #8831: Report before moving because moving might change the focus, which # might mutate the document, potentially invalidating info if it is # offset-based. # item.report() item.moveTo() item.report() # We must use core.callLater rather than wx.CallLater to ensure that the callback runs within NVDA's core pump. # If it didn't, and it directly or indirectly called wx.Yield, it could start executing NVDA's core pump from within the yield, causing recursion. core.callLater(100, move)
def doCopy(copyDirectory): # Borrowed from @ibrahim-s code for readFeeds in PR#4 # to ensure that the removed directory will not be one of the main directories such as documents or music or other important ones if not os.path.basename(copyDirectory) == "placeMarkersBackup": copyDirectory=os.path.join(copyDirectory, "placeMarkersBackup") try: if os.path.exists(copyDirectory): #if it exists, only placeMarkersBackup folder will be removed, which is the base name of copyDirectory path shutil.rmtree(copyDirectory, ignore_errors=True) shutil.copytree(PLACE_MARKERS_PATH, copyDirectory) core.callLater(100, ui.message, # Translators: Message presented when place markers have been copied. _("Place markers copied")) except Exception as e: wx.CallAfter(gui.messageBox, # Translators: label of error dialog shown when cannot copy placeMarkers folder. _("Folder not copied"), # Translators: title of error dialog shown when cannot copy placeMarkers folder. _("Copy Error"), wx.OK|wx.ICON_ERROR) raise e
def onDeleteSymbolButton(self, evt): index = self.symbolsListBox.GetSelection() if index == -1: core.callLater( 300, ui.message, # Translators: This is a message announced in Manage Symbols Dialog. _("No symbol selected")) return symbol = self.complexSymbolsList[index] description = self.symbolsListBox.GetStringSelection() categoryName = self.symbolCategoryListBox.GetStringSelection() del self.userComplexSymbols[categoryName][symbol] self.onSelect(evt) core.callLater( 300, ui.message, # Translators: This is a message announced in Manage Symbols Dialog. _("%s symbol deleted") % description) evt.Skip()
def sendChar(char): nvwave.playWaveFile(os.path.join(baseDir, "res/sounds/keyPress.wav")) core.callLater(0, brailleInput.handler.sendChars, char) if len(char) == 1: core.callLater(100, speech.speakSpelling, char) else: core.callLater(100, speech.speakMessage, char)
def onExportHtml(self, evt): library_name= self.parent.FindWindowById(self.objectId).GetStringSelection() path= os.path.join(LIBRARIES_DIR, library_name+'.pickle') try: with open(path, 'rb') as f: d= pickle.load(f) except EOFError: gui.messageBox( _('Failed to open library, or may be library selected is empty.'), # Translators:title of message dialog _('Error'), wx.OK|wx.ICON_ERROR) return else: #the library data as list of tuple of six items (name, author, about, size, url, url2), which are the attributes of a book. library_data= sorted([(key[0], key[1], d[key]['about'], d[key]['size'], d[key]['url'], d[key]['url2']) for key in d])#, key= lambda x: x[1]) dlg = wx.DirDialog(self.parent, "Choose a directory:", style=wx.DD_DEFAULT_STYLE | wx.DD_DIR_MUST_EXIST ) if dlg.ShowModal() == wx.ID_OK: path_chosen= dlg.GetPath() #log.info(path_chosen) dlg.Destroy() if path_chosen: html_path= os.path.join(path_chosen, library_name+ '.html') try: makeHtmlFile(library_name, library_data, html_path) except Exception as e: wx.CallAfter(gui.messageBox, # Translators: message of error dialog displayed when cannot export library file. _("Failed to export library"), # Translators: title of error dialog . _("Error"), wx.OK|wx.ICON_ERROR) raise e else: core.callLater(200, ui.message, # Translators: Message presented when library has been exported. _("Information: Library Exported"))
def _reportErrorInPreviousWord(self): try: # self might be a descendant of the text control; e.g. Symphony. # We want to deal with the entire text, so use the caret object. info = api.getCaretObject().makeTextInfo(textInfos.POSITION_CARET) # This gets called for characters which might end a word; e.g. space. # The character before the caret is the word end. # The one before that is the last of the word, which is what we want. info.move(textInfos.UNIT_CHARACTER, -2) info.expand(textInfos.UNIT_CHARACTER) except Exception: # Focus probably moved. log.debugWarning("Error fetching last character of previous word", exc_info=True) return # Fetch the formatting for the last word to see if it is marked as a spelling error, # However perform the fetch and check in a future core cycle # To give the content control more time to detect and mark the error itself. # #12161: MS Word's UIA implementation certainly requires this delay. def _delayedDetection(): try: fields = info.getTextWithFields() except Exception: log.debugWarning( "Error fetching formatting for last character of previous word", exc_info=True) return for command in fields: if (isinstance(command, textInfos.FieldCommand) and command.command == "formatChange" and command.field.get("invalid-spelling")): break else: # No error. return nvwave.playWaveFile( os.path.join(globalVars.appDir, "waves", "textError.wav")) core.callLater(50, _delayedDetection)
def onOk(self, evt): text = self.findTextField.GetValue() # update the list of searched entries so that it can be exibited in the next find dialog call self.updateSearchEntries(self.activeCursorManager._searchEntries, text) caseSensitive = self.caseSensitiveCheckBox.GetValue() setConfig(self.profile, "searchCaseSensitivity", caseSensitive) searchWrap = self.searchWrapCheckBox.GetValue() setConfig(self.profile, "searchWrap", searchWrap) if self._mustSaveProfile: scheduleProfileSave(self.profile) # We must use core.callLater rather than wx.CallLater to ensure that the callback runs within NVDA's core pump. # If it didn't, and it directly or indirectly called wx.Yield, it could start executing NVDA's core pump from within the yield, causing recursion. core.callLater(100, self.activeCursorManager.doFindText, text, caseSensitive=caseSensitive, searchWrap=searchWrap) self.Destroy()
def script_indentPaste(self, gesture): clipboardBackup = api.getClipData() try: focus = api.getFocusObject() selection = focus.makeTextInfo(textInfos.POSITION_SELECTION) if len(selection.text) != 0: ui.message(_("Some text selected! Cannot indent-paste.")) return line = focus.makeTextInfo(textInfos.POSITION_CARET) line.collapse() line.expand(textInfos.UNIT_LINE) # Make sure line doesn't include newline characters while len(line.text) > 0 and line.text[-1] in "\r\n": line.move(textInfos.UNIT_CHARACTER, -1, "end") lineLevel = self.getIndentLevel(line.text + "a") #ui.message(f"Level {level}") text = clipboardBackup textLevel = min([ self.getIndentLevel(s) for s in text.splitlines() if not speech.isBlank(s) ]) useTabs = '\t' in text or '\t' in line.text delta = lineLevel - textLevel text = text.replace("\t", " " * 4) if delta > 0: text = "\n".join([" " * delta + s for s in text.splitlines()]) elif delta < 0: text = "\n".join( [s[min(-delta, len(s)):] for s in text.splitlines()]) if useTabs: text = text.replace(" " * 4, "\t") api.copyToClip(text) line.updateSelection() time.sleep(0.1) keyboardHandler.KeyboardInputGesture.fromName("Control+v").send() finally: core.callLater(100, api.copyToClip, clipboardBackup) core.callLater(100, ui.message, _("Pasted"))
def script_spellingCheckerHelper(self, gesture): global GB_scriptTimer if not self.isSupportedVersion(): # Translators: message to the user when word version is not supported. speech.speakMessage(_("Not available for this Word version")) return stopScriptTimer() focus = api.getFocusObject() from .ww_spellingChecker import SpellingChecker sc = SpellingChecker(focus, self.WinwordVersion) if not sc.isInSpellingChecker(): queueHandler.queueFunction( queueHandler.eventQueue, speech.speakMessage, # Translators: message to indicate the focus is not in spellAndGrammar checker. # noqa:E501 _("You are Not in the spelling checker")) return if focus.role == controlTypes.ROLE_PANE: # focus on the pane not not on an object of the pane queueHandler.queueFunction( queueHandler.eventQueue, speech.speakMessage, # Translators: message to ask user to hit tab key. _("Hit tab to move focus in the spelling checker pane")) return count = scriptHandler.getLastScriptRepeatCount() count = scriptHandler.getLastScriptRepeatCount() if count == 0: GB_scriptTimer = core.callLater(_delay, sc.sayErrorAndSuggestion, spell=False, focusOnSuggestion=False) elif count == 1: GB_scriptTimer = core.callLater(_delay, sc.sayErrorAndSuggestion, spell=True, focusOnSuggestion=False) else: wx.CallAfter(sc.sayHelpText)
def onPasteButton(self, event): index = self.symbolsListBox.GetSelection() if index == -1: # Translators: This is a message announced in complex symbols dialog. speakLater(300, _("No symbol selected")) return symbol = self.complexSymbolsList[index] symbolDescription = self.symbolsListBox.GetString(index) result = copyToClip(symbol) if not result: c = ord(symbol) log.error("error copyToClip symbol:%s (%s) code = %d" % ( self.symbolDescriptionList[index], symbol, c)) else: # Translators: This is a message announced in complex symbols dialog. msg = _("{0} pasted").format(self.symbolDescriptionList[index]) ui.message(msg) time.sleep(2.0) core.callLater(200, SendKey, "Control+v") from ..settings import _addonConfigManager _addonConfigManager.updateLastSymbolsList(symbolDescription, symbol) self.Close()
def changeWatcher(self): self.schedule() edit = self.appModule.edit if None is edit: #The editor gained focus. We're gonna die anyway on the next round. return textInfo = edit.makeTextInfo(textInfos.POSITION_SELECTION) if textInfo.bookmark == IncrementalFind.cacheBookmark: #Nothing has changed. Just go away. return IncrementalFind.cacheBookmark = textInfo.bookmark textInfo.expand(textInfos.UNIT_LINE) #Reporting indentation here is not really necessary. idt = speech.splitTextIndentation(textInfo.text)[0] textInfo.move(textInfos.UNIT_CHARACTER, len(idt), "start") def present(): queueHandler.queueFunction(queueHandler.eventQueue, speech.speakTextInfo, (textInfo)) core.callLater( 100, present) #Slightly delay presentation in case the status changes.
def doCopy(copyDirectory): # to ensure that the removed directory will not be one of the main directories such as documents or music or other important ones if not os.path.basename(copyDirectory) == "personalFeeds": copyDirectory = os.path.join(copyDirectory, "personalFeeds") try: if os.path.exists(copyDirectory): #if it exists, only personalFeeds folder will be remove, which is the base name of copyDirectory path shutil.rmtree(copyDirectory, ignore_errors=True) shutil.copytree(FEEDS_PATH, copyDirectory) core.callLater( 100, ui.message, # Translators: Message presented when feeds have been copied. _("Feeds copied")) except Exception as e: wx.CallAfter( gui.messageBox, # Translators: label of error dialog shown when cannot copy feeds folder. _("Folder not copied"), # Translators: title of error dialog shown when cannot copy feeds folder. _("Copy Error"), wx.OK | wx.ICON_ERROR) raise e
def onPaste (self, evt): # Simulates typing the block of text in the edit area. self.Hide() evt.Skip() config = ConfigObj(_ffIniFile, list_values = True, encoding = "utf-8") blocks = config[Catg] index=self.listBox.GetFocusedItem() name = self.listBox.GetItemText(index) paste = blocks[name] pasteStr = "\r\n".join(paste) if len(paste) >= 2: pasteStr += "\r\n" try: clipboardBackup = api.getClipData() except OSError: api.copyToClip(pasteStr) time.sleep(0.1) api.processPendingEvents(False) focus = api.getFocusObject() if focus.windowClassName == "ConsoleWindowClass": # Windows console window - Control+V doesn't work here, so using an alternative method here WM_COMMAND = 0x0111 watchdog.cancellableSendMessage(focus.windowHandle, WM_COMMAND, 0xfff1, 0) else: KeyboardInputGesture.fromName("Control+v").send() else: api.copyToClip(pasteStr) time.sleep(0.1) api.processPendingEvents(False) focus = api.getFocusObject() if focus.windowClassName == "ConsoleWindowClass": # Windows console window - Control+V doesn't work here, so using an alternative method here WM_COMMAND = 0x0111 watchdog.cancellableSendMessage(focus.windowHandle, WM_COMMAND, 0xfff1, 0) else: KeyboardInputGesture.fromName("Control+v").send() core.callLater(300, lambda: api.copyToClip(clipboardBackup))
def onOk(self, evt): self.Destroy() if self.addCheckBox.Value or self.searchRadioBox.Selection < 2: # Add or search text = self.searchTextEdit.Value actionToPerform = self.searchRadioBox.Selection if actionToPerform < 2: # Search caseSensitive = self.caseSensitiveCheckBox.Value if actionToPerform == 0: core.callLater(1000, doFindText, text, caseSensitive=caseSensitive) else: core.callLater(1000, doFindTextUp, text, caseSensitive=caseSensitive) global lastFindText, lastCaseSensitivity lastFindText = text lastCaseSensitivity = caseSensitive if self.addCheckBox.Value or self.removeCheckBox.Value: savedStrings = self.savedTexts if self.removeCheckBox.Value: del savedStrings[self.savedTextsComboBox.Selection] if self.addCheckBox.Value and not "\n" in text and not text in savedStrings: savedStrings.insert(0, text) if len(savedStrings) == 0: os.remove(self.searchFile) return try: with open(self.searchFile, "w", encoding="utf-8") as f: f.write("\n".join(savedStrings)) except Exception as e: log.debugWarning( "Error saving strings of text for specific search", exc_info=True) raise e
def screenRapping(self, itemType, readUnit, msg, rpTo, tone=(500, 80), reverse='previous', direction='next'): updatePosition(self, rpTo) navItems = initNavItemsGenerator(self, itemType) try: rapping = next(navItems(direction, self.selection)) speak([msg]) rapping.moveTo() try: rapping = next(navItems(reverse, self.selection)) callLater(300, rapping.moveTo) except StopIteration: pass beep(tone[0], tone[1]) rapping.report(readUnit=readUnit) return True except StopIteration: pass
def onOk(self, evt): """Copy to clipboard the focused emoticon on the list.""" focusedItem = self.smileysList.GetFocusedItem() if focusedItem == -1: if self.smileysList.GetItemCount() > 0: focusedItem = 0 else: # Translators: Error message when none emoticon is selected or the list is empty, and title of the error dialog. gui.messageBox(_("There is not any emoticon selected."), translate("Error"), parent=self, style=wx.OK | wx.ICON_ERROR) return icon = self._filteredEmoticons[focusedItem] iconToInsert = icon.chars if api.copyToClip(iconToInsert): # Translators: This is the message when smiley has been copied to the clipboard. core.callLater( 100, ui.message, _("Smiley copied to clipboard, ready for you to paste.")) else: # Translators: Message when the emoticon couldn't be copied. core.callLater(100, ui.message, _("Cannot copy smiley.")) self.Destroy() InsertEmoticonDialog._instance = None
def sayInTimezone(self): selectedTz = self.getTimezone() if selectedTz == "": # For translators: message to inform there are no timezones defined core.callLater(0, ui.message, _("No timezones set")) return now = datetime.now(timezone("UTC")) destTimezone = now.astimezone(timezone(selectedTz)) # By the time the code gets down here, we could have signaled this thread to terminate. # This will be the case if retrieval is taking a long time and we've pressed the key multiple times to get successive information in our timezone ring, in which case this thread is marked dirty. if self.interrupted: return # We'll use the winKernel here to announce the time and date in the user's locale. theTime = winKernel.GetTimeFormatEx(winKernel.LOCALE_NAME_USER_DEFAULT, winKernel.TIME_NOSECONDS, destTimezone, None) theDate = winKernel.GetDateFormatEx(winKernel.LOCALE_NAME_USER_DEFAULT, winKernel.DATE_LONGDATE, destTimezone, None) # For translators: message to announce the time, date and timezone core.callLater( 0, ui.message, _("%s, %s (%s)" % (theTime, theDate, destTimezone.strftime("%Z") if self.announceAbbriv else selectedTz)))
def onListItemSelected(self, evt): index = evt.GetIndex() item = self.collection[index] if self.tc1: self.TC1.Clear() text = self.get_tc1Datas(item) self.TC1.AppendText(text) self.TC1.SetInsertionPoint(0) if self.timer != None: self.timer.Stop() self.timer = core.callLater(800, ui.message, text) if self.tc2: self.TC2.Clear() self.TC2.AppendText(self.get_tc2Datas(item)) self.TC2.SetInsertionPoint(0) evt.Skip()
def startRemanence(self, gesture): def endRemanence(gesture): self.stopRemanence(beep=True) if gesture.isNVDAModifierKey: gesture.noAction = True else: gesture.noAction = False queueHandler.queueFunction(queueHandler.eventQueue, self.executeNewGesture, gesture) if self.remanenceActivation is False: return if not self.isRemanenceStarted(): if toggleBeepAtRemanenceStartAdvancedOption(False): tones.beep(100, 60) else: self.remanenceTimer.Stop() self.remanenceTimer = core.callLater( _addonConfigManager.getRemanenceDelay(), endRemanence, gesture)
def onTreeChar(self, evt): key = evt.KeyCode if key == wx.WXK_RETURN: # The enter key should be propagated to the dialog and thus activate the default button, # but this is broken (wx ticket #3725). # Therefore, we must catch the enter key here. # Activate the current default button. evt = wx.CommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED, wx.ID_ANY) button = self.FindWindowById(self.AffirmativeId) if button.Enabled: button.ProcessEvent(evt) else: wx.Bell() elif key == wx.WXK_F2: item=self.tree.GetSelection() if item: if wx.version().startswith("4"): selectedItemType=self.tree.GetItemData(item).item else: selectedItemType=self.tree.GetItemPyData(item).item self.tree.EditLabel(item) evt.Skip() elif key >= wx.WXK_START or key == wx.WXK_BACK: # Non-printable character. self._searchText = "" evt.Skip() else: # Search the list. # We have to implement this ourselves, as tree views don't accept space as a search character. char = uniCHR(evt.UnicodeKey).lower() # IF the same character is typed twice, do the same search. if self._searchText != char: self._searchText += char if self._searchCallLater: self._searchCallLater.Restart() else: self._searchCallLater = core.callLater(1000, self._clearSearchText) self.search(self._searchText)
def sayNumberOfElements(self): def callback(count): self._timer = None # Check if the listbox is still alive. try: if not self.objectTypesListBox.HasFocus() and\ not self.objectListBox.HasFocus(): return except RuntimeError: return if count: msg = _("%s elements") % str(count) if count > 1 else _( "One element") ui.message(msg) else: ui.message(_("no element")) if self._timer is not None: self._timer.Stop() self._timer = core.callLater(200, callback, self.objectListBox.Count)
def validateSymbol(self, categoryName, symbol, description): if len(symbol) == 0 and len(description) == 0: return False if len(symbol) == 0: # Translators: This is a message announced in Manage Symbols Dialog. core.callLater(300, ui.message, _("No symbol entered")) return False if len(symbol) > 1: core.callLater( 300, ui.message, # Translators: This is a message announced in Manage Symbols Dialog. _("Symbol is not valid")) return False if len(description) == 0: core.callLater( 300, ui.message, # Translators: This is a message announced in Manage Symbols Dialog. _("There is no description for the symbol")) return False for cat in self.parent.categoryNamesList: (symbolList, descriptionList ) = self.symbolsManager.getSymbolAndDescriptionList(cat) if symbol in symbolList: description = descriptionList[symbolList.index(symbol)] if cat == categoryName: if gui.messageBox( # Translators: the label of a message box dialog. _("""The symbol is already in this category """ """under "%s" description. Do you want to replace it?""" ) % description, # Translators: the title of a message box dialog. _("Confirmation"), wx.YES | wx.NO | wx.ICON_WARNING) == wx.NO: return False else: if gui.messageBox( # Translators: the label of a message box dialog. _("""The symbol is allready in "{oldCat}" category. """ """Do you want to add this symbol also in "{newCat}" category?""" ).format(oldCat=cat, newCat=categoryName), # Translators: the title of a message box dialog. _("Confirmation"), wx.YES | wx.NO | wx.ICON_WARNING) == wx.NO: return False return True
def sayInTimezone(self): selectedTz = self.getTimezone() if selectedTz == "": # For translators: message to inform there are no timezones defined core.callLater(0, ui.message, _("No timezones set")) return now = datetime.now(pytz.timezone("UTC")) destTimezone = now.astimezone(pytz.timezone(selectedTz)) # By the time the code gets down here, we could have signaled this thread to terminate. # This will be the case if retrieval is taking a long time and we've pressed the key multiple times to get successive information in our timezone ring, in which case this thread is marked dirty. if self.interrupted: return # We'll use the winKernel here to announce the time and date in the user's locale. theTime = winKernel.GetTimeFormatEx(winKernel.LOCALE_NAME_USER_DEFAULT, winKernel.TIME_NOSECONDS, destTimezone, None) theDate = winKernel.GetDateFormatEx(winKernel.LOCALE_NAME_USER_DEFAULT, winKernel.DATE_LONGDATE, destTimezone, None) separator = selectedTz.find("/") country = timezoneToCountry.get(selectedTz, "Unknown country") timezone = destTimezone.strftime( "%Z") if self.announceAbbriv else selectedTz continent = "" city = "" if separator != -1: continent = selectedTz[:separator] city = selectedTz[separator + 1:] # For translators: message to announce the time, date and timezone core.callLater( 0, ui.message, _( self.formatStringL.format(time=theTime, date=theDate, country=country, continent=continent, city=city, timezone=timezone))) else: # For translators: message to announce the time, date and timezone core.callLater( 0, ui.message, _( self.formatStringS.format(time=theTime, date=theDate, timezone=timezone)))
def onOk(self, evt): self.Destroy() core.callLater(1000, moveToBookmark, self.pos)
def schedule(self): if self.die: self.die=False return core.callLater(5, self.changeWatcher)
def reportExtra(self): if self.vkCode in self.TOGGLE_KEYS: core.callLater(30, self._reportToggleKey)
def announceFilterAfterDelay(self, n): sleep(0.5) speech.cancelSpeech() # For translators: Message to announce the number of matches found core.callLater(0, ui.message, _("%d results now showing" % n))
def __init__(self, *args, **kwargs): super(GlobalPlugin, self).__init__(*args, **kwargs) #Call testForExitRequired at first core cycle core.callLater(0, testForExitRequired)