plover 5.0.0.dev3__py3-none-any.whl → 5.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. plover/__init__.py +1 -1
  2. plover/dictionary/loading_manager.py +22 -5
  3. plover/engine.py +11 -11
  4. plover/exception.py +0 -12
  5. plover/gui_qt/about_dialog_ui.py +1 -1
  6. plover/gui_qt/add_translation_dialog_ui.py +1 -1
  7. plover/gui_qt/add_translation_widget_ui.py +1 -1
  8. plover/gui_qt/config_file_widget_ui.py +1 -1
  9. plover/gui_qt/config_keyboard_widget_ui.py +1 -1
  10. plover/gui_qt/config_plover_hid_widget_ui.py +110 -0
  11. plover/gui_qt/config_serial_widget_ui.py +1 -1
  12. plover/gui_qt/config_window_ui.py +1 -1
  13. plover/gui_qt/console_widget_ui.py +1 -1
  14. plover/gui_qt/dictionaries_widget.py +9 -0
  15. plover/gui_qt/dictionaries_widget_ui.py +1 -1
  16. plover/gui_qt/dictionary_editor_ui.py +1 -1
  17. plover/gui_qt/engine.py +6 -1
  18. plover/gui_qt/lookup_dialog_ui.py +1 -1
  19. plover/gui_qt/machine_options.py +53 -1
  20. plover/gui_qt/main_window_ui.py +1 -1
  21. plover/gui_qt/paper_tape_ui.py +1 -1
  22. plover/gui_qt/plugins_manager_ui.py +1 -1
  23. plover/gui_qt/resources_rc.py +29 -29
  24. plover/gui_qt/run_dialog_ui.py +1 -1
  25. plover/gui_qt/suggestions_dialog_ui.py +1 -1
  26. plover/machine/plover_hid.py +312 -0
  27. plover/machine/procat.py +1 -1
  28. plover/oslayer/linux/keyboardcontrol_uinput.py +137 -37
  29. plover/oslayer/osx/keyboardlayout.py +4 -1
  30. plover/oslayer/windows/log.py +28 -6
  31. plover/system/english_stenotype.py +53 -0
  32. {plover-5.0.0.dev3.dist-info → plover-5.1.0.dist-info}/METADATA +2 -1
  33. {plover-5.0.0.dev3.dist-info → plover-5.1.0.dist-info}/RECORD +43 -40
  34. {plover-5.0.0.dev3.dist-info → plover-5.1.0.dist-info}/entry_points.txt +5 -3
  35. {plover-5.0.0.dev3.dist-info → plover-5.1.0.dist-info}/licenses/LICENSE.txt +4 -5
  36. plover_build_utils/deps.sh +2 -0
  37. plover_build_utils/download.py +5 -2
  38. plover_build_utils/functions.sh +80 -17
  39. /plover/machine/{geminipr.py → gemini_pr.py} +0 -0
  40. /plover/machine/{txbolt.py → tx_bolt.py} +0 -0
  41. {plover-5.0.0.dev3.dist-info → plover-5.1.0.dist-info}/WHEEL +0 -0
  42. {plover-5.0.0.dev3.dist-info → plover-5.1.0.dist-info}/top_level.txt +0 -0
  43. {plover-5.0.0.dev3.dist-info → plover-5.1.0.dist-info}/zip-safe +0 -0
plover/__init__.py CHANGED
@@ -13,7 +13,7 @@ else:
13
13
  # want to translate anyway.
14
14
  _ = lambda s: s
15
15
 
16
- __version__ = "5.0.0.dev3"
16
+ __version__ = "5.1.0"
17
17
  __copyright__ = "(C) Open Steno Project"
18
18
  __url__ = "http://www.openstenoproject.org/"
19
19
  __download_url__ = "http://www.openstenoproject.org/plover"
@@ -7,13 +7,19 @@ import threading
7
7
  import time
8
8
 
9
9
  from plover.dictionary.base import load_dictionary
10
- from plover.exception import DictionaryLoaderException
11
10
  from plover.resource import resource_timestamp
12
11
  from plover import log
13
12
 
14
13
 
15
14
  class DictionaryLoadingManager:
16
- def __init__(self):
15
+ def __init__(self, state_change_callback):
16
+ """
17
+ Parameters:
18
+ state_change_callback -- A function that will be called when any dictionary is loaded
19
+ with two parameters: the filename and the loaded StenoDictionary object
20
+ (or an instance of ErroredDictionary if the load fails).
21
+ """
22
+ self._state_change_callback = state_change_callback
17
23
  self.dictionaries = {}
18
24
 
19
25
  def __len__(self):
@@ -32,7 +38,7 @@ class DictionaryLoadingManager:
32
38
  log.info(
33
39
  "%s dictionary: %s", "loading" if op is None else "reloading", filename
34
40
  )
35
- op = DictionaryLoadingOperation(filename)
41
+ op = DictionaryLoadingOperation(filename, self._state_change_callback)
36
42
  self.dictionaries[filename] = op
37
43
  return op
38
44
 
@@ -52,7 +58,15 @@ class DictionaryLoadingManager:
52
58
 
53
59
 
54
60
  class DictionaryLoadingOperation:
55
- def __init__(self, filename):
61
+ def __init__(self, filename, state_change_callback):
62
+ """
63
+ Parameters:
64
+ filename -- Path to dictionary file.
65
+ state_change_callback -- A function that will be called when the load is finished
66
+ with two parameters: the filename and the loaded StenoDictionary object
67
+ (or an instance of ErroredDictionary if the load fails).
68
+ """
69
+ self._state_change_callback = state_change_callback
56
70
  self.loading_thread = threading.Thread(target=self.load)
57
71
  self.filename = filename
58
72
  self.result = None
@@ -87,8 +101,11 @@ class DictionaryLoadingOperation:
87
101
  self.result = load_dictionary(self.filename)
88
102
  except Exception as e:
89
103
  log.debug("loading dictionary %s failed", self.filename, exc_info=True)
90
- self.result = DictionaryLoaderException(self.filename, e)
104
+ from plover.engine import ErroredDictionary
105
+
106
+ self.result = ErroredDictionary(self.filename, e)
91
107
  self.result.timestamp = timestamp
108
+ self._state_change_callback(self.filename, self.result)
92
109
 
93
110
  def get(self):
94
111
  self.loading_thread.join()
plover/engine.py CHANGED
@@ -1,13 +1,13 @@
1
1
  from collections import namedtuple, OrderedDict
2
2
  from functools import wraps
3
3
  from queue import Queue
4
+ import functools
4
5
  import os
5
6
  import shutil
6
7
  import threading
7
8
 
8
9
  from plover import log, system
9
10
  from plover.dictionary.loading_manager import DictionaryLoadingManager
10
- from plover.exception import DictionaryLoaderException
11
11
  from plover.formatting import Formatter
12
12
  from plover.misc import shorten_path
13
13
  from plover.registry import registry
@@ -83,6 +83,7 @@ class StenoEngine:
83
83
  output_changed
84
84
  config_changed
85
85
  dictionaries_loaded
86
+ dictionary_state_changed
86
87
  send_string
87
88
  send_backspaces
88
89
  send_key_combination
@@ -116,8 +117,10 @@ class StenoEngine:
116
117
  self._translator = Translator()
117
118
  self._translator.add_listener(log.translation)
118
119
  self._translator.add_listener(self._formatter.format)
119
- self._dictionaries = self._translator.get_dictionary()
120
- self._dictionaries_manager = DictionaryLoadingManager()
120
+ self._dictionaries = self._translator.get_dictionary() # type: StenoDictionaryCollection
121
+ self._dictionaries_manager = DictionaryLoadingManager(
122
+ functools.partial(self._trigger_hook, "dictionary_state_changed")
123
+ )
121
124
  self._running_state = self._translator.get_state()
122
125
  self._translator.clear_state()
123
126
  self._keyboard_emulation = keyboard_emulation
@@ -282,18 +285,15 @@ class StenoEngine:
282
285
  )
283
286
  # And then (re)load all dictionaries.
284
287
  dictionaries = []
285
- for result in self._dictionaries_manager.load(config_dictionaries.keys()):
286
- if isinstance(result, DictionaryLoaderException):
287
- d = ErroredDictionary(result.path, result.exception)
288
+ for d in self._dictionaries_manager.load(config_dictionaries.keys()):
289
+ if isinstance(d, ErroredDictionary):
288
290
  # Only show an error if it's new.
289
- if d != self._dictionaries.get(result.path):
291
+ if d != self._dictionaries.get(d.path):
290
292
  log.error(
291
293
  "loading dictionary `%s` failed: %s",
292
- shorten_path(result.path),
293
- str(result.exception),
294
+ shorten_path(d.path),
295
+ str(d.exception),
294
296
  )
295
- else:
296
- d = result
297
297
  d.enabled = config_dictionaries[d.path].enabled
298
298
  dictionaries.append(d)
299
299
  self._set_dictionaries(dictionaries)
plover/exception.py CHANGED
@@ -13,15 +13,3 @@ class InvalidConfigurationError(Exception):
13
13
  "Raised when there is something wrong in the configuration."
14
14
 
15
15
  pass
16
-
17
-
18
- class DictionaryLoaderException(Exception):
19
- """Dictionary file could not be loaded."""
20
-
21
- def __init__(self, path, exception):
22
- super().__init__(path, exception)
23
- self.path = path
24
- self.exception = exception
25
-
26
- def __str__(self):
27
- return "loading dictionary `%s` failed: %s" % (self.path, self.exception)
@@ -4,7 +4,7 @@ _ = __import__(__package__.split(".", 1)[0])._
4
4
  ################################################################################
5
5
  ## Form generated from reading UI file 'about_dialog.ui'
6
6
  ##
7
- ## Created by: Qt User Interface Compiler version 6.9.1
7
+ ## Created by: Qt User Interface Compiler version 6.10.0
8
8
  ##
9
9
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
10
10
  ################################################################################
@@ -4,7 +4,7 @@ _ = __import__(__package__.split(".", 1)[0])._
4
4
  ################################################################################
5
5
  ## Form generated from reading UI file 'add_translation_dialog.ui'
6
6
  ##
7
- ## Created by: Qt User Interface Compiler version 6.9.1
7
+ ## Created by: Qt User Interface Compiler version 6.10.0
8
8
  ##
9
9
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
10
10
  ################################################################################
@@ -4,7 +4,7 @@ _ = __import__(__package__.split(".", 1)[0])._
4
4
  ################################################################################
5
5
  ## Form generated from reading UI file 'add_translation_widget.ui'
6
6
  ##
7
- ## Created by: Qt User Interface Compiler version 6.9.1
7
+ ## Created by: Qt User Interface Compiler version 6.10.0
8
8
  ##
9
9
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
10
10
  ################################################################################
@@ -4,7 +4,7 @@ _ = __import__(__package__.split(".", 1)[0])._
4
4
  ################################################################################
5
5
  ## Form generated from reading UI file 'config_file_widget.ui'
6
6
  ##
7
- ## Created by: Qt User Interface Compiler version 6.9.1
7
+ ## Created by: Qt User Interface Compiler version 6.10.0
8
8
  ##
9
9
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
10
10
  ################################################################################
@@ -4,7 +4,7 @@ _ = __import__(__package__.split(".", 1)[0])._
4
4
  ################################################################################
5
5
  ## Form generated from reading UI file 'config_keyboard_widget.ui'
6
6
  ##
7
- ## Created by: Qt User Interface Compiler version 6.9.1
7
+ ## Created by: Qt User Interface Compiler version 6.10.0
8
8
  ##
9
9
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
10
10
  ################################################################################
@@ -0,0 +1,110 @@
1
+ # -*- coding: utf-8 -*-
2
+ _ = __import__(__package__.split(".", 1)[0])._
3
+
4
+ ################################################################################
5
+ ## Form generated from reading UI file 'config_plover_hid_widget.ui'
6
+ ##
7
+ ## Created by: Qt User Interface Compiler version 6.10.0
8
+ ##
9
+ ## WARNING! All changes made in this file will be lost when recompiling UI file!
10
+ ################################################################################
11
+
12
+ from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
13
+ QMetaObject, QObject, QPoint, QRect,
14
+ QSize, QTime, QUrl, Qt)
15
+ from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
16
+ QFont, QFontDatabase, QGradient, QIcon,
17
+ QImage, QKeySequence, QLinearGradient, QPainter,
18
+ QPalette, QPixmap, QRadialGradient, QTransform)
19
+ from PySide6.QtWidgets import (QApplication, QCheckBox, QGridLayout, QLabel,
20
+ QLineEdit, QSizePolicy, QWidget)
21
+
22
+ class Ui_PloverHidWidget(object):
23
+ def setupUi(self, PloverHidWidget):
24
+ if not PloverHidWidget.objectName():
25
+ PloverHidWidget.setObjectName(u"PloverHidWidget")
26
+ PloverHidWidget.resize(260, 140)
27
+ PloverHidWidget.setWindowTitle(u"")
28
+ self.gridLayout = QGridLayout(PloverHidWidget)
29
+ self.gridLayout.setObjectName(u"gridLayout")
30
+ self.first_up_chord_send = QCheckBox(PloverHidWidget)
31
+ self.first_up_chord_send.setObjectName(u"first_up_chord_send")
32
+
33
+ self.gridLayout.addWidget(self.first_up_chord_send, 0, 0, 1, 2)
34
+
35
+ self.double_tap_repeat = QCheckBox(PloverHidWidget)
36
+ self.double_tap_repeat.setObjectName(u"double_tap_repeat")
37
+
38
+ self.gridLayout.addWidget(self.double_tap_repeat, 1, 0, 1, 2)
39
+
40
+ self.label_repeat_delay_ms = QLabel(PloverHidWidget)
41
+ self.label_repeat_delay_ms.setObjectName(u"label_repeat_delay_ms")
42
+
43
+ self.gridLayout.addWidget(self.label_repeat_delay_ms, 2, 0, 1, 1)
44
+
45
+ self.repeat_delay_ms = QLineEdit(PloverHidWidget)
46
+ self.repeat_delay_ms.setObjectName(u"repeat_delay_ms")
47
+
48
+ self.gridLayout.addWidget(self.repeat_delay_ms, 2, 1, 1, 1)
49
+
50
+ self.label_repeat_interval_ms = QLabel(PloverHidWidget)
51
+ self.label_repeat_interval_ms.setObjectName(u"label_repeat_interval_ms")
52
+
53
+ self.gridLayout.addWidget(self.label_repeat_interval_ms, 3, 0, 1, 1)
54
+
55
+ self.repeat_interval_ms = QLineEdit(PloverHidWidget)
56
+ self.repeat_interval_ms.setObjectName(u"repeat_interval_ms")
57
+
58
+ self.gridLayout.addWidget(self.repeat_interval_ms, 3, 1, 1, 1)
59
+
60
+ self.label_device_scan_interval_ms = QLabel(PloverHidWidget)
61
+ self.label_device_scan_interval_ms.setObjectName(u"label_device_scan_interval_ms")
62
+
63
+ self.gridLayout.addWidget(self.label_device_scan_interval_ms, 4, 0, 1, 1)
64
+
65
+ self.device_scan_interval_ms = QLineEdit(PloverHidWidget)
66
+ self.device_scan_interval_ms.setObjectName(u"device_scan_interval_ms")
67
+
68
+ self.gridLayout.addWidget(self.device_scan_interval_ms, 4, 1, 1, 1)
69
+
70
+ #if QT_CONFIG(shortcut)
71
+ self.label_repeat_delay_ms.setBuddy(self.repeat_delay_ms)
72
+ self.label_repeat_interval_ms.setBuddy(self.repeat_interval_ms)
73
+ self.label_device_scan_interval_ms.setBuddy(self.device_scan_interval_ms)
74
+ #endif // QT_CONFIG(shortcut)
75
+
76
+ self.retranslateUi(PloverHidWidget)
77
+ self.first_up_chord_send.clicked["bool"].connect(PloverHidWidget.update_first_up_chord_send)
78
+ self.double_tap_repeat.clicked["bool"].connect(PloverHidWidget.update_double_tap_repeat)
79
+ self.repeat_delay_ms.textChanged.connect(PloverHidWidget.update_repeat_delay_ms)
80
+ self.repeat_interval_ms.textChanged.connect(PloverHidWidget.update_repeat_interval_ms)
81
+ self.device_scan_interval_ms.textChanged.connect(PloverHidWidget.update_device_scan_interval_ms)
82
+
83
+ QMetaObject.connectSlotsByName(PloverHidWidget)
84
+ # setupUi
85
+
86
+ def retranslateUi(self, PloverHidWidget):
87
+ #if QT_CONFIG(tooltip)
88
+ self.first_up_chord_send.setToolTip(QCoreApplication.translate("PloverHidWidget", u"When the first key in a chord is released, the chord is sent.\n"
89
+ "If the key is pressed and released again, another chord is sent.", None))
90
+ #endif // QT_CONFIG(tooltip)
91
+ self.first_up_chord_send.setText(QCoreApplication.translate("PloverHidWidget", u"Send chord on first key release", None))
92
+ #if QT_CONFIG(tooltip)
93
+ self.double_tap_repeat.setToolTip(QCoreApplication.translate("PloverHidWidget", u"Tap and then hold a chord to send it repeatedly.", None))
94
+ #endif // QT_CONFIG(tooltip)
95
+ self.double_tap_repeat.setText(QCoreApplication.translate("PloverHidWidget", u"Double tap to repeat", None))
96
+ self.label_repeat_delay_ms.setText(QCoreApplication.translate("PloverHidWidget", u"Repeat delay (ms)", None))
97
+ #if QT_CONFIG(tooltip)
98
+ self.repeat_delay_ms.setToolTip(QCoreApplication.translate("PloverHidWidget", u"Delay before chord starts repeating.", None))
99
+ #endif // QT_CONFIG(tooltip)
100
+ self.label_repeat_interval_ms.setText(QCoreApplication.translate("PloverHidWidget", u"Repeat interval (ms)", None))
101
+ #if QT_CONFIG(tooltip)
102
+ self.repeat_interval_ms.setToolTip(QCoreApplication.translate("PloverHidWidget", u"Interval between chord repetitions.", None))
103
+ #endif // QT_CONFIG(tooltip)
104
+ self.label_device_scan_interval_ms.setText(QCoreApplication.translate("PloverHidWidget", u"Device scan interval (ms)", None))
105
+ #if QT_CONFIG(tooltip)
106
+ self.device_scan_interval_ms.setToolTip(QCoreApplication.translate("PloverHidWidget", u"How often to scan for newly plugged-in devices.", None))
107
+ #endif // QT_CONFIG(tooltip)
108
+ pass
109
+ # retranslateUi
110
+
@@ -4,7 +4,7 @@ _ = __import__(__package__.split(".", 1)[0])._
4
4
  ################################################################################
5
5
  ## Form generated from reading UI file 'config_serial_widget.ui'
6
6
  ##
7
- ## Created by: Qt User Interface Compiler version 6.9.1
7
+ ## Created by: Qt User Interface Compiler version 6.10.0
8
8
  ##
9
9
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
10
10
  ################################################################################
@@ -4,7 +4,7 @@ _ = __import__(__package__.split(".", 1)[0])._
4
4
  ################################################################################
5
5
  ## Form generated from reading UI file 'config_window.ui'
6
6
  ##
7
- ## Created by: Qt User Interface Compiler version 6.9.1
7
+ ## Created by: Qt User Interface Compiler version 6.10.0
8
8
  ##
9
9
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
10
10
  ################################################################################
@@ -4,7 +4,7 @@ _ = __import__(__package__.split(".", 1)[0])._
4
4
  ################################################################################
5
5
  ## Form generated from reading UI file 'console_widget.ui'
6
6
  ##
7
- ## Created by: Qt User Interface Compiler version 6.9.1
7
+ ## Created by: Qt User Interface Compiler version 6.10.0
8
8
  ##
9
9
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
10
10
  ################################################################################
@@ -132,6 +132,9 @@ class DictionariesModel(QAbstractListModel):
132
132
  config = engine.config
133
133
  engine.signal_connect("config_changed", self._on_config_changed)
134
134
  engine.signal_connect("dictionaries_loaded", self._on_dictionaries_loaded)
135
+ engine.signal_connect(
136
+ "dictionary_state_changed", self._on_dictionary_state_changed
137
+ )
135
138
  self._reset_items(
136
139
  config["dictionaries"],
137
140
  config["classic_dictionaries_display_order"],
@@ -248,6 +251,12 @@ class DictionariesModel(QAbstractListModel):
248
251
  updated_rows.update(self._update_favorite())
249
252
  self._updated_rows(updated_rows)
250
253
 
254
+ def _on_dictionary_state_changed(self, filename, d):
255
+ [item] = [item for item in self._from_row if item.path == filename]
256
+ if item.loaded != d:
257
+ item.loaded = d
258
+ self._updated_rows([item.row])
259
+
251
260
  def _move(self, index_list, step):
252
261
  row_list = sorted(self._normalized_row_list(index_list))
253
262
  if not row_list:
@@ -4,7 +4,7 @@ _ = __import__(__package__.split(".", 1)[0])._
4
4
  ################################################################################
5
5
  ## Form generated from reading UI file 'dictionaries_widget.ui'
6
6
  ##
7
- ## Created by: Qt User Interface Compiler version 6.9.1
7
+ ## Created by: Qt User Interface Compiler version 6.10.0
8
8
  ##
9
9
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
10
10
  ################################################################################
@@ -4,7 +4,7 @@ _ = __import__(__package__.split(".", 1)[0])._
4
4
  ################################################################################
5
5
  ## Form generated from reading UI file 'dictionary_editor.ui'
6
6
  ##
7
- ## Created by: Qt User Interface Compiler version 6.9.1
7
+ ## Created by: Qt User Interface Compiler version 6.10.0
8
8
  ##
9
9
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
10
10
  ################################################################################
plover/gui_qt/engine.py CHANGED
@@ -14,7 +14,12 @@ class Engine(StenoEngine, QThread):
14
14
  signal_machine_state_changed = Signal(str, str)
15
15
  signal_output_changed = Signal(bool)
16
16
  signal_config_changed = Signal(object)
17
- signal_dictionaries_loaded = Signal(object)
17
+ signal_dictionary_state_changed = Signal(
18
+ str, object
19
+ ) # Some dictionary has finished loading. Refer to class DictionaryLoadingManager for argument description.
20
+ signal_dictionaries_loaded = Signal(
21
+ object
22
+ ) # All dictionaries are loaded. Argument is a StenoDictionaryCollection instance.
18
23
  signal_send_string = Signal(str)
19
24
  signal_send_backspaces = Signal(int)
20
25
  signal_send_key_combination = Signal(str)
@@ -4,7 +4,7 @@ _ = __import__(__package__.split(".", 1)[0])._
4
4
  ################################################################################
5
5
  ## Form generated from reading UI file 'lookup_dialog.ui'
6
6
  ##
7
- ## Created by: Qt User Interface Compiler version 6.9.1
7
+ ## Created by: Qt User Interface Compiler version 6.10.0
8
8
  ##
9
9
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
10
10
  ################################################################################
@@ -3,6 +3,7 @@ from pathlib import Path
3
3
 
4
4
  from PySide6.QtCore import Qt, Signal, Slot
5
5
  from PySide6.QtGui import (
6
+ QIntValidator,
6
7
  QTextCharFormat,
7
8
  QTextFrameFormat,
8
9
  QTextListFormat,
@@ -11,8 +12,8 @@ from PySide6.QtGui import (
11
12
  )
12
13
  from PySide6.QtWidgets import (
13
14
  QGroupBox,
14
- QStyledItemDelegate,
15
15
  QStyle,
16
+ QStyledItemDelegate,
16
17
  QToolTip,
17
18
  )
18
19
 
@@ -24,6 +25,7 @@ from plover.oslayer.serial import patch_ports_info
24
25
 
25
26
  from plover.gui_qt.config_keyboard_widget_ui import Ui_KeyboardWidget
26
27
  from plover.gui_qt.config_serial_widget_ui import Ui_SerialWidget
28
+ from plover.gui_qt.config_plover_hid_widget_ui import Ui_PloverHidWidget
27
29
 
28
30
 
29
31
  def serial_port_details(port_info):
@@ -234,3 +236,53 @@ class KeyboardOption(QGroupBox, Ui_KeyboardWidget):
234
236
  def update_first_up_chord_send(self, value):
235
237
  self._value["first_up_chord_send"] = value
236
238
  self.valueChanged.emit(self._value)
239
+
240
+
241
+ class PloverHidOption(QGroupBox, Ui_PloverHidWidget):
242
+ valueChanged = Signal(object)
243
+
244
+ def __init__(self):
245
+ super().__init__()
246
+ self.setupUi(self)
247
+ self._value = {}
248
+ self.repeat_delay_ms.setValidator(QIntValidator(10, 10000, self))
249
+ self.repeat_interval_ms.setValidator(QIntValidator(10, 10000, self))
250
+ self.device_scan_interval_ms.setValidator(QIntValidator(250, 100000, self))
251
+
252
+ def setValue(self, value):
253
+ self._value = copy(value)
254
+ self.first_up_chord_send.setChecked(value["first_up_chord_send"])
255
+ self.double_tap_repeat.setChecked(value["double_tap_repeat"])
256
+ self.repeat_delay_ms.setText(str(value["repeat_delay_ms"]))
257
+ self.repeat_interval_ms.setText(str(value["repeat_interval_ms"]))
258
+ self.device_scan_interval_ms.setText(
259
+ str(value.get("device_scan_interval_ms", 1000))
260
+ )
261
+
262
+ @Slot(bool)
263
+ def update_first_up_chord_send(self, value):
264
+ self._value["first_up_chord_send"] = value
265
+ self.valueChanged.emit(self._value)
266
+
267
+ @Slot(bool)
268
+ def update_double_tap_repeat(self, value):
269
+ self._value["double_tap_repeat"] = value
270
+ self.valueChanged.emit(self._value)
271
+
272
+ @Slot(str)
273
+ def update_repeat_delay_ms(self, text):
274
+ if text.isdigit():
275
+ self._value["repeat_delay_ms"] = int(text)
276
+ self.valueChanged.emit(self._value)
277
+
278
+ @Slot(str)
279
+ def update_repeat_interval_ms(self, text):
280
+ if text.isdigit():
281
+ self._value["repeat_interval_ms"] = int(text)
282
+ self.valueChanged.emit(self._value)
283
+
284
+ @Slot(str)
285
+ def update_device_scan_interval_ms(self, text):
286
+ if text.isdigit():
287
+ self._value["device_scan_interval_ms"] = int(text)
288
+ self.valueChanged.emit(self._value)
@@ -4,7 +4,7 @@ _ = __import__(__package__.split(".", 1)[0])._
4
4
  ################################################################################
5
5
  ## Form generated from reading UI file 'main_window.ui'
6
6
  ##
7
- ## Created by: Qt User Interface Compiler version 6.9.1
7
+ ## Created by: Qt User Interface Compiler version 6.10.0
8
8
  ##
9
9
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
10
10
  ################################################################################
@@ -4,7 +4,7 @@ _ = __import__(__package__.split(".", 1)[0])._
4
4
  ################################################################################
5
5
  ## Form generated from reading UI file 'paper_tape.ui'
6
6
  ##
7
- ## Created by: Qt User Interface Compiler version 6.9.1
7
+ ## Created by: Qt User Interface Compiler version 6.10.0
8
8
  ##
9
9
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
10
10
  ################################################################################
@@ -4,7 +4,7 @@ _ = __import__(__package__.split(".", 1)[0])._
4
4
  ################################################################################
5
5
  ## Form generated from reading UI file 'plugins_manager.ui'
6
6
  ##
7
- ## Created by: Qt User Interface Compiler version 6.9.1
7
+ ## Created by: Qt User Interface Compiler version 6.10.0
8
8
  ##
9
9
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
10
10
  ################################################################################
@@ -1,6 +1,6 @@
1
1
  # Resource object code (Python 3)
2
2
  # Created by: object code
3
- # Created by: The Resource Compiler for Qt version 6.9.1
3
+ # Created by: The Resource Compiler for Qt version 6.10.0
4
4
  # WARNING! All changes made in this file will be lost!
5
5
 
6
6
  from PySide6 import QtCore
@@ -2853,61 +2853,61 @@ qt_resource_struct = b"\
2853
2853
  \x00\x00\x00\x00\x00\x02\x00\x00\x00\x1c\x00\x00\x00\x02\
2854
2854
  \x00\x00\x00\x00\x00\x00\x00\x00\
2855
2855
  \x00\x00\x01\x84\x00\x00\x00\x00\x00\x01\x00\x00:\x0b\
2856
- \x00\x00\x01\x98\x07\x8f\x01\x0b\
2856
+ \x00\x00\x01\x9aM\x95\xe1N\
2857
2857
  \x00\x00\x00\xcc\x00\x00\x00\x00\x00\x01\x00\x00\x0d\xac\
2858
- \x00\x00\x01\x98\x07\x8f\x01\x0b\
2858
+ \x00\x00\x01\x9aM\x95\xe1N\
2859
2859
  \x00\x00\x03H\x00\x00\x00\x00\x00\x01\x00\x00\x9aw\
2860
- \x00\x00\x01\x98\x07\x8f\x01\x0c\
2860
+ \x00\x00\x01\x9aM\x95\xe1N\
2861
2861
  \x00\x00\x01\x1c\x00\x00\x00\x00\x00\x01\x00\x00\x1a\xf6\
2862
- \x00\x00\x01\x98\x07\x8f\x01\x0b\
2862
+ \x00\x00\x01\x9aM\x95\xe1N\
2863
2863
  \x00\x00\x00X\x00\x00\x00\x00\x00\x01\x00\x00\x04*\
2864
- \x00\x00\x01\x98\x07\x8f\x01\x0c\
2864
+ \x00\x00\x01\x9aM\x95\xe1N\
2865
2865
  \x00\x00\x00.\x00\x00\x00\x00\x00\x01\x00\x00\x01\x06\
2866
- \x00\x00\x01\x98\x07\x8f\x01\x0c\
2866
+ \x00\x00\x01\x9aM\x95\xe1N\
2867
2867
  \x00\x00\x03.\x00\x00\x00\x00\x00\x01\x00\x00\x98\xcc\
2868
- \x00\x00\x01\x98\x07\x8f\x01\x0c\
2868
+ \x00\x00\x01\x9aM\x95\xe1N\
2869
2869
  \x00\x00\x00\x18\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
2870
- \x00\x00\x01\x98\x07\x8f\x01\x0b\
2870
+ \x00\x00\x01\x9aM\x95\xe1M\
2871
2871
  \x00\x00\x03\x00\x00\x00\x00\x00\x00\x01\x00\x00\x93:\
2872
- \x00\x00\x01\x98\x07\x8f\x01\x0b\
2872
+ \x00\x00\x01\x9aM\x95\xe1M\
2873
2873
  \x00\x00\x01p\x00\x00\x00\x00\x00\x01\x00\x0072\
2874
- \x00\x00\x01\x98\x07\x8f\x01\x0b\
2874
+ \x00\x00\x01\x9aM\x95\xe1N\
2875
2875
  \x00\x00\x01\xee\x00\x00\x00\x00\x00\x01\x00\x00E\x9b\
2876
- \x00\x00\x01\x98\x07\x8f\x01\x0b\
2876
+ \x00\x00\x01\x9aM\x95\xe1M\
2877
2877
  \x00\x00\x00\xa0\x00\x00\x00\x00\x00\x01\x00\x00\x0bW\
2878
- \x00\x00\x01\x98\x07\x8f\x01\x0c\
2878
+ \x00\x00\x01\x9aM\x95\xe1N\
2879
2879
  \x00\x00\x01H\x00\x00\x00\x00\x00\x01\x00\x00%i\
2880
- \x00\x00\x01\x98\x07\x8f\x01\x0b\
2880
+ \x00\x00\x01\x9aM\x95\xe1N\
2881
2881
  \x00\x00\x03p\x00\x00\x00\x00\x00\x01\x00\x00\x9b\xd6\
2882
- \x00\x00\x01\x98\x07\x8f\x01\x0c\
2882
+ \x00\x00\x01\x9aM\x95\xe1N\
2883
2883
  \x00\x00\x00\x8a\x00\x00\x00\x00\x00\x01\x00\x00\x06\xc2\
2884
- \x00\x00\x01\x98\x07\x8f\x01\x0c\
2884
+ \x00\x00\x01\x9aM\x95\xe1N\
2885
2885
  \x00\x00\x01\x04\x00\x00\x00\x00\x00\x01\x00\x00\x16:\
2886
- \x00\x00\x01\x98\x07\x8f\x01\x0c\
2886
+ \x00\x00\x01\x9aM\x95\xe1N\
2887
2887
  \x00\x00\x03\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x9f\xae\
2888
- \x00\x00\x01\x98\x07\x8f\x01\x0c\
2888
+ \x00\x00\x01\x9aM\x95\xe1N\
2889
2889
  \x00\x00\x01\xa4\x00\x00\x00\x00\x00\x01\x00\x00?\xd7\
2890
- \x00\x00\x01\x98\x07\x8f\x01\x0b\
2890
+ \x00\x00\x01\x9aM\x95\xe1N\
2891
2891
  \x00\x00\x02F\x00\x00\x00\x00\x00\x01\x00\x00si\
2892
- \x00\x00\x01\x98\x07\x8f\x01\x0b\
2892
+ \x00\x00\x01\x9aM\x95\xe1M\
2893
2893
  \x00\x00\x01\xbe\x00\x00\x00\x00\x00\x01\x00\x00C\x93\
2894
- \x00\x00\x01\x98\x07\x8f\x01\x0b\
2894
+ \x00\x00\x01\x9aM\x95\xe1M\
2895
2895
  \x00\x00\x00\xb2\x00\x00\x00\x00\x00\x01\x00\x00\x0c]\
2896
- \x00\x00\x01\x98\x07\x8f\x01\x0b\
2896
+ \x00\x00\x01\x9aM\x95\xe1M\
2897
2897
  \x00\x00\x02z\x00\x00\x00\x00\x00\x01\x00\x00{\x0c\
2898
- \x00\x00\x01\x98\x07\x8f\x01\x0b\
2898
+ \x00\x00\x01\x9aM\x95\xe1N\
2899
2899
  \x00\x00\x02\xcc\x00\x00\x00\x00\x00\x01\x00\x00\x8c^\
2900
- \x00\x00\x01\x98\x07\x8f\x01\x0b\
2900
+ \x00\x00\x01\x9aM\x95\xe1M\
2901
2901
  \x00\x00\x02\x1c\x00\x00\x00\x00\x00\x01\x00\x00p\xec\
2902
- \x00\x00\x01\x98\x07\x8f\x01\x0c\
2902
+ \x00\x00\x01\x9aM\x95\xe1N\
2903
2903
  \x00\x00\x00\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x10\xac\
2904
- \x00\x00\x01\x98\x07\x8f\x01\x0c\
2904
+ \x00\x00\x01\x9aM\x95\xe1N\
2905
2905
  \x00\x00\x02\x02\x00\x00\x00\x00\x00\x01\x00\x00F\xd9\
2906
- \x00\x00\x01\x98\x07\x8f\x01\x0b\
2906
+ \x00\x00\x01\x9aM\x95\xe1N\
2907
2907
  \x00\x00\x00D\x00\x00\x00\x00\x00\x01\x00\x00\x02Y\
2908
- \x00\x00\x01\x98\x07\x8f\x01\x0b\
2908
+ \x00\x00\x01\x9aM\x95\xe1N\
2909
2909
  \x00\x00\x02\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x7f#\
2910
- \x00\x00\x01\x98\x07\x8f\x01\x0b\
2910
+ \x00\x00\x01\x9aM\x95\xe1M\
2911
2911
  "
2912
2912
 
2913
2913
  def qInitResources():
@@ -4,7 +4,7 @@ _ = __import__(__package__.split(".", 1)[0])._
4
4
  ################################################################################
5
5
  ## Form generated from reading UI file 'run_dialog.ui'
6
6
  ##
7
- ## Created by: Qt User Interface Compiler version 6.9.1
7
+ ## Created by: Qt User Interface Compiler version 6.10.0
8
8
  ##
9
9
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
10
10
  ################################################################################
@@ -4,7 +4,7 @@ _ = __import__(__package__.split(".", 1)[0])._
4
4
  ################################################################################
5
5
  ## Form generated from reading UI file 'suggestions_dialog.ui'
6
6
  ##
7
- ## Created by: Qt User Interface Compiler version 6.9.1
7
+ ## Created by: Qt User Interface Compiler version 6.10.0
8
8
  ##
9
9
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
10
10
  ################################################################################