class BrailleViewerSpy: postBrailleUpdate = extensionPoints.Action() def __init__(self): self._last = "" def updateBrailleDisplayed( self, cells, # ignored rawText, currentCellCount, # ignored ): rawText = rawText.strip() if rawText and rawText != self._last: self._last = rawText self.postBrailleUpdate.notify(rawText=rawText) isDestroyed: bool = False def saveInfoAndDestroy(self): if not self.isDestroyed: self.isDestroyed = True import brailleViewer brailleViewer._onGuiDestroyed()
import sys import winVersion import threading import nvwave import os import time import ctypes import logHandler import globalVars from logHandler import log import addonHandler import extensionPoints import garbageHandler # noqa: E402 # inform those who want to know that NVDA has finished starting up. postNvdaStartup = extensionPoints.Action() PUMP_MAX_DELAY = 10 #: The thread identifier of the main thread. mainThreadId = threading.get_ident() #: Notifies when a window message has been received by NVDA. #: This allows components to perform an action when several system events occur, #: such as power, screen orientation and hardware changes. #: Handlers are called with three arguments. #: @param msg: The window message. #: @type msg: int #: @param wParam: Additional message information. #: @type wParam: int #: @param lParam: Additional message information.
import tempfile import hashlib import wx import gui from gui import guiHelper from logHandler import log import addonHandler import updateCheck import core import extensionPoints from gui.nvdaControls import AutoWidthColumnCheckListCtrl from .skipTranslation import translate # Temporary addonHandler.initTranslation() AddonUpdaterManualUpdateCheck = extensionPoints.Action() _progressDialog = None # The following event handler comes from a combination of StationPlaylist Studio and Windows 10 App Essentials. def onAddonUpdateCheck(evt): AddonUpdaterManualUpdateCheck.notify() global _progressDialog _progressDialog = gui.IndeterminateProgressDialog( gui.mainFrame, # Translators: The title of the dialog presented while checking for add-on updates. _("Add-on update check"), # Translators: The message displayed while checking for add-on updates. _("Checking for add-on updates..."))
from . import profileUpgrader from .configSpec import confspec from typing import Any, Dict, List, Optional, Set #: True if NVDA is running as a Windows Store Desktop Bridge application isAppX=False #: The active configuration, C{None} if it has not yet been loaded. #: @type: ConfigManager conf = None #: Notifies when the configuration profile is switched. #: This allows components and add-ons to apply changes required by the new configuration. #: For example, braille switches braille displays if necessary. #: Handlers are called with no arguments. post_configProfileSwitch = extensionPoints.Action() #: Notifies when NVDA is saving current configuration. #: Handlers can listen to "pre" and/or "post" action to perform tasks prior to and/or after NVDA's own configuration is saved. #: Handlers are called with no arguments. pre_configSave = extensionPoints.Action() post_configSave = extensionPoints.Action() #: Notifies when configuration is reloaded from disk or factory defaults are applied. #: Handlers can listen to "pre" and/or "post" action to perform tasks prior to and/or after NVDA's own configuration is reloaded. #: Handlers are called with a boolean argument indicating whether this is a factory reset (True) or just reloading from disk (False). pre_configReset = extensionPoints.Action() post_configReset = extensionPoints.Action() def initialize(): global conf conf = ConfigManager()
import appModules import exceptions import extensionPoints from fileUtils import getFileVersionInfo # Dictionary of processID:appModule pairs used to hold the currently running modules runningTable: Dict[int, AppModule] = {} #: The process ID of NVDA itself. NVDAProcessID = None _importers = None _getAppModuleLock = threading.RLock() #: Notifies when another application is taking foreground. #: This allows components to react upon application switches. #: For example, braille triggers bluetooth polling for braille displaysf necessary. #: Handlers are called with no arguments. post_appSwitch = extensionPoints.Action() class processEntry32W(ctypes.Structure): _fields_ = [("dwSize", ctypes.wintypes.DWORD), ("cntUsage", ctypes.wintypes.DWORD), ("th32ProcessID", ctypes.wintypes.DWORD), ("th32DefaultHeapID", ctypes.wintypes.DWORD), ("th32ModuleID", ctypes.wintypes.DWORD), ("cntThreads", ctypes.wintypes.DWORD), ("th32ParentProcessID", ctypes.wintypes.DWORD), ("pcPriClassBase", ctypes.c_long), ("dwFlags", ctypes.wintypes.DWORD), ("szExeFile", ctypes.c_wchar * 260)]
This is what happens by default. However, Speech itself may call this with false internally if this is a config profile switch within a currently processing speech sequence. @type resetSpeechIfNeeded: bool """ conf = config.conf["speech"] if conf["synth"] != _curSynth.name or conf[ "outputDevice"] != _audioOutputDevice: if resetSpeechIfNeeded: # Reset the speech queues as we are now going to be using a new synthesizer with entirely separate state. import speech speech.cancelSpeech() setSynth(conf["synth"]) return _curSynth.loadSettings(onlyChanged=True) def isDebugForSynthDriver(): return config.conf["debugLog"]["synthDriver"] #: Notifies when a synthesizer reaches an index during speech. #: Handlers are called with these keyword arguments: #: synth: The L{SynthDriver} which reached the index. #: index: The number of the index which has just been reached. synthIndexReached = extensionPoints.Action() #: Notifies when a synthesizer finishes speaking. #: Handlers are called with one keyword argument: #: synth: The L{SynthDriver} which reached the index. synthDoneSpeaking = extensionPoints.Action()
### Scrolling Scrolling is supported by binding a gesture to the braille_scroll_forward and braille scroll_back commands. For the same reason that Routing is not supported, scrolling via button clicks on the braille viewer window is not supported. """ # global braille viewer driver: _brailleGui: Optional[BrailleViewerFrame] = None # Extension points action: # Triggered every time the Braille Viewer is created / shown or hidden / destroyed. # Callback definition: Callable(created: bool) -> None # created - True for created/shown, False for hidden/destructed. postBrailleViewerToolToggledAction = extensionPoints.Action() # Devices with 40 cells are quite common. DEFAULT_NUM_CELLS = 40 def isBrailleViewerActive() -> bool: return bool(_brailleGui) def update(cells: List[int], rawText: str): if _brailleGui: _brailleGui.updateBrailleDisplayed( cells, rawText, _getDisplaySize() )
def setUp(self): self.action = extensionPoints.Action()
import extensionPoints from config import post_configSave, post_configReset, post_configProfileSwitch from .unspoken import UnspokenPlayer, libaudioverse, dll_hack import addonHandler addonHandler.initTranslation() THEMES_DIR = os.path.join(os.path.dirname(__file__), "Themes") INFO_FILE_NAME = "info.json" SUPPORTED_FILE_TYPES = OrderedDict() # Translators: The file type to be shown in a dialog used to browse for audio files. SUPPORTED_FILE_TYPES["ogg"] = _("Ogg audio files") # Translators: The file type to be shown in a dialog used to browse for audio files. SUPPORTED_FILE_TYPES["wav"] = _("Wave audio files") # When the active audio theme is being changed audiotheme_changed = extensionPoints.Action() # Configuration spec audiothemes_config_defaults = { "enable_audio_themes": "boolean(default= True)", "active_theme": 'string(default="Default")', "audio3d": "boolean(default=True)", "use_in_say_all": "boolean(default=True)", "speak_roles": "boolean(default=False)", "use_synth_volume": "boolean(default=True)", "volume": "integer(default=100)", } class SpecialProps(IntEnum): """Represents sounds defined by this addon."""
import extensionPoints import profileUpgrader from .configSpec import confspec #: True if NVDA is running as a Windows Store Desktop Bridge application isAppX=False #: The active configuration, C{None} if it has not yet been loaded. #: @type: ConfigObj conf = None #: Notifies when the configuration profile is switched. #: This allows components to apply changes required by the new configuration. #: For example, braille switches braille displays if necessary. #: Handlers are called with no arguments. configProfileSwitched = extensionPoints.Action() def initialize(): global conf conf = ConfigManager() def saveOnExit(): """Save the configuration if configured to save on exit. This should only be called if NVDA is about to exit. Errors are ignored. """ if conf["general"]["saveConfigurationOnExit"]: try: conf.save() except: pass
# Copyright (C) 2020 NV Access Limited # This file is covered by the GNU General Public License. # See the file COPYING for more details. """ This module is copied to the scratchPad/synthDrivers folder and set as the synthesizer to capture speech output during system tests. Note: The name of this module must match the name of the synth driver, and the configured synthesizer in the `tests/system/nvdaSettingsFiles/*.ini` files. """ import synthDriverHandler import extensionPoints import speech # inform those who want to know that there is new speech post_speech = extensionPoints.Action() class SpeechSpySynthDriver(synthDriverHandler.SynthDriver): """A synth driver configured during system tests to capture speech output """ name = "SpeechSpySynthDriver" # Name must match configuration files and module. description = "System test speech spy" @classmethod def check(cls): return True supportedSettings = [] supportedNotifications = { synthDriverHandler.synthIndexReached,
# SPL Studio Actions # An app module and global plugin package for NVDA # Copyright 2017-2018 Joseph Lee and others, released under GPL. # Defines various actions to be carried out by various add-on modules, powered by extension points. # This module provides services for other modules, not the other way around. # Thus, importing other add-on modules should not be attempted unless granted. # An action is a notification about something that has happened or about to happen. # In SPL add-on, an action is prefixed by SPLAction*. import sys py3 = sys.version.startswith("3") # Do not unlock the full power of action extension point until 2018. import extensionPoints # 40 (17.12): unconditionally define actions, but not until 2018. # Studio handle found, app module is fully ready. SPLActionAppReady = extensionPoints.Action() # Add-on settings were loaded. SPLActionSettingsLoaded = extensionPoints.Action() # Switching broadcast profiles. SPLActionProfileSwitched = extensionPoints.Action() # Settings are being saved. SPLActionSettingsSaved = extensionPoints.Action() # Studio is terminating. SPLActionAppTerminating = extensionPoints.Action()
# -*- coding: UTF-8 -*- # power status notiffications: This add-on plays a tone when the power status changes. # Copyright (C) 2019 David CM # Author: David CM <*****@*****.**> # Released under GPL 2 #globalPlugins/powerStatusNotiffications.py import extensionPoints, globalPluginHandler, tones, windowUtils, winKernel, addonHandler post_windowMessageReceipt = extensionPoints.Action() class MessageWindow(windowUtils.CustomWindow): className = u"PowerStatusNotiffications" WM_POWERBROADCAST = 0x218 PBT_APMPOWERSTATUSCHANGE = 0xA UNKNOWN_BATTERY_STATUS = 0xFF AC_ONLINE = 0X1 NO_SYSTEM_BATTERY = 0X80 def __init__(self, windowName=None): super(MessageWindow, self).__init__(windowName) self.oldBatteryStatus = None self.handlePowerStatusChange() def windowProc(self, hwnd, msg, wParam, lParam): post_windowMessageReceipt.notify(msg=msg, wParam=wParam, lParam=lParam) if msg == self.WM_POWERBROADCAST and wParam == self.PBT_APMPOWERSTATUSCHANGE: self.handlePowerStatusChange() def handlePowerStatusChange(self):