subtitld 0.0.0.dev0__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.
Files changed (237) hide show
  1. subtitld/__init__.py +19 -0
  2. subtitld/__main__.py +240 -0
  3. subtitld/ftfy/char_classes.dat +0 -0
  4. subtitld/graphics/Montserrat-Black.ttf +0 -0
  5. subtitld/graphics/Montserrat-BlackItalic.ttf +0 -0
  6. subtitld/graphics/Montserrat-Bold.ttf +0 -0
  7. subtitld/graphics/Montserrat-BoldItalic.ttf +0 -0
  8. subtitld/graphics/Montserrat-ExtraBold.ttf +0 -0
  9. subtitld/graphics/Montserrat-ExtraBoldItalic.ttf +0 -0
  10. subtitld/graphics/Montserrat-ExtraLight.ttf +0 -0
  11. subtitld/graphics/Montserrat-ExtraLightItalic.ttf +0 -0
  12. subtitld/graphics/Montserrat-Italic.ttf +0 -0
  13. subtitld/graphics/Montserrat-Light.ttf +0 -0
  14. subtitld/graphics/Montserrat-LightItalic.ttf +0 -0
  15. subtitld/graphics/Montserrat-Medium.ttf +0 -0
  16. subtitld/graphics/Montserrat-MediumItalic.ttf +0 -0
  17. subtitld/graphics/Montserrat-Regular.ttf +0 -0
  18. subtitld/graphics/Montserrat-SemiBold.ttf +0 -0
  19. subtitld/graphics/Montserrat-SemiBoldItalic.ttf +0 -0
  20. subtitld/graphics/Montserrat-Thin.ttf +0 -0
  21. subtitld/graphics/Montserrat-ThinItalic.ttf +0 -0
  22. subtitld/graphics/Ubuntu-B.ttf +0 -0
  23. subtitld/graphics/Ubuntu-BI.ttf +0 -0
  24. subtitld/graphics/Ubuntu-C.ttf +0 -0
  25. subtitld/graphics/Ubuntu-L.ttf +0 -0
  26. subtitld/graphics/Ubuntu-LI.ttf +0 -0
  27. subtitld/graphics/Ubuntu-M.ttf +0 -0
  28. subtitld/graphics/Ubuntu-MI.ttf +0 -0
  29. subtitld/graphics/Ubuntu-R.ttf +0 -0
  30. subtitld/graphics/Ubuntu-RI.ttf +0 -0
  31. subtitld/graphics/Ubuntu-Th.ttf +0 -0
  32. subtitld/graphics/UbuntuMono-B.ttf +0 -0
  33. subtitld/graphics/UbuntuMono-BI.ttf +0 -0
  34. subtitld/graphics/UbuntuMono-R.ttf +0 -0
  35. subtitld/graphics/UbuntuMono-RI.ttf +0 -0
  36. subtitld/graphics/add_and_play.svg +4 -0
  37. subtitld/graphics/add_from_last.svg +4 -0
  38. subtitld/graphics/add_from_last_checked.svg +4 -0
  39. subtitld/graphics/add_subtitle_icon.svg +4 -0
  40. subtitld/graphics/add_subtitle_to_next_start.svg +4 -0
  41. subtitld/graphics/add_subtitle_to_next_start_checked.svg +4 -0
  42. subtitld/graphics/background_watermark.svg +9 -0
  43. subtitld/graphics/character_count_icon.svg +1 -0
  44. subtitld/graphics/checkbox_checked.svg +8 -0
  45. subtitld/graphics/checkbox_checked_hover.svg +8 -0
  46. subtitld/graphics/checkbox_disabled.svg +4 -0
  47. subtitld/graphics/checkbox_unchecked.svg +5 -0
  48. subtitld/graphics/checkbox_unchecked_hover.svg +5 -0
  49. subtitld/graphics/combobox_down_arrow.svg +4 -0
  50. subtitld/graphics/cps_icon.svg +1 -0
  51. subtitld/graphics/dialog_close_icon.svg +4 -0
  52. subtitld/graphics/dialog_close_icon_hover.svg +4 -0
  53. subtitld/graphics/dubbing_container_collapse_icon.svg +8 -0
  54. subtitld/graphics/dubbing_container_expand_icon.svg +4 -0
  55. subtitld/graphics/file.svg +4 -0
  56. subtitld/graphics/gap_add_icon.svg +4 -0
  57. subtitld/graphics/gap_remove_icon.svg +4 -0
  58. subtitld/graphics/grid_frames_icon.svg +4 -0
  59. subtitld/graphics/grid_frames_icon_checked.svg +4 -0
  60. subtitld/graphics/grid_frames_icon_disabled.svg +4 -0
  61. subtitld/graphics/grid_scenes_icon.svg +4 -0
  62. subtitld/graphics/grid_scenes_icon_checked.svg +4 -0
  63. subtitld/graphics/grid_scenes_icon_disabled.svg +4 -0
  64. subtitld/graphics/grid_seconds_icon.svg +4 -0
  65. subtitld/graphics/grid_seconds_icon_checked.svg +4 -0
  66. subtitld/graphics/grid_seconds_icon_disabled.svg +4 -0
  67. subtitld/graphics/last_end_to_current_position_icon.svg +4 -0
  68. subtitld/graphics/last_start_last_end_to_current_position_button.svg +9 -0
  69. subtitld/graphics/last_start_to_current_position_icon.svg +4 -0
  70. subtitld/graphics/left_panel_autosave.svg +4 -0
  71. subtitld/graphics/left_panel_dubbing.svg +4 -0
  72. subtitld/graphics/left_panel_export.svg +4 -0
  73. subtitld/graphics/left_panel_global.svg +4 -0
  74. subtitld/graphics/left_panel_import.svg +4 -0
  75. subtitld/graphics/left_panel_interface.svg +4 -0
  76. subtitld/graphics/left_panel_keyboard.svg +4 -0
  77. subtitld/graphics/left_panel_metadata.svg +4 -0
  78. subtitld/graphics/left_panel_navigation_background.svg +11 -0
  79. subtitld/graphics/left_panel_qualitycheck.svg +4 -0
  80. subtitld/graphics/left_panel_speakers.svg +4 -0
  81. subtitld/graphics/left_panel_subtitles.svg +1 -0
  82. subtitld/graphics/left_panel_transcription.svg +4 -0
  83. subtitld/graphics/left_panel_translation.svg +4 -0
  84. subtitld/graphics/merge_back_selected_subtitle_icon.svg +4 -0
  85. subtitld/graphics/merge_next_selected_subtitle_icon.svg +4 -0
  86. subtitld/graphics/move_backward_subtitle.svg +4 -0
  87. subtitld/graphics/move_end_back_subtitle.svg +4 -0
  88. subtitld/graphics/move_end_forward_subtitle.svg +4 -0
  89. subtitld/graphics/move_forward_subtitle.svg +4 -0
  90. subtitld/graphics/move_start_back_subtitle.svg +4 -0
  91. subtitld/graphics/move_start_forward_subtitle.svg +4 -0
  92. subtitld/graphics/music_voice_separation_music_icon.svg +4 -0
  93. subtitld/graphics/music_voice_separation_music_icon_disabled.svg +4 -0
  94. subtitld/graphics/music_voice_separation_voice_icon.svg +4 -0
  95. subtitld/graphics/music_voice_separation_voice_icon_disabled.svg +4 -0
  96. subtitld/graphics/new_line_icon.svg +1 -0
  97. subtitld/graphics/next_end_to_current_position_icon.svg +4 -0
  98. subtitld/graphics/next_start_next_end_to_current_position_button.svg +4 -0
  99. subtitld/graphics/next_start_to_current_position_icon.svg +4 -0
  100. subtitld/graphics/pause_icon.svg +12 -0
  101. subtitld/graphics/play_from_last_start_icon.svg +5 -0
  102. subtitld/graphics/play_from_next_start_icon.svg +7 -0
  103. subtitld/graphics/play_icon.svg +12 -0
  104. subtitld/graphics/play_icon_hover.svg +12 -0
  105. subtitld/graphics/play_icon_pressed.svg +12 -0
  106. subtitld/graphics/playback_repeat.svg +4 -0
  107. subtitld/graphics/playback_speed.svg +6 -0
  108. subtitld/graphics/playbackspeed_border.svg +5 -0
  109. subtitld/graphics/playbackspeed_border_checked.svg +5 -0
  110. subtitld/graphics/playbackspeed_border_hover.svg +5 -0
  111. subtitld/graphics/playercontrols_button_first.svg +5 -0
  112. subtitld/graphics/playercontrols_button_first_hover.svg +6 -0
  113. subtitld/graphics/playercontrols_button_first_pressed.svg +6 -0
  114. subtitld/graphics/playercontrols_button_last.svg +6 -0
  115. subtitld/graphics/playercontrols_button_last_hover.svg +6 -0
  116. subtitld/graphics/playercontrols_button_last_pressed.svg +6 -0
  117. subtitld/graphics/playercontrols_widget_center_bottom_line.svg +13 -0
  118. subtitld/graphics/playercontrols_widget_center_top_line.svg +17 -0
  119. subtitld/graphics/plus_icon.svg +4 -0
  120. subtitld/graphics/record_icon.svg +8 -0
  121. subtitld/graphics/record_icon_pressed.svg +5 -0
  122. subtitld/graphics/remove_selected_subtitle_icon.svg +6 -0
  123. subtitld/graphics/repeat_playback_border.svg +5 -0
  124. subtitld/graphics/repeat_playback_border_checked.svg +5 -0
  125. subtitld/graphics/repeat_playback_border_hover.svg +5 -0
  126. subtitld/graphics/save.svg +4 -0
  127. subtitld/graphics/send_text_to_last_subtitle_and_slice_button.svg +8 -0
  128. subtitld/graphics/send_text_to_last_subtitle_icon.svg +8 -0
  129. subtitld/graphics/send_text_to_next_subtitle_and_slice_button.svg +8 -0
  130. subtitld/graphics/send_text_to_next_subtitle_icon.svg +8 -0
  131. subtitld/graphics/slice_selected_subtitle_icon.svg +4 -0
  132. subtitld/graphics/snap_grid_icon.svg +4 -0
  133. subtitld/graphics/snap_grid_icon_checked.svg +4 -0
  134. subtitld/graphics/snap_grid_icon_disabled.svg +4 -0
  135. subtitld/graphics/snap_limits_icon.svg +4 -0
  136. subtitld/graphics/snap_limits_icon_checked.svg +4 -0
  137. subtitld/graphics/snap_limits_icon_disabled.svg +4 -0
  138. subtitld/graphics/snap_move_next.svg +4 -0
  139. subtitld/graphics/snap_move_next_checked.svg +4 -0
  140. subtitld/graphics/snap_move_next_disabled.svg +4 -0
  141. subtitld/graphics/snap_moving_icon.svg +4 -0
  142. subtitld/graphics/snap_moving_icon_checked.svg +4 -0
  143. subtitld/graphics/snap_moving_icon_disabled.svg +4 -0
  144. subtitld/graphics/speaker_list_item_change_color_icon.svg +4 -0
  145. subtitld/graphics/speaker_list_item_change_color_icon_hover.svg +4 -0
  146. subtitld/graphics/speaker_list_item_change_image_icon.svg +4 -0
  147. subtitld/graphics/speaker_list_item_change_image_icon_hover.svg +4 -0
  148. subtitld/graphics/speaker_list_item_export_icon.svg +4 -0
  149. subtitld/graphics/speaker_list_item_export_icon_hover.svg +4 -0
  150. subtitld/graphics/speaker_list_item_remove_icon.svg +4 -0
  151. subtitld/graphics/speaker_list_item_remove_icon_hover.svg +4 -0
  152. subtitld/graphics/speaker_list_item_rename_icon.svg +4 -0
  153. subtitld/graphics/speaker_list_item_rename_icon_hover.svg +4 -0
  154. subtitld/graphics/spinbox_arrow_down.svg +4 -0
  155. subtitld/graphics/spinbox_arrow_up.svg +4 -0
  156. subtitld/graphics/start_screen_top_shadow.svg +23 -0
  157. subtitld/graphics/stop_icon.svg +6 -0
  158. subtitld/graphics/stop_icon_hover.svg +6 -0
  159. subtitld/graphics/stop_icon_pressed.svg +6 -0
  160. subtitld/graphics/stylesheet.qss +1838 -0
  161. subtitld/graphics/subtitld.ico +0 -0
  162. subtitld/graphics/subtitld.png +0 -0
  163. subtitld/graphics/subtitles_panel_simplelist_properties_duration_timing_lock_closed_icon.svg +4 -0
  164. subtitld/graphics/subtitles_panel_simplelist_properties_duration_timing_lock_open_icon.svg +4 -0
  165. subtitld/graphics/subtitles_panel_simplelist_properties_duration_timing_lock_open_icon_hover.svg +4 -0
  166. subtitld/graphics/timeline_bottom_controls_background.svg +25 -0
  167. subtitld/graphics/timeline_cursor_back_frame.svg +4 -0
  168. subtitld/graphics/timeline_cursor_back_frame_hover.svg +4 -0
  169. subtitld/graphics/timeline_cursor_next_frame.svg +4 -0
  170. subtitld/graphics/timeline_cursor_next_frame_hover.svg +4 -0
  171. subtitld/graphics/timeline_show_speaker_color.svg +5 -0
  172. subtitld/graphics/timeline_show_speaker_color_checked.svg +5 -0
  173. subtitld/graphics/timeline_show_speaker_in_tracks.svg +4 -0
  174. subtitld/graphics/timeline_show_speaker_in_tracks_checked.svg +4 -0
  175. subtitld/graphics/timelinescrolling_follow_icon.svg +4 -0
  176. subtitld/graphics/timelinescrolling_follow_icon_checked.svg +4 -0
  177. subtitld/graphics/timelinescrolling_none_icon.svg +6 -0
  178. subtitld/graphics/timelinescrolling_none_icon_checked.svg +6 -0
  179. subtitld/graphics/timelinescrolling_page_icon.svg +4 -0
  180. subtitld/graphics/timelinescrolling_page_icon_checked.svg +4 -0
  181. subtitld/graphics/titleBar_left_container_border.svg +113 -0
  182. subtitld/graphics/unknown_speaker.svg +5 -0
  183. subtitld/graphics/vosk_transcription_download_model_icon.svg +4 -0
  184. subtitld/graphics/vosk_transcription_update_model_icon.svg +4 -0
  185. subtitld/graphics/word_count_icon.svg +1 -0
  186. subtitld/graphics/wpm_icon.svg +1 -0
  187. subtitld/graphics/zoom_in_icon.svg +4 -0
  188. subtitld/graphics/zoom_in_icon_disabled.svg +4 -0
  189. subtitld/graphics/zoom_out_icon.svg +4 -0
  190. subtitld/graphics/zoom_out_icon_disabled.svg +4 -0
  191. subtitld/interface/__init__.py +0 -0
  192. subtitld/interface/actionmanager.py +18 -0
  193. subtitld/interface/bottom_panel.py +43 -0
  194. subtitld/interface/left_panel.py +144 -0
  195. subtitld/interface/left_panel_autosave.py +149 -0
  196. subtitld/interface/left_panel_dubbing.py +469 -0
  197. subtitld/interface/left_panel_export.py +755 -0
  198. subtitld/interface/left_panel_global.py +358 -0
  199. subtitld/interface/left_panel_import.py +82 -0
  200. subtitld/interface/left_panel_interface.py +616 -0
  201. subtitld/interface/left_panel_keyboard.py +261 -0
  202. subtitld/interface/left_panel_metadata.py +74 -0
  203. subtitld/interface/left_panel_qualitycheck.py +262 -0
  204. subtitld/interface/left_panel_speakers.py +737 -0
  205. subtitld/interface/left_panel_subtitleslist.py +791 -0
  206. subtitld/interface/left_panel_transcription.py +763 -0
  207. subtitld/interface/left_panel_translation.py +294 -0
  208. subtitld/interface/playercontrols.py +2348 -0
  209. subtitld/interface/preview_panel.py +407 -0
  210. subtitld/interface/productionscreen.py +65 -0
  211. subtitld/interface/startscreen.py +273 -0
  212. subtitld/interface/timeline.py +1308 -0
  213. subtitld/interface/top_bar.py +329 -0
  214. subtitld/interface/translation.py +68 -0
  215. subtitld/interface/utils.py +286 -0
  216. subtitld/locale/en_US.json +301 -0
  217. subtitld/locale/pt_BR.json +269 -0
  218. subtitld/modules/__init__.py +0 -0
  219. subtitld/modules/audioengine.py +606 -0
  220. subtitld/modules/bounce.py +229 -0
  221. subtitld/modules/config.py +84 -0
  222. subtitld/modules/file_io.py +870 -0
  223. subtitld/modules/history.py +31 -0
  224. subtitld/modules/quality_check.py +53 -0
  225. subtitld/modules/session.py +270 -0
  226. subtitld/modules/shortcuts.py +84 -0
  227. subtitld/modules/subtitles.py +413 -0
  228. subtitld/modules/timecode.py +496 -0
  229. subtitld/modules/usf.py +366 -0
  230. subtitld/modules/utils.py +79 -0
  231. subtitld/modules/waveform.py +53 -0
  232. subtitld-0.0.0.dev0.dist-info/METADATA +97 -0
  233. subtitld-0.0.0.dev0.dist-info/RECORD +237 -0
  234. subtitld-0.0.0.dev0.dist-info/WHEEL +5 -0
  235. subtitld-0.0.0.dev0.dist-info/entry_points.txt +2 -0
  236. subtitld-0.0.0.dev0.dist-info/licenses/LICENSE +674 -0
  237. subtitld-0.0.0.dev0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,791 @@
1
+ from PySide6.QtWidgets import QVBoxLayout, QWidget, QHBoxLayout, QSplitter, QPushButton, QListView, QStyledItemDelegate, QFrame, QLabel, QTextEdit, QSizePolicy, QLineEdit, QStyle, QDialog, QListWidget, QListWidgetItem, QAbstractScrollArea, QGraphicsOpacityEffect
2
+ from PySide6.QtCore import Qt, QAbstractListModel, QRect, QMargins, QSize, Signal, QPoint, QPropertyAnimation, QEasingCurve
3
+ from PySide6.QtGui import QColor, QFontMetrics, QFont, QIcon, QPixmap
4
+
5
+ from subtitld.interface import utils
6
+ from subtitld.interface import left_panel
7
+ from subtitld.interface import preview_panel
8
+ from subtitld.interface.translation import _
9
+
10
+ from subtitld.modules import session
11
+ from subtitld.modules import subtitles
12
+ from subtitld.modules import utils as modules_utils
13
+ from subtitld.modules import quality_check
14
+
15
+
16
+
17
+ TEXT_ALIGNMENTS = {
18
+ 'left' : Qt.AlignLeft,
19
+ 'center' : Qt.AlignHCenter,
20
+ 'right' : Qt.AlignRight
21
+ }
22
+
23
+ class subtitles_panel_qlistwidget(QListView):
24
+ def __init__(widget, parent=None):
25
+ super(subtitles_panel_qlistwidget, widget).__init__(parent)
26
+
27
+ class model(QAbstractListModel):
28
+ def __init__(self, *args, subs=None, **kwargs):
29
+ super(model, self).__init__(*args, **kwargs)
30
+ # self.subtitles = subs or []
31
+
32
+ def data(self, index, role):
33
+ if role == Qt.DisplayRole:
34
+ return session.SUBTITLE['segments'][index.row()] #['text']
35
+
36
+ # def translated_data(self, index, role):
37
+ # if role == Qt.DisplayRole:
38
+ # return session.SUBTITLE['segments'][index.row()].get('translations', {}).get(session.CONFIG['translation'].get('engine_options', {}).get('target_language', 'en-us'), '')
39
+
40
+ # if role == Qt.DecorationRole:
41
+ # status, _ = session.SUBTITLE['segments'][index.row()]
42
+ # if status:
43
+ # return tick
44
+
45
+ def get_index(self, subtitle):
46
+ index = session.SUBTITLE['segments'].index(subtitle)
47
+ return self.index(index)
48
+
49
+ def rowCount(self, _):
50
+ return len(session.SUBTITLE['segments'])
51
+
52
+ class delegate(QStyledItemDelegate):
53
+ def __init__(self, parent=None):
54
+ super(delegate, self).__init__(parent)
55
+
56
+ def get_number_width(self, index):
57
+ number_width = QFontMetrics(QFont('Montserrat', 8)).horizontalAdvance((len(str(index.model().rowCount(index)))) * '8')
58
+ return number_width
59
+
60
+ def get_text_height(self, option, index):
61
+ row_text = index.data(Qt.DisplayRole)['text']
62
+ width = option.rect.width()
63
+ if session.CONFIG['translation'].get('engine_options', {}).get('show_translations', False):
64
+ translated_text = index.data(Qt.DisplayRole).get('translations', {}).get(session.CONFIG['translation'].get('engine_options', {}).get('target_language', 'en-us'), '')
65
+ height_o = QFontMetrics(QFont('Montserrat', 10)).boundingRect(QRect(0, 0, (width/2) - (20 + 10 + self.get_number_width(index) + 10 + 10), 100), Qt.TextWordWrap, row_text).height()
66
+ height_t = QFontMetrics(QFont('Montserrat', 10)).boundingRect(QRect(width/2, 0, (width/2) - (20 + 10 + self.get_number_width(index) + 10 + 10), 100), Qt.TextWordWrap, translated_text).height()
67
+ height = max(height_o, height_t)
68
+ else:
69
+ height = QFontMetrics(QFont('Montserrat', 10)).boundingRect(QRect(0, 0, width - (20 + 10 + self.get_number_width(index) + 10 + 10), 100), Qt.TextWordWrap, row_text).height()
70
+ return height
71
+
72
+ def paint(self, painter, option, index):
73
+ segment = index.data(Qt.DisplayRole)
74
+ row_text = segment['text']
75
+ number_width = self.get_number_width(index)
76
+
77
+
78
+ if option.state & QStyle.State_Selected:
79
+ painter.setPen(Qt.NoPen)
80
+ painter.setBrush(QColor(session.CONFIG.get('subtitle_list', {}).get('background_color', '#802e3e4c')))
81
+ painter.drawRect(option.rect)
82
+ # painter.setBrush(QColor('#55d43f'))
83
+ # painter.drawRect(QRect(0, option.rect.y(), 20, option.rect.height()))
84
+
85
+ sub_is_ok = True
86
+ if session.CONFIG.get('quality_check', {}).get('enabled', False):
87
+ sub_is_ok, _, _ = quality_check.check_subtitle(session.SUBTITLE['segments'][index.row()])
88
+
89
+ painter.setPen(Qt.NoPen)
90
+ painter.setBrush(QColor(session.CONFIG.get('subtitle_list', {}).get('number_background_color', '#aa2e3e4c') if sub_is_ok else session.CONFIG.get('subtitle_list', {}).get('number_background_warning_color', '#aa9e1a1a')))
91
+
92
+ number_rect = QRect(0, option.rect.y(), 10 + number_width + 10, option.rect.height())
93
+ text_rect = QRect(number_rect.right(), option.rect.y(), option.rect.width() - number_rect.right(), option.rect.height())
94
+
95
+ painter.drawRect(number_rect)
96
+
97
+ painter.setPen(QColor(session.CONFIG.get('subtitle_list', {}).get('number_color', '#ffffff') if sub_is_ok else session.CONFIG.get('subtitle_list', {}).get('number_warning_color', '#ffffff')))
98
+
99
+ number_rect = number_rect.marginsRemoved(QMargins(10, 10, 10, 10))
100
+
101
+ painter.setFont(QFont('Montserrat', 8))
102
+ painter.drawText(number_rect, 0, str(index.row() + 1))
103
+
104
+ painter.setPen(Qt.NoPen)
105
+ painter.setBrush(QColor(session.CONFIG.get('subtitle_list', {}).get('text_background_color', '#102e3e4c') if sub_is_ok else session.CONFIG.get('subtitle_list', {}).get('text_background_warning_color', '#109e1a1a')))
106
+
107
+ painter.drawRect(text_rect)
108
+
109
+ painter.setPen(QColor(session.CONFIG.get('subtitle_list', {}).get('text_color', '#ffffff') if sub_is_ok else session.CONFIG.get('subtitle_list', {}).get('text_warning_color', '#9e1a1a')))
110
+ painter.setFont(QFont('Montserrat', 10))
111
+
112
+ qalignment = TEXT_ALIGNMENTS[session.CONFIG['default_values'].get('subtitle_alignment', 'left')]
113
+
114
+ if session.CONFIG['translation'].get('engine_options', {}).get('show_translations', False):
115
+ original_rect = text_rect.marginsRemoved(QMargins(0, 0, text_rect.width()*.5, 0))
116
+ original_rect = original_rect.marginsRemoved(QMargins(10, 10, 10, 10))
117
+ painter.drawText(original_rect, qalignment | Qt.AlignTop | Qt.TextWordWrap, row_text)
118
+ translated_rect = text_rect.marginsRemoved(QMargins(text_rect.width()*.5, 0, 0, 0))
119
+ painter.setPen(QColor(session.CONFIG.get('subtitle_list', {}).get('text_warning_color', '#0dffffff')))
120
+ painter.drawLine(translated_rect.topLeft(), translated_rect.bottomLeft())
121
+ painter.setPen(QColor(session.CONFIG.get('subtitle_list', {}).get('text_color', '#ffffff') if sub_is_ok else session.CONFIG.get('subtitle_list', {}).get('text_warning_color', '#9e1a1a')))
122
+ translated_rect = translated_rect.marginsRemoved(QMargins(10, 10, 10, 10))
123
+ translated_text = segment.get('translations', {}).get(session.CONFIG['translation'].get('engine_options', {}).get('target_language', 'en-us'), '')
124
+ painter.drawText(translated_rect, qalignment | Qt.AlignTop | Qt.TextWordWrap, translated_text)
125
+ else:
126
+ original_rect = text_rect.marginsRemoved(QMargins(10, 10, 10, 10))
127
+ painter.drawText(original_rect, qalignment | Qt.AlignTop | Qt.TextWordWrap, row_text)
128
+
129
+ def sizeHint(self, option, index):
130
+ width = option.rect.width()
131
+ height = self.get_text_height(option, index) + 20
132
+ return QSize(width, height)
133
+
134
+ widget.model = model()
135
+ widget.delegate = delegate()
136
+ widget.setViewMode(QListView.ListMode)
137
+ widget.setObjectName('subtitles_panel_qlistwidget')
138
+ widget.setContentsMargins(QMargins(0, 0, 0, 0))
139
+ widget.setSpacing(0)
140
+ widget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
141
+ widget.setFocusPolicy(Qt.NoFocus)
142
+ widget.setModel(widget.model)
143
+ widget.setItemDelegate(widget.delegate)
144
+ widget.clicked.connect(lambda index: widget.item_selected(index))
145
+
146
+ def resizeEvent(widget, event):
147
+ widget.model.layoutChanged.emit()
148
+ event.accept()
149
+
150
+ def showEvent(widget, event):
151
+ widget.update_content()
152
+ event.accept()
153
+
154
+ def update_content(widget):
155
+ current_sub = subtitles.subtitle_under_current_position()
156
+ index = session.SUBTITLE['segments'].index(current_sub) if current_sub else 0
157
+ if current_sub and not (widget.verticalScrollBar().value() + widget.verticalScrollBar().pageStep() > index > widget.verticalScrollBar().value()):
158
+ widget.verticalScrollBar().setValue(index - 1)
159
+
160
+ widget.model.layoutChanged.emit()
161
+
162
+ if session.SUBTITLE.get('selected', None) is not None:
163
+ widget.setCurrentIndex(widget.model.get_index(session.SUBTITLE['selected']))
164
+
165
+ # widget.update_properties_widget(widget.window())
166
+
167
+ def item_selected(widget, index):
168
+ session.SUBTITLE['selected'] = session.SUBTITLE['segments'][index.row()]
169
+ update(widget.window())
170
+
171
+ def load(self):
172
+ tab_name = 'subtitles'
173
+
174
+ left_panel_subtitles_panel = left_panel.left_panel(
175
+ parent=self,
176
+ tab_name=tab_name,
177
+ update_callback=update,
178
+ translate_callback=translate
179
+ )
180
+
181
+ left_panel_subtitles_panel.layout().setContentsMargins(0, 0, 0, 0)
182
+
183
+
184
+ subtitles_panel_simplelist_qsplitter = QSplitter(Qt.Vertical)
185
+
186
+ self.subtitles_panel_qlistwidget = subtitles_panel_qlistwidget()
187
+ subtitles_panel_simplelist_qsplitter.addWidget(self.subtitles_panel_qlistwidget)
188
+
189
+ self.left_panel_subtitleslist_bottom_panel = QWidget()
190
+ self.left_panel_subtitleslist_bottom_panel.setObjectName('left_panel_subtitleslist_bottom_panel')
191
+ self.left_panel_subtitleslist_bottom_panel.setLayout(QVBoxLayout())
192
+ self.left_panel_subtitleslist_bottom_panel.layout().setContentsMargins(0, 0, 0, 0)
193
+ self.left_panel_subtitleslist_bottom_panel.layout().setSpacing(0)
194
+ subtitles_panel_simplelist_qsplitter.addWidget(self.left_panel_subtitleslist_bottom_panel)
195
+
196
+ self.left_panel_subtitleslist_textedit = QTextEdit()
197
+ self.left_panel_subtitleslist_textedit.setObjectName('left_panel_subtitleslist_textedit')
198
+ self.left_panel_subtitleslist_textedit.setAcceptRichText(False)
199
+ self.left_panel_subtitleslist_textedit.textChanged.connect(lambda: left_panel_subtitleslist_textedit_changed(self))
200
+ self.left_panel_subtitleslist_bottom_panel.layout().addWidget(self.left_panel_subtitleslist_textedit)
201
+
202
+ self.left_panel_subtitleslist_translation_textedit = QTextEdit()
203
+ self.left_panel_subtitleslist_translation_textedit.setObjectName('left_panel_subtitleslist_translation_textedit')
204
+ self.left_panel_subtitleslist_translation_textedit.setAcceptRichText(False)
205
+ self.left_panel_subtitleslist_translation_textedit.textChanged.connect(lambda: left_panel_subtitleslist_translation_textedit_changed(self))
206
+ self.left_panel_subtitleslist_bottom_panel.layout().addWidget(self.left_panel_subtitleslist_translation_textedit)
207
+
208
+ self.left_panel_subtitleslist_textedit_bottom_line = QHBoxLayout()
209
+ self.left_panel_subtitleslist_textedit_bottom_line.setContentsMargins(0, 0, 0, 0)
210
+ self.left_panel_subtitleslist_textedit_bottom_line.setSpacing(0)
211
+ self.left_panel_subtitleslist_bottom_panel.layout().addLayout(self.left_panel_subtitleslist_textedit_bottom_line)
212
+
213
+ self.properties_information = QWidget()
214
+ self.properties_information.setObjectName('properties_information')
215
+ self.properties_information.setSizePolicy(QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum))
216
+ self.properties_information.setLayout(QVBoxLayout())
217
+ self.properties_information.layout().setContentsMargins(5, 5, 5, 5)
218
+ self.properties_information.layout().setSpacing(5)
219
+
220
+ self.properties_information_stats = QFrame()
221
+ self.properties_information_stats.setObjectName('properties_information')
222
+ self.properties_information_stats.setLayout(QHBoxLayout())
223
+ self.properties_information_stats.layout().setContentsMargins(0, 0, 0, 0)
224
+ self.properties_information_stats.layout().setSpacing(5)
225
+
226
+ self.properties_information_word_counter = QLabel()
227
+ self.properties_information_word_counter.setAlignment(Qt.AlignCenter)
228
+ self.properties_information_word_counter.setObjectName('properties_information_word_counter')
229
+ self.properties_information_stats.layout().addWidget(self.properties_information_word_counter)
230
+
231
+ self.properties_information_stats.layout().addSpacing(-5)
232
+
233
+ self.properties_information_wpm = QLabel()
234
+ self.properties_information_wpm.setAlignment(Qt.AlignCenter)
235
+ self.properties_information_wpm.setObjectName('properties_information_wpm')
236
+ self.properties_information_stats.layout().addWidget(self.properties_information_wpm)
237
+
238
+ self.properties_information_character_counter = QLabel()
239
+ self.properties_information_character_counter.setAlignment(Qt.AlignCenter)
240
+ self.properties_information_character_counter.setObjectName('properties_information_character_counter')
241
+ self.properties_information_stats.layout().addWidget(self.properties_information_character_counter)
242
+
243
+ self.properties_information_stats.layout().addSpacing(-5)
244
+
245
+ self.properties_information_cps = QLabel()
246
+ self.properties_information_cps.setAlignment(Qt.AlignCenter)
247
+ self.properties_information_cps.setObjectName('properties_information_cps')
248
+ self.properties_information_stats.layout().addWidget(self.properties_information_cps)
249
+
250
+ self.properties_information_sub_duration = QLabel()
251
+ self.properties_information_sub_duration.setAlignment(Qt.AlignCenter)
252
+ self.properties_information_sub_duration.setObjectName('properties_information_sub_duration')
253
+ self.properties_information_stats.layout().addWidget(self.properties_information_sub_duration)
254
+
255
+ self.properties_information_number_of_lines = QLabel()
256
+ self.properties_information_number_of_lines.setAlignment(Qt.AlignCenter)
257
+ self.properties_information_number_of_lines.setObjectName('properties_information_number_of_lines')
258
+ self.properties_information_stats.layout().addWidget(self.properties_information_number_of_lines)
259
+
260
+ self.properties_information_stats.layout().addSpacing(-5)
261
+
262
+ self.properties_information_cpl = QLabel()
263
+ self.properties_information_cpl.setObjectName('properties_information_cpl')
264
+ self.properties_information_cpl.setFixedWidth(30)
265
+ self.properties_information_stats.layout().addWidget(self.properties_information_cpl)
266
+
267
+ self.properties_information.layout().addWidget(self.properties_information_stats)
268
+
269
+ # self.properties_information_reason = QLabel()
270
+ # self.properties_information_reason.setObjectName('properties_information_reason')
271
+ # self.properties_information.layout().addWidget(self.properties_information_reason)
272
+
273
+ self.left_panel_subtitleslist_textedit_bottom_line.addWidget(self.properties_information, 1, Qt.AlignLeft | Qt.AlignBottom)
274
+
275
+ # self.subtitles_panel_simplelist_qsplitter.addWidget(self.subtitles_panel_simplelist_widget)
276
+
277
+ # self.subtitles_panel_simplelist_properties = QFrame()
278
+ # self.subtitles_panel_simplelist_properties.setLayout(QVBoxLayout())
279
+ # self.subtitles_panel_simplelist_properties.layout().setContentsMargins(20, 0, 0, 0)
280
+ # self.subtitles_panel_simplelist_properties.layout().setSpacing(0)
281
+
282
+ # self.subtitles_panel_simplelist_left_panel_subtitleslist_textedit_line = QHBoxLayout()
283
+ # self.subtitles_panel_simplelist_left_panel_subtitleslist_textedit_line.setContentsMargins(0, 0, 0, 0)
284
+ # self.subtitles_panel_simplelist_left_panel_subtitleslist_textedit_line.setSpacing(0)
285
+
286
+ # self.subtitles_panel_simplelist_properties.layout().addLayout(self.subtitles_panel_simplelist_left_panel_subtitleslist_textedit_line, 1)
287
+
288
+ # self.subtitles_panel_simplelist_qsplitter.addWidget(self.subtitles_panel_simplelist_properties)
289
+
290
+ self.left_panel_subtitleslist_speaker_selector = SpeakerSelector()
291
+ self.left_panel_subtitleslist_speaker_selector.setObjectName('left_panel_subtitleslist_speaker_selector')
292
+
293
+ self.left_panel_subtitleslist_textedit_bottom_line.addWidget(self.left_panel_subtitleslist_speaker_selector, 0, Qt.AlignRight | Qt.AlignBottom)
294
+
295
+ # self.left_panel_subtitleslist_textedit.layout().addLayout(self.left_panel_subtitleslist_textedit_bottom_line)
296
+
297
+ # self.left_panel_subtitleslist_bottom_panel.layout().addWidget(self.left_panel_subtitleslist_textedit)
298
+
299
+ self.subtitles_panel_simplelist_left_panel_subtitleslist_textedit_timings_row = QHBoxLayout()
300
+ self.subtitles_panel_simplelist_left_panel_subtitleslist_textedit_timings_row.setObjectName('subtitles_panel_simplelist_left_panel_subtitleslist_textedit_timings_row')
301
+ self.subtitles_panel_simplelist_left_panel_subtitleslist_textedit_timings_row.setContentsMargins(0, 0, 0, 0)
302
+ self.subtitles_panel_simplelist_left_panel_subtitleslist_textedit_timings_row.setSpacing(0)
303
+
304
+ self.subtitles_panel_simplelist_properties_start_timing_label = QLabel()
305
+ self.subtitles_panel_simplelist_properties_start_timing_label.setObjectName('subtitles_panel_simplelist_properties_start_timing_label')
306
+ self.subtitles_panel_simplelist_properties_start_timing_label.setProperty('class', 'properties_timing_labels')
307
+ self.subtitles_panel_simplelist_properties_start_timing_label.setAlignment(Qt.AlignLeft)
308
+ # self.subtitles_panel_simplelist_properties_start_timing_label.setSizePolicy(QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum))
309
+ # self.subtitles_panel_simplelist_left_panel_subtitleslist_textedit_timings_row.addWidget(self.subtitles_panel_simplelist_properties_start_timing_label)
310
+
311
+ self.subtitles_panel_simplelist_properties_start_timing_qlineedit = QLineEdit()
312
+ self.subtitles_panel_simplelist_properties_start_timing_qlineedit.setProperty('class', 'qlineedit_timings')
313
+ self.subtitles_panel_simplelist_properties_start_timing_qlineedit.setObjectName('subtitles_panel_simplelist_properties_start_timing_qlineedit')
314
+ # self.subtitles_panel_simplelist_properties_start_timing_qlineedit.setSizePolicy(QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum))
315
+ self.subtitles_panel_simplelist_properties_start_timing_qlineedit.setLayout(QVBoxLayout())
316
+ self.subtitles_panel_simplelist_properties_start_timing_qlineedit.layout().setContentsMargins(0, 0, 0, 0)
317
+ self.subtitles_panel_simplelist_properties_start_timing_qlineedit.layout().setSpacing(0)
318
+ self.subtitles_panel_simplelist_properties_start_timing_qlineedit.layout().addWidget(self.subtitles_panel_simplelist_properties_start_timing_label, 0, Qt.AlignLeft | Qt.AlignTop)
319
+ # self.subtitles_panel_simplelist_properties_start_timing_qlineedit.textEdited.connect(lambda: subtitles_panel_simplelist_properties_start_timing_qlineedit_text_edited(self))
320
+ self.subtitles_panel_simplelist_left_panel_subtitleslist_textedit_timings_row.addWidget(self.subtitles_panel_simplelist_properties_start_timing_qlineedit, 1)
321
+
322
+ self.subtitles_panel_simplelist_properties_duration_timing_label_row = QWidget()
323
+ self.subtitles_panel_simplelist_properties_duration_timing_label_row.setLayout(QHBoxLayout())
324
+ # self.subtitles_panel_simplelist_properties_duration_timing_label_row.setSizePolicy(QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum))
325
+ self.subtitles_panel_simplelist_properties_duration_timing_label_row.layout().setContentsMargins(0, 0, 0, 0)
326
+ self.subtitles_panel_simplelist_properties_duration_timing_label_row.layout().setSpacing(0)
327
+
328
+ self.subtitles_panel_simplelist_properties_duration_timing_label = QLabel()
329
+ self.subtitles_panel_simplelist_properties_duration_timing_label.setObjectName('subtitles_panel_simplelist_properties_duration_timing_label')
330
+ self.subtitles_panel_simplelist_properties_duration_timing_label.setProperty('class', 'properties_timing_labels')
331
+ # self.subtitles_panel_simplelist_properties_duration_timing_label.setSizePolicy(QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum))
332
+ self.subtitles_panel_simplelist_properties_duration_timing_label.setAlignment(Qt.AlignCenter)
333
+ self.subtitles_panel_simplelist_properties_duration_timing_label_row.layout().addWidget(self.subtitles_panel_simplelist_properties_duration_timing_label, 0, Qt.AlignTop)
334
+
335
+ self.subtitles_panel_simplelist_properties_duration_timing_lock_button = QPushButton()
336
+ self.subtitles_panel_simplelist_properties_duration_timing_lock_button.setObjectName('subtitles_panel_simplelist_properties_duration_timing_lock_button')
337
+ self.subtitles_panel_simplelist_properties_duration_timing_lock_button.setCheckable(True)
338
+ self.subtitles_panel_simplelist_properties_duration_timing_lock_button.setFixedSize(QSize(20, 16))
339
+ self.subtitles_panel_simplelist_properties_duration_timing_label_row.layout().addWidget(self.subtitles_panel_simplelist_properties_duration_timing_lock_button, 0, Qt.AlignTop)
340
+
341
+ self.subtitles_panel_simplelist_properties_duration_timing_qlineedit = QLineEdit()
342
+ self.subtitles_panel_simplelist_properties_duration_timing_qlineedit.setProperty('class', 'qlineedit_timings')
343
+ self.subtitles_panel_simplelist_properties_duration_timing_qlineedit.setObjectName('subtitles_panel_simplelist_properties_duration_timing_qlineedit')
344
+ # self.subtitles_panel_simplelist_properties_duration_timing_qlineedit.setSizePolicy(QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum))
345
+ self.subtitles_panel_simplelist_properties_duration_timing_qlineedit.setLayout(QVBoxLayout())
346
+ self.subtitles_panel_simplelist_properties_duration_timing_qlineedit.setAlignment(Qt.AlignCenter)
347
+ self.subtitles_panel_simplelist_properties_duration_timing_qlineedit.layout().setContentsMargins(0, 0, 0, 0)
348
+ self.subtitles_panel_simplelist_properties_duration_timing_qlineedit.layout().setSpacing(0)
349
+ self.subtitles_panel_simplelist_properties_duration_timing_qlineedit.layout().addWidget(self.subtitles_panel_simplelist_properties_duration_timing_label_row, 0, Qt.AlignCenter | Qt.AlignTop)
350
+ # self.subtitles_panel_simplelist_properties_duration_timing_qlineedit.textEdited.connect(lambda: subtitles_panel_simplelist_properties_duration_timing_qlineedit_text_edited(self))
351
+ self.subtitles_panel_simplelist_left_panel_subtitleslist_textedit_timings_row.addWidget(self.subtitles_panel_simplelist_properties_duration_timing_qlineedit, 1)
352
+
353
+ self.subtitles_panel_simplelist_properties_ending_timing_label = QLabel()
354
+ self.subtitles_panel_simplelist_properties_ending_timing_label.setObjectName('subtitles_panel_simplelist_properties_ending_timing_label')
355
+ self.subtitles_panel_simplelist_properties_ending_timing_label.setProperty('class', 'properties_timing_labels')
356
+ self.subtitles_panel_simplelist_properties_ending_timing_label.setAlignment(Qt.AlignRight)
357
+ # self.subtitles_panel_simplelist_properties_ending_timing_label.setSizePolicy(QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum))
358
+ # self.subtitles_panel_simplelist_left_panel_subtitleslist_textedit_timings_row.addWidget(self.subtitles_panel_simplelist_properties_ending_timing_label)
359
+
360
+ self.subtitles_panel_simplelist_properties_ending_timing_qlineedit = QLineEdit()
361
+ self.subtitles_panel_simplelist_properties_ending_timing_qlineedit.setProperty('class', 'qlineedit_timings')
362
+ self.subtitles_panel_simplelist_properties_ending_timing_qlineedit.setObjectName('subtitles_panel_simplelist_properties_ending_timing_qlineedit')
363
+ # self.subtitles_panel_simplelist_properties_ending_timing_qlineedit.setSizePolicy(QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum))
364
+ self.subtitles_panel_simplelist_properties_ending_timing_qlineedit.setLayout(QVBoxLayout())
365
+ self.subtitles_panel_simplelist_properties_ending_timing_qlineedit.setAlignment(Qt.AlignRight)
366
+ self.subtitles_panel_simplelist_properties_ending_timing_qlineedit.layout().setContentsMargins(0, 0, 0, 0)
367
+ self.subtitles_panel_simplelist_properties_ending_timing_qlineedit.layout().setSpacing(0)
368
+ self.subtitles_panel_simplelist_properties_ending_timing_qlineedit.layout().addWidget(self.subtitles_panel_simplelist_properties_ending_timing_label, 0, Qt.AlignRight | Qt.AlignTop)
369
+ # self.subtitles_panel_simplelist_properties_ending_timing_qlineedit.textEdited.connect(lambda: subtitles_panel_simplelist_properties_ending_timing_qlineedit_text_edited(self))
370
+ self.subtitles_panel_simplelist_left_panel_subtitleslist_textedit_timings_row.addWidget(self.subtitles_panel_simplelist_properties_ending_timing_qlineedit, 1)
371
+
372
+ self.subtitles_panel_simplelist_properties_duration_timing_lock_button.raise_()
373
+
374
+ self.left_panel_subtitleslist_bottom_panel.layout().addLayout(self.subtitles_panel_simplelist_left_panel_subtitleslist_textedit_timings_row)
375
+
376
+ subtitles_panel_simplelist_qsplitter.setSizes([subtitles_panel_simplelist_qsplitter.height()*.8, subtitles_panel_simplelist_qsplitter.height()*.2])
377
+
378
+ left_panel_subtitles_panel.layout().addWidget(subtitles_panel_simplelist_qsplitter)
379
+
380
+
381
+ self.left_panel_subtitleslist_new_name_dialog = new_speaker_name_dialog(self, 'New speaker')
382
+
383
+
384
+ def left_panel_subtitleslist_textedit_changed(self):
385
+ if 'selected' in session.SUBTITLE and session.SUBTITLE['selected']:
386
+ session.SUBTITLE['selected']['text'] = self.left_panel_subtitleslist_textedit.toPlainText()
387
+ self.timeline_widget.update()
388
+ self.preview_panel_player.update()
389
+
390
+
391
+ def left_panel_subtitleslist_translation_textedit_changed(self):
392
+ if 'selected' in session.SUBTITLE and session.SUBTITLE['selected']:
393
+ if not 'translations' in session.SUBTITLE['selected']:
394
+ session.SUBTITLE['selected']['translations'] = {}
395
+ session.SUBTITLE['selected']['translations'][session.CONFIG['translation'].get('engine_options', {}).get('target_language', 'en-us')] = self.left_panel_subtitleslist_translation_textedit.toPlainText()
396
+ self.timeline_widget.update()
397
+ self.preview_panel_player.update()
398
+
399
+
400
+ def update(self):
401
+ self.subtitles_panel_qlistwidget.update_content()
402
+
403
+ self.left_panel_subtitleslist_bottom_panel.setVisible(bool(session.SUBTITLE.get('selected', False)))
404
+ self.properties_information.setVisible(bool(session.SUBTITLE.get('selected', False)) and session.CONFIG.get('quality_check', {}).get('show_statistics', False))
405
+
406
+ if session.SUBTITLE.get('selected', None) is None:
407
+ self.subtitles_panel_qlistwidget.clearSelection()
408
+ else:
409
+ self.left_panel_subtitleslist_textedit.setText(session.SUBTITLE['selected']['text'])
410
+
411
+ self.left_panel_subtitleslist_translation_textedit.setVisible(session.CONFIG['translation'].get('engine_options', {}).get('show_translations', False))
412
+ self.left_panel_subtitleslist_translation_textedit.setText(session.SUBTITLE['selected'].get('translations', {}).get(session.CONFIG['translation'].get('engine_options', {}).get('target_language', 'en-us'), ''))
413
+
414
+ qalignment = TEXT_ALIGNMENTS[session.CONFIG['default_values'].get('subtitle_alignment', 'left')]
415
+ self.left_panel_subtitleslist_textedit.setAlignment(qalignment)
416
+ self.left_panel_subtitleslist_translation_textedit.setAlignment(qalignment)
417
+
418
+ if self.preview_panel_player.is_paused():
419
+ position = session.SUBTITLE.get('position', 0)
420
+ if position > session.SUBTITLE['selected']['end'] or position < session.SUBTITLE['selected']['start']:
421
+ position = session.SUBTITLE['selected']['start'] + ((session.SUBTITLE['selected']['end'] - session.SUBTITLE['selected']['start']) / 2)
422
+ if session.CONFIG.get('repeat_activated', False):
423
+ duration = session.CONFIG.get('playback_repeat_duration', 10.0)
424
+ times = session.CONFIG.get('playback_repeat_times', 1)
425
+ session.REPEAT_DURATION_BUFFER = [[position, position + duration] for _ in range(times)]
426
+ self.preview_panel_player.set_position(position)
427
+
428
+ self.left_panel_subtitleslist_speaker_selector.set_current_speaker(session.SUBTITLE['selected'].get('speaker', 'A'))
429
+
430
+ self.subtitles_panel_simplelist_properties_start_timing_qlineedit.setText(modules_utils.get_timeline_time_str(session.SUBTITLE['selected']['start'], ms=True))
431
+ self.subtitles_panel_simplelist_properties_duration_timing_qlineedit.setText(modules_utils.get_timeline_time_str((session.SUBTITLE['selected']['end'] - session.SUBTITLE['selected']['start']), ms=True))
432
+ self.subtitles_panel_simplelist_properties_ending_timing_qlineedit.setText(modules_utils.get_timeline_time_str(session.SUBTITLE['selected']['end'], ms=True))
433
+
434
+ if session.CONFIG.get('quality_check', {}).get('enabled', False):
435
+ text = ''
436
+ reasons = []
437
+ issues = []
438
+
439
+ _, reasons, issues = quality_check.check_subtitle(session.SUBTITLE['selected'])
440
+
441
+ n_words = len(session.SUBTITLE['selected']['text'].replace('\n', ' ').split(' '))
442
+ n_char = len(session.SUBTITLE['selected']['text'].replace('\n', '').replace(' ', ''))
443
+
444
+ self.properties_information_word_counter.setStyleSheet('QLabel { background-color: ' + ('#55d43f' if 'wpm' not in issues else '#aa9e1a1a') + '}')
445
+ self.properties_information_wpm.setStyleSheet('QLabel { background-color: ' + ('#bb55d43f' if 'wpm' not in issues else '#bb9e1a1a') + '}')
446
+ self.properties_information_character_counter.setStyleSheet('QLabel { background-color: ' + ('#55d43f' if 'cps' not in issues else '#aa9e1a1a') + '}')
447
+ self.properties_information_cps.setStyleSheet('QLabel { background-color: ' + ('#bb55d43f' if 'cps' not in issues else '#bb9e1a1a') + '}')
448
+ self.properties_information_sub_duration.setStyleSheet('QLabel { background-color: ' + ('#55d43f' if 'duration' not in issues else '#bb9e1a1a') + '}')
449
+ self.properties_information_number_of_lines.setStyleSheet('QLabel { background-color: ' + ('#55d43f' if 'number_of_lines' not in issues else '#bb9e1a1a') + '}')
450
+ self.properties_information_cpl.setStyleSheet('QLabel { background-color: ' + ('#bb55d43f' if 'cpl' not in issues else '#bb9e1a1a') + '}')
451
+
452
+ self.properties_information_word_counter.setText(str(n_words))
453
+ self.properties_information_wpm.setText(str(int(n_words / ((session.SUBTITLE['selected']['end'] - session.SUBTITLE['selected']['start']) / 60))))
454
+ self.properties_information_character_counter.setText(str(n_char))
455
+ self.properties_information_cps.setText(str(int(n_char / ((session.SUBTITLE['selected']['end'] - session.SUBTITLE['selected']['start'])))))
456
+ self.properties_information_sub_duration.setText(str(round((session.SUBTITLE['selected']['end'] - session.SUBTITLE['selected']['start']), 3)))
457
+ self.properties_information_number_of_lines.setText(str(int(len(session.SUBTITLE['selected']['text'].split('\n')))))
458
+
459
+ self.properties_information.setToolTip('\n'.join(reasons))
460
+
461
+ # self.properties_information_reason.setVisible(bool(reasons))
462
+ # self.properties_information_reason.setText('\n'.join(reasons))
463
+
464
+ # self.properties_information_issues.setVisible(bool(issues))
465
+ # self.properties_information_issues.setText('\n'.join(issues))
466
+
467
+ # def update_properties_widget(self):
468
+ # """Function to update properties panel widgets"""
469
+ # update(self)
470
+ # self.subtitles_panel_simplelist_properties.setVisible(bool(session.SUBTITLE['selected']))
471
+
472
+
473
+ # if not self.left_panel_subtitleslist_textedit.hasFocus():
474
+ # self.left_panel_subtitleslist_textedit.setText(text)
475
+ # self.properties_information_stats.setVisible(bool(session.SUBTITLE['selected']) and session.CONFIG.get('quality_check', {}).get('show_statistics', False))
476
+
477
+
478
+ def show(self):
479
+ update(self)
480
+
481
+
482
+ def hide(self):
483
+ pass
484
+
485
+
486
+ def _changed(self, selection):
487
+ if session.SUBTITLE.get('selected', False):
488
+ session.SUBTITLE['selected']['speaker'] = self.left_panel_subtitleslist_speaker_selector.currentText()
489
+
490
+
491
+ def on_clicked(self):
492
+ new_name = None
493
+ if self.left_panel_speakers_new_name_dialog.exec() == QDialog.Accepted:
494
+ new_name = self.left_panel_speakers_new_name_dialog.name
495
+ session.SUBTITLE['selected']['speaker'] = new_name
496
+ session.SPEAKERS[new_name] = {}
497
+ self.left_panel_subtitleslist_speaker_selector.update_list(self)
498
+ update(self)
499
+
500
+
501
+ def translate(self):
502
+ self.subtitles_panel_simplelist_properties_start_timing_label.setText(_('left_panel_subtitleslist.start'))
503
+ self.subtitles_panel_simplelist_properties_duration_timing_label.setText(_('left_panel_subtitleslist.duration'))
504
+ self.subtitles_panel_simplelist_properties_ending_timing_label.setText(_('left_panel_subtitleslist.end'))
505
+ self.left_panel_subtitleslist_speaker_selector.label.setText(_('left_panel_subtitleslist.speaker'))
506
+
507
+ # self.left_panel_speakers_new_name_dialog.set_title(_('subtitles_panel_widget_speakers.new_speaker'))
508
+ # self.left_panel_speakers_new_name_dialog.input_label.setText(_('subtitles_panel_widget_speakers.enter_speaker_name'))
509
+
510
+
511
+ class SpeakerSelector(QWidget):
512
+ def __init__(self, parent=None):
513
+ super(SpeakerSelector, self).__init__(parent)
514
+ self.setAttribute(Qt.WA_StyledBackground, True)
515
+ self.setSizePolicy(QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum))
516
+ self.setLayout(QHBoxLayout())
517
+ self.layout().setContentsMargins(0, 0, 0, 0)
518
+ self.layout().setSpacing(0)
519
+
520
+ self.left_container = QVBoxLayout()
521
+ self.left_container.setContentsMargins(0, 0, 0, 0)
522
+ self.left_container.setSpacing(0)
523
+
524
+ self.top_line = QHBoxLayout()
525
+ self.top_line.setContentsMargins(0, 0, 0, 0)
526
+ self.top_line.setSpacing(0)
527
+
528
+ self.label = QLabel()
529
+ self.label.setObjectName('label')
530
+ self.label.setProperty('class', 'properties_timing_labels')
531
+ self.label.setAlignment(Qt.AlignLeft)
532
+ self.label.setSizePolicy(QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum))
533
+ self.top_line.addWidget(self.label, 1)
534
+
535
+ self.add_button = QPushButton()
536
+ self.add_button.setObjectName('add_button')
537
+ self.add_button.setFixedSize(20, 14)
538
+ self.add_button.setIcon(QIcon(str(session.PATH_SUBTITLD_GRAPHICS / 'plus_icon.svg')))
539
+ self.add_button.setSizePolicy(QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum))
540
+ self.add_button.clicked.connect(lambda: self.add_button_clicked())
541
+ # self.add_button.opacity = QGraphicsOpacityEffect()
542
+ # self.add_button.setGraphicsEffect(self.add_button.opacity)
543
+ # self.add_button.opacity.setOpacity(0)
544
+ self.top_line.addWidget(self.add_button, 0, Qt.AlignRight | Qt.AlignTop)
545
+
546
+ self.left_container.layout().addLayout(self.top_line)
547
+
548
+ class SelectorButton(QWidget):
549
+ clicked = Signal()
550
+ def __init__(widget, parent=None):
551
+ super().__init__(parent)
552
+ widget.setObjectName('speaker_selector_button')
553
+ widget.setAttribute(Qt.WA_StyledBackground, True)
554
+ widget.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
555
+ widget.setLayout(QHBoxLayout())
556
+ widget.layout().setContentsMargins(0, 0, 2, 0)
557
+ widget.layout().setSpacing(0)
558
+
559
+ def mouseReleaseEvent(widget, event):
560
+ if event.button() == Qt.LeftButton:
561
+ widget.clicked.emit()
562
+ return
563
+ return super().mouseReleaseEvent(event)
564
+
565
+ self.selector_button = SelectorButton()
566
+ self.selector_button.clicked.connect(lambda: self.selector_button_clicked())
567
+
568
+ self.selector_button_label = QLabel()
569
+ self.selector_button_label.setObjectName('selector_button_label')
570
+ self.selector_button_label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
571
+ self.selector_button_label.setSizePolicy(QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum))
572
+ self.selector_button.layout().addWidget(self.selector_button_label, 1, Qt.AlignLeft | Qt.AlignVCenter)
573
+
574
+ self.selector_button_icon = QLabel()
575
+ self.selector_button_icon.setObjectName('selector_button_icon')
576
+ self.selector_button_icon.setSizePolicy(QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Minimum))
577
+ self.selector_button_icon.setPixmap(QPixmap(str(session.PATH_SUBTITLD_GRAPHICS / 'combobox_down_arrow.svg')).scaled(16, 16, Qt.KeepAspectRatio, Qt.SmoothTransformation))
578
+ self.selector_button.layout().addWidget(self.selector_button_icon, 0)
579
+
580
+ self.left_container.layout().addWidget(self.selector_button, 1)
581
+
582
+ self.layout().addLayout(self.left_container, 1)
583
+
584
+ # class SquareLabel(QLabel):
585
+ # def __init__(self, *args, **kwargs):
586
+ # super().__init__(*args, **kwargs)
587
+ # self.setScaledContents(True)
588
+ # self.setSizePolicy(QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum))
589
+
590
+ # def sizeHint(self):
591
+ # size = super().sizeHint()
592
+ # size.setWidth(size.height())
593
+ # return size
594
+
595
+ # def resizeEvent(self, event):
596
+ # size = event.size().height()
597
+ # self.setFixedSize(size, size)
598
+ # super().resizeEvent(event)
599
+
600
+ self.image = QLabel()
601
+ self.image.setObjectName('speaker_selector_image')
602
+ self.image.setFixedSize(36, 36)
603
+ self.image.setScaledContents(True)
604
+ self.image.setSizePolicy(QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum))
605
+ self.layout().addWidget(self.image, 0)
606
+
607
+ class list(QWidget):
608
+ def __init__(widget, parent=None):
609
+ super().__init__(parent)
610
+ widget.setObjectName('speaker_selector_list')
611
+ widget.setWindowFlags(Qt.Popup | Qt.FramelessWindowHint)
612
+ widget.setAttribute(Qt.WA_TranslucentBackground)
613
+ widget.setAttribute(Qt.WA_StyledBackground, True)
614
+ # widget.setAttribute(Qt.WA_TransparentForMouseEvents, True)
615
+ # widget.setFocusPolicy(Qt.NoFocus)
616
+ widget.setLayout(QVBoxLayout())
617
+ widget.layout().setContentsMargins(0, 0, 0, 0)
618
+ widget.layout().setSpacing(0)
619
+
620
+ widget.list_widget = QListWidget()
621
+ widget.list_widget.setObjectName('speaker_selector_list_widget')
622
+ widget.list_widget.setFocusPolicy(Qt.NoFocus)
623
+ widget.list_widget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
624
+ widget.list_widget.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
625
+ widget.list_widget.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents)
626
+ widget.list_widget.setSizePolicy(QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Minimum))
627
+ widget.list_widget.setMaximumHeight(400)
628
+ widget.list_widget.itemClicked.connect(lambda item: widget.parent().speaker_selected(item))
629
+ widget.layout().addWidget(widget.list_widget)
630
+
631
+ def set_position(widget, point):
632
+ widget.adjustSize()
633
+
634
+ x = point.x() - (widget.width() / 2)
635
+ if x < 0:
636
+ x = 0
637
+ elif x + widget.width() > widget.window().screen().geometry().width():
638
+ x = widget.window().screen().geometry().width() - widget.width()
639
+
640
+ widget.move(int(x), point.y() + 20)
641
+
642
+ def showEvent(widget, event):
643
+ widget.list_widget.clear()
644
+ widget.list_widget.setMinimumWidth(widget.parent().width())
645
+ for speaker_name, speaker_data in session.SPEAKERS.items():
646
+ item = QListWidgetItem()
647
+ wdg = QWidget()
648
+ wdg.setLayout(QHBoxLayout())
649
+ wdg.layout().setContentsMargins(6, 0, 0, 0)
650
+ wdg.layout().setSpacing(5)
651
+ wdg.setProperty('speaker_name', speaker_name)
652
+ label = QLabel(speaker_name)
653
+ label.setObjectName('speaker_selector_list_item_label')
654
+ label.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
655
+ wdg.layout().addWidget(label, 1)
656
+ icon_label = QLabel()
657
+ icon_label.setObjectName('speaker_selector_list_item_icon')
658
+ icon_label.setFixedSize(36, 36)
659
+ icon_label.setScaledContents(True)
660
+ icon_label.setSizePolicy(QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum))
661
+ if speaker_data.get('image', None):
662
+ icon_label.setPixmap(QPixmap.fromImage(speaker_data['image']).scaled(36, 36))
663
+ else:
664
+ icon_label.setPixmap(QPixmap(str(session.PATH_SUBTITLD_GRAPHICS / 'unknown_speaker.svg')).scaled(36, 36))
665
+ if not self.window().left_panel_speakers_image_test_thread.isRunning():
666
+ self.window().left_panel_speakers_image_test_thread.name = speaker_name
667
+ self.window().left_panel_speakers_image_test_thread.start()
668
+ wdg.layout().addWidget(icon_label, 0)
669
+ item.setSizeHint(wdg.sizeHint())
670
+ widget.list_widget.addItem(item)
671
+ widget.list_widget.setItemWidget(item, wdg)
672
+ # pixmap = QPixmap(str(session.PATH_SUBTITLD_GRAPHICS / 'unknown_speaker.svg')).scaled(32, 32)
673
+ # if session.SPEAKERS[speaker_name].get('image', None):
674
+ # pixmap = QPixmap.fromImage(session.SPEAKERS[speaker_name]['image']).scaled(32, 32)
675
+ # icon = QIcon(pixmap)
676
+ # item.setIcon(icon)
677
+ # widget.list_widget.addItem(item)
678
+
679
+ widget.adjustSize()
680
+
681
+ pos = widget.parent().mapToGlobal(QPoint(0, 0))
682
+ x, y = pos.x(), pos.y()
683
+ x += widget.parent().width()
684
+ y += widget.parent().height() / 2
685
+
686
+ x -= widget.width() + 1
687
+ y -= widget.height() / 2
688
+
689
+ widget.move(int(x), int(y))
690
+
691
+ return super().showEvent(event)
692
+
693
+ self.selector_list = list(parent=self)
694
+ self.selector_list.hide()
695
+
696
+ class NewNameDialog(QDialog):
697
+ def __init__(self, parent=None):
698
+ super().__init__(parent)
699
+ self.setWindowTitle("Enter Your Name")
700
+ self.name = None
701
+
702
+ layout = QVBoxLayout(self)
703
+
704
+ self.label = QLabel("Please enter your name:")
705
+ self.input = QLineEdit()
706
+ self.ok_button = QPushButton("OK")
707
+ self.cancel_button = QPushButton("Cancel")
708
+
709
+ layout.addWidget(self.label)
710
+ layout.addWidget(self.input)
711
+ layout.addWidget(self.ok_button)
712
+ layout.addWidget(self.cancel_button)
713
+
714
+ self.ok_button.clicked.connect(self.accept)
715
+ self.cancel_button.clicked.connect(self.reject)
716
+
717
+ def accept(self):
718
+ self.name = self.input.text().strip()
719
+ super().accept()
720
+
721
+ self.new_name_dialog = NewNameDialog(parent=self)
722
+
723
+ ## start animation on mouse hover:
724
+ def enterEvent(self, event):
725
+ # self.add_button.opacity.setOpacity(1)
726
+ super().enterEvent(event)
727
+
728
+ def leaveEvent(self, event):
729
+ # self.add_button.opacity.setOpacity(0)
730
+ super().leaveEvent(event)
731
+
732
+ def speaker_selected(self, item):
733
+ speaker = self.selector_list.list_widget.itemWidget(item).property('speaker_name')
734
+ session.SUBTITLE['selected']['speaker'] = speaker
735
+ self.set_current_speaker(speaker)
736
+ self.selector_list.hide()
737
+
738
+ def set_current_speaker(self, speaker_name):
739
+ self.selector_button_label.setText(speaker_name)
740
+ if session.SPEAKERS.get(speaker_name, {}).get('image', None):
741
+ self.image.setPixmap(QPixmap.fromImage(session.SPEAKERS[speaker_name]['image']))
742
+ else:
743
+ self.image.setPixmap(QPixmap(str(session.PATH_SUBTITLD_GRAPHICS / 'unknown_speaker.svg')))
744
+ if not self.window().left_panel_speakers_image_test_thread.isRunning():
745
+ self.window().left_panel_speakers_image_test_thread.name = speaker_name
746
+ self.window().left_panel_speakers_image_test_thread.start()
747
+
748
+ def selector_button_clicked(self):
749
+ if self.selector_list.isVisible():
750
+ self.selector_list.hide()
751
+ else:
752
+ self.selector_list.show()
753
+
754
+ def add_button_clicked(self):
755
+ new_name = None
756
+ self.window().left_panel_subtitleslist_new_name_dialog.input.setText('')
757
+ value = self.window().left_panel_subtitleslist_new_name_dialog.exec_and_get_values()
758
+
759
+ if value:
760
+ new_name = value.strip()
761
+ else:
762
+ pass
763
+
764
+ subtitles_names = [subtitle.get('speaker', 'A') for subtitle in session.SUBTITLE['segments']]
765
+ if new_name and new_name not in session.SPEAKERS and not new_name in subtitles_names:
766
+ session.SUBTITLE['selected']['speaker'] = new_name
767
+ session.SPEAKERS[new_name] = {}
768
+ self.set_current_speaker(new_name)
769
+
770
+
771
+ class new_speaker_name_dialog(utils.SimpleDialog):
772
+ def __init__(self, parent=None, title=''):
773
+ super().__init__(parent, title)
774
+
775
+ self.input_line = QWidget()
776
+ self.input_line.setLayout(QHBoxLayout())
777
+ self.input_line.layout().setContentsMargins(0, 0, 0, 0)
778
+
779
+ self.input_label = QLabel('Please enter your name:')
780
+ self.input_line.layout().addWidget(self.input_label)
781
+
782
+ self.input = QLineEdit()
783
+ self.input_line.layout().addWidget(self.input)
784
+
785
+ self.content.layout().addWidget(self.input_line)
786
+
787
+
788
+ def exec_and_get_values(self):
789
+ if self.exec() == QDialog.Accepted:
790
+ return self.input.text()
791
+ return None