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

Closed
Closed
3 changes: 3 additions & 0 deletions source/gui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from . import guiHelper
from .settingsDialogs import (
SettingsDialog,
MultiCategorySettingsDialog,
DefaultDictionaryDialog,
VoiceDictionaryDialog,
TemporaryDictionaryDialog,
Expand Down Expand Up @@ -152,6 +153,8 @@ def _popupSettingsDialog(self, dialog, *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
53 changes: 39 additions & 14 deletions source/gui/settingsDialogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
import vision
import vision.providerInfo
import vision.providerBase
from typing import Callable, List, Optional, Any
from typing import Callable, List, Optional, Any, Union
import core
import keyboardHandler
import characterProcessing
Expand Down Expand Up @@ -425,23 +425,16 @@ class MultiCategorySettingsDialog(SettingsDialog):

class CategoryUnavailableError(RuntimeError): pass

def __init__(self, parent, initialCategory=None):
def __init__(
self,
parent: Union[wx.Window, None],
CyrilleB79 marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -552,6 +545,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: Union[SettingsPanel, None]) -> 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 @@ -624,6 +636,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