Anchor-annotator 0.4.0__py3-none-any.whl → 0.6.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
@@ -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
 
@@ -57,7 +58,7 @@ class ErrorButtonBox(QtWidgets.QDialogButtonBox):
57
58
  super().__init__(*args, **kwargs)
58
59
  self.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Close)
59
60
  self.report_bug_button = QtWidgets.QPushButton("Report bug")
60
- self.report_bug_button.setIcon(QtGui.QIcon(":external-link.svg"))
61
+ self.report_bug_button.setIcon(QtGui.QIcon.fromTheme("folder-open"))
61
62
  self.addButton(self.report_bug_button, QtWidgets.QDialogButtonBox.ButtonRole.ActionRole)
62
63
 
63
64
 
@@ -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.loadNewFile)
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,31 +175,31 @@ 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.QtAudio.convertVolume(
178
+ linearVolume = QtMultimedia.QAudio.convertVolume(
179
179
  volume / 100.0,
180
- QtMultimedia.QtAudio.VolumeScale.LogarithmicVolumeScale,
181
- QtMultimedia.QtAudio.VolumeScale.LinearVolumeScale,
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.QtAudio.convertVolume(
191
+ QtMultimedia.QAudio.convertVolume(
193
192
  volume,
194
- QtMultimedia.QtAudio.VolumeScale.LinearVolumeScale,
195
- QtMultimedia.QtAudio.VolumeScale.LogarithmicVolumeScale,
193
+ QtMultimedia.QAudio.VolumeScale.LinearVolumeScale,
194
+ QtMultimedia.QAudio.VolumeScale.LogarithmicVolumeScale,
196
195
  )
197
196
  * 100
198
197
  )
199
198
  return volume
200
199
 
201
- def update_selection_times(self):
202
- self.setCurrentTime(self.startTime())
200
+ def update_selection_times(self, update=False):
201
+ if update or self.playbackState() != QtMultimedia.QMediaPlayer.PlaybackState.PlayingState:
202
+ self.setCurrentTime(self.startTime())
203
203
 
204
204
  def update_times(self):
205
205
  if self.playbackState() == QtMultimedia.QMediaPlayer.PlaybackState.PlayingState:
@@ -210,9 +210,13 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
210
210
  self.stop()
211
211
  self.setCurrentTime(self.startTime())
212
212
 
213
- def loadNewFile(self, *args):
214
- self.audioReady.emit(False)
215
- self.stop()
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)
216
220
  try:
217
221
  new_file = self.selection_model.model().file.sound_file.sound_file_path
218
222
  except Exception:
@@ -226,8 +230,6 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
226
230
  self.setSource(QtCore.QUrl())
227
231
  return
228
232
  self.setSource(f"file:///{new_file}")
229
- self.setPosition(0)
230
- self.audioReady.emit(True)
231
233
 
232
234
  def currentTime(self):
233
235
  pos = self.position()
@@ -271,9 +273,7 @@ class NewSpeakerField(QtWidgets.QLineEdit):
271
273
  self.setSizePolicy(
272
274
  QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Preferred
273
275
  )
274
- clear_icon = QtGui.QIcon()
275
- clear_icon.addFile(":clear.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off)
276
- clear_icon.addFile(":disabled/clear.svg", mode=QtGui.QIcon.Mode.Active)
276
+ clear_icon = QtGui.QIcon.fromTheme("edit-clear")
277
277
 
278
278
  self.clear_action = QtGui.QAction(icon=clear_icon, parent=self)
279
279
  self.clear_action.triggered.connect(self.clear)
@@ -454,9 +454,7 @@ class CompleterLineEdit(QtWidgets.QWidget):
454
454
  # self.model = QtCore.QStringListModel(self)
455
455
  # self.completer.setModel(self.model)
456
456
  layout.addWidget(self.line_edit)
457
- clear_icon = QtGui.QIcon()
458
- clear_icon.addFile(":clear.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off)
459
- clear_icon.addFile(":disabled/clear.svg", mode=QtGui.QIcon.Mode.Active)
457
+ clear_icon = QtGui.QIcon.fromTheme("edit-clear")
460
458
  self.button = QtWidgets.QToolButton(self)
461
459
  self.button.clicked.connect(self.clear_text)
462
460
  self.line_edit.textChanged.connect(self.check_actions)
@@ -515,9 +513,7 @@ class ClearableDropDown(QtWidgets.QWidget):
515
513
  self.combo_box = QtWidgets.QComboBox(self)
516
514
  layout = QtWidgets.QHBoxLayout()
517
515
  layout.addWidget(self.combo_box)
518
- clear_icon = QtGui.QIcon()
519
- clear_icon.addFile(":clear.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off)
520
- clear_icon.addFile(":disabled/clear.svg", mode=QtGui.QIcon.Mode.Active)
516
+ clear_icon = QtGui.QIcon.fromTheme("edit-clear")
521
517
  self.combo_box.currentIndexChanged.connect(self.check_actions)
522
518
  self.button = QtWidgets.QToolButton(self)
523
519
  self.button.clicked.connect(self.clear_index)
@@ -568,10 +564,10 @@ class PaginationWidget(QtWidgets.QToolBar):
568
564
  self.num_pages = 1
569
565
  self.result_count = 0
570
566
  self.next_page_action = QtGui.QAction(
571
- icon=QtGui.QIcon(":caret-right.svg"), text="Next page"
567
+ icon=QtGui.QIcon.fromTheme("media-seek-forward"), text="Next page"
572
568
  )
573
569
  self.previous_page_action = QtGui.QAction(
574
- icon=QtGui.QIcon(":caret-left.svg"), text="Previous page"
570
+ icon=QtGui.QIcon.fromTheme("media-seek-backward"), text="Previous page"
575
571
  )
576
572
  self.addWidget(w)
577
573
  self.page_label = QtWidgets.QLabel("Page 1 of 1")
@@ -1019,9 +1015,7 @@ class ClearableField(InternalToolButtonEdit):
1019
1015
  def __init__(self, *args):
1020
1016
  super().__init__(*args)
1021
1017
 
1022
- clear_icon = QtGui.QIcon()
1023
- clear_icon.addFile(":clear.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off)
1024
- clear_icon.addFile(":disabled/clear.svg", mode=QtGui.QIcon.Mode.Active)
1018
+ clear_icon = QtGui.QIcon.fromTheme("edit-clear")
1025
1019
  self.clear_action = QtGui.QAction(icon=clear_icon, parent=self)
1026
1020
  self.clear_action.triggered.connect(self.clear)
1027
1021
  self.clear_action.setVisible(False)
@@ -1070,33 +1064,72 @@ class SearchBox(ClearableField):
1070
1064
 
1071
1065
  def __init__(self, *args):
1072
1066
  super().__init__(*args)
1067
+ settings = AnchorSettings()
1073
1068
  self.returnPressed.connect(self.activate)
1074
1069
  self.setObjectName("search_box")
1075
1070
 
1076
1071
  self.clear_action.triggered.connect(self.returnPressed.emit)
1077
1072
 
1078
1073
  regex_icon = QtGui.QIcon()
1079
- regex_icon.addFile(":regex.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off)
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
+ )
1080
1111
  regex_icon.addFile(
1081
- ":highlighted/regex.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.On
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,
1082
1125
  )
1083
1126
 
1084
1127
  self.regex_action = QtGui.QAction(icon=regex_icon, parent=self)
1085
1128
  self.regex_action.setCheckable(True)
1086
1129
 
1087
- word_icon = QtGui.QIcon()
1088
- word_icon.addFile(":word.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off)
1089
- word_icon.addFile(
1090
- ":highlighted/word.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.On
1091
- )
1092
1130
  self.word_action = QtGui.QAction(icon=word_icon, parent=self)
1093
1131
  self.word_action.setCheckable(True)
1094
1132
 
1095
- case_icon = QtGui.QIcon()
1096
- case_icon.addFile(":case.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off)
1097
- case_icon.addFile(
1098
- ":highlighted/case.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.On
1099
- )
1100
1133
  self.case_action = QtGui.QAction(icon=case_icon, parent=self)
1101
1134
  self.case_action.setCheckable(True)
1102
1135
 
@@ -1400,7 +1433,7 @@ class IconDelegate(QtWidgets.QStyledItemDelegate):
1400
1433
  options = QtWidgets.QStyleOptionViewItem(option)
1401
1434
  self.initStyleOption(options, index)
1402
1435
  if options.checkState == QtCore.Qt.CheckState.Checked:
1403
- icon = QtGui.QIcon(":disabled/oov-check.svg")
1436
+ icon = QtGui.QIcon(":oov-check.svg")
1404
1437
  icon.paint(painter, options.rect, QtCore.Qt.AlignmentFlag.AlignCenter)
1405
1438
 
1406
1439
  painter.restore()
@@ -1413,10 +1446,10 @@ class ModelIconDelegate(QtWidgets.QStyledItemDelegate):
1413
1446
 
1414
1447
  self.settings = AnchorSettings()
1415
1448
  self.icon_mapping = {
1416
- "available": QtGui.QIcon(":file-circle-check-solid.svg"),
1417
- "unavailable": QtGui.QIcon(":file-circle-xmark-solid.svg"),
1418
- "remote": QtGui.QIcon(":file-arrow-down-solid.svg"),
1419
- "unknown": QtGui.QIcon(":file-circle-question-solid.svg"),
1449
+ "available": QtGui.QIcon.fromTheme("emblem-default"),
1450
+ "unavailable": QtGui.QIcon.fromTheme("emblem-important"),
1451
+ "remote": QtGui.QIcon.fromTheme("sync-synchronizing"),
1452
+ "unknown": QtGui.QIcon.fromTheme("emblem-unknown"),
1420
1453
  }
1421
1454
 
1422
1455
  def refresh_settings(self):
@@ -1437,7 +1470,16 @@ class ModelIconDelegate(QtWidgets.QStyledItemDelegate):
1437
1470
  options = QtWidgets.QStyleOptionViewItem(option)
1438
1471
  self.initStyleOption(options, index)
1439
1472
  icon = self.icon_mapping[options.text]
1440
- icon.paint(painter, options.rect, QtCore.Qt.AlignmentFlag.AlignLeft)
1473
+ r = option.rect
1474
+ half_size = int(self.settings.icon_size / 2)
1475
+ x = r.left() + (r.width() / 2) - half_size
1476
+ y = r.top() + (r.height() / 2) - half_size
1477
+ options.rect = QtCore.QRect(x, y, self.settings.icon_size, self.settings.icon_size)
1478
+ icon.paint(
1479
+ painter,
1480
+ options.rect,
1481
+ QtCore.Qt.AlignmentFlag.AlignCenter | QtCore.Qt.AlignmentFlag.AlignVCenter,
1482
+ )
1441
1483
 
1442
1484
  painter.restore()
1443
1485
 
@@ -1459,7 +1501,7 @@ class StoppableProgressBar(QtWidgets.QWidget):
1459
1501
  layout.addWidget(self.progress_bar)
1460
1502
  self.cancel_button = QtWidgets.QToolButton()
1461
1503
  self.cancel_action = QtGui.QAction("select", self)
1462
- self.cancel_action.setIcon(QtGui.QIcon(":clear.svg"))
1504
+ self.cancel_action.setIcon(QtGui.QIcon.fromTheme("edit-clear"))
1463
1505
  self.cancel_action.triggered.connect(worker.cancel)
1464
1506
  self.cancel_button.setDefaultAction(self.cancel_action)
1465
1507
  layout.addWidget(self.cancel_button)
@@ -1527,7 +1569,7 @@ class ProgressMenu(QtWidgets.QMenu):
1527
1569
  class ProgressWidget(QtWidgets.QPushButton):
1528
1570
  def __init__(self, *args):
1529
1571
  super().__init__(*args)
1530
- self.done_icon = QtGui.QIcon(":check-circle.svg")
1572
+ self.done_icon = QtGui.QIcon.fromTheme("emblem-default")
1531
1573
  self.animated = QtGui.QMovie(":spinning_blue.svg")
1532
1574
  self.animated.frameChanged.connect(self.update_animation)
1533
1575
  self.setIcon(self.done_icon)
@@ -1766,34 +1808,16 @@ class PronunciationInput(QtWidgets.QToolBar):
1766
1808
  self.setContentsMargins(0, 0, 0, 0)
1767
1809
  self.setFocusProxy(self.input)
1768
1810
 
1769
- accept_icon = QtGui.QIcon()
1770
- accept_icon.addFile(
1771
- ":check-circle.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off
1772
- )
1773
- accept_icon.addFile(
1774
- ":highlighted/check-circle.svg",
1775
- mode=QtGui.QIcon.Mode.Normal,
1776
- state=QtGui.QIcon.State.On,
1777
- )
1811
+ accept_icon = QtGui.QIcon.fromTheme("emblem-default")
1778
1812
 
1779
1813
  self.accept_action = QtGui.QAction(icon=accept_icon, parent=self)
1780
1814
  self.accept_action.triggered.connect(self.returnPressed.emit)
1781
1815
 
1782
- cancel_icon = QtGui.QIcon()
1783
- cancel_icon.addFile(":undo.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off)
1784
- cancel_icon.addFile(
1785
- ":highlighted/undo.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.On
1786
- )
1816
+ cancel_icon = QtGui.QIcon.fromTheme("edit-undo")
1787
1817
 
1788
1818
  self.cancel_action = QtGui.QAction(icon=cancel_icon, parent=self)
1789
1819
  self.cancel_action.triggered.connect(self.cancel)
1790
- keyboard_icon = QtGui.QIcon()
1791
- keyboard_icon.addFile(
1792
- ":keyboard.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.Off
1793
- )
1794
- keyboard_icon.addFile(
1795
- ":highlighted/keyboard.svg", mode=QtGui.QIcon.Mode.Normal, state=QtGui.QIcon.State.On
1796
- )
1820
+ keyboard_icon = QtGui.QIcon.fromTheme("input-keyboard")
1797
1821
 
1798
1822
  self.keyboard_widget = QtWidgets.QPushButton(self)
1799
1823
  self.keyboard_widget.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
@@ -1819,7 +1843,7 @@ class PronunciationInput(QtWidgets.QToolBar):
1819
1843
  self.returnPressed.emit()
1820
1844
  return True
1821
1845
  elif (
1822
- isinstance(watched, (IpaKeyboard))
1846
+ isinstance(watched, IpaKeyboard)
1823
1847
  and event.type() == QtCore.QEvent.Type.KeyPress
1824
1848
  and event.key() not in {QtGui.Qt.Key.Key_Escape}
1825
1849
  ):
@@ -1910,14 +1934,18 @@ class CountDelegate(QtWidgets.QStyledItemDelegate):
1910
1934
  super().paint(painter, option, index)
1911
1935
  painter.save()
1912
1936
  r = option.rect
1913
- size = int(self.settings.icon_size / 2)
1937
+ half_size = int(self.settings.icon_size / 2)
1914
1938
  x = r.left() + r.width() - self.settings.icon_size
1915
- y = r.top()
1939
+ y = r.top() + (r.height() / 2) - half_size
1916
1940
  options = QtWidgets.QStyleOptionViewItem(option)
1917
- options.rect = QtCore.QRect(x, y, size, r.height())
1941
+ options.rect = QtCore.QRect(x, y, self.settings.icon_size, self.settings.icon_size)
1918
1942
  self.initStyleOption(options, index)
1919
- icon = QtGui.QIcon(":external-link.svg")
1920
- icon.paint(painter, options.rect, QtCore.Qt.AlignmentFlag.AlignCenter)
1943
+ icon = QtGui.QIcon.fromTheme("folder-open")
1944
+ icon.paint(
1945
+ painter,
1946
+ options.rect,
1947
+ QtCore.Qt.AlignmentFlag.AlignCenter | QtCore.Qt.AlignmentFlag.AlignVCenter,
1948
+ )
1921
1949
 
1922
1950
  painter.restore()
1923
1951
 
@@ -1941,14 +1969,18 @@ class WordTypeDelegate(QtWidgets.QStyledItemDelegate):
1941
1969
  super().paint(painter, option, index)
1942
1970
  painter.save()
1943
1971
  r = option.rect
1944
- size = int(self.settings.icon_size / 2)
1972
+ half_size = int(self.settings.icon_size / 2)
1945
1973
  x = r.left() + r.width() - self.settings.icon_size
1946
- y = r.top()
1974
+ y = r.top() + (r.height() / 2) - half_size
1947
1975
  options = QtWidgets.QStyleOptionViewItem(option)
1948
- options.rect = QtCore.QRect(x, y, size, r.height())
1976
+ options.rect = QtCore.QRect(x, y, self.settings.icon_size, self.settings.icon_size)
1949
1977
  self.initStyleOption(options, index)
1950
- icon = QtGui.QIcon(":rotate.svg")
1951
- icon.paint(painter, options.rect, QtCore.Qt.AlignmentFlag.AlignCenter)
1978
+ icon = QtGui.QIcon.fromTheme("sync-synchronizing")
1979
+ icon.paint(
1980
+ painter,
1981
+ options.rect,
1982
+ QtCore.Qt.AlignmentFlag.AlignCenter | QtCore.Qt.AlignmentFlag.AlignVCenter,
1983
+ )
1952
1984
 
1953
1985
  painter.restore()
1954
1986
 
@@ -2225,8 +2257,7 @@ class SpeakerTableView(AnchorTableView):
2225
2257
  | QtWidgets.QAbstractItemView.EditTrigger.DoubleClicked
2226
2258
  )
2227
2259
  self.speaker_model: SpeakerModel = None
2228
- self.view_delegate = ButtonDelegate(":magnifying-glass.svg", self)
2229
- self.delete_delegate = ButtonDelegate(":expand.svg", self)
2260
+ self.view_delegate = ButtonDelegate("edit-find", self)
2230
2261
  self.edit_delegate = EditableDelegate(self)
2231
2262
  self.speaker_delegate = SpeakerViewDelegate(self)
2232
2263
  self.setItemDelegateForColumn(1, self.speaker_delegate)
@@ -2483,13 +2514,13 @@ class SpeakerViewDelegate(QtWidgets.QStyledItemDelegate):
2483
2514
  painter.save()
2484
2515
 
2485
2516
  r = option.rect
2486
- size = int(self.settings.icon_size / 2)
2517
+ half_size = int(self.settings.icon_size / 2)
2487
2518
  x = r.left() + r.width() - self.settings.icon_size
2488
- y = r.top()
2519
+ y = r.top() + (r.height() / 2) - half_size
2489
2520
  options = QtWidgets.QStyleOptionViewItem(option)
2490
- options.rect = QtCore.QRect(x, y, size, r.height())
2521
+ options.rect = QtCore.QRect(x, y, self.settings.icon_size, self.settings.icon_size)
2491
2522
  self.initStyleOption(options, index)
2492
- icon = QtGui.QIcon(":external-link.svg")
2523
+ icon = QtGui.QIcon.fromTheme("folder-open")
2493
2524
  icon.paint(painter, options.rect, QtCore.Qt.AlignmentFlag.AlignCenter)
2494
2525
 
2495
2526
  painter.restore()
@@ -2514,13 +2545,13 @@ class ButtonDelegate(QtWidgets.QStyledItemDelegate):
2514
2545
  ) -> None:
2515
2546
  painter.save()
2516
2547
  r = option.rect
2517
- size = int(self.settings.icon_size / 2)
2548
+ half_size = int(self.settings.icon_size / 2)
2518
2549
  x = r.left() + r.width() - self.settings.icon_size
2519
- y = r.top()
2550
+ y = r.top() + (r.height() / 2) - half_size
2520
2551
  options = QtWidgets.QStyleOptionViewItem(option)
2521
- options.rect = QtCore.QRect(x, y, size, r.height())
2552
+ options.rect = QtCore.QRect(x, y, self.settings.icon_size, self.settings.icon_size)
2522
2553
  self.initStyleOption(options, index)
2523
- icon = QtGui.QIcon(self.icon_path)
2554
+ icon = QtGui.QIcon.fromTheme(self.icon_path)
2524
2555
  icon.paint(painter, options.rect, QtCore.Qt.AlignmentFlag.AlignCenter)
2525
2556
 
2526
2557
  painter.restore()
@@ -3054,11 +3085,11 @@ class DictionaryWidget(QtWidgets.QWidget):
3054
3085
  self.current_search_query = None
3055
3086
  self.current_search_text = ""
3056
3087
  self.refresh_word_counts_action = QtGui.QAction(self)
3057
- self.refresh_word_counts_action.setIcon(QtGui.QIcon(":oov-check.svg"))
3088
+ self.refresh_word_counts_action.setIcon(QtGui.QIcon.fromTheme("tools-check-spelling"))
3058
3089
  self.refresh_word_counts_action.setEnabled(True)
3059
3090
  self.toolbar.addAction(self.refresh_word_counts_action)
3060
3091
  self.rebuild_lexicon_action = QtGui.QAction(self)
3061
- self.rebuild_lexicon_action.setIcon(QtGui.QIcon(":rotate.svg"))
3092
+ self.rebuild_lexicon_action.setIcon(QtGui.QIcon.fromTheme("sync-synchronizing"))
3062
3093
  self.rebuild_lexicon_action.setEnabled(True)
3063
3094
  self.toolbar.addAction(self.rebuild_lexicon_action)
3064
3095
  dict_layout.addWidget(self.toolbar)
@@ -3297,31 +3328,33 @@ class SpeakerWidget(QtWidgets.QWidget):
3297
3328
 
3298
3329
 
3299
3330
  class ColorEdit(QtWidgets.QPushButton): # pragma: no cover
3331
+ colorChanged = QtCore.Signal()
3332
+
3300
3333
  def __init__(self, parent=None):
3301
3334
  super(ColorEdit, self).__init__(parent=parent)
3302
3335
  self.setText("")
3303
3336
  self.clicked.connect(self.open_dialog)
3337
+ self.color = None
3304
3338
 
3305
- def set_color(self, color: QtGui.QColor):
3306
- self._color = color
3339
+ def set_color(self, color: typing.Union[str, QtGui.QColor]):
3340
+ if isinstance(color, str):
3341
+ color = QtGui.QColor(color)
3342
+ self.color = color
3307
3343
  self.update_icon()
3308
3344
 
3309
3345
  def update_icon(self):
3310
3346
  pixmap = QtGui.QPixmap(100, 100)
3311
- pixmap.fill(self._color)
3347
+ pixmap.fill(self.color)
3312
3348
  icon = QtGui.QIcon(pixmap)
3313
3349
  icon.addPixmap(pixmap, QtGui.QIcon.Mode.Disabled)
3314
3350
  self.setIcon(icon)
3315
3351
 
3316
- @property
3317
- def color(self) -> str:
3318
- return self._color.name()
3319
-
3320
3352
  def open_dialog(self):
3321
3353
  color = QtWidgets.QColorDialog.getColor()
3322
- if color.isValid():
3323
- self._color = color
3354
+ if color.isValid() and self.color != color.name():
3355
+ self.color = color.name()
3324
3356
  self.update_icon()
3357
+ self.colorChanged.emit()
3325
3358
 
3326
3359
 
3327
3360
  class FontDialog(QtWidgets.QFontDialog):
@@ -3473,8 +3506,8 @@ class PathSelectWidget(QtWidgets.QWidget):
3473
3506
  self.setLayout(layout)
3474
3507
 
3475
3508
  self.select_button.clicked.connect(self.select_path)
3476
- self.exists_icon = QtGui.QIcon(":check-circle.svg")
3477
- self.not_exists_icon = QtGui.QIcon(":disabled/exclamation-triangle.svg")
3509
+ self.exists_icon = QtGui.QIcon.fromTheme("emblem-default")
3510
+ self.not_exists_icon = QtGui.QIcon.fromTheme("emblem-important")
3478
3511
 
3479
3512
  def value(self):
3480
3513
  if not self.path_edit.text():
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,27 @@ 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 = (
3390
+ session.query(Dictionary.path).filter(Dictionary.path != "").first()
3391
+ )
3392
+ if dictionary is not None:
3393
+ self.dictionary_path = dictionary[0]
3394
+ except (sqlalchemy.exc.OperationalError, sqlalchemy.exc.ProgrammingError):
3395
+ pass
3368
3396
  try:
3369
3397
  if dataset_type is DatasetType.NONE:
3370
3398
  if self.dictionary_path and os.path.exists(self.dictionary_path):
@@ -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=j90u3VVU4UrJf1fgMUhaZarHK_Do2XGYXr-vZvOFzVo,411
4
- anchor/command_line.py,sha256=EucG805HyWk_zkMO9RXv9Yj0I0JVdDLZb1_DX2_ISjM,503
5
- anchor/db.py,sha256=ef4lO6HtCKoxC9CorIc0ZbPxKpjHa576a0ZIBOWNU9E,4956
6
- anchor/main.py,sha256=cZjj_PbAC2CPDneEy8HGNfH7F1hZpQexevFjBev9YxE,120664
7
- anchor/models.py,sha256=Uaz_IobsG6aPDH9xfZYwN8bBDzc7U-rcbgm0jqihyd4,95763
8
- anchor/plot.py,sha256=fUIVvSV7MIvV1HyNo5eZmi1PKun0WFDrnSXHkJD70zA,105668
9
- anchor/resources_rc.py,sha256=94wgxDTpP4Oy55Br7CZ_YnmvaqzHr4n-AydBPhZc-es,8427242
10
- anchor/settings.py,sha256=OdJQl54rhQ-JmsDiWIULxMFZZatM4arZ37hnmkk_VM4,47583
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=FrzTz9hSUXV6jFJ7EUurxY5NmftQ5NWhtVzzYuVmcRo,32959
16
- anchor/widgets.py,sha256=Lw2y9bymDiu01eGqLR0M8CSjXYV5-e037XqRQiX7Wn8,157619
17
- anchor/workers.py,sha256=SUrafStLUrdhi5b3QhkRYKdFghasDc8lxsUCZOF_FRg,171159
18
- Anchor_annotator-0.4.0.dist-info/LICENSE,sha256=C0oIsblENEgWQ7XMNdYoXyXsIA5wa3YF0I9lK3H7A1s,1076
19
- Anchor_annotator-0.4.0.dist-info/METADATA,sha256=EMWnDUTa3Di2cpH4RiP6buwD67Nj-m5vdkkstIFf8M8,1500
20
- Anchor_annotator-0.4.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
21
- Anchor_annotator-0.4.0.dist-info/top_level.txt,sha256=wX6ZKxImGRZKFQjs3f6XYw_TfbAp6Xs3SmbLfLbFAJ0,7
22
- Anchor_annotator-0.4.0.dist-info/RECORD,,