plover2cat 4.0.0a1__py3-none-any.whl → 4.0.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plover2cat
3
- Version: 4.0.0a1
3
+ Version: 4.0.2
4
4
  Summary: A CAT software for Plover
5
5
  Home-page: https://github.com/greenwyrt/plover2CAT/
6
6
  Author: plants
@@ -19,7 +19,8 @@ Classifier: Programming Language :: Python :: 3.10
19
19
  Description-Content-Type: text/markdown
20
20
  License-File: LICENSE.txt
21
21
  Requires-Dist: plover>=5.0.0.dev2
22
- Requires-Dist: PySide6-Addons>=6.9.0
22
+ Requires-Dist: PySide6-Essentials>=6.10.0
23
+ Requires-Dist: PySide6-Addons>=6.10.0
23
24
  Requires-Dist: odfpy
24
25
  Requires-Dist: pyparsing>3.0.7
25
26
  Requires-Dist: spylls
@@ -29,8 +30,6 @@ Dynamic: license-file
29
30
 
30
31
  # plover2CAT
31
32
 
32
- Note: In line with the new Plover 5 release, Plover2CAT is releasing 4.0.0-alpha, which should retain all existing functionalities and is installable on Plover 5 by Github. All issues can be reported here or in Discord.
33
-
34
33
  Plover2CAT is a plugin for Plover, the open-source stenography engine. If the only user requirement is to write steno on the computer, this plugin is not needed as Plover is more than sufficient. Plover2CAT supplements Plover by providing some features of a computer-aided-transcription (CAT) program.
35
34
 
36
35
  ## Features Overview
@@ -55,7 +54,7 @@ Plover2CAT is a plugin for Plover, the open-source stenography engine. If the on
55
54
  - timestamped paper tape
56
55
  - creation and loading of transcript-specific dictionaries for each transcript
57
56
 
58
- - audiovisual synchonization and recording
57
+ - media (audio/video) synchonization and recording
59
58
 
60
59
  - captioning features such as:
61
60
  - separate window to display captions
@@ -0,0 +1,42 @@
1
+ plover2cat-4.0.2.dist-info/licenses/LICENSE.txt,sha256=nmGAW0AJG4ke0VT1kvbz6m_jBMcnRRcJQnBtJmKAKU0,1084
2
+ plover_cat/FlowLayout.py,sha256=3sCpVJCNJNwIimyFFlSOaNt-TNb-6kFwvlxwRI3QtNg,3707
3
+ plover_cat/PloverCATWindow.py,sha256=hQRmN6UY9i0jmj2qhCUwTo6gYnC_V-4rsE4AXULJfXA,157834
4
+ plover_cat/TextEditor.py,sha256=1YC2DMczfNMs_nzF0iBJ2TYRR4AgHU6fnZzFLMmIYlo,63269
5
+ plover_cat/__init__.py,sha256=Lq2ydZPCJhq4vEbiuNtFEoBM4i4vU8onupJY3N5r2do,964
6
+ plover_cat/__version__.py,sha256=45KtQfHIsnl8P4MO15r2HBP33RYIRoThY4TQan3SXgo,25
7
+ plover_cat/affixDialogWindow.py,sha256=p-SlQR7rDYeTWJeSwjT0RqqLUtvxgeWQUzA9HBLwSME,2729
8
+ plover_cat/affix_dialog_ui.py,sha256=R0aLLClSJiAFu6IALryqIwp_ZvHHDiVP146js2iEvIw,5666
9
+ plover_cat/captionDialogWindow.py,sha256=Zc3JqwaHasJF7FsmLH7hAEYDvbvbuKNihsXDIBqlZN0,2817
10
+ plover_cat/captionWorker.py,sha256=MFjoYnJ2pEeU9KalUlN0PmygVoOvKAdlc1LM8SPQRlw,8210
11
+ plover_cat/caption_dialog_ui.py,sha256=-IYGhZ8QyGQTEqsC2gXFvfpy0YX6BLvncZean4mWEXI,9726
12
+ plover_cat/constants.py,sha256=wDKCJPJuasBpHu6DsiOPW2dlRTWR1ayUYCjEEutQvKs,4933
13
+ plover_cat/create_dialog_ui.py,sha256=6RF0zDPmhO3nreLJtXy7qmSj0IAMaAFbCg8wr_Duye4,4388
14
+ plover_cat/documentWorker.py,sha256=VmgqscHSEjxIEOpdHSydTkOm9mg1zUc5Djkgkc4S1uA,33512
15
+ plover_cat/export_helpers.py,sha256=Tw2r8JroK3lbFpinmBuZKEpt7M1N9-USehwT-EHbXMQ,20116
16
+ plover_cat/fieldDialogWindow.py,sha256=DhVxHb5r1Hp_JUvEX9zicH695pG2RUQXol6PTOKsJjA,3134
17
+ plover_cat/field_dialog_ui.py,sha256=-lDA5-lXV8mtwjRBj7nwiu4F0l7tRtvbHrARrY9KOxw,5586
18
+ plover_cat/helpers.py,sha256=xImF2Rgj246TGotVfvW8jOJEdbo3IfqzwGnSb5mw87U,5582
19
+ plover_cat/indexDialogWindow.py,sha256=tx5dIAVKuEAMBsmudjb8G4le22ySEQ1blXe-WT_VyUA,5640
20
+ plover_cat/index_dialog_ui.py,sha256=zKm4XrS6tLE1noA5G3CnnQqKth5cwochjJmettSh7lY,8063
21
+ plover_cat/plover_cat_ui.py,sha256=it_ZMR1rNjM19Fx0lpSqt0X32BBFYUONUojpmY1xNis,159256
22
+ plover_cat/qcommands.py,sha256=5HGazgGS_KgOjowzEMpBiP4O5dQGYvKhc3GhlFjGjaM,39342
23
+ plover_cat/recorderDialogWindow.py,sha256=PqcM4kmg1ipNiNG3g97MWC5Wfaeu7wQqLxmZ9-6gf1I,2917
24
+ plover_cat/recorder_dialog_ui.py,sha256=ej6Mu54haTFlxBBLhUntiimLgINmJ67WkcoroZK04xQ,7782
25
+ plover_cat/resources_rc.py,sha256=prG98RZmEMVqs7NeA6JoJurYrDdqBDCsliI3KZ0Mpbk,126111
26
+ plover_cat/rtf_parsing.py,sha256=6p-9oH73vep4dG53tl9TDfNfoX0Ggv8KPeDXolXH5nY,21299
27
+ plover_cat/shortcutDialogWindow.py,sha256=8Tlk6v2-z6lyRdDR4Y7rquKxoqGL1UkCnYiKVHipgoQ,2453
28
+ plover_cat/shortcut_dialog_ui.py,sha256=BLr5BMPEdtmXXnJpJf83nKJLTgjmFQlx2SRcCJTNLz8,4504
29
+ plover_cat/spellcheck.py,sha256=r0dO34PGLpMbPypkFHE08jTrClGWen8C89BdmMidKVU,6695
30
+ plover_cat/steno_objects.py,sha256=JEEL3f5sXolLp3q68DMbJuvSsqiXWcoRFIlTHrq1qQY,42778
31
+ plover_cat/suggestDialogWindow.py,sha256=Oa2HSh9b8rsxjtcxgMFSqpNnwmPuYoLywIkYUL_19z0,6404
32
+ plover_cat/suggest_dialog_ui.py,sha256=65HVlhpI08Ke4MonXK2c4-kKsdsm-ML7oKPAW4me8xg,8783
33
+ plover_cat/tapeDialogWindow.py,sha256=yLzBLrJzj27MqOSYFiwR2nYzX7LLOkwLp-i6SApPL6A,4085
34
+ plover_cat/tape_dialog_ui.py,sha256=2t1gyuZ80j-G9dBb2a7V4uyi8j6OHWP45LlDXJZ9g_Q,4049
35
+ plover_cat/testDialogWindow.py,sha256=wqkk_6mGRcKlNHdVc3P_yTkt4x70MOtUZlLYU3RN0bM,21821
36
+ plover_cat/test_dialog_ui.py,sha256=P6joXflNVjhVkvY-pmgpQDqelQDRe_E92MqK1sBVwvc,4736
37
+ plover2cat-4.0.2.dist-info/METADATA,sha256=w6L8busygoyPRkuGna3mfFqXz7GUpmTzmW0HaT4pZ64,4900
38
+ plover2cat-4.0.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
39
+ plover2cat-4.0.2.dist-info/entry_points.txt,sha256=bZekpaOB8tv7DjkjuOBYrIdcMgCNuOYDrXKmV6Mgd1o,55
40
+ plover2cat-4.0.2.dist-info/top_level.txt,sha256=q7Rw-aE6ep8anwrqhiZOlCig80KhoV4bmE8yWiIlL4E,11
41
+ plover2cat-4.0.2.dist-info/zip-safe,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
42
+ plover2cat-4.0.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -9,32 +9,23 @@ from collections import Counter, deque
9
9
  from copy import deepcopy
10
10
  from sys import platform
11
11
  from tempfile import gettempdir, TemporaryDirectory
12
-
13
-
14
12
  from PySide6 import QtCore, QtGui, QtWidgets
15
- from PySide6.QtGui import (QBrush, QColor, QTextCursor, QFont, QFontMetrics, QTextDocument,
16
- QCursor, QStandardItem, QStandardItemModel, QPageSize, QTextBlock, QTextFormat, QTextBlockFormat,
17
- QTextOption, QTextCharFormat, QKeySequence, QPalette, QDesktopServices, QPixmap, QAction, QIcon)
13
+ from PySide6.QtGui import (QColor, QTextCursor, QFont, QFontMetrics, QTextDocument,
14
+ QStandardItem, QStandardItemModel, QPageSize,
15
+ QTextOption, QKeySequence, QPalette, QDesktopServices, QPixmap, QAction, QIcon)
18
16
  from PySide6.QtWidgets import (QMainWindow, QFileDialog, QInputDialog, QListWidgetItem, QTableWidgetItem,
19
- QStyle, QStyleFactory, QMessageBox, QDialog, QFontDialog, QColorDialog, QLabel, QMenu,
17
+ QMessageBox, QDialog, QFontDialog, QColorDialog, QLabel, QMenu,
20
18
  QCompleter, QApplication, QTextEdit, QPlainTextEdit, QProgressBar, QToolButton, QDockWidget)
21
19
  from PySide6.QtMultimedia import (QMediaPlayer, QMediaRecorder, QMediaFormat, QMediaDevices, QAudioInput)
22
20
  from PySide6.QtMultimediaWidgets import QVideoWidget
23
- from PySide6.QtCore import Qt, QFile, QTextStream, QUrl, QTime, QDateTime, QSettings, QRegularExpression, QSize, QStringListModel, QSizeF, QTimer, QThread
24
- _ = lambda txt: QtCore.QCoreApplication.translate("Plover2CAT", txt)
21
+ from PySide6.QtCore import Qt, QFile, QLocale, QUrl, QTime, QDateTime, QSettings, QRegularExpression, QSize, QStringListModel, QSizeF, QTimer, QThread
25
22
  from PySide6.QtTextToSpeech import QTextToSpeech
26
-
27
23
  import plover
28
-
29
- from plover.engine import StenoEngine
30
24
  from plover.steno import Stroke, normalize_steno, normalize_stroke
31
- from plover.dictionary.base import load_dictionary
32
25
  from plover.system.english_stenotype import DICTIONARIES_ROOT, ORTHOGRAPHY_WORDLIST
33
26
  from plover.system import _load_wordlist
34
27
  from plover import log
35
-
36
28
  from plover_cat.__version__ import __version__
37
-
38
29
  from plover_cat.plover_cat_ui import Ui_PloverCAT
39
30
  from plover_cat.TextEditor import PloverCATEditor
40
31
  from plover_cat.fieldDialogWindow import fieldDialogWindow
@@ -44,8 +35,8 @@ from plover_cat.indexDialogWindow import indexDialogWindow
44
35
  from plover_cat.suggestDialogWindow import suggestDialogWindow
45
36
  from plover_cat.captionDialogWindow import captionDialogWindow
46
37
  from plover_cat.recorderDialogWindow import recorderDialogWindow
38
+ from plover_cat.tapeDialogWindow import tapeDialogWindow
47
39
  from plover_cat.testDialogWindow import testDialogWindow
48
-
49
40
  from plover_cat.rtf_parsing import *
50
41
  from plover_cat.constants import *
51
42
  from plover_cat.qcommands import *
@@ -57,6 +48,8 @@ from plover_cat.FlowLayout import FlowLayout
57
48
  from plover_cat.documentWorker import documentWorker
58
49
  from plover_cat.captionWorker import captionWorker
59
50
 
51
+ _ = lambda txt: QtCore.QCoreApplication.translate("Plover2CAT", txt)
52
+
60
53
  scowl = _load_wordlist(ORTHOGRAPHY_WORDLIST, DICTIONARIES_ROOT)
61
54
 
62
55
  try:
@@ -92,6 +85,7 @@ class PloverCATWindow(QMainWindow, Ui_PloverCAT):
92
85
  :ivar textEdit: hold current transcript
93
86
  :ivar index_dialog: instance of ``indexDialogWindow``
94
87
  :ivar caption_dialog: instance of ``captionDialogWindow``
88
+ :ivar tape_dialog: instance of ``tapeDialogWindow``
95
89
  :ivar suggest_dialog: instance of ``suggestDialogWindow``
96
90
  :ivar cap_worker: instance of ``capWorker``
97
91
  :ivar autosave_time: autosave timer as ``QTimer``
@@ -152,6 +146,8 @@ class PloverCATWindow(QMainWindow, Ui_PloverCAT):
152
146
  self.index_dialog = indexDialogWindow({})
153
147
  self.caption_dialog = captionDialogWindow()
154
148
  self.suggest_dialog = suggestDialogWindow(None, self.engine, scowl)
149
+ self.tape_dialog = tapeDialogWindow()
150
+ self.tape_dialog.translate_stroke_from_tape.connect(self.tape_stroke_translate)
155
151
  self.cap_worker = None
156
152
  self.autosave_time = QTimer()
157
153
  self.cutcopy_storage = deque(maxlen = 5)
@@ -1529,7 +1525,7 @@ class PloverCATWindow(QMainWindow, Ui_PloverCAT):
1529
1525
  else:
1530
1526
  self.close_file()
1531
1527
  self.display_message("Closing window.")
1532
- self.parent().close()
1528
+ self.parent().done(1)
1533
1529
 
1534
1530
  def close_file(self, tab_index = None):
1535
1531
  """Close transcript tab, checking for changes.
@@ -1859,10 +1855,10 @@ class PloverCATWindow(QMainWindow, Ui_PloverCAT):
1859
1855
  return
1860
1856
  self.textEdit.log_to_tape(stroke)
1861
1857
 
1862
- def on_send_string(self, string):
1858
+ def on_send_string(self, txt_string):
1863
1859
  """Set string sent by Plover in transcript.
1864
1860
  """
1865
- self.textEdit.last_string_sent = string
1861
+ self.textEdit.last_string_sent = txt_string
1866
1862
 
1867
1863
  def count_backspaces(self, backspace):
1868
1864
  """Set number of backspaces sent by Plover in transcript.
@@ -1888,6 +1884,9 @@ class PloverCATWindow(QMainWindow, Ui_PloverCAT):
1888
1884
  self.display_captions()
1889
1885
  self.textEdit.on_stroke(stroke_pressed, self.actionCursorAtEnd.isChecked())
1890
1886
 
1887
+ def reconnect_keyboard(self):
1888
+ self.engine._keyboard_emulation = self.kc
1889
+
1891
1890
  def tape_translate(self):
1892
1891
  """Translate tape contents into transcript.
1893
1892
  """
@@ -1897,71 +1896,40 @@ class PloverCATWindow(QMainWindow, Ui_PloverCAT):
1897
1896
  self.engine.set_output(True)
1898
1897
  else:
1899
1898
  return
1900
- # do not erase any content before, case of too many asterisks for example
1901
1899
  self.engine.clear_translator_state()
1902
- # bit of a hack since triggering stroked hook through code
1903
- selected_file = QFileDialog.getOpenFileName(
1904
- self,
1905
- _("Select tape file to translate"),
1906
- str(self.textEdit.file_name), _("Tape (*.tape *.txt)"))[0]
1907
- if not selected_file:
1908
- return
1909
- transcript_dir = self.textEdit.file_name
1910
- if pathlib.Path(selected_file) == transcript_dir.joinpath(transcript_dir.stem).with_suffix(".tape"):
1911
- self.statusBar.showMessage("Cannot translate from own transcript tape.")
1912
- return
1913
- selected_file = pathlib.Path(selected_file)
1914
- paper_format, ok = QInputDialog.getItem(self, "Translate Tape", "Format of tape file:", ["Plover2CAT", "Plover (raw)", "Plover (paper)"], editable = False)
1915
- log.debug(f"Translating tape from {selected_file} with {paper_format} format.")
1916
- self.mainTabs.hide()
1917
- self.textEdit.blockSignals(True)
1918
- self.textEdit.document().blockSignals(True)
1919
1900
  self.kc = self.engine._keyboard_emulation
1920
1901
  self.engine._keyboard_emulation = mock_output()
1921
- count = 0
1922
- if paper_format == "Plover (raw)":
1923
- with open(selected_file) as f:
1924
- for line in f:
1925
- stroke = Stroke(normalize_stroke(line.strip().replace(" ", "")))
1926
- self.engine._translator.translate(stroke)
1927
- self.engine._trigger_hook('stroked', stroke)
1928
- count += 1
1929
- if count > 100:
1930
- self.textEdit.undo_stack.clear()
1931
- count = 0
1932
- elif paper_format == "Plover2CAT":
1933
- with open(selected_file) as f:
1934
- for line in f:
1935
- stroke_contents = line.strip().split("|")[3]
1936
- keys = []
1937
- for i in range(len(stroke_contents)):
1938
- if not stroke_contents[i].isspace() and i < len(plover.system.KEYS):
1939
- keys.append(plover.system.KEYS[i])
1940
- self.engine._translator.translate(Stroke(keys))
1941
- self.engine._trigger_hook('stroked', Stroke(keys))
1942
- count += 1
1943
- if count > 100:
1944
- self.textEdit.undo_stack.clear()
1945
- count = 0
1946
- elif paper_format == "Plover (paper)":
1947
- with open(selected_file) as f:
1948
- for line in f:
1949
- keys = []
1950
- for i in range(len(line)):
1951
- if not line[i].isspace() and i < len(plover.system.KEYS):
1952
- keys.append(plover.system.KEYS[i])
1953
- self.engine._translator.translate(Stroke(keys))
1954
- self.engine._trigger_hook('stroked', Stroke(keys))
1955
- count += 1
1956
- if count > 100:
1957
- self.textEdit.undo_stack.clear()
1958
- count = 0
1959
- self.textEdit.undo_stack.clear()
1902
+ self.tape_dialog.open()
1903
+ self.tape_dialog.finished.connect(self.reconnect_keyboard)
1904
+ # # do not erase any content before, case of too many asterisks for example
1905
+ # self.engine.clear_translator_state()
1906
+ # self.mainTabs.hide()
1907
+ # self.textEdit.blockSignals(True)
1908
+ # self.textEdit.document().blockSignals(True)
1909
+
1910
+ # self.textEdit.undo_stack.clear()
1911
+ # self.textEdit.document().blockSignals(False)
1912
+ # self.textEdit.blockSignals(False)
1913
+ # self.mainTabs.show()
1914
+ # self.engine._keyboard_emulation = self.kc
1915
+ # todo, if format has time data, that should be inserted into stroke data of editor too
1916
+
1917
+ def tape_stroke_translate(self, strokes = 1):
1918
+ if strokes > 50:
1919
+ self.mainTabs.hide()
1920
+ self.textEdit.blockSignals(True)
1921
+ self.textEdit.document().blockSignals(True)
1922
+ selected_row = self.tape_dialog.tape_view.currentIndex().row()
1923
+ for idx in range(selected_row, selected_row + strokes):
1924
+ if idx >= self.tape_dialog.tape_model.rowCount():
1925
+ break
1926
+ stroke_data = self.tape_dialog.tape_model.item(idx)
1927
+ print(stroke_data.data(Qt.UserRole))
1928
+ self.engine._translator.translate(Stroke(stroke_data.data(Qt.UserRole)))
1960
1929
  self.textEdit.document().blockSignals(False)
1961
1930
  self.textEdit.blockSignals(False)
1962
- self.mainTabs.show()
1963
- self.engine._keyboard_emulation = self.kc
1964
- # todo, if format has time data, that should be inserted into stroke data of editor too
1931
+ if strokes > 50:
1932
+ self.mainTabs.show()
1965
1933
 
1966
1934
  def reset_paragraph(self):
1967
1935
  """Remove all data from paragraph block, and erase action history.
@@ -2772,42 +2740,117 @@ class PloverCATWindow(QMainWindow, Ui_PloverCAT):
2772
2740
  self.textEdit.recorder.durationChanged.disconnect()
2773
2741
 
2774
2742
  def tts_synthesize(self):
2775
- pass
2743
+ """TTS synthesize from selection or cursor position"""
2744
+ self.tts_play.setEnabled(False)
2745
+ current_cursor = self.textEdit.textCursor()
2746
+ if current_cursor.hasSelection():
2747
+ document_text = current_cursor.selectedText()
2748
+ else:
2749
+ document_text = self.textEdit.toPlainText()
2750
+ document_text = document_text[current_cursor.position():]
2751
+ print(document_text)
2752
+ if document_text.strip():
2753
+ self.tts_instance.enqueue(document_text)
2754
+
2776
2755
 
2777
2756
  def tts_setup(self):
2757
+ """Set up TTS engine and connections"""
2778
2758
  self.tts_instance = QTextToSpeech(self)
2779
- for engine in QTextToSpeech.availableEngines():
2780
- if engine != "mock":
2781
- self.tts_engine.addItem(engine)
2782
- self.tts_engine.setCurrentIndex(0)
2783
- self.tts_instance.setEngine(self.tts_engine.currentText())
2759
+ self.tts_pop_engine()
2760
+ if self.tts_instance.engineCapabilities() & QTextToSpeech.Capability.PauseResume:
2761
+ self.tts_pause.setVisible(True)
2762
+ self.tts_resume.setVisible(True)
2763
+ else:
2764
+ self.tts_pause.setVisible(False)
2765
+ self.tts_resume.setVisible(False)
2784
2766
  self.tts_pitch.valueChanged.connect(self.tts_set_pitch)
2785
2767
  self.tts_volume.valueChanged.connect(self.tts_set_volume)
2786
2768
  self.tts_rate.valueChanged.connect(self.tts_set_rate)
2787
- self.tts_locale.currentIndexChanged.connect(self.tts_set_locale)
2788
- self.tts_voice.currentIndexChanged.connect(self.tts_set_voice)
2789
2769
  self.tts_engine.currentIndexChanged.connect(self.tts_set_engine)
2790
-
2791
- def tts_set_engine(self, index):
2792
- pass
2770
+ self.tts_locale.currentIndexChanged.connect(self.tts_set_locale)
2771
+ self.tts_voice.currentIndexChanged.connect(self.tts_set_voice)
2772
+ self.tts_play.clicked.connect(self.tts_synthesize)
2773
+ self.tts_stop.clicked.connect(self.tts_end)
2774
+ self.tts_pause.clicked.connect(lambda: self.tts_instance.pause())
2775
+ self.tts_resume.clicked.connect(lambda: self.tts_instance.resume())
2776
+ self.tts_instance.stateChanged.connect(self.tts_state_manage)
2777
+ self.tts_set_engine()
2778
+
2779
+ def tts_end(self):
2780
+ """Stop TTS playback"""
2781
+ self.tts_instance.stop()
2782
+ self.tts_play.setEnabled(True)
2783
+
2784
+ def tts_pop_engine(self, index=None):
2785
+ """Populate TTS engine choices"""
2786
+ self.tts_engine.blockSignals(True)
2787
+ self.tts_engine.clear()
2788
+ for engine in QTextToSpeech.availableEngines():
2789
+ if engine != "mock":
2790
+ self.tts_engine.addItem(engine)
2791
+ self.tts_engine.blockSignals(False)
2792
+ if index:
2793
+ self.tts_engine.setCurrentIndex(index)
2794
+ else:
2795
+ self.tts_engine.setCurrentIndex(0)
2796
+
2797
+ def tts_state_manage(self, state):
2798
+ """Respond to changes in TTS state"""
2799
+ if state == QTextToSpeech.State.Ready:
2800
+ self.tts_play.setEnabled(True)
2801
+ elif state == QTextToSpeech.State.Error:
2802
+ self.display_message(self.tts_instance.errorString())
2803
+
2804
+ def tts_set_engine(self, index = None):
2805
+ """Set TTS engine"""
2806
+ user_select = self.tts_engine.currentText()
2807
+ self.tts_instance.setEngine(user_select)
2808
+ self.tts_pop_locale()
2809
+
2810
+ def tts_pop_locale(self):
2811
+ """Populate locales in ui for selected TTS engine"""
2812
+ self.tts_locale.blockSignals(True)
2813
+ self.tts_locale.clear()
2814
+ for loc in self.tts_instance.availableLocales():
2815
+ self.tts_locale.addItem(f"{QLocale.languageToString(loc.language())} ({QLocale.territoryToString(loc.territory())})", loc)
2816
+ self.tts_locale.blockSignals(False)
2817
+ self.tts_locale.setCurrentIndex(0)
2818
+ self.tts_pop_voice()
2793
2819
 
2794
2820
  def tts_set_locale(self, index):
2795
- pass
2821
+ """Set locale for present TTS engine"""
2822
+ user_select = self.tts_locale.currentData()
2823
+ self.tts_instance.setLocale(user_select)
2824
+ self.tts_pop_voice()
2825
+
2826
+ def tts_pop_voice(self):
2827
+ """Populate voices in ui for selected TTS engine"""
2828
+ self.tts_voice.blockSignals(True)
2829
+ self.tts_voice.clear()
2830
+ for voice in self.tts_instance.availableVoices():
2831
+ self.tts_voice.addItem(voice.name(), voice)
2832
+ self.tts_voice.blockSignals(False)
2833
+ self.tts_voice.setCurrentIndex(0)
2796
2834
 
2797
2835
  def tts_set_voice(self, index):
2798
- pass
2836
+ """Set voice for present TTS engine"""
2837
+ user_select = self.tts_voice.currentData()
2838
+ self.tts_instance.setVoice(user_select)
2799
2839
 
2800
2840
  def tts_set_pitch(self, pitch):
2841
+ """Set TTS pitch"""
2801
2842
  pitch = pitch / 10
2802
2843
  if self.tts_instance:
2803
2844
  self.tts_instance.setPitch(pitch)
2804
2845
 
2805
2846
  def tts_set_volume(self, volume):
2847
+ """Set TTS volume"""
2806
2848
  volume = volume / 10
2807
2849
  if self.tts_instance:
2808
2850
  self.tts_instance.setVolume(volume)
2809
2851
 
2810
2852
  def tts_set_rate(self, rate):
2853
+ """Set TTS rate"""
2811
2854
  rate = rate / 10
2812
2855
  if self.tts_instance:
2813
2856
  self.tts_instance.setRate(rate)
plover_cat/TextEditor.py CHANGED
@@ -1,4 +1,3 @@
1
- import string
2
1
  import pathlib
3
2
  import json
4
3
  import os
@@ -9,13 +8,11 @@ from dulwich.errors import NotGitRepository
9
8
  from dulwich import porcelain
10
9
  from spylls.hunspell import Dictionary
11
10
 
12
- from PySide6 import QtCore, QtGui, QtWidgets
13
- from PySide6.QtGui import QCursor, QKeySequence, QTextCursor, QTextDocument, QColor, QUndoStack
14
- from PySide6.QtCore import QFile, QStringListModel, Qt, QModelIndex, Signal, QUrl, QSettings
11
+ from PySide6 import QtCore, QtGui
12
+ from PySide6.QtGui import QTextCursor, QTextDocument, QColor, QUndoStack
13
+ from PySide6.QtCore import Qt, Signal, QUrl, QSettings
15
14
  from PySide6.QtWidgets import QCompleter, QTextEdit, QMessageBox, QApplication
16
- from PySide6.QtMultimedia import (QMediaPlayer, QMediaRecorder, QMediaDevices, QMediaCaptureSession, QMediaFormat, QAudioOutput)
17
-
18
- _ = lambda txt: QtCore.QCoreApplication.translate("Plover2CAT", txt)
15
+ from PySide6.QtMultimedia import (QMediaPlayer, QMediaRecorder, QMediaCaptureSession, QAudioOutput)
19
16
 
20
17
  import plover
21
18
 
@@ -29,6 +26,8 @@ from plover_cat.export_helpers import load_odf_styles, recursive_style_format, p
29
26
  from plover_cat.helpers import ms_to_hours, save_json, backup_dictionary_stack, add_custom_dicts, load_dictionary_stack_from_backup, return_commits, hide_file
30
27
  from plover_cat.constants import default_styles, default_config, default_dict
31
28
 
29
+ _ = lambda txt: QtCore.QCoreApplication.translate("Plover2CAT", txt)
30
+
32
31
  class PloverCATEditor(QTextEdit):
33
32
  """Editor object for a transcript.
34
33
 
@@ -185,6 +184,7 @@ class PloverCATEditor(QTextEdit):
185
184
  self.mock_type(event.text())
186
185
  # print(event.key())
187
186
  QTextEdit.keyPressEvent(self, event)
187
+
188
188
  def recorder_error(self, error, message):
189
189
  log.debug(f"{error}: {message}")
190
190
 
plover_cat/__init__.py CHANGED
@@ -1,5 +1,5 @@
1
- from PySide6.QtCore import Qt, QTimer
2
- from PySide6.QtWidgets import QMainWindow, QHBoxLayout
1
+ from PySide6.QtCore import Qt
2
+ from PySide6.QtWidgets import QHBoxLayout
3
3
 
4
4
  from plover.gui_qt.tool import Tool
5
5
 
@@ -18,12 +18,14 @@ class PloverCAT(Tool):
18
18
 
19
19
  def __init__(self, engine):
20
20
  super().__init__(engine)
21
-
22
21
  self.setWindowFlags(Qt.Window | Qt.WindowMinMaxButtonsHint)
23
22
  self.layout = QHBoxLayout()
24
- self.layout.addWidget(PloverCATWindow(engine))
23
+ self.everything = PloverCATWindow(engine)
24
+ self.layout.addWidget(self.everything)
25
25
  self.layout.setContentsMargins(0,0,0,0)
26
26
  self.setLayout(self.layout)
27
-
28
27
  #what does this do?
29
- self.finished.connect(lambda: None)
28
+ # self.finished.connect(lambda: None)
29
+ def keyPressEvent(self, event):
30
+ if event.key() != Qt.Key_Escape:
31
+ Tool.keyPressEvent(self, event)
plover_cat/__version__.py CHANGED
@@ -1,2 +1,2 @@
1
- __version__ = "4.0.0-alpha.1"
1
+ __version__ = "4.0.2"
2
2
 
@@ -3,7 +3,7 @@
3
3
  ################################################################################
4
4
  ## Form generated from reading UI file 'affix_dialog.ui'
5
5
  ##
6
- ## Created by: Qt User Interface Compiler version 6.9.2
6
+ ## Created by: Qt User Interface Compiler version 6.10.2
7
7
  ##
8
8
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
9
9
  ################################################################################
@@ -3,7 +3,7 @@
3
3
  ################################################################################
4
4
  ## Form generated from reading UI file 'caption_dialog.ui'
5
5
  ##
6
- ## Created by: Qt User Interface Compiler version 6.9.2
6
+ ## Created by: Qt User Interface Compiler version 6.10.2
7
7
  ##
8
8
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
9
9
  ################################################################################
@@ -3,7 +3,7 @@
3
3
  ################################################################################
4
4
  ## Form generated from reading UI file 'create_dialog.ui'
5
5
  ##
6
- ## Created by: Qt User Interface Compiler version 6.9.2
6
+ ## Created by: Qt User Interface Compiler version 6.10.2
7
7
  ##
8
8
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
9
9
  ################################################################################
@@ -3,7 +3,7 @@
3
3
  ################################################################################
4
4
  ## Form generated from reading UI file 'field_dialog.ui'
5
5
  ##
6
- ## Created by: Qt User Interface Compiler version 6.9.2
6
+ ## Created by: Qt User Interface Compiler version 6.10.2
7
7
  ##
8
8
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
9
9
  ################################################################################
@@ -3,7 +3,7 @@
3
3
  ################################################################################
4
4
  ## Form generated from reading UI file 'index_dialog.ui'
5
5
  ##
6
- ## Created by: Qt User Interface Compiler version 6.9.2
6
+ ## Created by: Qt User Interface Compiler version 6.10.2
7
7
  ##
8
8
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
9
9
  ################################################################################
@@ -3,7 +3,7 @@
3
3
  ################################################################################
4
4
  ## Form generated from reading UI file 'plover_cat.ui'
5
5
  ##
6
- ## Created by: Qt User Interface Compiler version 6.9.2
6
+ ## Created by: Qt User Interface Compiler version 6.10.2
7
7
  ##
8
8
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
9
9
  ################################################################################
@@ -387,6 +387,10 @@ class Ui_PloverCAT(object):
387
387
  self.actionColorField.setObjectName(u"actionColorField")
388
388
  self.actionColorIndex = QAction(PloverCAT)
389
389
  self.actionColorIndex.setObjectName(u"actionColorIndex")
390
+ self.actionPlayTTS = QAction(PloverCAT)
391
+ self.actionPlayTTS.setObjectName(u"actionPlayTTS")
392
+ self.actionStopTTS = QAction(PloverCAT)
393
+ self.actionStopTTS.setObjectName(u"actionStopTTS")
390
394
  self.centralwidget = QWidget(PloverCAT)
391
395
  self.centralwidget.setObjectName(u"centralwidget")
392
396
  self.verticalLayout_24 = QVBoxLayout(self.centralwidget)
@@ -1584,12 +1588,12 @@ class Ui_PloverCAT(object):
1584
1588
  self.tabWidget.addTab(self.stenospell_pane, icon32, "")
1585
1589
  self.tts_pane = QWidget()
1586
1590
  self.tts_pane.setObjectName(u"tts_pane")
1587
- self.tts_pane.setEnabled(False)
1591
+ self.tts_pane.setEnabled(True)
1588
1592
  self.verticalLayout_8 = QVBoxLayout(self.tts_pane)
1589
1593
  self.verticalLayout_8.setObjectName(u"verticalLayout_8")
1590
1594
  self.tts_settings_group = QGroupBox(self.tts_pane)
1591
1595
  self.tts_settings_group.setObjectName(u"tts_settings_group")
1592
- self.tts_settings_group.setEnabled(False)
1596
+ self.tts_settings_group.setEnabled(True)
1593
1597
  self.verticalLayout_9 = QVBoxLayout(self.tts_settings_group)
1594
1598
  self.verticalLayout_9.setObjectName(u"verticalLayout_9")
1595
1599
  self.formLayout = QFormLayout()
@@ -1675,21 +1679,25 @@ class Ui_PloverCAT(object):
1675
1679
  self.horizontalLayout_19.setObjectName(u"horizontalLayout_19")
1676
1680
  self.tts_play = QPushButton(self.tts_pane)
1677
1681
  self.tts_play.setObjectName(u"tts_play")
1682
+ self.tts_play.setFocusPolicy(Qt.FocusPolicy.NoFocus)
1678
1683
 
1679
1684
  self.horizontalLayout_19.addWidget(self.tts_play)
1680
1685
 
1681
1686
  self.tts_pause = QPushButton(self.tts_pane)
1682
1687
  self.tts_pause.setObjectName(u"tts_pause")
1688
+ self.tts_pause.setFocusPolicy(Qt.FocusPolicy.NoFocus)
1683
1689
 
1684
1690
  self.horizontalLayout_19.addWidget(self.tts_pause)
1685
1691
 
1686
1692
  self.tts_resume = QPushButton(self.tts_pane)
1687
1693
  self.tts_resume.setObjectName(u"tts_resume")
1694
+ self.tts_resume.setFocusPolicy(Qt.FocusPolicy.NoFocus)
1688
1695
 
1689
1696
  self.horizontalLayout_19.addWidget(self.tts_resume)
1690
1697
 
1691
1698
  self.tts_stop = QPushButton(self.tts_pane)
1692
1699
  self.tts_stop.setObjectName(u"tts_stop")
1700
+ self.tts_stop.setFocusPolicy(Qt.FocusPolicy.NoFocus)
1693
1701
 
1694
1702
  self.horizontalLayout_19.addWidget(self.tts_stop)
1695
1703
 
@@ -1858,6 +1866,9 @@ class Ui_PloverCAT(object):
1858
1866
  self.menuAudio.addAction(self.actionFlushCaption)
1859
1867
  self.menuAudio.addSeparator()
1860
1868
  self.menuAudio.addAction(self.actionAddChangeAudioTimestamps)
1869
+ self.menuAudio.addSeparator()
1870
+ self.menuAudio.addAction(self.actionPlayTTS)
1871
+ self.menuAudio.addAction(self.actionStopTTS)
1861
1872
  self.menuView.addAction(self.actionShowAllCharacters)
1862
1873
  self.menuView.addAction(self.actionWindowFont)
1863
1874
  self.menuView.addAction(self.actionBackgroundColor)
@@ -1957,9 +1968,11 @@ class Ui_PloverCAT(object):
1957
1968
  self.dockSuggest.visibilityChanged.connect(self.actionSuggestions.setChecked)
1958
1969
  self.actionNavigation.triggered["bool"].connect(self.dockNavigation.setVisible)
1959
1970
  self.actionAutomaticAffixes.toggled.connect(self.actionEditAffixes.setEnabled)
1971
+ self.actionPlayTTS.triggered.connect(self.tts_play.click)
1972
+ self.actionStopTTS.triggered.connect(self.tts_stop.click)
1960
1973
 
1961
1974
  self.mainTabs.setCurrentIndex(0)
1962
- self.tabWidget.setCurrentIndex(5)
1975
+ self.tabWidget.setCurrentIndex(6)
1963
1976
 
1964
1977
 
1965
1978
  QMetaObject.connectSlotsByName(PloverCAT)
@@ -2042,28 +2055,28 @@ class Ui_PloverCAT(object):
2042
2055
  #endif // QT_CONFIG(shortcut)
2043
2056
  self.actionOpenAudio.setText(QCoreApplication.translate("PloverCAT", u"Open Media", None))
2044
2057
  #if QT_CONFIG(tooltip)
2045
- self.actionOpenAudio.setToolTip(QCoreApplication.translate("PloverCAT", u"Select an audiovisual file on computer to play", None))
2058
+ self.actionOpenAudio.setToolTip(QCoreApplication.translate("PloverCAT", u"Select a media file to play", None))
2046
2059
  #endif // QT_CONFIG(tooltip)
2047
2060
  #if QT_CONFIG(shortcut)
2048
2061
  self.actionOpenAudio.setShortcut(QCoreApplication.translate("PloverCAT", u"Ctrl+Shift+O", None))
2049
2062
  #endif // QT_CONFIG(shortcut)
2050
2063
  self.actionSkipBack.setText(QCoreApplication.translate("PloverCAT", u"Skip Back", None))
2051
2064
  #if QT_CONFIG(tooltip)
2052
- self.actionSkipBack.setToolTip(QCoreApplication.translate("PloverCAT", u"Skip back in audio/video", None))
2065
+ self.actionSkipBack.setToolTip(QCoreApplication.translate("PloverCAT", u"Skip back in media", None))
2053
2066
  #endif // QT_CONFIG(tooltip)
2054
2067
  #if QT_CONFIG(shortcut)
2055
2068
  self.actionSkipBack.setShortcut(QCoreApplication.translate("PloverCAT", u"Ctrl+J", None))
2056
2069
  #endif // QT_CONFIG(shortcut)
2057
2070
  self.actionSkipForward.setText(QCoreApplication.translate("PloverCAT", u"Skip Forward", None))
2058
2071
  #if QT_CONFIG(tooltip)
2059
- self.actionSkipForward.setToolTip(QCoreApplication.translate("PloverCAT", u"Skip forward in audio/video", None))
2072
+ self.actionSkipForward.setToolTip(QCoreApplication.translate("PloverCAT", u"Skip forward in media", None))
2060
2073
  #endif // QT_CONFIG(tooltip)
2061
2074
  #if QT_CONFIG(shortcut)
2062
2075
  self.actionSkipForward.setShortcut(QCoreApplication.translate("PloverCAT", u"Ctrl+L", None))
2063
2076
  #endif // QT_CONFIG(shortcut)
2064
2077
  self.actionStopAudio.setText(QCoreApplication.translate("PloverCAT", u"Stop", None))
2065
2078
  #if QT_CONFIG(tooltip)
2066
- self.actionStopAudio.setToolTip(QCoreApplication.translate("PloverCAT", u"Stop selected audio/video being played", None))
2079
+ self.actionStopAudio.setToolTip(QCoreApplication.translate("PloverCAT", u"Stop currently playing media", None))
2067
2080
  #endif // QT_CONFIG(tooltip)
2068
2081
  #if QT_CONFIG(shortcut)
2069
2082
  self.actionStopAudio.setShortcut(QCoreApplication.translate("PloverCAT", u"Ctrl+W", None))
@@ -2084,7 +2097,7 @@ class Ui_PloverCAT(object):
2084
2097
  #endif // QT_CONFIG(shortcut)
2085
2098
  self.actionPlayPause.setText(QCoreApplication.translate("PloverCAT", u"Play/Pause", None))
2086
2099
  #if QT_CONFIG(tooltip)
2087
- self.actionPlayPause.setToolTip(QCoreApplication.translate("PloverCAT", u"Play or pause selected audio/video", None))
2100
+ self.actionPlayPause.setToolTip(QCoreApplication.translate("PloverCAT", u"Play or pause media", None))
2088
2101
  #endif // QT_CONFIG(tooltip)
2089
2102
  #if QT_CONFIG(shortcut)
2090
2103
  self.actionPlayPause.setShortcut(QCoreApplication.translate("PloverCAT", u"Ctrl+P", None))
@@ -2125,14 +2138,14 @@ class Ui_PloverCAT(object):
2125
2138
  #endif // QT_CONFIG(tooltip)
2126
2139
  self.actionRecordPause.setText(QCoreApplication.translate("PloverCAT", u"Record/Pause", None))
2127
2140
  #if QT_CONFIG(tooltip)
2128
- self.actionRecordPause.setToolTip(QCoreApplication.translate("PloverCAT", u"Start or pause the recording of audio", None))
2141
+ self.actionRecordPause.setToolTip(QCoreApplication.translate("PloverCAT", u"Start or pause media recording", None))
2129
2142
  #endif // QT_CONFIG(tooltip)
2130
2143
  #if QT_CONFIG(shortcut)
2131
2144
  self.actionRecordPause.setShortcut(QCoreApplication.translate("PloverCAT", u"Ctrl+Shift+P", None))
2132
2145
  #endif // QT_CONFIG(shortcut)
2133
2146
  self.actionStopRecording.setText(QCoreApplication.translate("PloverCAT", u"Stop Recording", None))
2134
2147
  #if QT_CONFIG(tooltip)
2135
- self.actionStopRecording.setToolTip(QCoreApplication.translate("PloverCAT", u"Stop recording audio", None))
2148
+ self.actionStopRecording.setToolTip(QCoreApplication.translate("PloverCAT", u"Stop recording media", None))
2136
2149
  #endif // QT_CONFIG(tooltip)
2137
2150
  self.actionShowVideo.setText(QCoreApplication.translate("PloverCAT", u"Show/Hide Video", None))
2138
2151
  #if QT_CONFIG(tooltip)
@@ -2163,7 +2176,7 @@ class Ui_PloverCAT(object):
2163
2176
  self.actionSuggestions.setText(QCoreApplication.translate("PloverCAT", u"Suggestions", None))
2164
2177
  self.actionHistory.setText(QCoreApplication.translate("PloverCAT", u"History", None))
2165
2178
  self.actionRevealSteno.setText(QCoreApplication.translate("PloverCAT", u"Reveal Steno", None))
2166
- self.actionAudioControls.setText(QCoreApplication.translate("PloverCAT", u"Audio Controls", None))
2179
+ self.actionAudioControls.setText(QCoreApplication.translate("PloverCAT", u"Media Controls", None))
2167
2180
  self.actionToolbox.setText(QCoreApplication.translate("PloverCAT", u"Toolbox", None))
2168
2181
  self.actionClearParagraph.setText(QCoreApplication.translate("PloverCAT", u"Reset Paragraph", None))
2169
2182
  #if QT_CONFIG(tooltip)
@@ -2301,7 +2314,7 @@ class Ui_PloverCAT(object):
2301
2314
  self.actionCaptioning.setText(QCoreApplication.translate("PloverCAT", u"Captioning", None))
2302
2315
  self.actionFlushCaption.setText(QCoreApplication.translate("PloverCAT", u"Flush Caption", None))
2303
2316
  self.actionMassTimestampChange.setText(QCoreApplication.translate("PloverCAT", u"Mass Timestamp Change", None))
2304
- self.actionAddChangeAudioTimestamps.setText(QCoreApplication.translate("PloverCAT", u"Add/Change All Audio Timestamps", None))
2317
+ self.actionAddChangeAudioTimestamps.setText(QCoreApplication.translate("PloverCAT", u"Add/Change All Media Timestamps", None))
2305
2318
  self.actionTape.setText(QCoreApplication.translate("PloverCAT", u"Paper Tape (*.tape)", None))
2306
2319
  #if QT_CONFIG(tooltip)
2307
2320
  self.actionTape.setToolTip(QCoreApplication.translate("PloverCAT", u"Exports only the strokes from paper tape", None))
@@ -2357,6 +2370,8 @@ class Ui_PloverCAT(object):
2357
2370
  self.actionColorAutomatic.setText(QCoreApplication.translate("PloverCAT", u"Automatic", None))
2358
2371
  self.actionColorField.setText(QCoreApplication.translate("PloverCAT", u"Field", None))
2359
2372
  self.actionColorIndex.setText(QCoreApplication.translate("PloverCAT", u"Index", None))
2373
+ self.actionPlayTTS.setText(QCoreApplication.translate("PloverCAT", u"Play (TTS)", None))
2374
+ self.actionStopTTS.setText(QCoreApplication.translate("PloverCAT", u"Stop (TTS)", None))
2360
2375
  self.label_39.setText(QCoreApplication.translate("PloverCAT", u"Welcome to Plover2CAT. Create a new transcript or select a recent transcript below.", None))
2361
2376
  self.mainTabs.setTabText(self.mainTabs.indexOf(self.homeTab), QCoreApplication.translate("PloverCAT", u"Recent Files", None))
2362
2377
  self.menuFile.setTitle(QCoreApplication.translate("PloverCAT", u"File", None))
@@ -2387,7 +2402,7 @@ class Ui_PloverCAT(object):
2387
2402
  #endif // QT_CONFIG(accessibility)
2388
2403
  #if QT_CONFIG(tooltip)
2389
2404
  self.dockPaper.setToolTip(QCoreApplication.translate("PloverCAT", u"Displays steno notes, time of\n"
2390
- "stroke, audio time, and cursor\n"
2405
+ "stroke, media time, and cursor\n"
2391
2406
  "position.", None))
2392
2407
  #endif // QT_CONFIG(tooltip)
2393
2408
  #if QT_CONFIG(whatsthis)
@@ -2420,16 +2435,16 @@ class Ui_PloverCAT(object):
2420
2435
  #endif // QT_CONFIG(tooltip)
2421
2436
  self.suggest_sort.setText(QCoreApplication.translate("PloverCAT", u"By Recency", None))
2422
2437
  #if QT_CONFIG(tooltip)
2423
- self.dockAudio.setToolTip(QCoreApplication.translate("PloverCAT", u"Audio seeker and other controls", None))
2438
+ self.dockAudio.setToolTip(QCoreApplication.translate("PloverCAT", u"Media playback controls", None))
2424
2439
  #endif // QT_CONFIG(tooltip)
2425
- self.dockAudio.setWindowTitle(QCoreApplication.translate("PloverCAT", u"Audio Controls", None))
2426
- self.audio_label.setText(QCoreApplication.translate("PloverCAT", u"Select file to play audio", None))
2440
+ self.dockAudio.setWindowTitle(QCoreApplication.translate("PloverCAT", u"Media Controls", None))
2441
+ self.audio_label.setText(QCoreApplication.translate("PloverCAT", u"Select media file to play", None))
2427
2442
  #if QT_CONFIG(tooltip)
2428
2443
  self.playRate.setToolTip(QCoreApplication.translate("PloverCAT", u"Playback rate", None))
2429
2444
  #endif // QT_CONFIG(tooltip)
2430
2445
  self.playRate.setSuffix(QCoreApplication.translate("PloverCAT", u"x", None))
2431
2446
  #if QT_CONFIG(tooltip)
2432
- self.audioDelay.setToolTip(QCoreApplication.translate("PloverCAT", u"Millisecond adjustment between actual timestamp and audio and steno timestamps.", None))
2447
+ self.audioDelay.setToolTip(QCoreApplication.translate("PloverCAT", u"Millisecond adjustment between actual timestamp and media and steno timestamps.", None))
2433
2448
  #endif // QT_CONFIG(tooltip)
2434
2449
  self.audioDelay.setSuffix(QCoreApplication.translate("PloverCAT", u"ms", None))
2435
2450
  #if QT_CONFIG(tooltip)
@@ -2707,14 +2722,14 @@ class Ui_PloverCAT(object):
2707
2722
  self.editorEditTime.setToolTip(QCoreApplication.translate("PloverCAT", u"Read only. Displays edit time of paragraph. Will change upon any cursor movement.", None))
2708
2723
  #endif // QT_CONFIG(tooltip)
2709
2724
  self.editorEditTime.setDisplayFormat(QCoreApplication.translate("PloverCAT", u"yyyy-MM-dd hh:mm:ss.zzz", None))
2710
- self.label_4.setText(QCoreApplication.translate("PloverCAT", u"Audio Start Time", None))
2725
+ self.label_4.setText(QCoreApplication.translate("PloverCAT", u"Media Start Time", None))
2711
2726
  #if QT_CONFIG(tooltip)
2712
- self.editorAudioStart.setToolTip(QCoreApplication.translate("PloverCAT", u"Modifies audio start time of paragraph.", None))
2727
+ self.editorAudioStart.setToolTip(QCoreApplication.translate("PloverCAT", u"Modifies media start time of paragraph.", None))
2713
2728
  #endif // QT_CONFIG(tooltip)
2714
2729
  self.editorAudioStart.setDisplayFormat(QCoreApplication.translate("PloverCAT", u"hh:mm:ss.zzz", None))
2715
- self.label_5.setText(QCoreApplication.translate("PloverCAT", u"Audio End Time", None))
2730
+ self.label_5.setText(QCoreApplication.translate("PloverCAT", u"Media End Time", None))
2716
2731
  #if QT_CONFIG(tooltip)
2717
- self.editorAudioEnd.setToolTip(QCoreApplication.translate("PloverCAT", u"Sets audio end time for this paragraph. ", None))
2732
+ self.editorAudioEnd.setToolTip(QCoreApplication.translate("PloverCAT", u"Sets media end time for this paragraph. ", None))
2718
2733
  #endif // QT_CONFIG(tooltip)
2719
2734
  self.editorAudioEnd.setDisplayFormat(QCoreApplication.translate("PloverCAT", u"hh:mm:ss.zzz", None))
2720
2735
  self.label_7.setText(QCoreApplication.translate("PloverCAT", u"Notes", None))
@@ -2760,9 +2775,9 @@ class Ui_PloverCAT(object):
2760
2775
  #if QT_CONFIG(accessibility)
2761
2776
  self.toolbarSteno.setAccessibleName(QCoreApplication.translate("PloverCAT", u"Editing Toolbar", None))
2762
2777
  #endif // QT_CONFIG(accessibility)
2763
- self.toolbarAudio.setWindowTitle(QCoreApplication.translate("PloverCAT", u"Audio Toolbar", None))
2778
+ self.toolbarAudio.setWindowTitle(QCoreApplication.translate("PloverCAT", u"Media Toolbar", None))
2764
2779
  #if QT_CONFIG(accessibility)
2765
- self.toolbarAudio.setAccessibleName(QCoreApplication.translate("PloverCAT", u"Audiovisual Toolbar", None))
2780
+ self.toolbarAudio.setAccessibleName(QCoreApplication.translate("PloverCAT", u"Media Toolbar", None))
2766
2781
  #endif // QT_CONFIG(accessibility)
2767
2782
  self.dockHistoryStack.setWindowTitle(QCoreApplication.translate("PloverCAT", u"History", None))
2768
2783
  #if QT_CONFIG(tooltip)
@@ -3,7 +3,7 @@
3
3
  ################################################################################
4
4
  ## Form generated from reading UI file 'recorder_dialog.ui'
5
5
  ##
6
- ## Created by: Qt User Interface Compiler version 6.9.2
6
+ ## Created by: Qt User Interface Compiler version 6.10.2
7
7
  ##
8
8
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
9
9
  ################################################################################
@@ -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.2
3
+ # Created by: The Resource Compiler for Qt version 6.10.2
4
4
  # WARNING! All changes made in this file will be lost!
5
5
 
6
6
  from PySide6 import QtCore
@@ -3,7 +3,7 @@
3
3
  ################################################################################
4
4
  ## Form generated from reading UI file 'shortcut_dialog.ui'
5
5
  ##
6
- ## Created by: Qt User Interface Compiler version 6.9.2
6
+ ## Created by: Qt User Interface Compiler version 6.10.2
7
7
  ##
8
8
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
9
9
  ################################################################################
@@ -10,8 +10,8 @@ from plover_cat.constants import user_field_dict
10
10
  from PySide6.QtCore import QByteArray, QBuffer, QIODevice
11
11
  from PySide6.QtGui import QImage, QImageReader
12
12
  from odf.teletype import addTextToElement
13
- from odf.text import P, UserFieldDecls, UserFieldDecl, UserFieldGet, UserIndexMarkStart, UserIndexMarkEnd
14
- from odf.draw import Frame, TextBox, Image
13
+ from odf.text import UserFieldDecls, UserFieldDecl, UserFieldGet, UserIndexMarkStart, UserIndexMarkEnd
14
+ from odf.draw import Frame, Image
15
15
 
16
16
  _whitespace = '\u2029\t\n\x0b\x0c\r '
17
17
  whitespace = r'[%s]' % re.escape(_whitespace)
@@ -339,7 +339,7 @@ class text_field(text_element):
339
339
  user_declares = document.text.getElementsByType(UserFieldDecls)
340
340
  if user_declares:
341
341
  field_names = [i.getAttribute("name") for i in document.text.getElementsByType(UserFieldDecl)]
342
- if not self.name in field_names:
342
+ if self.name not in field_names:
343
343
  user_declares = document.text.getElementsByType(UserFieldDecls)[0]
344
344
  user_dec = UserFieldDecl(name = self.name, stringvalue = self.data, valuetype = "string")
345
345
  user_declares.addElement(user_dec)
@@ -573,18 +573,19 @@ class element_factory:
573
573
  """
574
574
  # default is always a text element
575
575
  element = text_element()
576
- if element_dict["element"] == "stroke":
577
- element = stroke_text()
576
+ match element_dict["element"]:
577
+ case "stroke":
578
+ element = stroke_text()
578
579
  # elif element_dict["element"] == "dummy":
579
580
  # element = dummy_element()
580
- elif element_dict["element"] == "image":
581
- element = image_text()
582
- elif element_dict["element"] == "field":
583
- element = text_field(user_dict = user_field_dict)
584
- elif element_dict["element"] == "automatic":
585
- element = automatic_text()
586
- elif element_dict["element"] == "index":
587
- element = index_text()
581
+ case "image":
582
+ element = image_text()
583
+ case "field":
584
+ element = text_field(user_dict = user_field_dict)
585
+ case "automatic":
586
+ element = automatic_text()
587
+ case "index":
588
+ element = index_text()
588
589
  element.from_dict(element_dict)
589
590
  return(element)
590
591
 
@@ -651,12 +652,12 @@ class element_collection(UserList):
651
652
  if first_whole == last_whole:
652
653
  el_part.append(data[last_whole][first_remain:last_remain])
653
654
  return(el_part)
654
- if not start in el_lengths:
655
+ if start not in el_lengths:
655
656
  el_part.append(data[first_whole][first_remain:])
656
657
  if (first_whole + 1) != last_whole:
657
658
  for i in data[(first_whole + 1): last_whole]:
658
659
  el_part.append(i)
659
- if not end in el_lengths:
660
+ if end not in el_lengths:
660
661
  el_part.append(data[last_whole][:last_remain])
661
662
  else:
662
663
  el_part.append(data[last_whole])
@@ -3,7 +3,7 @@
3
3
  ################################################################################
4
4
  ## Form generated from reading UI file 'suggest_dialog.ui'
5
5
  ##
6
- ## Created by: Qt User Interface Compiler version 6.9.2
6
+ ## Created by: Qt User Interface Compiler version 6.10.2
7
7
  ##
8
8
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
9
9
  ################################################################################
@@ -0,0 +1,96 @@
1
+ from PySide6.QtWidgets import QDialog, QFileDialog, QInputDialog, QListView
2
+ from PySide6.QtGui import QStandardItem, QStandardItemModel
3
+ from PySide6.QtCore import Qt, Signal
4
+ import pathlib
5
+ from plover_cat.tape_dialog_ui import Ui_tapeDialog
6
+ from plover.steno import Stroke, normalize_stroke
7
+ from plover import system
8
+
9
+ class tapeDialogWindow(QDialog, Ui_tapeDialog):
10
+ """Set up configuration for translating from tape
11
+ """
12
+ translate_stroke_from_tape = Signal(int)
13
+ """Signal sent for translate, int being index at start"""
14
+ undo_from_tape = Signal()
15
+ """Signal sent to trigger undo of last stroke"""
16
+ def __init__(self):
17
+ super().__init__()
18
+ self.setupUi(self)
19
+ self.tape_data = []
20
+ self.select_tape.clicked.connect(self.load_tape)
21
+ self.tape_view.setUniformItemSizes(True)
22
+ self.tape_view.setLayoutMode(QListView.LayoutMode.Batched)
23
+ self.translate.clicked.connect(lambda: self.signal_stroke())
24
+ self.translate_ten.clicked.connect(lambda: self.signal_stroke(10))
25
+ self.translate_all.clicked.connect(lambda: self.signal_stroke_all())
26
+ self.undo_last.clicked.connect(lambda: self.signal_undo())
27
+
28
+ def signal_undo(self):
29
+ self.undo_from_tape.emit()
30
+ current = self.tape_view.currentIndex().row()
31
+ self.tape_view.setCurrentIndex(current - 1)
32
+
33
+ def signal_stroke(self, strokes = 1):
34
+ self.translate_stroke_from_tape.emit(strokes)
35
+ current = self.tape_view.currentIndex().row()
36
+ self.tape_view.setCurrentIndex(current + strokes)
37
+
38
+ def signal_stroke_all(self):
39
+ current = self.tape_view.currentIndex().row()
40
+ self.translate_stroke_from_tape.emit(self.tape_model.rowCount() - current + 1)
41
+
42
+ def load_tape(self):
43
+ selected_file = QFileDialog.getOpenFileName(
44
+ self,
45
+ "Select tape file to translate",
46
+ "", "Tape (*.tape *.txt)")[0]
47
+ if not selected_file:
48
+ return
49
+ selected_file = pathlib.Path(selected_file)
50
+ self.select_tape.setText(selected_file.stem)
51
+ paper_format, ok = QInputDialog.getItem(self, "Translate Tape", "Format of tape file:", ["Plover2CAT", "Plover (raw)", "Plover (paper)"], editable = False)
52
+ if not ok:
53
+ return
54
+ self.tape_data = []
55
+ match paper_format:
56
+ case "Plover (raw)":
57
+ self.load_raw_paper(selected_file)
58
+ case "Plover2CAT":
59
+ self.load_plover2cat(selected_file)
60
+ case "Plover (paper)":
61
+ self.load_plover_paper(selected_file)
62
+ self.pop_view()
63
+
64
+ def load_raw_paper(self, file_path):
65
+ with open(file_path) as f:
66
+ for line in f:
67
+ stroke = Stroke(normalize_stroke(line.strip().replace(" ", "")))
68
+ self.tape_data.append(stroke.rtfcre)
69
+
70
+ def load_plover2cat(self, file_path):
71
+ with open(file_path) as f:
72
+ for line in f:
73
+ stroke_contents = line.strip().split("|")[3]
74
+ keys = []
75
+ for i in range(len(stroke_contents)):
76
+ if not stroke_contents[i].isspace() and i < len(system.KEYS):
77
+ keys.append(system.KEYS[i])
78
+ self.tape_data.append(Stroke(keys).rtfcre)
79
+
80
+ def load_plover_paper(self, file_path):
81
+ with open(file_path) as f:
82
+ for line in f:
83
+ keys = []
84
+ for i in range(len(line)):
85
+ if not line[i].isspace() and i < len(system.KEYS):
86
+ keys.append(system.KEYS[i])
87
+ self.tape_data.append(Stroke(keys).rtfcre)
88
+
89
+ def pop_view(self):
90
+ self.tape_model = QStandardItemModel(self)
91
+ for stroke in self.tape_data:
92
+ item = QStandardItem()
93
+ item.setText(stroke)
94
+ item.setData(stroke, Qt.UserRole)
95
+ self.tape_model.appendRow(item)
96
+ self.tape_view.setModel(self.tape_model)
@@ -0,0 +1,94 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ################################################################################
4
+ ## Form generated from reading UI file 'tape_dialog.ui'
5
+ ##
6
+ ## Created by: Qt User Interface Compiler version 6.10.2
7
+ ##
8
+ ## WARNING! All changes made in this file will be lost when recompiling UI file!
9
+ ################################################################################
10
+
11
+ from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
12
+ QMetaObject, QObject, QPoint, QRect,
13
+ QSize, QTime, QUrl, Qt)
14
+ from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
15
+ QFont, QFontDatabase, QGradient, QIcon,
16
+ QImage, QKeySequence, QLinearGradient, QPainter,
17
+ QPalette, QPixmap, QRadialGradient, QTransform)
18
+ from PySide6.QtWidgets import (QAbstractButton, QAbstractItemView, QApplication, QDialog,
19
+ QDialogButtonBox, QHBoxLayout, QListView, QPushButton,
20
+ QSizePolicy, QVBoxLayout, QWidget)
21
+
22
+ class Ui_tapeDialog(object):
23
+ def setupUi(self, tapeDialog):
24
+ if not tapeDialog.objectName():
25
+ tapeDialog.setObjectName(u"tapeDialog")
26
+ tapeDialog.resize(400, 300)
27
+ self.verticalLayout = QVBoxLayout(tapeDialog)
28
+ self.verticalLayout.setObjectName(u"verticalLayout")
29
+ self.horizontalLayout = QHBoxLayout()
30
+ self.horizontalLayout.setObjectName(u"horizontalLayout")
31
+ self.verticalLayout_2 = QVBoxLayout()
32
+ self.verticalLayout_2.setObjectName(u"verticalLayout_2")
33
+ self.select_tape = QPushButton(tapeDialog)
34
+ self.select_tape.setObjectName(u"select_tape")
35
+
36
+ self.verticalLayout_2.addWidget(self.select_tape)
37
+
38
+ self.translate = QPushButton(tapeDialog)
39
+ self.translate.setObjectName(u"translate")
40
+
41
+ self.verticalLayout_2.addWidget(self.translate)
42
+
43
+ self.translate_ten = QPushButton(tapeDialog)
44
+ self.translate_ten.setObjectName(u"translate_ten")
45
+
46
+ self.verticalLayout_2.addWidget(self.translate_ten)
47
+
48
+ self.translate_all = QPushButton(tapeDialog)
49
+ self.translate_all.setObjectName(u"translate_all")
50
+
51
+ self.verticalLayout_2.addWidget(self.translate_all)
52
+
53
+ self.undo_last = QPushButton(tapeDialog)
54
+ self.undo_last.setObjectName(u"undo_last")
55
+
56
+ self.verticalLayout_2.addWidget(self.undo_last)
57
+
58
+
59
+ self.horizontalLayout.addLayout(self.verticalLayout_2)
60
+
61
+ self.tape_view = QListView(tapeDialog)
62
+ self.tape_view.setObjectName(u"tape_view")
63
+ self.tape_view.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
64
+ self.tape_view.setProperty(u"showDropIndicator", False)
65
+
66
+ self.horizontalLayout.addWidget(self.tape_view)
67
+
68
+
69
+ self.verticalLayout.addLayout(self.horizontalLayout)
70
+
71
+ self.buttonBox = QDialogButtonBox(tapeDialog)
72
+ self.buttonBox.setObjectName(u"buttonBox")
73
+ self.buttonBox.setOrientation(Qt.Orientation.Horizontal)
74
+ self.buttonBox.setStandardButtons(QDialogButtonBox.StandardButton.Cancel|QDialogButtonBox.StandardButton.Ok)
75
+
76
+ self.verticalLayout.addWidget(self.buttonBox)
77
+
78
+
79
+ self.retranslateUi(tapeDialog)
80
+ self.buttonBox.accepted.connect(tapeDialog.accept)
81
+ self.buttonBox.rejected.connect(tapeDialog.reject)
82
+
83
+ QMetaObject.connectSlotsByName(tapeDialog)
84
+ # setupUi
85
+
86
+ def retranslateUi(self, tapeDialog):
87
+ tapeDialog.setWindowTitle(QCoreApplication.translate("tapeDialog", u"Dialog", None))
88
+ self.select_tape.setText(QCoreApplication.translate("tapeDialog", u"Select Tape File", None))
89
+ self.translate.setText(QCoreApplication.translate("tapeDialog", u"Translate 1", None))
90
+ self.translate_ten.setText(QCoreApplication.translate("tapeDialog", u"Translate 10", None))
91
+ self.translate_all.setText(QCoreApplication.translate("tapeDialog", u"Translate All Succeeding", None))
92
+ self.undo_last.setText(QCoreApplication.translate("tapeDialog", u"Undo Last", None))
93
+ # retranslateUi
94
+
@@ -3,7 +3,7 @@
3
3
  ################################################################################
4
4
  ## Form generated from reading UI file 'test_dialog.ui'
5
5
  ##
6
- ## Created by: Qt User Interface Compiler version 6.9.2
6
+ ## Created by: Qt User Interface Compiler version 6.10.2
7
7
  ##
8
8
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
9
9
  ################################################################################
@@ -1,40 +0,0 @@
1
- plover2cat-4.0.0a1.dist-info/licenses/LICENSE.txt,sha256=nmGAW0AJG4ke0VT1kvbz6m_jBMcnRRcJQnBtJmKAKU0,1084
2
- plover_cat/FlowLayout.py,sha256=3sCpVJCNJNwIimyFFlSOaNt-TNb-6kFwvlxwRI3QtNg,3707
3
- plover_cat/PloverCATWindow.py,sha256=CGgJ381usOx9kC8zekVK70892hC8thi8uAmqla8vkqA,156212
4
- plover_cat/TextEditor.py,sha256=EdC3D60cLypoHg80jizljEkfJt7Ja-j5Ri9foiN_sV4,63383
5
- plover_cat/__init__.py,sha256=vg2Hh4rB32Uasptr9ZZPhBpAaI5lUV0m4G6WiLt3nOU,820
6
- plover_cat/__version__.py,sha256=_fsxWOZfbNI4mXLh4P-xhdbPcH5o8IXuGvbnQj1c3N0,33
7
- plover_cat/affixDialogWindow.py,sha256=p-SlQR7rDYeTWJeSwjT0RqqLUtvxgeWQUzA9HBLwSME,2729
8
- plover_cat/affix_dialog_ui.py,sha256=8dqlCZCEOA29fzOFpSa66lehjYt7QOJcwSUesKIZOPc,5665
9
- plover_cat/captionDialogWindow.py,sha256=Zc3JqwaHasJF7FsmLH7hAEYDvbvbuKNihsXDIBqlZN0,2817
10
- plover_cat/captionWorker.py,sha256=MFjoYnJ2pEeU9KalUlN0PmygVoOvKAdlc1LM8SPQRlw,8210
11
- plover_cat/caption_dialog_ui.py,sha256=hPLVru4II6CtHDMjr7qMZvG-1NXzEvIZES2xcHIyyo4,9725
12
- plover_cat/constants.py,sha256=wDKCJPJuasBpHu6DsiOPW2dlRTWR1ayUYCjEEutQvKs,4933
13
- plover_cat/create_dialog_ui.py,sha256=q3467-b9u4EVYcSf_a1n44Ob3kzhDHJSK1jWEFoZNzY,4387
14
- plover_cat/documentWorker.py,sha256=VmgqscHSEjxIEOpdHSydTkOm9mg1zUc5Djkgkc4S1uA,33512
15
- plover_cat/export_helpers.py,sha256=Tw2r8JroK3lbFpinmBuZKEpt7M1N9-USehwT-EHbXMQ,20116
16
- plover_cat/fieldDialogWindow.py,sha256=DhVxHb5r1Hp_JUvEX9zicH695pG2RUQXol6PTOKsJjA,3134
17
- plover_cat/field_dialog_ui.py,sha256=Mp6LEkjtsWC9rF6_ityZidv4vm2NRNIwJEJH7W3DLPg,5585
18
- plover_cat/helpers.py,sha256=xImF2Rgj246TGotVfvW8jOJEdbo3IfqzwGnSb5mw87U,5582
19
- plover_cat/indexDialogWindow.py,sha256=tx5dIAVKuEAMBsmudjb8G4le22ySEQ1blXe-WT_VyUA,5640
20
- plover_cat/index_dialog_ui.py,sha256=nX18ThtZi8uM0a-6W5Y7dxnahfm6LciKaJhmh6Cf9VU,8062
21
- plover_cat/plover_cat_ui.py,sha256=hwQeyvwIlfvBRGTX0977trX303AvwhyU9LaBZm4O3uI,158388
22
- plover_cat/qcommands.py,sha256=5HGazgGS_KgOjowzEMpBiP4O5dQGYvKhc3GhlFjGjaM,39342
23
- plover_cat/recorderDialogWindow.py,sha256=PqcM4kmg1ipNiNG3g97MWC5Wfaeu7wQqLxmZ9-6gf1I,2917
24
- plover_cat/recorder_dialog_ui.py,sha256=2Bn8RW3alXV29bU46R0YrM7rKTROrFGkGyopkZHWLXE,7781
25
- plover_cat/resources_rc.py,sha256=YMhA4nqYfp7vItP3zJL7qlItKGALOsMuPXB2ba8c7Mw,126110
26
- plover_cat/rtf_parsing.py,sha256=6p-9oH73vep4dG53tl9TDfNfoX0Ggv8KPeDXolXH5nY,21299
27
- plover_cat/shortcutDialogWindow.py,sha256=8Tlk6v2-z6lyRdDR4Y7rquKxoqGL1UkCnYiKVHipgoQ,2453
28
- plover_cat/shortcut_dialog_ui.py,sha256=_TayFrjTBdTj_y9dAV_Iz7GPLe0BEv9tbCOSQaq_Gtc,4503
29
- plover_cat/spellcheck.py,sha256=r0dO34PGLpMbPypkFHE08jTrClGWen8C89BdmMidKVU,6695
30
- plover_cat/steno_objects.py,sha256=RfMUofAC2TZvi4zhe8qdzY-2iHjn2ePxogLCH9aGVAQ,42843
31
- plover_cat/suggestDialogWindow.py,sha256=Oa2HSh9b8rsxjtcxgMFSqpNnwmPuYoLywIkYUL_19z0,6404
32
- plover_cat/suggest_dialog_ui.py,sha256=6Ds50LoSE7N2AqzYnvbh4uzyDqv4HMTvZHizFm_dtSA,8782
33
- plover_cat/testDialogWindow.py,sha256=wqkk_6mGRcKlNHdVc3P_yTkt4x70MOtUZlLYU3RN0bM,21821
34
- plover_cat/test_dialog_ui.py,sha256=BdJYfN7Ua7SGIUR-iOvs7MzbHlRj8cIyUu-HCMHpTfM,4735
35
- plover2cat-4.0.0a1.dist-info/METADATA,sha256=DQeqs9XoZ3i-tCzSizCapI07-y3ahv_-3w8nANukA6A,5073
36
- plover2cat-4.0.0a1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
- plover2cat-4.0.0a1.dist-info/entry_points.txt,sha256=bZekpaOB8tv7DjkjuOBYrIdcMgCNuOYDrXKmV6Mgd1o,55
38
- plover2cat-4.0.0a1.dist-info/top_level.txt,sha256=q7Rw-aE6ep8anwrqhiZOlCig80KhoV4bmE8yWiIlL4E,11
39
- plover2cat-4.0.0a1.dist-info/zip-safe,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
40
- plover2cat-4.0.0a1.dist-info/RECORD,,