Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
28 changes: 18 additions & 10 deletions source/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,23 @@ def _setInitialFocus():
except:
log.exception("Error retrieving initial focus")


def getWxLang(lang):
Comment thread
seanbudd marked this conversation as resolved.
Outdated
import wx
locale = wx.Locale()
wxLang = locale.FindLanguageInfo(lang)
if not wxLang and '_' in lang:
wxLang = locale.FindLanguageInfo(lang.split('_')[0])
# #8064: Wx might know the language, but may not actually contain a translation database for that language.
# If we try to initialize this language, wx will show a warning dialog.
# #9089: some languages (such as Aragonese) do not have language info, causing language getter to fail.
# In this case, wxLang is already set to None.
# Therefore treat these situations like wx not knowing the language at all.
if wxLang and not locale.IsAvailable(wxLang.Language):
Comment thread
feerrenrut marked this conversation as resolved.
wxLang = None
return wxLang


def main():
"""NVDA's core main loop.
This initializes all modules such as audio, IAccessible, keyboard, mouse, and GUI.
Expand Down Expand Up @@ -419,18 +436,9 @@ def handlePowerStatusChange(self):
# initialize wxpython localization support
locale = wx.Locale()
lang=languageHandler.getLanguage()
Comment thread
feerrenrut marked this conversation as resolved.
Outdated
wxLang=locale.FindLanguageInfo(lang)
if not wxLang and '_' in lang:
wxLang=locale.FindLanguageInfo(lang.split('_')[0])
wxLang = getWxLang(lang)
if hasattr(sys,'frozen'):
locale.AddCatalogLookupPathPrefix(os.path.join(globalVars.appDir, "locale"))
# #8064: Wx might know the language, but may not actually contain a translation database for that language.
# If we try to initialize this language, wx will show a warning dialog.
# #9089: some languages (such as Aragonese) do not have language info, causing language getter to fail.
# In this case, wxLang is already set to None.
# Therefore treat these situations like wx not knowing the language at all.
if wxLang and not locale.IsAvailable(wxLang.Language):
wxLang=None
if wxLang:
try:
locale.Init(wxLang.Language)
Expand Down
24 changes: 12 additions & 12 deletions source/gui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,8 @@ def initialize():
if mainFrame:
raise RuntimeError("GUI already initialized")
mainFrame = MainFrame()
wxLang = core.getWxLang(languageHandler.getLanguage())
mainFrame.SetLayoutDirection(wxLang.LayoutDirection)
Comment thread
feerrenrut marked this conversation as resolved.
Outdated
wx.GetApp().SetTopWindow(mainFrame)
# In wxPython >= 4.1,
# wx.CallAfter no longer executes callbacks while NVDA's main thread is within apopup menu or message box.
Expand Down Expand Up @@ -725,14 +727,10 @@ def __init__(self, parent):
welcomeTextDetail = wx.StaticText(self, wx.ID_ANY, self.WELCOME_MESSAGE_DETAIL)
mainSizer.Add(welcomeTextDetail,border=20,flag=wx.EXPAND|wx.LEFT|wx.RIGHT)

optionsSizer = wx.StaticBoxSizer(
wx.StaticBox(
self,
# Translators: The label for a group box containing the NVDA welcome dialog options.
label=_("Options")
),
wx.VERTICAL
)
# Translators: The label for a group box containing the NVDA welcome dialog options.
optionsLabel = _("Options")
optionsSizer = wx.StaticBoxSizer(wx.VERTICAL, self, label=optionsLabel)
optionsBox = optionsSizer.GetStaticBox()
sHelper = guiHelper.BoxSizerHelper(self, sizer=optionsSizer)
# Translators: The label of a combobox in the Welcome dialog.
kbdLabelText = _("&Keyboard layout:")
Expand All @@ -747,17 +745,18 @@ def __init__(self, parent):
log.error("Could not set Keyboard layout list to current layout",exc_info=True)
# Translators: The label of a checkbox in the Welcome dialog.
capsAsNVDAModifierText = _("&Use CapsLock as an NVDA modifier key")
self.capsAsNVDAModifierCheckBox = sHelper.addItem(wx.CheckBox(self, label=capsAsNVDAModifierText))
self.capsAsNVDAModifierCheckBox = sHelper.addItem(wx.CheckBox(optionsBox, label=capsAsNVDAModifierText))
self.capsAsNVDAModifierCheckBox.SetValue(config.conf["keyboard"]["useCapsLockAsNVDAModifierKey"])
# Translators: The label of a checkbox in the Welcome dialog.
startAfterLogonText = _("St&art NVDA after I sign in")
self.startAfterLogonCheckBox = sHelper.addItem(wx.CheckBox(self, label=startAfterLogonText))
self.startAfterLogonCheckBox = sHelper.addItem(wx.CheckBox(optionsBox, label=startAfterLogonText))
self.startAfterLogonCheckBox.Value = config.getStartAfterLogon()
if globalVars.appArgs.secure or config.isAppX or not config.isInstalledCopy():
self.startAfterLogonCheckBox.Disable()
# Translators: The label of a checkbox in the Welcome dialog.
showWelcomeDialogAtStartupText = _("&Show this dialog when NVDA starts")
self.showWelcomeDialogAtStartupCheckBox = sHelper.addItem(wx.CheckBox(self, label=showWelcomeDialogAtStartupText))
_showWelcomeDialogAtStartupCheckBox = wx.CheckBox(optionsBox, label=showWelcomeDialogAtStartupText)
self.showWelcomeDialogAtStartupCheckBox = sHelper.addItem(_showWelcomeDialogAtStartupCheckBox)
self.showWelcomeDialogAtStartupCheckBox.SetValue(config.conf["general"]["showWelcomeDialogAtStartup"])
mainSizer.Add(optionsSizer, border=guiHelper.BORDER_FOR_DIALOGS, flag=wx.ALL)
mainSizer.Add(self.CreateButtonSizer(wx.OK), border=guiHelper.BORDER_FOR_DIALOGS, flag=wx.ALL|wx.ALIGN_RIGHT)
Expand Down Expand Up @@ -810,7 +809,8 @@ def __init__(self, parent):

# Translators: The label of the license text which will be shown when NVDA installation program starts.
groupLabel = _("License Agreement")
sizer = sHelper.addItem(wx.StaticBoxSizer(wx.StaticBox(self, label=groupLabel), wx.VERTICAL))
sizer = wx.StaticBoxSizer(wx.VERTICAL, self, label=groupLabel)
sHelper.addItem(sizer)
licenseTextCtrl = wx.TextCtrl(self, size=(500, 400), style=wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_RICH)
licenseTextCtrl.Value = codecs.open(getDocFilePath("copying.txt", False), "r", encoding="UTF-8").read()
sizer.Add(licenseTextCtrl)
Expand Down
17 changes: 10 additions & 7 deletions source/gui/configProfiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,24 @@ def __init__(self, parent):

mainSizer = wx.BoxSizer(wx.VERTICAL)
sHelper = guiHelper.BoxSizerHelper(self,orientation=wx.VERTICAL)
profilesListGroupSizer = wx.StaticBoxSizer(wx.StaticBox(self), wx.HORIZONTAL)
profilesListGroupSizer = wx.StaticBoxSizer(wx.HORIZONTAL, self)
profilesListBox = profilesListGroupSizer.GetStaticBox()
profilesListGroupContents = wx.BoxSizer(wx.HORIZONTAL)

#contains the profile list and activation button in vertical arrangement.
changeProfilesSizer = wx.BoxSizer(wx.VERTICAL)
item = self.profileList = wx.ListBox(self,
choices=[self.getProfileDisplay(name, includeStates=True) for name in self.profileNames])
item = self.profileList = wx.ListBox(
profilesListBox,
choices=[self.getProfileDisplay(name, includeStates=True) for name in self.profileNames]
)
self.bindHelpEvent("ProfilesBasicManagement", self.profileList)
item.Bind(wx.EVT_LISTBOX, self.onProfileListChoice)
item.Selection = self.profileNames.index(config.conf.profiles[-1].name)
changeProfilesSizer.Add(item, proportion=1.0)

changeProfilesSizer.AddSpacer(guiHelper.SPACE_BETWEEN_BUTTONS_VERTICAL)

self.changeStateButton = wx.Button(self)
self.changeStateButton = wx.Button(profilesListBox)
self.bindHelpEvent("ConfigProfileManual", self.changeStateButton)
self.changeStateButton.Bind(wx.EVT_BUTTON, self.onChangeState)
self.AffirmativeId = self.changeStateButton.Id
Expand All @@ -68,17 +71,17 @@ def __init__(self, parent):

buttonHelper = guiHelper.ButtonHelper(wx.VERTICAL)
# Translators: The label of a button to create a new configuration profile.
newButton = buttonHelper.addButton(self, label=_("&New"))
newButton = buttonHelper.addButton(profilesListBox, label=_("&New"))
self.bindHelpEvent("ProfilesCreating", newButton)
newButton.Bind(wx.EVT_BUTTON, self.onNew)

# Translators: The label of a button to rename a configuration profile.
self.renameButton = buttonHelper.addButton(self, label=_("&Rename"))
self.renameButton = buttonHelper.addButton(profilesListBox, label=_("&Rename"))
self.bindHelpEvent("ProfilesBasicManagement", self.renameButton)
self.renameButton.Bind(wx.EVT_BUTTON, self.onRename)

# Translators: The label of a button to delete a configuration profile.
self.deleteButton = buttonHelper.addButton(self, label=_("&Delete"))
self.deleteButton = buttonHelper.addButton(profilesListBox, label=_("&Delete"))
self.bindHelpEvent("ProfilesBasicManagement", self.deleteButton)
self.deleteButton.Bind(wx.EVT_BUTTON, self.onDelete)

Expand Down
13 changes: 9 additions & 4 deletions source/gui/guiHelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,10 @@ def addLabeledControl(self, labelText, wxCtrlClass, **kwargs):
Relies on guiHelper.LabeledControlHelper and thus guiHelper.associateElements, and therefore inherits any
limitations from there.
"""
labeledControl = LabeledControlHelper(self._parent, labelText, wxCtrlClass, **kwargs)
parent = self._parent
if isinstance(self.sizer, wx.StaticBoxSizer):
parent = self.sizer.GetStaticBox()
labeledControl = LabeledControlHelper(parent, labelText, wxCtrlClass, **kwargs)
if(isinstance(labeledControl.control, (wx.ListCtrl,wx.ListBox,wx.TreeCtrl))):
self.addItem(labeledControl.sizer, flag=wx.EXPAND, proportion=1)
else:
Expand All @@ -345,6 +348,9 @@ def addDialogDismissButtons(self, buttons, separated=False):
Should be set to L{False} for message or single input dialogs, L{True} otherwise.
@type separated: L{bool}
"""
parent = self._parent
if isinstance(self.sizer, wx.StaticBoxSizer):
parent = self.sizer.GetStaticBox()
if self.sizer.GetOrientation() != wx.VERTICAL:
raise NotImplementedError(
"Adding dialog dismiss buttons to a horizontal BoxSizerHelper is not implemented."
Expand All @@ -354,16 +360,15 @@ def addDialogDismissButtons(self, buttons, separated=False):
elif isinstance(buttons, (wx.Sizer, wx.Button)):
toAdd = buttons
elif isinstance(buttons, int):
toAdd = self._parent.CreateButtonSizer(buttons)
toAdd = parent.CreateButtonSizer(buttons)
else:
raise NotImplementedError("Unknown type: {}".format(buttons))
if separated:
self.addItem(wx.StaticLine(self._parent), flag=wx.EXPAND)
self.addItem(wx.StaticLine(parent), flag=wx.EXPAND)
self.addItem(toAdd, flag=wx.ALIGN_RIGHT)
self.dialogDismissButtonsAdded = True
return buttons

class SIPABCMeta(wx.siplib.wrappertype, ABCMeta):
"""Meta class to be used for wx subclasses with abstract methods."""
pass

45 changes: 24 additions & 21 deletions source/gui/installerGui.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,18 +175,15 @@ def __init__(self, parent, isUpdate):
self.bindHelpEvent("InstallWithIncompatibleAddons", self.confirmationCheckbox)
self.confirmationCheckbox.SetFocus()

optionsSizer = guiHelper.BoxSizerHelper(self, sizer=sHelper.addItem(wx.StaticBoxSizer(
wx.StaticBox(
self,
# Translators: The label for a group box containing the NVDA installation dialog options.
label=_("Options")
),
wx.VERTICAL
)))
# Translators: The label for a group box containing the NVDA installation dialog options.
optionsLabel = _("Options")
optionsHelper = sHelper.addItem(wx.StaticBoxSizer(wx.VERTICAL, self, label=optionsLabel))
optionsSizer = guiHelper.BoxSizerHelper(self, sizer=optionsHelper)
optionsBox = optionsSizer.GetStaticBox()

# Translators: The label of a checkbox option in the Install NVDA dialog.
startOnLogonText = _("Use NVDA during sign-in")
self.startOnLogonCheckbox = optionsSizer.addItem(wx.CheckBox(self, label=startOnLogonText))
self.startOnLogonCheckbox = optionsSizer.addItem(wx.CheckBox(optionsBox, label=startOnLogonText))
self.bindHelpEvent("StartAtWindowsLogon", self.startOnLogonCheckbox)
if globalVars.appArgs.enableStartOnLogon is not None:
self.startOnLogonCheckbox.Value = globalVars.appArgs.enableStartOnLogon
Expand All @@ -197,19 +194,22 @@ def __init__(self, parent, isUpdate):
if self.isUpdate and shortcutIsPrevInstalled:
# Translators: The label of a checkbox option in the Install NVDA dialog.
keepShortCutText = _("&Keep existing desktop shortcut")
self.createDesktopShortcutCheckbox = optionsSizer.addItem(wx.CheckBox(self, label=keepShortCutText))
keepShortCutBox = wx.CheckBox(optionsBox, label=keepShortCutText)
self.createDesktopShortcutCheckbox = optionsSizer.addItem(keepShortCutBox)
else:
# Translators: The label of the option to create a desktop shortcut in the Install NVDA dialog.
# If the shortcut key has been changed for this locale,
# this change must also be reflected here.
createShortcutText = _("Create &desktop icon and shortcut key (control+alt+n)")
self.createDesktopShortcutCheckbox = optionsSizer.addItem(wx.CheckBox(self, label=createShortcutText))
createShortcutBox = wx.CheckBox(optionsBox, label=createShortcutText)
self.createDesktopShortcutCheckbox = optionsSizer.addItem(createShortcutBox)
self.bindHelpEvent("CreateDesktopShortcut", self.createDesktopShortcutCheckbox)
self.createDesktopShortcutCheckbox.Value = shortcutIsPrevInstalled if self.isUpdate else True

# Translators: The label of a checkbox option in the Install NVDA dialog.
createPortableText = _("Copy &portable configuration to current user account")
self.copyPortableConfigCheckbox = optionsSizer.addItem(wx.CheckBox(self, label=createPortableText))
createPortableBox = wx.CheckBox(optionsBox, label=createPortableText)
self.copyPortableConfigCheckbox = optionsSizer.addItem(createPortableBox)
self.bindHelpEvent("CopyPortableConfigurationToCurrentUserAccount", self.copyPortableConfigCheckbox)
self.copyPortableConfigCheckbox.Value = bool(globalVars.appArgs.copyPortableConfig)
if globalVars.appArgs.copyPortableConfig is None:
Expand All @@ -220,12 +220,12 @@ def __init__(self, parent, isUpdate):
bHelper = sHelper.addDialogDismissButtons(guiHelper.ButtonHelper(wx.HORIZONTAL))
if shouldAskAboutAddons:
# Translators: The label of a button to launch the add-on compatibility review dialog.
reviewAddonButton = bHelper.addButton(self, label=_("&Review add-ons..."))
reviewAddonButton = bHelper.addButton(optionsBox, label=_("&Review add-ons..."))
self.bindHelpEvent("InstallWithIncompatibleAddons", reviewAddonButton)
reviewAddonButton.Bind(wx.EVT_BUTTON, self.onReviewAddons)

# Translators: The label of a button to continue with the operation.
continueButton = bHelper.addButton(self, label=_("&Continue"), id=wx.ID_OK)
continueButton = bHelper.addButton(optionsBox, label=_("&Continue"), id=wx.ID_OK)
continueButton.SetDefault()
continueButton.Bind(wx.EVT_BUTTON, self.onInstall)
if shouldAskAboutAddons:
Expand All @@ -235,7 +235,7 @@ def __init__(self, parent, isUpdate):
)
continueButton.Enable(False)

bHelper.addButton(self, id=wx.ID_CANCEL)
bHelper.addButton(optionsBox, id=wx.ID_CANCEL)
# If we bind this using button.Bind, it fails to trigger when the dialog is closed.
self.Bind(wx.EVT_BUTTON, self.onCancel, id=wx.ID_CANCEL)

Expand Down Expand Up @@ -349,35 +349,38 @@ def __init__(self, parent):
# Translators: The label of a grouping containing controls to select the destination directory
# in the Create Portable NVDA dialog.
directoryGroupText = _("Portable &directory:")
groupHelper = sHelper.addItem(gui.guiHelper.BoxSizerHelper(self, sizer=wx.StaticBoxSizer(wx.StaticBox(self, label=directoryGroupText), wx.VERTICAL)))
groupSizer = wx.StaticBoxSizer(wx.VERTICAL, self, label=directoryGroupText)
groupHelper = sHelper.addItem(gui.guiHelper.BoxSizerHelper(self, sizer=groupSizer))
groupBox = groupSizer.GetStaticBox()
# Translators: The label of a button to browse for a directory.
browseText = _("Browse...")
# Translators: The title of the dialog presented when browsing for the
# destination directory when creating a portable copy of NVDA.
dirDialogTitle = _("Select portable directory")
directoryEntryControl = groupHelper.addItem(gui.guiHelper.PathSelectionHelper(self, browseText, dirDialogTitle))
directoryPathHelper = gui.guiHelper.PathSelectionHelper(groupBox, browseText, dirDialogTitle)
directoryEntryControl = groupHelper.addItem(directoryPathHelper)
self.portableDirectoryEdit = directoryEntryControl.pathControl
if globalVars.appArgs.portablePath:
self.portableDirectoryEdit.Value = globalVars.appArgs.portablePath

# Translators: The label of a checkbox option in the Create Portable NVDA dialog.
copyConfText = _("Copy current &user configuration")
self.copyUserConfigCheckbox = sHelper.addItem(wx.CheckBox(self, label=copyConfText))
self.copyUserConfigCheckbox = sHelper.addItem(wx.CheckBox(groupBox, label=copyConfText))
self.copyUserConfigCheckbox.Value = False
if globalVars.appArgs.launcher:
self.copyUserConfigCheckbox.Disable()
# Translators: The label of a checkbox option in the Create Portable NVDA dialog.
startAfterCreateText = _("&Start the new portable copy after creation")
self.startAfterCreateCheckbox = sHelper.addItem(wx.CheckBox(self, label=startAfterCreateText))
self.startAfterCreateCheckbox = sHelper.addItem(wx.CheckBox(groupBox, label=startAfterCreateText))
self.startAfterCreateCheckbox.Value = False

bHelper = sHelper.addDialogDismissButtons(gui.guiHelper.ButtonHelper(wx.HORIZONTAL), separated=True)

continueButton = bHelper.addButton(self, label=_("&Continue"), id=wx.ID_OK)
continueButton = bHelper.addButton(groupBox, label=_("&Continue"), id=wx.ID_OK)
continueButton.SetDefault()
continueButton.Bind(wx.EVT_BUTTON, self.onCreatePortable)

bHelper.addButton(self, id=wx.ID_CANCEL)
bHelper.addButton(groupBox, id=wx.ID_CANCEL)
# If we bind this using button.Bind, it fails to trigger when the dialog is closed.
self.Bind(wx.EVT_BUTTON, self.onCancel, id=wx.ID_CANCEL)

Expand Down
Loading