Anchor-annotator 0.3.3__py3-none-any.whl → 0.5.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/widgets.py CHANGED
@@ -57,7 +57,7 @@ class ErrorButtonBox(QtWidgets.QDialogButtonBox):
57
57
  super().__init__(*args, **kwargs)
58
58
  self.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Close)
59
59
  self.report_bug_button = QtWidgets.QPushButton("Report bug")
60
- self.report_bug_button.setIcon(QtGui.QIcon(":external-link.svg"))
60
+ self.report_bug_button.setIcon(QtGui.QIcon.fromTheme("folder-open"))
61
61
  self.addButton(self.report_bug_button, QtWidgets.QDialogButtonBox.ButtonRole.ActionRole)
62
62
 
63
63
 
@@ -74,10 +74,7 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
74
74
  self.start_load_time = None
75
75
  self.min_time = None
76
76
  self.selection_model = None
77
- self.timer = QtCore.QTimer(self)
78
- self.timer.setInterval(1)
79
- self.timer.timeout.connect(self.checkStop)
80
- # self.positionChanged.connect(self.checkStop)
77
+ self.positionChanged.connect(self.checkStop)
81
78
  # self.positionChanged.connect(self.positionDebug)
82
79
  self.errorOccurred.connect(self.handle_error)
83
80
  o = None
@@ -89,7 +86,6 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
89
86
  self._audio_output.setDevice(self.devices.defaultAudioOutput())
90
87
  self.setAudioOutput(self._audio_output)
91
88
  self.playbackStateChanged.connect(self.reset_position)
92
- self.set_volume(self.settings.value(self.settings.VOLUME))
93
89
  self.fade_in_anim = QtCore.QPropertyAnimation(self._audio_output, b"volume")
94
90
  self.fade_in_anim.setDuration(10)
95
91
  self.fade_in_anim.setStartValue(0.1)
@@ -105,6 +101,7 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
105
101
  self.fade_out_anim.setKeyValueAt(0.1, self._audio_output.volume())
106
102
  self.fade_out_anim.finished.connect(super().pause)
107
103
  self.file_path = None
104
+ self.set_volume(self.settings.value(self.settings.VOLUME))
108
105
 
109
106
  def setMuted(self, muted: bool):
110
107
  self.audioOutput().setMuted(muted)
@@ -125,7 +122,6 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
125
122
  or self.currentTime() >= self.maxTime()
126
123
  ):
127
124
  self.setCurrentTime(self.startTime())
128
- self.timer.start()
129
125
  super(MediaPlayer, self).play()
130
126
  if fade_in:
131
127
  self.fade_in_anim.start()
@@ -153,14 +149,11 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
153
149
  def reset_position(self):
154
150
  state = self.playbackState()
155
151
  if state == QtMultimedia.QMediaPlayer.PlaybackState.StoppedState:
156
- self.timer.stop()
157
152
  self.setCurrentTime(self.startTime())
158
- self.timeChanged.emit(self.currentTime())
159
- elif state == QtMultimedia.QMediaPlayer.PlaybackState.PausedState:
160
- self.timer.stop()
161
153
 
162
154
  def update_audio_device(self):
163
155
  self._audio_output.setDevice(self.devices.defaultAudioOutput())
156
+ self.setAudioOutput(self._audio_output)
164
157
 
165
158
  def refresh_settings(self):
166
159
  self.settings.sync()
@@ -177,9 +170,9 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
177
170
  self.selection_model.fileChanged.connect(self.loadNewFile)
178
171
  self.selection_model.viewChanged.connect(self.update_times)
179
172
  self.selection_model.selectionAudioChanged.connect(self.update_selection_times)
180
- self.selection_model.currentTimeChanged.connect(self.update_selection_times)
181
173
 
182
174
  def set_volume(self, volume: int):
175
+ self.settings.setValue(self.settings.VOLUME, volume)
183
176
  if self.audioOutput() is None:
184
177
  return
185
178
  linearVolume = QtMultimedia.QtAudio.convertVolume(
@@ -188,6 +181,8 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
188
181
  QtMultimedia.QtAudio.VolumeScale.LinearVolumeScale,
189
182
  )
190
183
  self.audioOutput().setVolume(linearVolume)
184
+ self.fade_in_anim.setEndValue(linearVolume)
185
+ self.fade_out_anim.setStartValue(linearVolume)
191
186
 
192
187
  def volume(self) -> int:
193
188
  if self.audioOutput() is None:
@@ -203,13 +198,17 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
203
198
  )
204
199
  return volume
205
200
 
206
- def update_selection_times(self):
207
- self.setCurrentTime(self.startTime())
201
+ def update_selection_times(self, update=False):
202
+ if update or self.playbackState() != QtMultimedia.QMediaPlayer.PlaybackState.PlayingState:
203
+ self.setCurrentTime(self.startTime())
208
204
 
209
205
  def update_times(self):
206
+ if self.playbackState() == QtMultimedia.QMediaPlayer.PlaybackState.PlayingState:
207
+ return
210
208
  if self.currentTime() < self.startTime() or self.currentTime() > self.maxTime():
211
209
  self.stop()
212
210
  if self.playbackState() != QtMultimedia.QMediaPlayer.PlaybackState.PlayingState:
211
+ self.stop()
213
212
  self.setCurrentTime(self.startTime())
214
213
 
215
214
  def loadNewFile(self, *args):
@@ -238,27 +237,14 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
238
237
  def setCurrentTime(self, time):
239
238
  if time is None:
240
239
  time = 0
241
- if self.playbackState() == QtMultimedia.QMediaPlayer.PlaybackState.PlayingState:
242
- return
243
240
  pos = int(time * 1000)
244
241
  self.setPosition(pos)
245
- self.timeChanged.emit(self.currentTime())
246
242
 
247
243
  def checkStop(self):
248
- if not self.hasAudio():
249
- self.stop()
250
- self.setSource(
251
- QtCore.QUrl.fromLocalFile(
252
- self.selection_model.model().file.sound_file.sound_file_path
253
- )
254
- )
255
- self.play()
256
- return
244
+ self.timeChanged.emit(self.currentTime())
257
245
  if self.playbackState() == QtMultimedia.QMediaPlayer.PlaybackState.PlayingState:
258
246
  if self.maxTime() is None or self.currentTime() > self.maxTime():
259
247
  self.stop()
260
- self.reset_position()
261
- self.timeChanged.emit(self.currentTime())
262
248
 
263
249
 
264
250
  class NewSpeakerField(QtWidgets.QLineEdit):
@@ -286,9 +272,7 @@ class NewSpeakerField(QtWidgets.QLineEdit):
286
272
  self.setSizePolicy(
287
273
  QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Preferred
288
274
  )
289
- clear_icon = QtGui.QIcon()
290
- clear_icon.addFile(":clear.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off)
291
- clear_icon.addFile(":disabled/clear.svg", mode=QtGui.QIcon.Mode.Active)
275
+ clear_icon = QtGui.QIcon.fromTheme("edit-clear")
292
276
 
293
277
  self.clear_action = QtGui.QAction(icon=clear_icon, parent=self)
294
278
  self.clear_action.triggered.connect(self.clear)
@@ -469,9 +453,7 @@ class CompleterLineEdit(QtWidgets.QWidget):
469
453
  # self.model = QtCore.QStringListModel(self)
470
454
  # self.completer.setModel(self.model)
471
455
  layout.addWidget(self.line_edit)
472
- clear_icon = QtGui.QIcon()
473
- clear_icon.addFile(":clear.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off)
474
- clear_icon.addFile(":disabled/clear.svg", mode=QtGui.QIcon.Mode.Active)
456
+ clear_icon = QtGui.QIcon.fromTheme("edit-clear")
475
457
  self.button = QtWidgets.QToolButton(self)
476
458
  self.button.clicked.connect(self.clear_text)
477
459
  self.line_edit.textChanged.connect(self.check_actions)
@@ -530,9 +512,7 @@ class ClearableDropDown(QtWidgets.QWidget):
530
512
  self.combo_box = QtWidgets.QComboBox(self)
531
513
  layout = QtWidgets.QHBoxLayout()
532
514
  layout.addWidget(self.combo_box)
533
- clear_icon = QtGui.QIcon()
534
- clear_icon.addFile(":clear.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off)
535
- clear_icon.addFile(":disabled/clear.svg", mode=QtGui.QIcon.Mode.Active)
515
+ clear_icon = QtGui.QIcon.fromTheme("edit-clear")
536
516
  self.combo_box.currentIndexChanged.connect(self.check_actions)
537
517
  self.button = QtWidgets.QToolButton(self)
538
518
  self.button.clicked.connect(self.clear_index)
@@ -583,10 +563,10 @@ class PaginationWidget(QtWidgets.QToolBar):
583
563
  self.num_pages = 1
584
564
  self.result_count = 0
585
565
  self.next_page_action = QtGui.QAction(
586
- icon=QtGui.QIcon(":caret-right.svg"), text="Next page"
566
+ icon=QtGui.QIcon.fromTheme("media-seek-forward"), text="Next page"
587
567
  )
588
568
  self.previous_page_action = QtGui.QAction(
589
- icon=QtGui.QIcon(":caret-left.svg"), text="Previous page"
569
+ icon=QtGui.QIcon.fromTheme("media-seek-backward"), text="Previous page"
590
570
  )
591
571
  self.addWidget(w)
592
572
  self.page_label = QtWidgets.QLabel("Page 1 of 1")
@@ -1034,9 +1014,7 @@ class ClearableField(InternalToolButtonEdit):
1034
1014
  def __init__(self, *args):
1035
1015
  super().__init__(*args)
1036
1016
 
1037
- clear_icon = QtGui.QIcon()
1038
- clear_icon.addFile(":clear.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off)
1039
- clear_icon.addFile(":disabled/clear.svg", mode=QtGui.QIcon.Mode.Active)
1017
+ clear_icon = QtGui.QIcon.fromTheme("edit-clear")
1040
1018
  self.clear_action = QtGui.QAction(icon=clear_icon, parent=self)
1041
1019
  self.clear_action.triggered.connect(self.clear)
1042
1020
  self.clear_action.setVisible(False)
@@ -1090,28 +1068,16 @@ class SearchBox(ClearableField):
1090
1068
 
1091
1069
  self.clear_action.triggered.connect(self.returnPressed.emit)
1092
1070
 
1093
- regex_icon = QtGui.QIcon()
1094
- regex_icon.addFile(":regex.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off)
1095
- regex_icon.addFile(
1096
- ":highlighted/regex.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.On
1097
- )
1071
+ regex_icon = QtGui.QIcon.fromTheme("edit-regex")
1098
1072
 
1099
1073
  self.regex_action = QtGui.QAction(icon=regex_icon, parent=self)
1100
1074
  self.regex_action.setCheckable(True)
1101
1075
 
1102
- word_icon = QtGui.QIcon()
1103
- word_icon.addFile(":word.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off)
1104
- word_icon.addFile(
1105
- ":highlighted/word.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.On
1106
- )
1076
+ word_icon = QtGui.QIcon.fromTheme("edit-word")
1107
1077
  self.word_action = QtGui.QAction(icon=word_icon, parent=self)
1108
1078
  self.word_action.setCheckable(True)
1109
1079
 
1110
- case_icon = QtGui.QIcon()
1111
- case_icon.addFile(":case.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off)
1112
- case_icon.addFile(
1113
- ":highlighted/case.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.On
1114
- )
1080
+ case_icon = QtGui.QIcon.fromTheme("edit-case")
1115
1081
  self.case_action = QtGui.QAction(icon=case_icon, parent=self)
1116
1082
  self.case_action.setCheckable(True)
1117
1083
 
@@ -1415,7 +1381,7 @@ class IconDelegate(QtWidgets.QStyledItemDelegate):
1415
1381
  options = QtWidgets.QStyleOptionViewItem(option)
1416
1382
  self.initStyleOption(options, index)
1417
1383
  if options.checkState == QtCore.Qt.CheckState.Checked:
1418
- icon = QtGui.QIcon(":disabled/oov-check.svg")
1384
+ icon = QtGui.QIcon(":oov-check.svg")
1419
1385
  icon.paint(painter, options.rect, QtCore.Qt.AlignmentFlag.AlignCenter)
1420
1386
 
1421
1387
  painter.restore()
@@ -1428,10 +1394,10 @@ class ModelIconDelegate(QtWidgets.QStyledItemDelegate):
1428
1394
 
1429
1395
  self.settings = AnchorSettings()
1430
1396
  self.icon_mapping = {
1431
- "available": QtGui.QIcon(":file-circle-check-solid.svg"),
1432
- "unavailable": QtGui.QIcon(":file-circle-xmark-solid.svg"),
1433
- "remote": QtGui.QIcon(":file-arrow-down-solid.svg"),
1434
- "unknown": QtGui.QIcon(":file-circle-question-solid.svg"),
1397
+ "available": QtGui.QIcon.fromTheme("emblem-default"),
1398
+ "unavailable": QtGui.QIcon.fromTheme("emblem-important"),
1399
+ "remote": QtGui.QIcon.fromTheme("sync-synchronizing"),
1400
+ "unknown": QtGui.QIcon.fromTheme("emblem-unknown"),
1435
1401
  }
1436
1402
 
1437
1403
  def refresh_settings(self):
@@ -1452,7 +1418,16 @@ class ModelIconDelegate(QtWidgets.QStyledItemDelegate):
1452
1418
  options = QtWidgets.QStyleOptionViewItem(option)
1453
1419
  self.initStyleOption(options, index)
1454
1420
  icon = self.icon_mapping[options.text]
1455
- icon.paint(painter, options.rect, QtCore.Qt.AlignmentFlag.AlignLeft)
1421
+ r = option.rect
1422
+ half_size = int(self.settings.icon_size / 2)
1423
+ x = r.left() + (r.width() / 2) - half_size
1424
+ y = r.top() + (r.height() / 2) - half_size
1425
+ options.rect = QtCore.QRect(x, y, self.settings.icon_size, self.settings.icon_size)
1426
+ icon.paint(
1427
+ painter,
1428
+ options.rect,
1429
+ QtCore.Qt.AlignmentFlag.AlignCenter | QtCore.Qt.AlignmentFlag.AlignVCenter,
1430
+ )
1456
1431
 
1457
1432
  painter.restore()
1458
1433
 
@@ -1474,7 +1449,7 @@ class StoppableProgressBar(QtWidgets.QWidget):
1474
1449
  layout.addWidget(self.progress_bar)
1475
1450
  self.cancel_button = QtWidgets.QToolButton()
1476
1451
  self.cancel_action = QtGui.QAction("select", self)
1477
- self.cancel_action.setIcon(QtGui.QIcon(":clear.svg"))
1452
+ self.cancel_action.setIcon(QtGui.QIcon.fromTheme("edit-clear"))
1478
1453
  self.cancel_action.triggered.connect(worker.cancel)
1479
1454
  self.cancel_button.setDefaultAction(self.cancel_action)
1480
1455
  layout.addWidget(self.cancel_button)
@@ -1542,7 +1517,7 @@ class ProgressMenu(QtWidgets.QMenu):
1542
1517
  class ProgressWidget(QtWidgets.QPushButton):
1543
1518
  def __init__(self, *args):
1544
1519
  super().__init__(*args)
1545
- self.done_icon = QtGui.QIcon(":check-circle.svg")
1520
+ self.done_icon = QtGui.QIcon.fromTheme("emblem-default")
1546
1521
  self.animated = QtGui.QMovie(":spinning_blue.svg")
1547
1522
  self.animated.frameChanged.connect(self.update_animation)
1548
1523
  self.setIcon(self.done_icon)
@@ -1781,34 +1756,16 @@ class PronunciationInput(QtWidgets.QToolBar):
1781
1756
  self.setContentsMargins(0, 0, 0, 0)
1782
1757
  self.setFocusProxy(self.input)
1783
1758
 
1784
- accept_icon = QtGui.QIcon()
1785
- accept_icon.addFile(
1786
- ":check-circle.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off
1787
- )
1788
- accept_icon.addFile(
1789
- ":highlighted/check-circle.svg",
1790
- mode=QtGui.QIcon.Mode.Normal,
1791
- state=QtGui.QIcon.State.On,
1792
- )
1759
+ accept_icon = QtGui.QIcon.fromTheme("emblem-default")
1793
1760
 
1794
1761
  self.accept_action = QtGui.QAction(icon=accept_icon, parent=self)
1795
1762
  self.accept_action.triggered.connect(self.returnPressed.emit)
1796
1763
 
1797
- cancel_icon = QtGui.QIcon()
1798
- cancel_icon.addFile(":undo.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off)
1799
- cancel_icon.addFile(
1800
- ":highlighted/undo.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.On
1801
- )
1764
+ cancel_icon = QtGui.QIcon.fromTheme("edit-undo")
1802
1765
 
1803
1766
  self.cancel_action = QtGui.QAction(icon=cancel_icon, parent=self)
1804
1767
  self.cancel_action.triggered.connect(self.cancel)
1805
- keyboard_icon = QtGui.QIcon()
1806
- keyboard_icon.addFile(
1807
- ":keyboard.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off
1808
- )
1809
- keyboard_icon.addFile(
1810
- ":highlighted/keyboard.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.On
1811
- )
1768
+ keyboard_icon = QtGui.QIcon.fromTheme("input-keyboard")
1812
1769
 
1813
1770
  self.keyboard_widget = QtWidgets.QPushButton(self)
1814
1771
  self.keyboard_widget.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
@@ -1834,7 +1791,7 @@ class PronunciationInput(QtWidgets.QToolBar):
1834
1791
  self.returnPressed.emit()
1835
1792
  return True
1836
1793
  elif (
1837
- isinstance(watched, (IpaKeyboard))
1794
+ isinstance(watched, IpaKeyboard)
1838
1795
  and event.type() == QtCore.QEvent.Type.KeyPress
1839
1796
  and event.key() not in {QtGui.Qt.Key.Key_Escape}
1840
1797
  ):
@@ -1925,14 +1882,18 @@ class CountDelegate(QtWidgets.QStyledItemDelegate):
1925
1882
  super().paint(painter, option, index)
1926
1883
  painter.save()
1927
1884
  r = option.rect
1928
- size = int(self.settings.icon_size / 2)
1885
+ half_size = int(self.settings.icon_size / 2)
1929
1886
  x = r.left() + r.width() - self.settings.icon_size
1930
- y = r.top()
1887
+ y = r.top() + (r.height() / 2) - half_size
1931
1888
  options = QtWidgets.QStyleOptionViewItem(option)
1932
- options.rect = QtCore.QRect(x, y, size, r.height())
1889
+ options.rect = QtCore.QRect(x, y, self.settings.icon_size, self.settings.icon_size)
1933
1890
  self.initStyleOption(options, index)
1934
- icon = QtGui.QIcon(":external-link.svg")
1935
- icon.paint(painter, options.rect, QtCore.Qt.AlignmentFlag.AlignCenter)
1891
+ icon = QtGui.QIcon.fromTheme("folder-open")
1892
+ icon.paint(
1893
+ painter,
1894
+ options.rect,
1895
+ QtCore.Qt.AlignmentFlag.AlignCenter | QtCore.Qt.AlignmentFlag.AlignVCenter,
1896
+ )
1936
1897
 
1937
1898
  painter.restore()
1938
1899
 
@@ -1956,14 +1917,18 @@ class WordTypeDelegate(QtWidgets.QStyledItemDelegate):
1956
1917
  super().paint(painter, option, index)
1957
1918
  painter.save()
1958
1919
  r = option.rect
1959
- size = int(self.settings.icon_size / 2)
1920
+ half_size = int(self.settings.icon_size / 2)
1960
1921
  x = r.left() + r.width() - self.settings.icon_size
1961
- y = r.top()
1922
+ y = r.top() + (r.height() / 2) - half_size
1962
1923
  options = QtWidgets.QStyleOptionViewItem(option)
1963
- options.rect = QtCore.QRect(x, y, size, r.height())
1924
+ options.rect = QtCore.QRect(x, y, self.settings.icon_size, self.settings.icon_size)
1964
1925
  self.initStyleOption(options, index)
1965
- icon = QtGui.QIcon(":rotate.svg")
1966
- icon.paint(painter, options.rect, QtCore.Qt.AlignmentFlag.AlignCenter)
1926
+ icon = QtGui.QIcon.fromTheme("sync-synchronizing")
1927
+ icon.paint(
1928
+ painter,
1929
+ options.rect,
1930
+ QtCore.Qt.AlignmentFlag.AlignCenter | QtCore.Qt.AlignmentFlag.AlignVCenter,
1931
+ )
1967
1932
 
1968
1933
  painter.restore()
1969
1934
 
@@ -2498,13 +2463,13 @@ class SpeakerViewDelegate(QtWidgets.QStyledItemDelegate):
2498
2463
  painter.save()
2499
2464
 
2500
2465
  r = option.rect
2501
- size = int(self.settings.icon_size / 2)
2466
+ half_size = int(self.settings.icon_size / 2)
2502
2467
  x = r.left() + r.width() - self.settings.icon_size
2503
- y = r.top()
2468
+ y = r.top() + (r.height() / 2) - half_size
2504
2469
  options = QtWidgets.QStyleOptionViewItem(option)
2505
- options.rect = QtCore.QRect(x, y, size, r.height())
2470
+ options.rect = QtCore.QRect(x, y, self.settings.icon_size, self.settings.icon_size)
2506
2471
  self.initStyleOption(options, index)
2507
- icon = QtGui.QIcon(":external-link.svg")
2472
+ icon = QtGui.QIcon.fromTheme("folder-open")
2508
2473
  icon.paint(painter, options.rect, QtCore.Qt.AlignmentFlag.AlignCenter)
2509
2474
 
2510
2475
  painter.restore()
@@ -2529,11 +2494,11 @@ class ButtonDelegate(QtWidgets.QStyledItemDelegate):
2529
2494
  ) -> None:
2530
2495
  painter.save()
2531
2496
  r = option.rect
2532
- size = int(self.settings.icon_size / 2)
2497
+ half_size = int(self.settings.icon_size / 2)
2533
2498
  x = r.left() + r.width() - self.settings.icon_size
2534
- y = r.top()
2499
+ y = r.top() + (r.height() / 2) - half_size
2535
2500
  options = QtWidgets.QStyleOptionViewItem(option)
2536
- options.rect = QtCore.QRect(x, y, size, r.height())
2501
+ options.rect = QtCore.QRect(x, y, self.settings.icon_size, self.settings.icon_size)
2537
2502
  self.initStyleOption(options, index)
2538
2503
  icon = QtGui.QIcon(self.icon_path)
2539
2504
  icon.paint(painter, options.rect, QtCore.Qt.AlignmentFlag.AlignCenter)
@@ -2546,6 +2511,7 @@ class SpeakerClustersWidget(QtWidgets.QWidget):
2546
2511
 
2547
2512
  def __init__(self, *args, **kwargs):
2548
2513
  super().__init__(*args, **kwargs)
2514
+ self.speaker_model = None
2549
2515
  self.settings = AnchorSettings()
2550
2516
  self.settings.sync()
2551
2517
  form_layout = QtWidgets.QHBoxLayout()
@@ -2640,7 +2606,7 @@ class DiarizationTable(AnchorTableView):
2640
2606
  self.doubleClicked.connect(self.search_utterance)
2641
2607
  self.clicked.connect(self.reassign_utterance)
2642
2608
  self.diarization_model: Optional[DiarizationModel] = None
2643
- self.selection_model: Optional[CorpusSelectionModel] = None
2609
+ self.selection_model: Optional[FileSelectionModel] = None
2644
2610
  self.set_reference_utterance_action = QtGui.QAction("Use utterance as reference", self)
2645
2611
  self.set_reference_utterance_action.triggered.connect(self.set_reference_utterance)
2646
2612
  self.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.CustomContextMenu)
@@ -2648,7 +2614,7 @@ class DiarizationTable(AnchorTableView):
2648
2614
 
2649
2615
  def generate_context_menu(self, location):
2650
2616
  menu = QtWidgets.QMenu()
2651
- # menu.setStyleSheet(self.settings.menu_style_sheet)
2617
+ menu.setStyleSheet(self.settings.menu_style_sheet)
2652
2618
  menu.addAction(self.set_reference_utterance_action)
2653
2619
  menu.exec_(self.mapToGlobal(location))
2654
2620
 
@@ -2656,7 +2622,7 @@ class DiarizationTable(AnchorTableView):
2656
2622
  rows = self.selectionModel().selectedRows()
2657
2623
  if not rows:
2658
2624
  return
2659
- utterance_id = self.diarization_model._utterance_ids[rows[0].row()]
2625
+ utterance_id = self.diarization_model.utterance_ids[rows[0].row()]
2660
2626
  self.diarization_model.set_utterance_filter(utterance_id)
2661
2627
  self.referenceUtteranceSelected.emit(
2662
2628
  self.diarization_model.data(
@@ -2665,7 +2631,7 @@ class DiarizationTable(AnchorTableView):
2665
2631
  )
2666
2632
  )
2667
2633
 
2668
- def set_models(self, model: DiarizationModel, selection_model: CorpusSelectionModel):
2634
+ def set_models(self, model: DiarizationModel, selection_model: FileSelectionModel):
2669
2635
  self.diarization_model = model
2670
2636
  self.selection_model = selection_model
2671
2637
  self.setModel(model)
@@ -2684,14 +2650,14 @@ class DiarizationTable(AnchorTableView):
2684
2650
  return
2685
2651
  if index.column() == 0:
2686
2652
  row = index.row()
2687
- utterance_id = self.diarization_model._utterance_ids[row]
2653
+ utterance_id = self.diarization_model.utterance_ids[row]
2688
2654
  if utterance_id is None:
2689
2655
  return
2690
2656
  with self.diarization_model.corpus_model.corpus.session() as session:
2691
2657
  try:
2692
- file_id, begin, end, channel = (
2658
+ file_id, begin, end, speaker_id = (
2693
2659
  session.query(
2694
- Utterance.file_id, Utterance.begin, Utterance.end, Utterance.channel
2660
+ Utterance.file_id, Utterance.begin, Utterance.end, Utterance.speaker_id
2695
2661
  )
2696
2662
  .filter(Utterance.id == utterance_id)
2697
2663
  .first()
@@ -2701,19 +2667,18 @@ class DiarizationTable(AnchorTableView):
2701
2667
  return
2702
2668
  else:
2703
2669
  if index.column() == 1:
2704
- speaker_id = self.diarization_model._suggested_indices[index.row()]
2670
+ speaker_id = self.diarization_model.suggested_indices[index.row()]
2705
2671
  else:
2706
- speaker_id = self.diarization_model._speaker_indices[index.row()]
2672
+ speaker_id = self.diarization_model.speaker_indices[index.row()]
2707
2673
  with self.diarization_model.corpus_model.corpus.session() as session:
2708
2674
  c = session.query(Corpus).first()
2709
2675
  try:
2710
- utterance_id, file_id, begin, end, channel = (
2676
+ utterance_id, file_id, begin, end = (
2711
2677
  session.query(
2712
2678
  Utterance.id,
2713
2679
  Utterance.file_id,
2714
2680
  Utterance.begin,
2715
2681
  Utterance.end,
2716
- Utterance.channel,
2717
2682
  )
2718
2683
  .join(Utterance.speaker)
2719
2684
  .filter(Utterance.speaker_id == speaker_id)
@@ -2725,12 +2690,12 @@ class DiarizationTable(AnchorTableView):
2725
2690
  except TypeError:
2726
2691
  self.selection_model.clearSelection()
2727
2692
  return
2728
- self.selection_model.set_current_utterance(utterance_id)
2729
2693
  self.selection_model.set_current_file(
2730
2694
  file_id,
2731
2695
  begin,
2732
2696
  end,
2733
- channel,
2697
+ utterance_id,
2698
+ speaker_id,
2734
2699
  force_update=True,
2735
2700
  )
2736
2701
 
@@ -3069,11 +3034,11 @@ class DictionaryWidget(QtWidgets.QWidget):
3069
3034
  self.current_search_query = None
3070
3035
  self.current_search_text = ""
3071
3036
  self.refresh_word_counts_action = QtGui.QAction(self)
3072
- self.refresh_word_counts_action.setIcon(QtGui.QIcon(":oov-check.svg"))
3037
+ self.refresh_word_counts_action.setIcon(QtGui.QIcon.fromTheme("tools-check-spelling"))
3073
3038
  self.refresh_word_counts_action.setEnabled(True)
3074
3039
  self.toolbar.addAction(self.refresh_word_counts_action)
3075
3040
  self.rebuild_lexicon_action = QtGui.QAction(self)
3076
- self.rebuild_lexicon_action.setIcon(QtGui.QIcon(":rotate.svg"))
3041
+ self.rebuild_lexicon_action.setIcon(QtGui.QIcon.fromTheme("sync-synchronizing"))
3077
3042
  self.rebuild_lexicon_action.setEnabled(True)
3078
3043
  self.toolbar.addAction(self.rebuild_lexicon_action)
3079
3044
  dict_layout.addWidget(self.toolbar)
@@ -3280,7 +3245,7 @@ class SpeakerWidget(QtWidgets.QWidget):
3280
3245
  def set_models(
3281
3246
  self,
3282
3247
  corpus_model: CorpusModel,
3283
- selection_model: CorpusSelectionModel,
3248
+ selection_model: FileSelectionModel,
3284
3249
  speaker_model: SpeakerModel,
3285
3250
  ):
3286
3251
  self.speaker_model = speaker_model
@@ -3312,31 +3277,33 @@ class SpeakerWidget(QtWidgets.QWidget):
3312
3277
 
3313
3278
 
3314
3279
  class ColorEdit(QtWidgets.QPushButton): # pragma: no cover
3280
+ colorChanged = QtCore.Signal()
3281
+
3315
3282
  def __init__(self, parent=None):
3316
3283
  super(ColorEdit, self).__init__(parent=parent)
3317
3284
  self.setText("")
3318
3285
  self.clicked.connect(self.open_dialog)
3286
+ self.color = None
3319
3287
 
3320
- def set_color(self, color: QtGui.QColor):
3321
- self._color = color
3288
+ def set_color(self, color: typing.Union[str, QtGui.QColor]):
3289
+ if isinstance(color, str):
3290
+ color = QtGui.QColor(color)
3291
+ self.color = color
3322
3292
  self.update_icon()
3323
3293
 
3324
3294
  def update_icon(self):
3325
3295
  pixmap = QtGui.QPixmap(100, 100)
3326
- pixmap.fill(self._color)
3296
+ pixmap.fill(self.color)
3327
3297
  icon = QtGui.QIcon(pixmap)
3328
3298
  icon.addPixmap(pixmap, QtGui.QIcon.Mode.Disabled)
3329
3299
  self.setIcon(icon)
3330
3300
 
3331
- @property
3332
- def color(self) -> str:
3333
- return self._color.name()
3334
-
3335
3301
  def open_dialog(self):
3336
3302
  color = QtWidgets.QColorDialog.getColor()
3337
- if color.isValid():
3338
- self._color = color
3303
+ if color.isValid() and self.color != color.name():
3304
+ self.color = color.name()
3339
3305
  self.update_icon()
3306
+ self.colorChanged.emit()
3340
3307
 
3341
3308
 
3342
3309
  class FontDialog(QtWidgets.QFontDialog):
@@ -3488,8 +3455,8 @@ class PathSelectWidget(QtWidgets.QWidget):
3488
3455
  self.setLayout(layout)
3489
3456
 
3490
3457
  self.select_button.clicked.connect(self.select_path)
3491
- self.exists_icon = QtGui.QIcon(":check-circle.svg")
3492
- self.not_exists_icon = QtGui.QIcon(":disabled/exclamation-triangle.svg")
3458
+ self.exists_icon = QtGui.QIcon.fromTheme("emblem-default")
3459
+ self.not_exists_icon = QtGui.QIcon.fromTheme("emblem-important")
3493
3460
 
3494
3461
  def value(self):
3495
3462
  if not self.path_edit.text():
@@ -3576,7 +3543,6 @@ class ModelSelectWidget(QtWidgets.QWidget):
3576
3543
  for i, m in enumerate(self.model.models):
3577
3544
  if not m.available_locally or not os.path.exists(m.path):
3578
3545
  continue
3579
- print(m.name, m.path, os.path.exists(m.path))
3580
3546
  self.model_select.addItem(m.name, userData=m.id)
3581
3547
  if m.id == current_model:
3582
3548
  index = i
anchor/workers.py CHANGED
@@ -3071,7 +3071,11 @@ class WaveformWorker(FunctionWorker): # pragma: no cover
3071
3071
  def run(self):
3072
3072
  self.stopped.clear()
3073
3073
  with self.lock:
3074
- y, _ = soundfile.read(self.file_path)
3074
+ try:
3075
+ y, _ = soundfile.read(self.file_path)
3076
+ except soundfile.LibsndfileError:
3077
+ logger.warning(f"Could not read {self.file_path}")
3078
+ y = None
3075
3079
  if self.stopped.is_set():
3076
3080
  return
3077
3081
  self.signals.result.emit((y, self.file_path))
@@ -3351,6 +3355,9 @@ class DownloadWorker(FunctionWorker): # pragma: no cover
3351
3355
  class ImportCorpusWorker(FunctionWorker): # pragma: no cover
3352
3356
  def __init__(self, *args):
3353
3357
  super().__init__("Importing corpus", *args)
3358
+ self.corpus_path = None
3359
+ self.dictionary_path = None
3360
+ self.reset = None
3354
3361
 
3355
3362
  def stop(self):
3356
3363
  if hasattr(self, "corpus") and self.corpus is not None:
@@ -3365,6 +3372,25 @@ class ImportCorpusWorker(FunctionWorker): # pragma: no cover
3365
3372
  config.CLEAN = self.reset
3366
3373
  corpus_name = os.path.basename(self.corpus_path)
3367
3374
  dataset_type = inspect_database(corpus_name)
3375
+ if (
3376
+ dataset_type is DatasetType.ACOUSTIC_CORPUS_WITH_DICTIONARY
3377
+ and self.dictionary_path is None
3378
+ ):
3379
+ string = f"postgresql+psycopg2://@/{corpus_name}?host={config.database_socket()}"
3380
+ try:
3381
+ engine = sqlalchemy.create_engine(
3382
+ string,
3383
+ poolclass=sqlalchemy.NullPool,
3384
+ pool_reset_on_return=None,
3385
+ isolation_level="AUTOCOMMIT",
3386
+ logging_name="inspect_dataset_engine",
3387
+ ).execution_options(logging_token="inspect_dataset_engine")
3388
+ with sqlalchemy.orm.Session(engine) as session:
3389
+ dictionary = session.query(Dictionary.path).first()
3390
+ if dictionary is not None:
3391
+ self.dictionary_path = dictionary[0]
3392
+ except (sqlalchemy.exc.OperationalError, sqlalchemy.exc.ProgrammingError):
3393
+ pass
3368
3394
  try:
3369
3395
  if dataset_type is DatasetType.NONE:
3370
3396
  if self.dictionary_path and os.path.exists(self.dictionary_path):
@@ -3650,6 +3676,8 @@ class ImportG2PModelWorker(FunctionWorker): # pragma: no cover
3650
3676
  try:
3651
3677
  generator = Generator(g2p_model_path=self.model_path, num_pronunciations=5)
3652
3678
  generator.setup()
3679
+ except shutil.ReadError:
3680
+ self.signals.result.emit(None)
3653
3681
  except Exception:
3654
3682
  exctype, value = sys.exc_info()[:2]
3655
3683
  self.signals.error.emit((exctype, value, traceback.format_exc()))
@@ -1,22 +0,0 @@
1
- anchor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- anchor/__main__.py,sha256=5ufG8lcx2x1am-04xI991AG7saJd24dxPw5JzjmB878,45
3
- anchor/_version.py,sha256=FKnJIExgNrZG2xJ0y_dGNBpxGbGBYylvfat-jHhLUuM,411
4
- anchor/command_line.py,sha256=EucG805HyWk_zkMO9RXv9Yj0I0JVdDLZb1_DX2_ISjM,503
5
- anchor/db.py,sha256=ef4lO6HtCKoxC9CorIc0ZbPxKpjHa576a0ZIBOWNU9E,4956
6
- anchor/main.py,sha256=wX6LLudTX5-HOxqBB-BGLXTdYJuDGQbV11gA2XBvQ8w,120605
7
- anchor/models.py,sha256=sCZf5wF6g1KorMgb0AifmqhaxZp5fiYmlmaJoow-tFI,95230
8
- anchor/plot.py,sha256=eNVG9sDdRA9_KKrHKSb2TF66bIluJsJzVnTGN3q-Brk,104878
9
- anchor/resources_rc.py,sha256=94wgxDTpP4Oy55Br7CZ_YnmvaqzHr4n-AydBPhZc-es,8427242
10
- anchor/settings.py,sha256=QdfBtJowHpkBLzJ_3bZRKxF1rJDBW9Z5kp83sJVz0pA,46965
11
- anchor/ui_corpus_manager.py,sha256=e3ybOd4UdYarrLBATxI8vIFnioa4R_BHrbsEz5mJ5eA,8564
12
- anchor/ui_error_dialog.py,sha256=c_QS0s1VaJEV9AhcrQZQyWHHpUPudWjJY1NI7Ytipio,3832
13
- anchor/ui_main_window.py,sha256=MYb4PtV1sHYgnc3QwPphKjU3LepzBJpxllhN4nyDook,63525
14
- anchor/ui_preferences.py,sha256=MOC2dY4qkViW9cUbC0DVSO7FLg-dGSbmR630WFQ6V9c,41843
15
- anchor/undo.py,sha256=HXhrzV-T2JKwPd28KCaR9S6GWmi2Wr2Xk7IBEonRRCs,32564
16
- anchor/widgets.py,sha256=arL006v_cOGWudEF4Adbh_wRjiyFRGHP9BXOtfCr0h0,158301
17
- anchor/workers.py,sha256=iWLBGCg6jJr_OmVFJCRGMgF5Rw5G9IhpdNiqDv8ZBxU,171083
18
- Anchor_annotator-0.3.3.dist-info/LICENSE,sha256=C0oIsblENEgWQ7XMNdYoXyXsIA5wa3YF0I9lK3H7A1s,1076
19
- Anchor_annotator-0.3.3.dist-info/METADATA,sha256=KPemKhTKt7Rh3N4-k-f8V4tHoAkvoUKrhUlonplJrLo,1500
20
- Anchor_annotator-0.3.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
21
- Anchor_annotator-0.3.3.dist-info/top_level.txt,sha256=wX6ZKxImGRZKFQjs3f6XYw_TfbAp6Xs3SmbLfLbFAJ0,7
22
- Anchor_annotator-0.3.3.dist-info/RECORD,,