Skip to content

Commit

Permalink
Config: add saveConfig and resetConfig actions (PR #7606)
Browse files Browse the repository at this point in the history
Closes #7598

Config: add the following actions so add-ons can respond and perform appropriate actions when saving or reverting settings, respectively:
* `config.post_configSave` 
* `config.pre_configSave`
* `config.post_configReset`
* `config.pre_configReset`
* `config.post_configProfileSwitch`

Some add-ons do not participate in ConfigManager/profiles at the moment. For these, there's no easy way to revert settings or Control+NVDA+C cannot be used to let add-ons save settings. These new actions now alleviate this.
 Example use cases:
* pre/post config save: allows add-ons to save settings to custom location(s).
* pre/post config reset: allows add-ons to reload settings from anywhere and/or reset configuration to defaults (controlled by a boolean).

Pre / post: there are times it is helpful to let modules perform actions prior to and/or after NVDA settings are saved, most likely when add-ons need to save settings and/or a module will transport settings to a cloud location for safekeeping or synchronization purposes. Not all modules should listen to both events at once - mostly, `pre_configSave` action is enough.
  • Loading branch information
josephsl authored and feerrenrut committed Aug 1, 2018
1 parent ef9be39 commit 6522a9b
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 14 deletions.
4 changes: 2 additions & 2 deletions source/audioDucking.py
Expand Up @@ -117,7 +117,7 @@ def initialize():
return
_setDuckingState(False)
setAudioDuckingMode(config.conf['audio']['audioDuckingMode'])
config.configProfileSwitched.register(handleConfigProfileSwitch)
config.post_configProfileSwitch.register(handlePostConfigProfileSwitch)

_isAudioDuckingSupported=None
def isAudioDuckingSupported():
Expand All @@ -126,7 +126,7 @@ def isAudioDuckingSupported():
_isAudioDuckingSupported=config.isInstalledCopy() and hasattr(oledll.oleacc,'AccSetRunningUtilityState')
return _isAudioDuckingSupported

def handleConfigProfileSwitch():
def handlePostConfigProfileSwitch():
setAudioDuckingMode(config.conf['audio']['audioDuckingMode'])

class AudioDucker(object):
Expand Down
6 changes: 3 additions & 3 deletions source/braille.py
Expand Up @@ -1567,7 +1567,7 @@ def __init__(self):
self._cursorBlinkUp = True
self._cells = []
self._cursorBlinkTimer = None
config.configProfileSwitched.register(self.handleConfigProfileSwitch)
config.post_configProfileSwitch.register(self.handlePostConfigProfileSwitch)
self._tether = config.conf["braille"]["tetherTo"]
self._detectionEnabled = False
self._detector = None
Expand All @@ -1581,7 +1581,7 @@ def terminate(self):
if self._cursorBlinkTimer:
self._cursorBlinkTimer.Stop()
self._cursorBlinkTimer = None
config.configProfileSwitched.unregister(self.handleConfigProfileSwitch)
config.post_configProfileSwitch.unregister(self.handlePostConfigProfileSwitch)
if self.display:
self.display.terminate()
self.display = None
Expand Down Expand Up @@ -1963,7 +1963,7 @@ def initialDisplay(self):
else:
self.handleReviewMove(shouldAutoTether=False)

def handleConfigProfileSwitch(self):
def handlePostConfigProfileSwitch(self):
display = config.conf["braille"]["display"]
# Do not choose a new display if:
if not (
Expand Down
4 changes: 2 additions & 2 deletions source/brailleInput.py
Expand Up @@ -93,7 +93,7 @@ def __init__(self):
self._uncontSentTime = None
#: The modifiers currently being held virtually to be part of the next braille input gesture.
self.currentModifiers = set()
config.configProfileSwitched.register(self.handleConfigProfileSwitch)
config.post_configProfileSwitch.register(self.handlePostConfigProfileSwitch)

def _get_table(self):
"""The translation table to use for braille input.
Expand Down Expand Up @@ -419,7 +419,7 @@ def handleCaretMove(self, obj):
# Clear all state.
self.flushBuffer()

def handleConfigProfileSwitch(self):
def handlePostConfigProfileSwitch(self):
table = config.conf["braille"]["inputTable"]
if table != self._table.fileName:
self._table = brailleTables.getTable(table)
Expand Down
27 changes: 23 additions & 4 deletions source/config/__init__.py
Expand Up @@ -6,7 +6,11 @@
#See the file COPYING for more details.

"""Manages NVDA configuration.
The heart of NVDA's configuration is Configuration Manager, which records current options, profile information and functions to load, save, and switch amongst configuration profiles.
In addition, this module provides three actions: profile switch notifier, an action to be performed when NVDA saves settings, and action to be performed when NVDA is asked to reload configuration from disk or reset settings to factory defaults.
For the latter two actions, one can perform actions prior to and/or after they take place.
"""

import globalVars
import _winreg
import ctypes
Expand Down Expand Up @@ -35,14 +39,24 @@
isAppX=False

#: The active configuration, C{None} if it has not yet been loaded.
#: @type: ConfigObj
#: @type: ConfigManager
conf = None

#: Notifies when the configuration profile is switched.
#: This allows components to apply changes required by the new configuration.
#: 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.
configProfileSwitched = extensionPoints.Action()
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
Expand Down Expand Up @@ -353,7 +367,7 @@ def _handleProfileSwitch(self):
if init:
# We're still initialising, so don't notify anyone about this change.
return
configProfileSwitched.notify()
post_configProfileSwitch.notify()

def _initBaseConf(self, factoryDefaults=False):
fn = os.path.join(globalVars.appArgs.configPath, "nvda.ini")
Expand Down Expand Up @@ -490,6 +504,8 @@ def _writeProfileToFile(self, filename, profile):
def save(self):
"""Save all modified profiles and the base configuration to disk.
"""
# #7598: give others a chance to either save settings early or terminate tasks.
pre_configSave.notify()
if not self._shouldWriteProfile:
log.info("Not writing profile, either --secure or --launcher args present")
return
Expand All @@ -504,17 +520,20 @@ def save(self):
log.warning("Error saving configuration; probably read only file system")
log.debugWarning("", exc_info=True)
raise e
post_configSave.notify()

def reset(self, factoryDefaults=False):
"""Reset the configuration to saved settings or factory defaults.
@param factoryDefaults: C{True} to reset to factory defaults, C{False} to reset to saved configuration.
@type factoryDefaults: bool
"""
pre_configReset.notify(factoryDefaults=factoryDefaults)
self.profiles = []
self._profileCache.clear()
# Signal that we're initialising.
self.rootSection = None
self._initBaseConf(factoryDefaults=factoryDefaults)
post_configReset.notify(factoryDefaults=factoryDefaults)

def createProfile(self, name):
"""Create a profile.
Expand Down
2 changes: 1 addition & 1 deletion source/core.py
Expand Up @@ -157,7 +157,7 @@ def resetConfiguration(factoryDefaults=False):
inputCore.manager.loadLocaleGestureMap()
import audioDucking
if audioDucking.isAudioDuckingSupported():
audioDucking.handleConfigProfileSwitch()
audioDucking.handlePostConfigProfileSwitch()
log.info("Reverted to saved configuration")


Expand Down
4 changes: 2 additions & 2 deletions source/synthDriverHandler.py
Expand Up @@ -23,7 +23,7 @@

def initialize():
config.addConfigDirsToPythonPackagePath(synthDrivers)
config.configProfileSwitched.register(handleConfigProfileSwitch)
config.post_configProfileSwitch.register(handlePostConfigProfileSwitch)

def changeVoice(synth, voice):
# This function can be called with no voice if the synth doesn't support the voice setting (only has one voice).
Expand Down Expand Up @@ -118,7 +118,7 @@ def setSynth(name,isFallback=False):
setSynth('silence',isFallback=True)
return False

def handleConfigProfileSwitch():
def handlePostConfigProfileSwitch():
conf = config.conf["speech"]
if conf["synth"] != _curSynth.name or conf["outputDevice"] != _audioOutputDevice:
setSynth(conf["synth"])
Expand Down
4 changes: 4 additions & 0 deletions user_docs/en/changes.t2t
Expand Up @@ -61,6 +61,10 @@ What's New in NVDA
- Dictionaries yielded by listComPorts now also contain a usbID entry for COM ports with USB VID/PID information in their hardware ID.
- Updated wxPython to 4.0.3. (#7077)
- As NVDA now only supports Windows 7 SP1 and later, the key "minWindowsVersion" used to check if UIA should be enabled for a particular release of Windows has been removed. (#8422)
- You can now register to be notified about configuration saves/reset actions via new config.pre_configSave, config.post_configSave, config.pre_configReset, and config.post_configReset actions. (#7598)
- config.pre_configSave is used to be notified when NVDA's configuration is about to be saved, and config.post_configSave is called after configuration has been saved.
- config.pre_configReset and config.post_configReset includes a factory defaults flag to specify if settings are reloaded from disk (false) or reset to defaults (true).
- config.configProfileSwitch has been renamed to config.post_configProfileSwitch to reflect the fact that this action is called after profile switch takes place. (#7598)
- UI Automation interfaces updated to Windows 10 October 2018 Update and Server 2019 (IUIAutomation6 / IUIAutomationElement9). (#8473)


Expand Down

0 comments on commit 6522a9b

Please sign in to comment.