|
46 | 46 | import gui.contextHelp |
47 | 47 | import globalVars |
48 | 48 | from logHandler import log |
| 49 | +from remoteClient import configuration |
49 | 50 | import nvwave |
50 | 51 | import audio |
51 | 52 | import audioDucking |
@@ -3345,6 +3346,159 @@ def onSave(self): |
3345 | 3346 | config.conf["addonStore"]["automaticUpdates"] = [x.value for x in AddonsAutomaticUpdate][index] |
3346 | 3347 |
|
3347 | 3348 |
|
| 3349 | +class RemoteSettingsPanel(SettingsPanel): |
| 3350 | + # Translators: This is the label for the remote settings category in NVDA Settings screen. |
| 3351 | + title = _("Remote") |
| 3352 | + autoconnect: wx.CheckBox |
| 3353 | + client_or_server: wx.RadioBox |
| 3354 | + connection_type: wx.RadioBox |
| 3355 | + host: wx.TextCtrl |
| 3356 | + port: wx.SpinCtrl |
| 3357 | + key: wx.TextCtrl |
| 3358 | + play_sounds: wx.CheckBox |
| 3359 | + delete_fingerprints: wx.Button |
| 3360 | + |
| 3361 | + def makeSettings(self, settingsSizer): |
| 3362 | + self.config = configuration.get_config() |
| 3363 | + sHelper = gui.guiHelper.BoxSizerHelper(self, sizer=settingsSizer) |
| 3364 | + self.autoconnect = wx.CheckBox( |
| 3365 | + parent=self, |
| 3366 | + id=wx.ID_ANY, |
| 3367 | + # Translators: A checkbox in add-on options dialog to set whether NVDA should automatically connect to a control server on startup. |
| 3368 | + label=_("Auto-connect to control server on startup"), |
| 3369 | + ) |
| 3370 | + self.autoconnect.Bind(wx.EVT_CHECKBOX, self.on_autoconnect) |
| 3371 | + sHelper.addItem(self.autoconnect) |
| 3372 | + # Translators: Whether or not to use a relay server when autoconnecting |
| 3373 | + self.client_or_server = wx.RadioBox( |
| 3374 | + self, |
| 3375 | + wx.ID_ANY, |
| 3376 | + choices=( |
| 3377 | + # Translators: Use a remote control server |
| 3378 | + _("Use Remote Control Server"), |
| 3379 | + # Translators: Host a control server |
| 3380 | + _("Host Control Server"), |
| 3381 | + ), |
| 3382 | + style=wx.RA_VERTICAL, |
| 3383 | + ) |
| 3384 | + self.client_or_server.Bind(wx.EVT_RADIOBOX, self.on_client_or_server) |
| 3385 | + self.client_or_server.SetSelection(0) |
| 3386 | + self.client_or_server.Enable(False) |
| 3387 | + sHelper.addItem(self.client_or_server) |
| 3388 | + choices = [ |
| 3389 | + # Translators: Radio button to allow this machine to be controlled |
| 3390 | + _("Allow this machine to be controlled"), |
| 3391 | + # Translators: Radio button to allow this machine to control another machine |
| 3392 | + _("Control another machine"), |
| 3393 | + ] |
| 3394 | + self.connection_type = wx.RadioBox(self, wx.ID_ANY, choices=choices, style=wx.RA_VERTICAL) |
| 3395 | + self.connection_type.SetSelection(0) |
| 3396 | + self.connection_type.Enable(False) |
| 3397 | + sHelper.addItem(self.connection_type) |
| 3398 | + sHelper.addItem(wx.StaticText(self, wx.ID_ANY, label=_("&Host:"))) |
| 3399 | + self.host = wx.TextCtrl(self, wx.ID_ANY) |
| 3400 | + self.host.Enable(False) |
| 3401 | + sHelper.addItem(self.host) |
| 3402 | + sHelper.addItem(wx.StaticText(self, wx.ID_ANY, label=_("&Port:"))) |
| 3403 | + self.port = wx.SpinCtrl(self, wx.ID_ANY, min=1, max=65535) |
| 3404 | + self.port.Enable(False) |
| 3405 | + sHelper.addItem(self.port) |
| 3406 | + sHelper.addItem(wx.StaticText(self, wx.ID_ANY, label=_("&Key:"))) |
| 3407 | + self.key = wx.TextCtrl(self, wx.ID_ANY) |
| 3408 | + self.key.Enable(False) |
| 3409 | + sHelper.addItem(self.key) |
| 3410 | + # Translators: A checkbox in add-on options dialog to set whether sounds play instead of beeps. |
| 3411 | + self.play_sounds = wx.CheckBox(self, wx.ID_ANY, label=_("Play sounds instead of beeps")) |
| 3412 | + sHelper.addItem(self.play_sounds) |
| 3413 | + # Translators: A button in add-on options dialog to delete all fingerprints of unauthorized certificates. |
| 3414 | + self.delete_fingerprints = wx.Button(self, wx.ID_ANY, label=_("Delete all trusted fingerprints")) |
| 3415 | + self.delete_fingerprints.Bind(wx.EVT_BUTTON, self.on_delete_fingerprints) |
| 3416 | + sHelper.addItem(self.delete_fingerprints) |
| 3417 | + self.set_from_config() |
| 3418 | + |
| 3419 | + def on_autoconnect(self, evt: wx.CommandEvent) -> None: |
| 3420 | + self.set_controls() |
| 3421 | + |
| 3422 | + def set_controls(self) -> None: |
| 3423 | + state = bool(self.autoconnect.GetValue()) |
| 3424 | + self.client_or_server.Enable(state) |
| 3425 | + self.connection_type.Enable(state) |
| 3426 | + self.key.Enable(state) |
| 3427 | + self.host.Enable(not bool(self.client_or_server.GetSelection()) and state) |
| 3428 | + self.port.Enable(bool(self.client_or_server.GetSelection()) and state) |
| 3429 | + |
| 3430 | + def on_client_or_server(self, evt: wx.CommandEvent) -> None: |
| 3431 | + evt.Skip() |
| 3432 | + self.set_controls() |
| 3433 | + |
| 3434 | + def set_from_config(self) -> None: |
| 3435 | + cs = self.config["controlserver"] |
| 3436 | + self_hosted = cs["self_hosted"] |
| 3437 | + connection_type = cs["connection_type"] |
| 3438 | + self.autoconnect.SetValue(cs["autoconnect"]) |
| 3439 | + self.client_or_server.SetSelection(int(self_hosted)) |
| 3440 | + self.connection_type.SetSelection(connection_type) |
| 3441 | + self.host.SetValue(cs["host"]) |
| 3442 | + self.port.SetValue(str(cs["port"])) |
| 3443 | + self.key.SetValue(cs["key"]) |
| 3444 | + self.set_controls() |
| 3445 | + self.play_sounds.SetValue(self.config["ui"]["play_sounds"]) |
| 3446 | + |
| 3447 | + def on_delete_fingerprints(self, evt: wx.CommandEvent) -> None: |
| 3448 | + if ( |
| 3449 | + gui.messageBox( |
| 3450 | + _( |
| 3451 | + # Translators: This message is presented when the user tries to delete all stored trusted fingerprints. |
| 3452 | + "When connecting to an unauthorized server, you will again be prompted to accepts its certificate.", |
| 3453 | + ), |
| 3454 | + # Translators: This is the title of the dialog presented when the user tries to delete all stored trusted fingerprints. |
| 3455 | + _("Are you sure you want to delete all stored trusted fingerprints?"), |
| 3456 | + wx.YES | wx.NO | wx.NO_DEFAULT | wx.ICON_WARNING, |
| 3457 | + ) |
| 3458 | + == wx.YES |
| 3459 | + ): |
| 3460 | + self.config["trusted_certs"].clear() |
| 3461 | + evt.Skip() |
| 3462 | + |
| 3463 | + def isValid(self) -> bool: |
| 3464 | + if self.autoconnect.GetValue(): |
| 3465 | + if not self.client_or_server.GetSelection() and ( |
| 3466 | + not self.host.GetValue() or not self.key.GetValue() |
| 3467 | + ): |
| 3468 | + gui.messageBox( |
| 3469 | + # Translators: This message is presented when the user tries to save the settings with the host or key field empty. |
| 3470 | + _("Both host and key must be set in the Remote section."), |
| 3471 | + # Translators: This is the title of the dialog presented when the user tries to save the settings with the host or key field empty. |
| 3472 | + _("Remote Error"), |
| 3473 | + wx.OK | wx.ICON_ERROR, |
| 3474 | + ) |
| 3475 | + return False |
| 3476 | + elif self.client_or_server.GetSelection() and not self.port.GetValue() or not self.key.GetValue(): |
| 3477 | + gui.messageBox( |
| 3478 | + # Translators: This message is presented when the user tries to save the settings with the port or key field empty. |
| 3479 | + _("Both port and key must be set in the Remote section."), |
| 3480 | + # Translators: This is the title of the dialog presented when the user tries to save the settings with the port or key field empty. |
| 3481 | + _("Remote Error"), |
| 3482 | + wx.OK | wx.ICON_ERROR, |
| 3483 | + ) |
| 3484 | + return False |
| 3485 | + return True |
| 3486 | + |
| 3487 | + def onSave(self): |
| 3488 | + cs = self.config["controlserver"] |
| 3489 | + cs["autoconnect"] = self.autoconnect.GetValue() |
| 3490 | + self_hosted = bool(self.client_or_server.GetSelection()) |
| 3491 | + connection_type = self.connection_type.GetSelection() |
| 3492 | + cs["self_hosted"] = self_hosted |
| 3493 | + cs["connection_type"] = connection_type |
| 3494 | + if not self_hosted: |
| 3495 | + cs["host"] = self.host.GetValue() |
| 3496 | + else: |
| 3497 | + cs["port"] = int(self.port.GetValue()) |
| 3498 | + cs["key"] = self.key.GetValue() |
| 3499 | + self.config["ui"]["play_sounds"] = self.play_sounds.GetValue() |
| 3500 | + |
| 3501 | + |
3348 | 3502 | class TouchInteractionPanel(SettingsPanel): |
3349 | 3503 | # Translators: This is the label for the touch interaction settings panel. |
3350 | 3504 | title = _("Touch Interaction") |
@@ -5212,6 +5366,8 @@ class NVDASettingsDialog(MultiCategorySettingsDialog): |
5212 | 5366 | DocumentNavigationPanel, |
5213 | 5367 | AddonStorePanel, |
5214 | 5368 | ] |
| 5369 | + if not globalVars.appArgs.secure: |
| 5370 | + categoryClasses.append(RemoteSettingsPanel) |
5215 | 5371 | if touchHandler.touchSupported(): |
5216 | 5372 | categoryClasses.append(TouchInteractionPanel) |
5217 | 5373 | if winVersion.isUwpOcrAvailable(): |
|
0 commit comments