Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refocus multi-category settings dialog with the provided category. #12995

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions source/gui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ def popupSettingsDialog(self, dialog: Type[SettingsDialog], *args, **kwargs):
dialog(self, *args, **kwargs).Show()
except SettingsDialog.MultiInstanceErrorWithDialog as errorWithDialog:
errorWithDialog.dialog.SetFocus()
if isinstance(errorWithDialog.dialog, MultiCategorySettingsDialog) and len(args) > 0:
errorWithDialog.dialog.selectNewCategory(args[0])
except MultiCategorySettingsDialog.CategoryUnavailableError:
# Translators: Message shown when trying to open an unavailable category of a multi category settings dialog
# (example: when trying to open touch interaction settings on an unsupported system).
Expand Down
51 changes: 38 additions & 13 deletions source/gui/settingsDialogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -493,23 +493,16 @@ class MultiCategorySettingsDialog(SettingsDialog):

class CategoryUnavailableError(RuntimeError): pass

def __init__(self, parent, initialCategory=None):
def __init__(
self,
parent: Optional[wx.Window],
initialCategory: Optional[SettingsPanel] = None,
):
"""
@param parent: The parent for this dialog; C{None} for no parent.
@type parent: wx.Window
@param initialCategory: The initial category to select when opening this dialog
@type parent: SettingsPanel
"""
if initialCategory and not issubclass(initialCategory,SettingsPanel):
if gui._isDebug():
log.debug("Unable to open category: {}".format(initialCategory), stack_info=True)
raise TypeError("initialCategory should be an instance of SettingsPanel")
if initialCategory and initialCategory not in self.categoryClasses:
if gui._isDebug():
log.debug("Unable to open category: {}".format(initialCategory), stack_info=True)
raise MultiCategorySettingsDialog.CategoryUnavailableError(
"The provided initial category is not a part of this dialog"
)
self.checkCategory(initialCategory)
self.initialCategory = initialCategory
self.currentCategory = None
self.setPostInitFocus = None
Expand Down Expand Up @@ -620,6 +613,25 @@ def makeSettings(self, settingsSizer):
self.Bind(wx.EVT_CHAR_HOOK, self.onCharHook)
self.Bind(EVT_RW_LAYOUT_NEEDED, self._onPanelLayoutChanged)

def checkCategory(self, cat: Optional[SettingsPanel]) -> None:
"""
@param cat: The class of the panel on which the dialog should be opened or C{None} if no specific panel
is targetted.

"""
if cat is None:
return
if not issubclass(cat, SettingsPanel):
if gui._isDebug():
log.debug("Unable to open category: {}".format(cat), stack_info=True)
raise TypeError("cat should be an instance of SettingsPanel")
if cat not in self.categoryClasses:
if gui._isDebug():
log.debug("Unable to open category: {}".format(cat), stack_info=True)
raise MultiCategorySettingsDialog.CategoryUnavailableError(
"The provided initial category is not a part of this dialog"
)

def _getCategoryPanel(self, catId):
panel = self.catIdToInstanceMap.get(catId, None)
if not panel:
Expand Down Expand Up @@ -692,6 +704,19 @@ def _onPanelLayoutChanged(self,evt):
# erase the old contents and must be redrawn
self.container.Refresh()

def selectNewCategory(self, cat):
self.checkCategory(cat)
currentCat = self.currentCategory
newIndex = self.categoryClasses.index(cat)
if not currentCat or newIndex != self.categoryClasses.index(currentCat.__class__):
listHadFocus = self.catListCtrl.HasFocus()
if not listHadFocus:
self.catListCtrl.SetFocus()
self.catListCtrl.Select(newIndex)
# we must focus the new selection in the category list to trigger the change of category.
self.catListCtrl.Focus(newIndex)
self.currentCategory.SetFocus()

def _doCategoryChange(self, newCatId):
oldCat = self.currentCategory
# Freeze and Thaw are called to stop visual artifact's while the GUI
Expand Down
1 change: 1 addition & 0 deletions user_docs/en/changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Unicode CLDR has been updated.
* NVDA will correctly announce selection changes when editing a cell's text in Microsoft Excel. (#15843)
* In applications using Java Access Bridge, NVDA will now correctly read the last blank line of a text instead of repeating the previous line. (#9376, @dmitrii-drobotov)
* In LibreOffice Writer (version 24.8 and newer), when toggling text formatting (bold, italic, underline, subscript/superscript, alignment) using the corresponding keyboard shortcut, NVDA announces the new formatting attribute (e.g. "Bold on", "Bold off"). (#4248, @michaelweghorn)
* Opening the settings dialog a second time with a keyboard shortcut now opens the expected settings panel. (#12995)

### Changes for Developers

Expand Down