Skip to content

Commit 115968b

Browse files
committed
Last changes/bugs before new release
1 parent 7cbb5f5 commit 115968b

File tree

10 files changed

+142
-61
lines changed

10 files changed

+142
-61
lines changed

CHANGES.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CHANGES
22

3-
Unreleased (ver 2.2.0):
3+
# Ver 2.2.0 (2023-08-13)
44

55
- Change: Style submenu added, now style change shortcuts are visible to user (`Ctrl + {0-9}`) for first ten styles.
66

@@ -12,7 +12,11 @@ Unreleased (ver 2.2.0):
1212

1313
- Bug: Multiple empty line strings were not generating the paragraphs needed, ie `\n\n`
1414

15-
- Change: text elements and stroke elements now have `__add__`, other classes raise errors. This is used to collapse like-class elements for steno wrapping.
15+
- Change: text elements and stroke elements now have `__add__` and `__radd__`, other classes raise errors. This is used to collapse like-class elements for steno wrapping.
16+
17+
- Change: Window titlebar now updates with transcript name when transcript is opened.
18+
19+
- Bug: removed thread deletion from `export_*` as before, a second export would crash.
1620

1721
## Ver 2.1.1 (2023-08-06)
1822

docs/howto/captions.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
Plover2CAT can display input text in a separate window as captions.
44

5+
![Gif showing captioning.](images/caption_example.gif)
6+
57
## Caption set up
68

79
Click `Audiovisual > Captioning` to activate the captioning settings dialog, use or set the settings below, and then click `OK`.
357 KB
Loading

docs/reference/elements.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ It has the methods:
2828
- `__getitem__`: returns new instance after deepcopy
2929
- `__repr__`: representation as `dict`
3030
- `__add__`: adds together text, and updates time from other
31+
- `__radd__`: returns `NotImplemented`
3132
- `length`: returns length of string, here as placeholder in order to keep consistency with other subclassed elements, the functional length
3233
- `split`: splits text string on whitespace (re from textwrapper), returns list of elements containing each text piece separately, but same otherwise as original
3334
- `from_dict`: can populate class using a dict
@@ -50,7 +51,8 @@ It has the additional attributes:
5051

5152
Overriding methods:
5253

53-
- `__add__`: will only combine elements but not across word boundaries (spaces)
54+
- `__add__`: will only combine elements but not across word boundaries (spaces), can accept `stroke_text` and `text_element`
55+
- `__radd__`: works with `text_element` addition properly, `NotImplemented` otherwise
5456
- `to_rtf`
5557
- `to_display`
5658

@@ -67,7 +69,7 @@ It has the additional attributes:
6769

6870
Overriding methods:
6971

70-
- `__add__`: throws error
72+
- `__add__`: `NotImplemented`
7173
- `length`: 1
7274
- `to_display`
7375
- `to_odt`
@@ -85,7 +87,7 @@ It has the additional elements:
8587

8688
Overriding methods:
8789

88-
- `__add__`: throws error
90+
- `__add__`: `NotImplemented`
8991
- `length`: 1
9092
- `to_json`: do not output `user_field_dict`, no need for a copy of all fields with each element
9193
- `to_display`:
@@ -111,7 +113,8 @@ It has the additional attributes:
111113

112114
It has the methods:
113115

114-
- `__add__`: throws error
116+
- `__add__`: `NotImplemented`
117+
- `__radd__`: `NotImplemented`, overrides `__radd__` from `stroke_text`
115118
- *`length`*: the length of the text only, the element's "functional" length
116119
- `__len__`: returns length of prefix + text + suffix
117120
- `to_text`: string of prefix + text + suffix
@@ -137,12 +140,16 @@ It has the additional attributes:
137140

138141
Overriding methods:
139142

140-
- `__add__`: throws error
143+
- `__add__`: `NotImplemented`
141144

142145
The actual "number" for the exhibit is stored in the `text` attribute.
143146

144147
Has non-breaking space in `to_text` so that "prefix" and "number" are always together even for text formats.
145148

149+
## Combining elements
150+
151+
Only strictly text and stroke elements can be combined through `__add__` and `__radd__`, ie while `automatic_text` subclasses `stroke_text`, the two should not be combined. This is primarily for the use of collapsing elements into word chunks, as `pre` and `pare ` may be two stroke elements, but should be treated as one for wrapping, otherwise, steno wrapping may wrap in unwanted places.
152+
146153
## element_collection
147154

148155
This is the container holding a list of elements. It subclasses `UserList` and overrides some methods. Despite being an `UserList` list, the methods mean it behaves like a `string` in many ways.

plover_cat/captionWorker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def make_caps(self):
4444
else:
4545
self.cap_line += self.next_word
4646
def send_cap(self):
47-
print(f"queue size {self.cap_queue.qsize()}.")
47+
# print(f"queue size {self.cap_queue.qsize()}.")
4848
try:
4949
cap, time = self.cap_queue.get_nowait()
5050
self.capSend.emit(cap)

plover_cat/caption_dialog.ui

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@
6969
<property name="toolTip">
7070
<string>Optional, only display this number of lines in caption window</string>
7171
</property>
72+
<property name="value">
73+
<number>2</number>
74+
</property>
7275
</widget>
7376
</item>
7477
<item row="5" column="0">

plover_cat/documentWorker.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,5 +529,4 @@ def save_srt(self):
529529
with open(file_path, "w", encoding="utf-8") as f:
530530
for line in doc_lines:
531531
f.write(f"{line}\n")
532-
# self.statusBar.showMessage("Exported in srt format")
533532
self.finished.emit()

plover_cat/main_window.py

Lines changed: 52 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ def __init__(self, engine):
207207
self.actionShowVideo.triggered.connect(lambda: self.show_hide_video())
208208
self.actionCaptioning.triggered.connect(self.setup_captions)
209209
self.actionFlushCaption.triggered.connect(self.flush_caption)
210+
self.actionAddChangeAudioTimestamps.triggered.connect(self.modify_audiotime)
210211
## editor related connections
211212
self.actionClearParagraph.triggered.connect(lambda: self.reset_paragraph())
212213
self.textEdit.complete.connect(self.insert_autocomplete)
@@ -648,7 +649,6 @@ def autosave_setup(self, checked):
648649
# open/close/save
649650
def create_new(self):
650651
self.mainTabs.setCurrentIndex(1)
651-
## make new dir, sets gui input
652652
project_dir = QFileDialog.getExistingDirectory(self, "Select Directory", plover.oslayer.config.CONFIG_DIR)
653653
if not project_dir:
654654
log.debug("No directory selected, not creating transcript folder.")
@@ -708,7 +708,8 @@ def create_new(self):
708708
self.textEdit.setCurrentCharFormat(self.txt_formats[self.style_selector.currentText()])
709709
self.textEdit.setTextCursor(document_cursor)
710710
self.textEdit.document().setDefaultFont(self.txt_formats[self.style_selector.currentText()].font())
711-
self.undo_stack.clear()
711+
self.undo_stack.clear()
712+
self.parent().setWindowTitle(f"Plover2CAT - {str(self.file_name.stem)}")
712713

713714
def open_file(self, file_path = ""):
714715
self.mainTabs.setCurrentIndex(1)
@@ -797,7 +798,8 @@ def open_file(self, file_path = ""):
797798
document_cursor.setBlockFormat(self.par_formats[self.style_selector.currentText()])
798799
document_cursor.setCharFormat(self.txt_formats[self.style_selector.currentText()])
799800
self.textEdit.document().setDefaultFont(self.txt_formats[self.style_selector.currentText()].font())
800-
self.undo_stack.clear()
801+
self.undo_stack.clear()
802+
self.parent().setWindowTitle(f"Plover2CAT - {str(self.file_name.stem)}")
801803

802804
def save_file(self):
803805
if not self.file_name:
@@ -828,7 +830,7 @@ def save_transcript(self, path):
828830
if block.userData():
829831
block_dict = deepcopy(block.userData().return_all())
830832
else:
831-
return
833+
return False
832834
block_num = block.blockNumber()
833835
# print(f"Paragraph {block_num} changed.")
834836
block_dict["strokes"] = block_dict["strokes"].to_json()
@@ -844,6 +846,7 @@ def save_transcript(self, path):
844846
json_document.pop(str(num), None)
845847
save_json(json_document, path)
846848
QApplication.restoreOverrideCursor()
849+
return True
847850

848851
def dulwich_save(self, message = "autosave"):
849852
self.statusBar.showMessage("Saving versioned copy.")
@@ -1015,11 +1018,11 @@ def autosave(self):
10151018
transcript = pathlib.Path(transcript)
10161019
if transcript.exists():
10171020
transcript.unlink()
1018-
self.save_transcript(transcript)
1019-
if os.name == "nt":
1021+
save_res = self.save_transcript(transcript)
1022+
if save_res and os.name == "nt":
10201023
# hide file on windows systems
10211024
hide_file(str(transcript))
1022-
self.statusBar.showMessage("Autosave complete.")
1025+
self.statusBar.showMessage("Autosave complete.")
10231026

10241027
def close_file(self):
10251028
if not self.undo_stack.isClean():
@@ -1057,6 +1060,7 @@ def close_file(self):
10571060
self.parSteno.clear()
10581061
self.autosave_time.stop()
10591062
self.statusBar.showMessage("Project closed")
1063+
self.parent()._update_title()
10601064
return True
10611065

10621066
def action_close(self):
@@ -2506,19 +2510,21 @@ def extract_indexes(self):
25062510
if len(self.textEdit.toPlainText()) == 0:
25072511
return
25082512
while True:
2509-
block_strokes = block.userData()["strokes"]
2510-
for ind, el in enumerate(block_strokes.data):
2511-
# print(ind)
2512-
if el.element == "index":
2513-
if el.indexname not in index_dict:
2514-
index_dict[el.indexname] = {}
2515-
if "prefix" not in index_dict[el.indexname]:
2516-
index_dict[el.indexname]["prefix"] = el.prefix
2517-
if "hidden" not in index_dict[el.indexname]:
2518-
index_dict[el.indexname]["hidden"] = el.hidden
2519-
if "entries" not in index_dict[el.indexname]:
2520-
index_dict[el.indexname]["entries"] = {}
2521-
index_dict[el.indexname]["entries"][el.data] = el.description
2513+
# print(block.blockNumber())
2514+
if block.userData():
2515+
block_strokes = block.userData()["strokes"]
2516+
for ind, el in enumerate(block_strokes.data):
2517+
# print(ind)
2518+
if el.element == "index":
2519+
if el.indexname not in index_dict:
2520+
index_dict[el.indexname] = {}
2521+
if "prefix" not in index_dict[el.indexname]:
2522+
index_dict[el.indexname]["prefix"] = el.prefix
2523+
if "hidden" not in index_dict[el.indexname]:
2524+
index_dict[el.indexname]["hidden"] = el.hidden
2525+
if "entries" not in index_dict[el.indexname]:
2526+
index_dict[el.indexname]["entries"] = {}
2527+
index_dict[el.indexname]["entries"][el.data] = el.description
25222528
if block == self.textEdit.document().lastBlock():
25232529
break
25242530
block = block.next()
@@ -3042,7 +3048,7 @@ def setup_captions(self, checked):
30423048
self.thread.started.connect(self.cap_worker.make_caps)
30433049
self.cap_worker.finished.connect(self.thread.quit)
30443050
self.cap_worker.finished.connect(self.cap_worker.deleteLater)
3045-
self.thread.finished.connect(self.thread.deleteLater)
3051+
# self.thread.finished.connect(self.thread.deleteLater)
30463052
self.cap_worker.capSend.connect(self.add_cap)
30473053
self.cap_worker.postMessage.connect(self.statusBar.showMessage)
30483054
self.thread.start()
@@ -3079,6 +3085,19 @@ def flush_caption(self):
30793085
self.cap_worker.intake(new_text + "\u2029")
30803086
self.caption_cursor_pos = max(current_cursor.position(), current_cursor.anchor())
30813087

3088+
def modify_audiotime(self):
3089+
block = self.textEdit.document().begin()
3090+
times = []
3091+
for i in range(self.textEdit.document().blockCount()):
3092+
if block.userData():
3093+
times.append(block.userData["creationtime"])
3094+
block_time = block.userData()["strokes"].collection_time()
3095+
times.append(block_time)
3096+
if block == self.textEdit.document().lastBlock():
3097+
break
3098+
block = block.next()
3099+
earliest = min([t for t in times if t])
3100+
print(earliest)
30823101
# export functions
30833102
def export_text(self):
30843103
selected_folder = pathlib.Path(self.file_name) / "export"
@@ -3127,8 +3146,8 @@ def export_ascii(self):
31273146
self.worker.progress.connect(self.progressBar.setValue)
31283147
self.worker.finished.connect(self.thread.quit)
31293148
self.worker.finished.connect(self.worker.deleteLater)
3130-
self.thread.finished.connect(self.thread.deleteLater)
3131-
self.thread.finished.connect(lambda: self.statusBar.showMessage("Exported in ASCII format."))
3149+
self.worker.finished.connect(lambda: self.statusBar.showMessage("Exported in ASCII format."))
3150+
# self.thread.finished.connect(self.thread.deleteLater)
31323151
self.thread.start()
31333152

31343153
def export_html(self):
@@ -3159,8 +3178,8 @@ def export_html(self):
31593178
self.worker.progress.connect(self.progressBar.setValue)
31603179
self.worker.finished.connect(self.thread.quit)
31613180
self.worker.finished.connect(self.worker.deleteLater)
3162-
self.thread.finished.connect(self.thread.deleteLater)
3163-
self.thread.finished.connect(lambda: self.statusBar.showMessage("Exported in HTML format."))
3181+
self.worker.finished.connect(lambda: self.statusBar.showMessage("Exported in HTML format."))
3182+
# self.thread.finished.connect(self.thread.deleteLater)
31643183
self.thread.start()
31653184

31663185
def export_plain_ascii(self):
@@ -3190,8 +3209,8 @@ def export_plain_ascii(self):
31903209
self.worker.progress.connect(self.progressBar.setValue)
31913210
self.worker.finished.connect(self.thread.quit)
31923211
self.worker.finished.connect(self.worker.deleteLater)
3193-
self.thread.finished.connect(self.thread.deleteLater)
3194-
self.thread.finished.connect(lambda: self.statusBar.showMessage("Exported in plain ASCII format."))
3212+
self.worker.finished.connect(lambda: self.statusBar.showMessage("Exported in plain ASCII format."))
3213+
# self.thread.finished.connect(self.thread.deleteLater)
31953214
self.thread.start()
31963215

31973216
def export_srt(self):
@@ -3227,8 +3246,8 @@ def export_srt(self):
32273246
self.worker.progress.connect(self.progressBar.setValue)
32283247
self.worker.finished.connect(self.thread.quit)
32293248
self.worker.finished.connect(self.worker.deleteLater)
3230-
self.thread.finished.connect(self.thread.deleteLater)
3231-
self.thread.finished.connect(lambda: self.statusBar.showMessage("Exported in srt format."))
3249+
self.worker.finished.connect(lambda: self.statusBar.showMessage("Exported in srt format."))
3250+
# self.thread.finished.connect(self.thread.deleteLater)
32323251
self.thread.start()
32333252

32343253
def export_odt(self):
@@ -3259,8 +3278,8 @@ def export_odt(self):
32593278
self.worker.progress.connect(self.progressBar.setValue)
32603279
self.worker.finished.connect(self.thread.quit)
32613280
self.worker.finished.connect(self.worker.deleteLater)
3262-
self.thread.finished.connect(self.thread.deleteLater)
3263-
self.thread.finished.connect(lambda: self.statusBar.showMessage("Exported in Open Document Format."))
3281+
self.worker.finished.connect(lambda: self.statusBar.showMessage("Exported in Open Document Format."))
3282+
# self.thread.finished.connect(self.thread.deleteLater)
32643283
self.thread.start()
32653284
# import rtf
32663285
def import_rtf(self):
@@ -3353,7 +3372,7 @@ def export_rtf(self):
33533372
self.worker.progress.connect(self.progressBar.setValue)
33543373
self.worker.finished.connect(self.thread.quit)
33553374
self.worker.finished.connect(self.worker.deleteLater)
3356-
self.thread.finished.connect(self.thread.deleteLater)
3357-
self.thread.finished.connect(lambda: self.statusBar.showMessage("Exported in RTF/CRE format."))
3375+
self.worker.finished.connect(lambda: self.statusBar.showMessage("Exported in RTF/CRE format."))
3376+
# self.thread.finished.connect(self.thread.deleteLater)
33583377
self.thread.start()
33593378

0 commit comments

Comments
 (0)