Anchor-annotator 0.5.0__py3-none-any.whl → 0.7.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.
- {Anchor_annotator-0.5.0.dist-info → Anchor_annotator-0.7.0.dist-info}/METADATA +1 -1
- Anchor_annotator-0.7.0.dist-info/RECORD +22 -0
- {Anchor_annotator-0.5.0.dist-info → Anchor_annotator-0.7.0.dist-info}/WHEEL +1 -1
- anchor/_version.py +2 -2
- anchor/db.py +1 -0
- anchor/main.py +31 -10
- anchor/models.py +103 -58
- anchor/plot.py +383 -362
- anchor/resources_rc.py +331 -150
- anchor/settings.py +10 -4
- anchor/ui_main_window.py +10 -0
- anchor/undo.py +18 -18
- anchor/widgets.py +103 -38
- anchor/workers.py +2485 -2462
- Anchor_annotator-0.5.0.dist-info/RECORD +0 -22
- {Anchor_annotator-0.5.0.dist-info → Anchor_annotator-0.7.0.dist-info}/LICENSE +0 -0
- {Anchor_annotator-0.5.0.dist-info → Anchor_annotator-0.7.0.dist-info}/top_level.txt +0 -0
anchor/settings.py
CHANGED
@@ -116,6 +116,8 @@ class AnchorSettings(QtCore.QSettings):
|
|
116
116
|
CLUSTERING_DISTANCE_THRESHOLD = "anchor/clustering/distance_threshold"
|
117
117
|
CLUSTERING_METRIC = "anchor/clustering/metric"
|
118
118
|
|
119
|
+
PLOT_THREAD_COUNT = "anchor/plot/max_thread_count"
|
120
|
+
|
119
121
|
PITCH_MAX_TIME = "anchor/pitch/max_time"
|
120
122
|
PITCH_MIN_F0 = "anchor/pitch/min_f0"
|
121
123
|
PITCH_MAX_F0 = "anchor/pitch/max_f0"
|
@@ -218,6 +220,7 @@ class AnchorSettings(QtCore.QSettings):
|
|
218
220
|
AnchorSettings.TIER_TRANSCRIBED_WORDS_VISIBLE: True,
|
219
221
|
AnchorSettings.TIER_TRANSCRIBED_PHONES_VISIBLE: True,
|
220
222
|
AnchorSettings.THEME_PRESET: "MFA",
|
223
|
+
AnchorSettings.PLOT_THREAD_COUNT: 10,
|
221
224
|
}
|
222
225
|
self.default_values.update(self.mfa_theme)
|
223
226
|
self.border_radius = 5
|
@@ -264,9 +267,10 @@ class AnchorSettings(QtCore.QSettings):
|
|
264
267
|
super(AnchorSettings, self).value(arg__1, self.default_values[arg__1])
|
265
268
|
)
|
266
269
|
elif "color" in arg__1:
|
267
|
-
value =
|
268
|
-
|
269
|
-
|
270
|
+
value = super(AnchorSettings, self).value(arg__1, self.default_values[arg__1])
|
271
|
+
if value is None:
|
272
|
+
value = self.default_values[arg__1]
|
273
|
+
value = QtGui.QColor(value)
|
270
274
|
elif "keybind" in arg__1:
|
271
275
|
value = QtGui.QKeySequence(
|
272
276
|
super(AnchorSettings, self).value(arg__1, self.default_values[arg__1])
|
@@ -319,6 +323,8 @@ class AnchorSettings(QtCore.QSettings):
|
|
319
323
|
|
320
324
|
def set_theme(self, theme):
|
321
325
|
for k, v in theme.items():
|
326
|
+
if v is None:
|
327
|
+
continue
|
322
328
|
self.setValue(k, v)
|
323
329
|
self.sync()
|
324
330
|
self.themeUpdated.emit()
|
@@ -909,7 +915,7 @@ class AnchorSettings(QtCore.QSettings):
|
|
909
915
|
}}
|
910
916
|
QToolButton:checked {{
|
911
917
|
color: {active_color};
|
912
|
-
background-color: {
|
918
|
+
background-color: {hover_background_color};
|
913
919
|
border-color: {active_border_color};
|
914
920
|
}}
|
915
921
|
QPushButton:disabled, QToolButton:disabled {{
|
anchor/ui_main_window.py
CHANGED
@@ -262,6 +262,8 @@ class Ui_MainWindow(object):
|
|
262
262
|
self.segmentUtteranceAct.setIcon(icon6)
|
263
263
|
self.openCorpusManagerAct = QAction(MainWindow)
|
264
264
|
self.openCorpusManagerAct.setObjectName("openCorpusManagerAct")
|
265
|
+
self.verifyTranscriptsAct = QAction(MainWindow)
|
266
|
+
self.verifyTranscriptsAct.setObjectName("verifyTranscriptsAct")
|
265
267
|
self.centralwidget = QWidget(MainWindow)
|
266
268
|
self.centralwidget.setObjectName("centralwidget")
|
267
269
|
self.verticalLayout_4 = QVBoxLayout(self.centralwidget)
|
@@ -663,6 +665,14 @@ class Ui_MainWindow(object):
|
|
663
665
|
QCoreApplication.translate("MainWindow", "Manage corpora and models", None)
|
664
666
|
)
|
665
667
|
# endif // QT_CONFIG(tooltip)
|
668
|
+
self.verifyTranscriptsAct.setText(
|
669
|
+
QCoreApplication.translate("MainWindow", "Verify transcripts", None)
|
670
|
+
)
|
671
|
+
# if QT_CONFIG(tooltip)
|
672
|
+
self.verifyTranscriptsAct.setToolTip(
|
673
|
+
QCoreApplication.translate("MainWindow", "Verify transcripts", None)
|
674
|
+
)
|
675
|
+
# endif // QT_CONFIG(tooltip)
|
666
676
|
self.menuCorpus.setTitle(QCoreApplication.translate("MainWindow", "Corpus", None))
|
667
677
|
self.loadRecentCorpusMenu.setTitle(
|
668
678
|
QCoreApplication.translate("MainWindow", "Load a recent corpus", None)
|
anchor/undo.py
CHANGED
@@ -427,28 +427,26 @@ class UpdateUtteranceTextCommand(FileCommand):
|
|
427
427
|
"UpdateUtteranceTextCommand", "Update utterance text"
|
428
428
|
)
|
429
429
|
)
|
430
|
+
self.tokenizer = self.corpus_model.corpus.get_tokenizer(
|
431
|
+
self.corpus_model.corpus.get_dict_id_for_speaker(
|
432
|
+
self.corpus_model.get_speaker_name(self.speaker_id)
|
433
|
+
)
|
434
|
+
)
|
430
435
|
|
431
|
-
def
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
self.utterance.text = self.new_text
|
437
|
-
self.utterance.normalized_text = self.new_text # FIXME: Update this
|
436
|
+
def _process_text(self, session, text: str):
|
437
|
+
self.utterance.text = text
|
438
|
+
normalized_text, normalized_character_text, oovs = self.tokenizer(text)
|
439
|
+
self.utterance.normalized_text = normalized_text
|
440
|
+
self.utterance.normalized_character_text = normalized_character_text
|
438
441
|
self.utterance.oovs = " ".join(oovs)
|
439
|
-
self.utterance.ignored = not
|
442
|
+
self.utterance.ignored = not text
|
440
443
|
session.merge(self.utterance)
|
441
444
|
|
445
|
+
def _redo(self, session) -> None:
|
446
|
+
self._process_text(session, self.new_text)
|
447
|
+
|
442
448
|
def _undo(self, session) -> None:
|
443
|
-
|
444
|
-
for w in self.new_text.split():
|
445
|
-
if not self.corpus_model.dictionary_model.check_word(w, self.speaker_id):
|
446
|
-
oovs.add(w)
|
447
|
-
self.utterance.text = self.old_text
|
448
|
-
self.utterance.normalized_text = self.old_text # FIXME: Update this
|
449
|
-
self.utterance.oovs = " ".join(oovs)
|
450
|
-
self.utterance.ignored = not self.old_text
|
451
|
-
session.merge(self.utterance)
|
449
|
+
self._process_text(session, self.old_text)
|
452
450
|
|
453
451
|
def id(self) -> int:
|
454
452
|
return 1
|
@@ -767,7 +765,9 @@ class AddPronunciationCommand(DictionaryCommand):
|
|
767
765
|
|
768
766
|
def _redo(self, session) -> None:
|
769
767
|
if self.word_id is None:
|
770
|
-
|
768
|
+
q = session.query(Word.id).filter(Word.word == self.word).first()
|
769
|
+
if q is not None:
|
770
|
+
self.word_id = q[0]
|
771
771
|
if self.word_id is None:
|
772
772
|
self.word_id = session.query(sqlalchemy.func.max(Word.id)).scalar() + 1
|
773
773
|
word_mapping_id = (
|
anchor/widgets.py
CHANGED
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
import os
|
4
4
|
import re
|
5
|
+
import time
|
5
6
|
import typing
|
6
7
|
from typing import TYPE_CHECKING, Optional
|
7
8
|
|
@@ -93,13 +94,6 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
|
|
93
94
|
self.fade_in_anim.setEasingCurve(QtCore.QEasingCurve.Type.Linear)
|
94
95
|
self.fade_in_anim.setKeyValueAt(0.1, 0.1)
|
95
96
|
|
96
|
-
self.fade_out_anim = QtCore.QPropertyAnimation(self._audio_output, b"volume")
|
97
|
-
self.fade_out_anim.setDuration(5)
|
98
|
-
self.fade_out_anim.setStartValue(self._audio_output.volume())
|
99
|
-
self.fade_out_anim.setEndValue(0)
|
100
|
-
self.fade_out_anim.setEasingCurve(QtCore.QEasingCurve.Type.Linear)
|
101
|
-
self.fade_out_anim.setKeyValueAt(0.1, self._audio_output.volume())
|
102
|
-
self.fade_out_anim.finished.connect(super().pause)
|
103
97
|
self.file_path = None
|
104
98
|
self.set_volume(self.settings.value(self.settings.VOLUME))
|
105
99
|
|
@@ -113,6 +107,12 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
|
|
113
107
|
def play(self) -> None:
|
114
108
|
if self.startTime() is None:
|
115
109
|
return
|
110
|
+
if self.mediaStatus() not in {
|
111
|
+
QtMultimedia.QMediaPlayer.MediaStatus.BufferedMedia,
|
112
|
+
QtMultimedia.QMediaPlayer.MediaStatus.LoadedMedia,
|
113
|
+
QtMultimedia.QMediaPlayer.MediaStatus.EndOfMedia,
|
114
|
+
}:
|
115
|
+
return
|
116
116
|
fade_in = self.settings.value(self.settings.ENABLE_FADE)
|
117
117
|
if fade_in:
|
118
118
|
self._audio_output.setVolume(0.1)
|
@@ -167,7 +167,7 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
|
|
167
167
|
if selection_model is None:
|
168
168
|
return
|
169
169
|
self.selection_model = selection_model
|
170
|
-
self.selection_model.fileChanged.connect(self.
|
170
|
+
self.selection_model.fileChanged.connect(self.load_new_file)
|
171
171
|
self.selection_model.viewChanged.connect(self.update_times)
|
172
172
|
self.selection_model.selectionAudioChanged.connect(self.update_selection_times)
|
173
173
|
|
@@ -175,24 +175,23 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
|
|
175
175
|
self.settings.setValue(self.settings.VOLUME, volume)
|
176
176
|
if self.audioOutput() is None:
|
177
177
|
return
|
178
|
-
linearVolume = QtMultimedia.
|
178
|
+
linearVolume = QtMultimedia.QAudio.convertVolume(
|
179
179
|
volume / 100.0,
|
180
|
-
QtMultimedia.
|
181
|
-
QtMultimedia.
|
180
|
+
QtMultimedia.QAudio.VolumeScale.LogarithmicVolumeScale,
|
181
|
+
QtMultimedia.QAudio.VolumeScale.LinearVolumeScale,
|
182
182
|
)
|
183
183
|
self.audioOutput().setVolume(linearVolume)
|
184
184
|
self.fade_in_anim.setEndValue(linearVolume)
|
185
|
-
self.fade_out_anim.setStartValue(linearVolume)
|
186
185
|
|
187
186
|
def volume(self) -> int:
|
188
187
|
if self.audioOutput() is None:
|
189
188
|
return 100
|
190
189
|
volume = self.audioOutput().volume()
|
191
190
|
volume = int(
|
192
|
-
QtMultimedia.
|
191
|
+
QtMultimedia.QAudio.convertVolume(
|
193
192
|
volume,
|
194
|
-
QtMultimedia.
|
195
|
-
QtMultimedia.
|
193
|
+
QtMultimedia.QAudio.VolumeScale.LinearVolumeScale,
|
194
|
+
QtMultimedia.QAudio.VolumeScale.LogarithmicVolumeScale,
|
196
195
|
)
|
197
196
|
* 100
|
198
197
|
)
|
@@ -211,9 +210,13 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
|
|
211
210
|
self.stop()
|
212
211
|
self.setCurrentTime(self.startTime())
|
213
212
|
|
214
|
-
def
|
215
|
-
self.
|
216
|
-
|
213
|
+
def load_new_file(self, *args):
|
214
|
+
if self.playbackState() in {
|
215
|
+
QtMultimedia.QMediaPlayer.PlaybackState.PlayingState,
|
216
|
+
QtMultimedia.QMediaPlayer.PlaybackState.PausedState,
|
217
|
+
}:
|
218
|
+
self.stop()
|
219
|
+
time.sleep(0.1)
|
217
220
|
try:
|
218
221
|
new_file = self.selection_model.model().file.sound_file.sound_file_path
|
219
222
|
except Exception:
|
@@ -227,8 +230,6 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
|
|
227
230
|
self.setSource(QtCore.QUrl())
|
228
231
|
return
|
229
232
|
self.setSource(f"file:///{new_file}")
|
230
|
-
self.setPosition(0)
|
231
|
-
self.audioReady.emit(True)
|
232
233
|
|
233
234
|
def currentTime(self):
|
234
235
|
pos = self.position()
|
@@ -1063,21 +1064,72 @@ class SearchBox(ClearableField):
|
|
1063
1064
|
|
1064
1065
|
def __init__(self, *args):
|
1065
1066
|
super().__init__(*args)
|
1067
|
+
settings = AnchorSettings()
|
1066
1068
|
self.returnPressed.connect(self.activate)
|
1067
1069
|
self.setObjectName("search_box")
|
1068
1070
|
|
1069
1071
|
self.clear_action.triggered.connect(self.returnPressed.emit)
|
1070
1072
|
|
1071
|
-
regex_icon = QtGui.QIcon
|
1073
|
+
regex_icon = QtGui.QIcon()
|
1074
|
+
word_icon = QtGui.QIcon()
|
1075
|
+
case_icon = QtGui.QIcon()
|
1076
|
+
if (
|
1077
|
+
settings.theme_preset == "Native"
|
1078
|
+
and QtGui.QGuiApplication.styleHints().colorScheme() == QtCore.Qt.ColorScheme.Dark
|
1079
|
+
):
|
1080
|
+
regex_icon.addFile(
|
1081
|
+
":icons/anchor_dark/actions/edit-regex.svg",
|
1082
|
+
mode=QtGui.QIcon.Mode.Normal,
|
1083
|
+
state=QtGui.QIcon.State.Off,
|
1084
|
+
)
|
1085
|
+
word_icon.addFile(
|
1086
|
+
":icons/anchor_dark/actions/edit-word.svg",
|
1087
|
+
mode=QtGui.QIcon.Mode.Normal,
|
1088
|
+
state=QtGui.QIcon.State.Off,
|
1089
|
+
)
|
1090
|
+
case_icon.addFile(
|
1091
|
+
":icons/anchor_dark/actions/edit-case.svg",
|
1092
|
+
mode=QtGui.QIcon.Mode.Normal,
|
1093
|
+
state=QtGui.QIcon.State.Off,
|
1094
|
+
)
|
1095
|
+
else:
|
1096
|
+
regex_icon.addFile(
|
1097
|
+
":icons/anchor_light/actions/edit-regex.svg",
|
1098
|
+
mode=QtGui.QIcon.Mode.Normal,
|
1099
|
+
state=QtGui.QIcon.State.Off,
|
1100
|
+
)
|
1101
|
+
word_icon.addFile(
|
1102
|
+
":icons/anchor_light/actions/edit-word.svg",
|
1103
|
+
mode=QtGui.QIcon.Mode.Normal,
|
1104
|
+
state=QtGui.QIcon.State.Off,
|
1105
|
+
)
|
1106
|
+
case_icon.addFile(
|
1107
|
+
":icons/anchor_light/actions/edit-case.svg",
|
1108
|
+
mode=QtGui.QIcon.Mode.Normal,
|
1109
|
+
state=QtGui.QIcon.State.Off,
|
1110
|
+
)
|
1111
|
+
regex_icon.addFile(
|
1112
|
+
":icons/edit-regex-checked.svg",
|
1113
|
+
mode=QtGui.QIcon.Mode.Normal,
|
1114
|
+
state=QtGui.QIcon.State.On,
|
1115
|
+
)
|
1116
|
+
word_icon.addFile(
|
1117
|
+
":icons/edit-word-checked.svg",
|
1118
|
+
mode=QtGui.QIcon.Mode.Normal,
|
1119
|
+
state=QtGui.QIcon.State.On,
|
1120
|
+
)
|
1121
|
+
case_icon.addFile(
|
1122
|
+
":icons/edit-case-checked.svg",
|
1123
|
+
mode=QtGui.QIcon.Mode.Normal,
|
1124
|
+
state=QtGui.QIcon.State.On,
|
1125
|
+
)
|
1072
1126
|
|
1073
1127
|
self.regex_action = QtGui.QAction(icon=regex_icon, parent=self)
|
1074
1128
|
self.regex_action.setCheckable(True)
|
1075
1129
|
|
1076
|
-
word_icon = QtGui.QIcon.fromTheme("edit-word")
|
1077
1130
|
self.word_action = QtGui.QAction(icon=word_icon, parent=self)
|
1078
1131
|
self.word_action.setCheckable(True)
|
1079
1132
|
|
1080
|
-
case_icon = QtGui.QIcon.fromTheme("edit-case")
|
1081
1133
|
self.case_action = QtGui.QAction(icon=case_icon, parent=self)
|
1082
1134
|
self.case_action.setCheckable(True)
|
1083
1135
|
|
@@ -1108,7 +1160,7 @@ class SearchBox(ClearableField):
|
|
1108
1160
|
def query(self) -> TextFilterQuery:
|
1109
1161
|
filter = TextFilterQuery(
|
1110
1162
|
super().text(),
|
1111
|
-
self.regex_action.isChecked()
|
1163
|
+
self.regex_action.isChecked(),
|
1112
1164
|
self.word_action.isChecked(),
|
1113
1165
|
self.case_action.isChecked(),
|
1114
1166
|
)
|
@@ -2063,7 +2115,7 @@ class OovTableView(AnchorTableView):
|
|
2063
2115
|
|
2064
2116
|
def generate_context_menu(self, location):
|
2065
2117
|
menu = QtWidgets.QMenu()
|
2066
|
-
|
2118
|
+
menu.setStyleSheet(self.settings.menu_style_sheet)
|
2067
2119
|
menu.addAction(self.add_pronunciation_action)
|
2068
2120
|
menu.exec_(self.mapToGlobal(location))
|
2069
2121
|
|
@@ -2122,7 +2174,7 @@ class DictionaryTableView(AnchorTableView):
|
|
2122
2174
|
|
2123
2175
|
def generate_context_menu(self, location):
|
2124
2176
|
menu = QtWidgets.QMenu()
|
2125
|
-
|
2177
|
+
menu.setStyleSheet(self.settings.menu_style_sheet)
|
2126
2178
|
menu.addAction(self.add_pronunciation_action)
|
2127
2179
|
menu.addSeparator()
|
2128
2180
|
menu.addAction(self.delete_words_action)
|
@@ -2205,8 +2257,7 @@ class SpeakerTableView(AnchorTableView):
|
|
2205
2257
|
| QtWidgets.QAbstractItemView.EditTrigger.DoubleClicked
|
2206
2258
|
)
|
2207
2259
|
self.speaker_model: SpeakerModel = None
|
2208
|
-
self.view_delegate = ButtonDelegate("
|
2209
|
-
self.delete_delegate = ButtonDelegate(":expand.svg", self)
|
2260
|
+
self.view_delegate = ButtonDelegate("edit-find", self)
|
2210
2261
|
self.edit_delegate = EditableDelegate(self)
|
2211
2262
|
self.speaker_delegate = SpeakerViewDelegate(self)
|
2212
2263
|
self.setItemDelegateForColumn(1, self.speaker_delegate)
|
@@ -2500,7 +2551,7 @@ class ButtonDelegate(QtWidgets.QStyledItemDelegate):
|
|
2500
2551
|
options = QtWidgets.QStyleOptionViewItem(option)
|
2501
2552
|
options.rect = QtCore.QRect(x, y, self.settings.icon_size, self.settings.icon_size)
|
2502
2553
|
self.initStyleOption(options, index)
|
2503
|
-
icon = QtGui.QIcon(self.icon_path)
|
2554
|
+
icon = QtGui.QIcon.fromTheme(self.icon_path)
|
2504
2555
|
icon.paint(painter, options.rect, QtCore.Qt.AlignmentFlag.AlignCenter)
|
2505
2556
|
|
2506
2557
|
painter.restore()
|
@@ -2899,9 +2950,13 @@ class AlignmentWidget(QtWidgets.QWidget):
|
|
2899
2950
|
def __init__(self, *args):
|
2900
2951
|
super().__init__(*args)
|
2901
2952
|
self.button = QtWidgets.QToolButton()
|
2902
|
-
|
2953
|
+
self.verify_button = QtWidgets.QToolButton()
|
2954
|
+
form_layout = QtWidgets.QFormLayout()
|
2955
|
+
button_layout = QtWidgets.QHBoxLayout()
|
2956
|
+
layout = QtWidgets.QVBoxLayout()
|
2903
2957
|
self.acoustic_model_label = QtWidgets.QLabel("Not loaded")
|
2904
2958
|
self.dictionary_label = QtWidgets.QLabel("Not loaded")
|
2959
|
+
self.interjection_word_label = QtWidgets.QLabel("Not loaded")
|
2905
2960
|
self.fine_tune_check = QtWidgets.QCheckBox()
|
2906
2961
|
self.beam = QtWidgets.QSpinBox()
|
2907
2962
|
self.beam.setMinimum(6)
|
@@ -2914,14 +2969,18 @@ class AlignmentWidget(QtWidgets.QWidget):
|
|
2914
2969
|
self.silence_boost = ThresholdWidget()
|
2915
2970
|
self.silence_boost.setText("1.0")
|
2916
2971
|
self.cutoff_check = QtWidgets.QCheckBox()
|
2917
|
-
|
2918
|
-
|
2919
|
-
|
2920
|
-
|
2921
|
-
|
2922
|
-
|
2923
|
-
|
2924
|
-
|
2972
|
+
form_layout.addRow(QtWidgets.QLabel("Acoustic model"), self.acoustic_model_label)
|
2973
|
+
form_layout.addRow(QtWidgets.QLabel("Dictionary"), self.dictionary_label)
|
2974
|
+
form_layout.addRow(QtWidgets.QLabel("Beam"), self.beam)
|
2975
|
+
form_layout.addRow(QtWidgets.QLabel("Retry beam"), self.retry_beam)
|
2976
|
+
form_layout.addRow(QtWidgets.QLabel("Silence boost factor"), self.silence_boost)
|
2977
|
+
form_layout.addRow(QtWidgets.QLabel("Fine tune"), self.fine_tune_check)
|
2978
|
+
form_layout.addRow(QtWidgets.QLabel("Cutoff modeling"), self.cutoff_check)
|
2979
|
+
form_layout.addRow(QtWidgets.QLabel("Interjection words"), self.interjection_word_label)
|
2980
|
+
layout.addLayout(form_layout)
|
2981
|
+
button_layout.addWidget(self.button)
|
2982
|
+
button_layout.addWidget(self.verify_button)
|
2983
|
+
layout.addLayout(button_layout)
|
2925
2984
|
self.text = QtWidgets.QTextEdit()
|
2926
2985
|
self.text.setReadOnly(True)
|
2927
2986
|
layout.addWidget(self.text)
|
@@ -2930,6 +2989,10 @@ class AlignmentWidget(QtWidgets.QWidget):
|
|
2930
2989
|
|
2931
2990
|
def refresh(self):
|
2932
2991
|
validate_enabled = True
|
2992
|
+
num_interjection_words = self.corpus_model.get_interjection_count()
|
2993
|
+
self.interjection_word_label.setText(str(num_interjection_words))
|
2994
|
+
if self.verify_button.defaultAction() is not None:
|
2995
|
+
self.verify_button.defaultAction().setEnabled(num_interjection_words > 0)
|
2933
2996
|
if self.corpus_model.has_dictionary:
|
2934
2997
|
self.dictionary_label.setText(self.corpus_model.corpus.dictionary_model.name)
|
2935
2998
|
else:
|
@@ -2948,6 +3011,7 @@ class AlignmentWidget(QtWidgets.QWidget):
|
|
2948
3011
|
self.refresh()
|
2949
3012
|
self.corpus_model.dictionaryChanged.connect(self.refresh)
|
2950
3013
|
self.corpus_model.acousticModelChanged.connect(self.refresh)
|
3014
|
+
self.corpus_model.corpusLoaded.connect(self.refresh)
|
2951
3015
|
|
2952
3016
|
def parameters(self):
|
2953
3017
|
return {
|
@@ -3228,6 +3292,7 @@ class SpeakerWidget(QtWidgets.QWidget):
|
|
3228
3292
|
session.query(Speaker.id).filter(Speaker.name == speaker_id).first()
|
3229
3293
|
)
|
3230
3294
|
if actual_speaker_id is None:
|
3295
|
+
self.speaker_model.set_speaker_filter(speaker_id)
|
3231
3296
|
return
|
3232
3297
|
self.speaker_dropdown.completions[speaker_id] = actual_speaker_id[0]
|
3233
3298
|
speaker_id = actual_speaker_id[0]
|