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,358 @@
1
+ from PySide6.QtWidgets import QVBoxLayout, QWidget, QLabel, QScrollArea, QCheckBox, QComboBox, QHBoxLayout, QPushButton, QDoubleSpinBox, QFileDialog, QListWidget, QListWidgetItem, QTabWidget
2
+ from PySide6.QtCore import Qt, QMimeData
3
+ from PySide6.QtGui import QDragEnterEvent, QDropEvent
4
+
5
+ import json
6
+ import copy
7
+
8
+ from subtitld.interface import left_panel
9
+ from subtitld.interface import utils
10
+ from subtitld.interface.translation import _
11
+ from subtitld.modules import session
12
+ from subtitld.modules.config import Config
13
+
14
+
15
+ class DragDropWidget(QWidget):
16
+ def __init__(self, parent=None):
17
+ super().__init__(parent)
18
+ self.setAcceptDrops(True)
19
+ self.parent_window = None
20
+
21
+ def dragEnterEvent(self, event: QDragEnterEvent):
22
+ if event.mimeData().hasUrls():
23
+ for url in event.mimeData().urls():
24
+ if url.isLocalFile() and url.toLocalFile().endswith('.json'):
25
+ event.acceptProposedAction()
26
+ return
27
+ event.ignore()
28
+
29
+ def dragMoveEvent(self, event):
30
+ if event.mimeData().hasUrls():
31
+ for url in event.mimeData().urls():
32
+ if url.isLocalFile() and url.toLocalFile().endswith('.json'):
33
+ event.acceptProposedAction()
34
+ return
35
+ event.ignore()
36
+
37
+ def dropEvent(self, event: QDropEvent):
38
+ if event.mimeData().hasUrls():
39
+ for url in event.mimeData().urls():
40
+ if url.isLocalFile() and url.toLocalFile().endswith('.json'):
41
+ handle_json_drop(self.parent_window, url.toLocalFile())
42
+ event.acceptProposedAction()
43
+ return
44
+ event.ignore()
45
+
46
+
47
+ def handle_json_drop(window, filepath):
48
+ try:
49
+ with open(filepath, 'r', encoding='utf-8') as f:
50
+ config_data = json.load(f)
51
+ except (json.JSONDecodeError, IOError) as e:
52
+ error_dialog = utils.SimpleDialog(window, title=_('global_panel.import_error'))
53
+ error_dialog.content.layout().addWidget(QLabel(_('global_panel.import_error_message')))
54
+ error_dialog.reject_button.hide()
55
+ error_dialog.exec()
56
+ return
57
+
58
+ valid_keys = Config.get_valid_keys()
59
+ filtered_config_data = {k: v for k, v in config_data.items() if k in valid_keys}
60
+
61
+ if not filtered_config_data:
62
+ error_dialog = utils.SimpleDialog(window, title=_('global_panel.import_error'))
63
+ error_dialog.content.layout().addWidget(QLabel(_('global_panel.import_no_valid_keys')))
64
+ error_dialog.reject_button.hide()
65
+ error_dialog.exec()
66
+ return
67
+
68
+ available_sections = [key for key in filtered_config_data.keys() if key != 'recent_files']
69
+
70
+ if not available_sections:
71
+ error_dialog = utils.SimpleDialog(window, title=_('global_panel.no_sections'))
72
+ error_dialog.content.layout().addWidget(QLabel(_('global_panel.no_sections_message')))
73
+ error_dialog.reject_button.hide()
74
+ error_dialog.exec()
75
+ return
76
+
77
+ select_dialog = utils.SimpleDialog(window, title=_('global_panel.select_sections'))
78
+
79
+ list_widget = QListWidget()
80
+ list_widget.setMinimumHeight(400)
81
+ list_widget.setProperty('class', 'section_list')
82
+ for section in sorted(available_sections):
83
+ item = QListWidgetItem(section)
84
+ item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
85
+ item.setCheckState(Qt.Checked)
86
+ list_widget.addItem(item)
87
+
88
+ select_dialog.content.layout().addWidget(list_widget)
89
+ select_dialog.reject_button.setText(_('cancel'))
90
+ select_dialog.accept_button.setText(_('import'))
91
+
92
+ def import_sections():
93
+ sections_to_import = []
94
+ for i in range(list_widget.count()):
95
+ item = list_widget.item(i)
96
+ if item.checkState() == Qt.Checked:
97
+ sections_to_import.append(item.text())
98
+
99
+ if not sections_to_import:
100
+ error_dialog = utils.SimpleDialog(window, title=_('global_panel.no_sections'))
101
+ error_dialog.content.layout().addWidget(QLabel(_('global_panel.select_at_least_one')))
102
+ error_dialog.reject_button.hide()
103
+ error_dialog.exec()
104
+ return
105
+
106
+ for section_name in sections_to_import:
107
+ section_data = filtered_config_data.get(section_name, {})
108
+
109
+ if isinstance(section_data, dict):
110
+ if section_name not in session.CONFIG:
111
+ session.CONFIG[section_name] = {}
112
+ session.CONFIG[section_name].update(section_data)
113
+ else:
114
+ session.CONFIG[section_name] = section_data
115
+
116
+ session.CONFIG.save()
117
+ update(window)
118
+ select_dialog.accept()
119
+
120
+ select_dialog.accept_button.clicked.connect(import_sections)
121
+ select_dialog.exec()
122
+
123
+
124
+ def load(self):
125
+ tab_name = 'global'
126
+
127
+ left_panel_global_panel = left_panel.left_panel(
128
+ parent=self,
129
+ tab_name=tab_name,
130
+ update_callback=update,
131
+ translate_callback=translate
132
+ )
133
+
134
+ left_panel_global_panel_scroll = QScrollArea()
135
+ left_panel_global_panel_scroll.setObjectName('left_panel_global_panel_scroll')
136
+ left_panel_global_panel_scroll.setWidgetResizable(True)
137
+ left_panel_global_panel_scroll.setFrameShape(QScrollArea.NoFrame)
138
+ left_panel_global_panel.layout().addWidget(left_panel_global_panel_scroll)
139
+
140
+ self.left_panel_global_panel_widget = DragDropWidget()
141
+ self.left_panel_global_panel_widget.setProperty('class', 'transparent_panel')
142
+ self.left_panel_global_panel_widget.setObjectName('left_panel_global_panel_widget')
143
+ self.left_panel_global_panel_widget.setLayout(QVBoxLayout())
144
+ self.left_panel_global_panel_widget.layout().setContentsMargins(0, 0, 0, 0)
145
+ self.left_panel_global_panel_widget.parent_window = self
146
+ left_panel_global_panel_scroll.setWidget(self.left_panel_global_panel_widget)
147
+
148
+ self.left_panel_global_tabs = QTabWidget()
149
+ self.left_panel_global_tabs.setObjectName('left_panel_global_tabs')
150
+ self.left_panel_global_panel_widget.layout().addWidget(self.left_panel_global_tabs)
151
+
152
+ # --- General tab ---
153
+ self.left_panel_global_tab_general = QWidget()
154
+ self.left_panel_global_tab_general.setProperty('class', 'transparent_panel')
155
+ self.left_panel_global_tab_general.setLayout(QVBoxLayout())
156
+ self.left_panel_global_tab_general.layout().setContentsMargins(10, 10, 10, 10)
157
+ self.left_panel_global_tab_general.layout().setSpacing(10)
158
+ self.left_panel_global_tabs.addTab(self.left_panel_global_tab_general, '')
159
+
160
+ self.global_panel_general_save_as_line = QVBoxLayout()
161
+ self.global_panel_general_save_as_line.setContentsMargins(0, 0, 0, 0)
162
+ self.global_panel_general_save_as_line.setSpacing(5)
163
+
164
+ self.global_subtitlesvideo_save_as_label = QLabel(parent=self.left_panel_global_tab_general)
165
+ self.global_subtitlesvideo_save_as_label.setProperty('class', 'widget_label')
166
+ self.global_panel_general_save_as_line.addWidget(self.global_subtitlesvideo_save_as_label, 0, Qt.AlignLeft)
167
+
168
+ list_of_subtitle_extensions = []
169
+ for extformat in session.LIST_OF_SUPPORTED_SUBTITLE_EXTENSIONS:
170
+ list_of_subtitle_extensions.append(extformat + ' - ' + session.LIST_OF_SUPPORTED_SUBTITLE_EXTENSIONS[extformat]['description'])
171
+ self.global_subtitlesvideo_save_as_combobox = QComboBox(parent=self.left_panel_global_tab_general)
172
+ self.global_subtitlesvideo_save_as_combobox.setProperty('class', 'button')
173
+ self.global_subtitlesvideo_save_as_combobox.addItems(list_of_subtitle_extensions)
174
+ self.global_subtitlesvideo_save_as_combobox.activated.connect(lambda: global_subtitlesvideo_save_as_combobox_activated(self))
175
+ self.global_panel_general_save_as_line.addWidget(self.global_subtitlesvideo_save_as_combobox, 0, Qt.AlignLeft)
176
+
177
+ self.global_panel_general_save_copy = QCheckBox()
178
+ self.global_panel_general_save_copy.stateChanged.connect(lambda: global_panel_general_save_copy_changed(self))
179
+ self.global_panel_general_save_as_line.addWidget(self.global_panel_general_save_copy, 0, Qt.AlignLeft)
180
+
181
+ self.left_panel_global_tab_general.layout().addLayout(self.global_panel_general_save_as_line)
182
+
183
+ self.global_panel_general_minimum_duration_line = QVBoxLayout()
184
+ self.global_panel_general_minimum_duration_line.setContentsMargins(0, 0, 0, 0)
185
+ self.global_panel_general_minimum_duration_line.setSpacing(2)
186
+
187
+ self.global_panel_general_minimum_duration_label = QLabel()
188
+ self.global_panel_general_minimum_duration_label.setProperty('class', 'widget_label')
189
+ self.global_panel_general_minimum_duration_line.addWidget(self.global_panel_general_minimum_duration_label, 0, Qt.AlignLeft)
190
+
191
+ self.global_panel_general_minimum_duration_line_2 = QHBoxLayout()
192
+ self.global_panel_general_minimum_duration_line_2.setContentsMargins(0, 0, 0, 0)
193
+ self.global_panel_general_minimum_duration_line_2.setSpacing(5)
194
+
195
+ self.global_panel_general_minimum_duration_spinbox = QDoubleSpinBox()
196
+ self.global_panel_general_minimum_duration_spinbox.setMinimum(.1)
197
+ self.global_panel_general_minimum_duration_spinbox.setMaximum(999.999)
198
+ self.global_panel_general_minimum_duration_spinbox.valueChanged.connect(lambda: global_panel_general_minimum_duration_spinbox_changed(self))
199
+ self.global_panel_general_minimum_duration_line_2.addWidget(self.global_panel_general_minimum_duration_spinbox, 0, Qt.AlignLeft)
200
+
201
+ self.global_panel_general_minimum_duration_seconds_label = QLabel()
202
+ self.global_panel_general_minimum_duration_seconds_label.setProperty('class', 'units_label')
203
+ self.global_panel_general_minimum_duration_line_2.addWidget(self.global_panel_general_minimum_duration_seconds_label, 0, Qt.AlignLeft)
204
+
205
+ self.global_panel_general_minimum_duration_line_2.addStretch()
206
+
207
+ self.global_panel_general_minimum_duration_line.addLayout(self.global_panel_general_minimum_duration_line_2)
208
+
209
+ self.left_panel_global_tab_general.layout().addLayout(self.global_panel_general_minimum_duration_line)
210
+
211
+ self.left_panel_global_subtitle_alignment = utils.LabeledComboBox()
212
+ self.left_panel_global_subtitle_alignment.addItems(['Left', 'Center', 'Right'])
213
+ self.left_panel_global_subtitle_alignment.activated.connect(lambda: left_panel_global_subtitle_alignment_activated(self))
214
+ self.left_panel_global_tab_general.layout().addWidget(self.left_panel_global_subtitle_alignment)
215
+
216
+ self.left_panel_global_tab_general.layout().addStretch()
217
+
218
+ # --- USFX tab ---
219
+ self.left_panel_global_tab_usfx = QWidget()
220
+ self.left_panel_global_tab_usfx.setProperty('class', 'transparent_panel')
221
+ self.left_panel_global_tab_usfx.setLayout(QVBoxLayout())
222
+ self.left_panel_global_tab_usfx.layout().setContentsMargins(10, 10, 10, 10)
223
+ self.left_panel_global_tab_usfx.layout().setSpacing(6)
224
+ self.left_panel_global_tabs.addTab(self.left_panel_global_tab_usfx, '')
225
+
226
+ self.left_panel_global_tab_usfx_intro = QLabel()
227
+ self.left_panel_global_tab_usfx_intro.setProperty('class', 'widget_label')
228
+ self.left_panel_global_tab_usfx_intro.setWordWrap(True)
229
+ self.left_panel_global_tab_usfx.layout().addWidget(self.left_panel_global_tab_usfx_intro)
230
+
231
+ self.usfx_include_speaker_images_checkbox = QCheckBox()
232
+ self.usfx_include_speaker_images_checkbox.stateChanged.connect(lambda: usfx_option_changed(self, 'include_speaker_images', self.usfx_include_speaker_images_checkbox.isChecked()))
233
+ self.left_panel_global_tab_usfx.layout().addWidget(self.usfx_include_speaker_images_checkbox, 0, Qt.AlignLeft)
234
+
235
+ self.usfx_include_waveform_cache_checkbox = QCheckBox()
236
+ self.usfx_include_waveform_cache_checkbox.stateChanged.connect(lambda: usfx_option_changed(self, 'include_waveform_cache', self.usfx_include_waveform_cache_checkbox.isChecked()))
237
+ self.left_panel_global_tab_usfx.layout().addWidget(self.usfx_include_waveform_cache_checkbox, 0, Qt.AlignLeft)
238
+
239
+ self.usfx_include_original_audio_checkbox = QCheckBox()
240
+ self.usfx_include_original_audio_checkbox.stateChanged.connect(lambda: usfx_option_changed(self, 'include_original_audio', self.usfx_include_original_audio_checkbox.isChecked()))
241
+ self.left_panel_global_tab_usfx.layout().addWidget(self.usfx_include_original_audio_checkbox, 0, Qt.AlignLeft)
242
+
243
+ self.usfx_include_processed_audio_checkbox = QCheckBox()
244
+ self.usfx_include_processed_audio_checkbox.stateChanged.connect(lambda: usfx_option_changed(self, 'include_processed_audio', self.usfx_include_processed_audio_checkbox.isChecked()))
245
+ self.left_panel_global_tab_usfx.layout().addWidget(self.usfx_include_processed_audio_checkbox, 0, Qt.AlignLeft)
246
+
247
+ self.usfx_include_original_video_checkbox = QCheckBox()
248
+ self.usfx_include_original_video_checkbox.stateChanged.connect(lambda: usfx_option_changed(self, 'include_original_video', self.usfx_include_original_video_checkbox.isChecked()))
249
+ self.left_panel_global_tab_usfx.layout().addWidget(self.usfx_include_original_video_checkbox, 0, Qt.AlignLeft)
250
+
251
+ self.left_panel_global_tab_usfx.layout().addStretch()
252
+
253
+ # --- Export settings button stays at the bottom, below tabs ---
254
+ self.left_panel_global_panel_export_settings_button = QPushButton()
255
+ self.left_panel_global_panel_export_settings_button.clicked.connect(lambda: left_panel_global_panel_export_settings_button_clicked(self))
256
+ self.left_panel_global_panel_widget.layout().addWidget(self.left_panel_global_panel_export_settings_button, 0, Qt.AlignRight)
257
+
258
+ update(self)
259
+
260
+
261
+ def show(self):
262
+ update(self)
263
+
264
+
265
+ USFX_OPTION_DEFAULTS = {
266
+ 'include_speaker_images': True,
267
+ 'include_waveform_cache': False,
268
+ 'include_original_audio': False,
269
+ 'include_processed_audio': False,
270
+ 'include_original_video': False,
271
+ }
272
+
273
+
274
+ def _get_usfx_options():
275
+ return {**USFX_OPTION_DEFAULTS, **(session.CONFIG.get('default_values', {}).get('usfx_options') or {})}
276
+
277
+
278
+ def usfx_option_changed(self, key, value):
279
+ options = _get_usfx_options()
280
+ options[key] = bool(value)
281
+ session.CONFIG.setdefault('default_values', {})['usfx_options'] = options
282
+
283
+
284
+ def update(self):
285
+ for item in [self.global_subtitlesvideo_save_as_combobox.itemText(i) for i in range(self.global_subtitlesvideo_save_as_combobox.count())]:
286
+ if session.CONFIG['default_values'] and item.startswith(session.CONFIG['default_values'].get('subtitle_format', 'USFX')):
287
+ self.global_subtitlesvideo_save_as_combobox.setCurrentText(item)
288
+ break
289
+
290
+ self.global_panel_general_save_copy.setChecked(session.CONFIG['default_values'].get('save_automatic_copy', False))
291
+
292
+ self.global_panel_general_minimum_duration_spinbox.setValue(session.CONFIG['default_values'].get('minimum_subtitle_width', 1.0))
293
+
294
+ self.left_panel_global_subtitle_alignment.setCurrentText(session.CONFIG['default_values'].get('subtitle_alignment', 'left').capitalize())
295
+
296
+ options = _get_usfx_options()
297
+ for key, checkbox in (
298
+ ('include_speaker_images', self.usfx_include_speaker_images_checkbox),
299
+ ('include_waveform_cache', self.usfx_include_waveform_cache_checkbox),
300
+ ('include_original_audio', self.usfx_include_original_audio_checkbox),
301
+ ('include_processed_audio', self.usfx_include_processed_audio_checkbox),
302
+ ('include_original_video', self.usfx_include_original_video_checkbox),
303
+ ):
304
+ checkbox.blockSignals(True)
305
+ checkbox.setChecked(bool(options.get(key, False)))
306
+ checkbox.blockSignals(False)
307
+
308
+
309
+ def left_panel_global_subtitle_alignment_activated(self):
310
+ session.CONFIG['default_values']['subtitle_alignment'] = self.left_panel_global_subtitle_alignment.currentText().lower()
311
+ self.timeline_widget.subtitle_alignment = {'left' : Qt.AlignLeft, 'center' : Qt.AlignCenter, 'right' : Qt.AlignRight}[session.CONFIG['default_values'].get('subtitle_alignment', 'left')]
312
+
313
+
314
+ def global_subtitlesvideo_save_as_combobox_activated(self):
315
+ session.CONFIG['default_values']['subtitle_format'] = self.global_subtitlesvideo_save_as_combobox.currentText().split(' ', 1)[0]
316
+
317
+
318
+ def global_panel_general_save_copy_changed(self):
319
+ session.CONFIG['default_values']['save_automatic_copy'] = self.global_panel_general_save_copy.isChecked()
320
+
321
+
322
+ def global_panel_general_minimum_duration_spinbox_changed(self):
323
+ session.CONFIG['default_values']['minimum_subtitle_width'] = self.global_panel_general_minimum_duration_spinbox.value()
324
+
325
+
326
+ def left_panel_global_panel_export_settings_button_clicked(self):
327
+ filedialog = QFileDialog.getSaveFileName(parent=self, caption='Save settings', filter='JSON (*.json)')
328
+ config_dict = copy.deepcopy(session.CONFIG)
329
+ if 'recent_files' in config_dict:
330
+ del config_dict['recent_files']
331
+ if filedialog[0] and filedialog[1]:
332
+ with open(filedialog[0], mode='w', encoding='utf-8') as json_file:
333
+ json.dump(config_dict, json_file, indent=4)
334
+
335
+
336
+ def hide(self):
337
+ pass
338
+
339
+
340
+ def translate(self):
341
+ self.left_panel_global_tabs.setTabText(0, _('global_panel.tab_general'))
342
+ self.left_panel_global_tabs.setTabText(1, _('global_panel.tab_usfx'))
343
+ self.left_panel_global_tab_usfx_intro.setText(_('global_panel.usfx_intro'))
344
+ self.usfx_include_speaker_images_checkbox.setText(_('global_panel.usfx_include_speaker_images'))
345
+ self.usfx_include_waveform_cache_checkbox.setText(_('global_panel.usfx_include_waveform_cache'))
346
+ self.usfx_include_original_audio_checkbox.setText(_('global_panel.usfx_include_original_audio'))
347
+ self.usfx_include_processed_audio_checkbox.setText(_('global_panel.usfx_include_processed_audio'))
348
+ self.usfx_include_original_video_checkbox.setText(_('global_panel.usfx_include_original_video'))
349
+ self.global_subtitlesvideo_save_as_label.setText(_('global_panel.default_format_save'))
350
+ self.global_panel_general_save_copy.setText(_('global_panel.save_copy'))
351
+ self.global_panel_general_minimum_duration_label.setText(_('global_panel.minimum_duration'))
352
+ self.global_panel_general_minimum_duration_seconds_label.setText(_('units.seconds'))
353
+ self.left_panel_global_panel_export_settings_button.setText(_('global_panel.export_settings'))
354
+ self.left_panel_global_subtitle_alignment.setLabel(_('global_panel.subtitle_alignment'))
355
+
356
+
357
+
358
+
@@ -0,0 +1,82 @@
1
+ import os
2
+ from translate import Translator
3
+
4
+ from PySide6.QtWidgets import QVBoxLayout, QWidget, QScrollArea, QFileDialog, QPushButton
5
+ from PySide6.QtCore import Qt, QThread, Signal, QRect, QSize, QMargins
6
+ from PySide6.QtGui import QPainter, QColor, QPen, QFont
7
+
8
+ from subtitld.interface import left_panel
9
+ from subtitld.interface.translation import _
10
+ from subtitld.modules import session
11
+ from subtitld.modules import file_io
12
+ from subtitld.modules.session import LIST_OF_SUPPORTED_IMPORT_EXTENSIONS
13
+
14
+ list_of_supported_import_extensions = []
15
+ for exttype in LIST_OF_SUPPORTED_IMPORT_EXTENSIONS:
16
+ for ext in LIST_OF_SUPPORTED_IMPORT_EXTENSIONS[exttype]['extensions']:
17
+ list_of_supported_import_extensions.append(ext)
18
+
19
+
20
+ def load(self):
21
+ tab_name = 'import'
22
+
23
+ left_panel_import_panel = left_panel.left_panel(
24
+ parent=self,
25
+ tab_name=tab_name,
26
+ update_callback=update,
27
+ translate_callback=translate
28
+ )
29
+
30
+ left_panel_import_panel_scroll = QScrollArea()
31
+ left_panel_import_panel_scroll.setObjectName('left_panel_import_panel_scroll')
32
+ left_panel_import_panel_scroll.setWidgetResizable(True)
33
+ left_panel_import_panel_scroll.setFrameShape(QScrollArea.NoFrame)
34
+ left_panel_import_panel.layout().addWidget(left_panel_import_panel_scroll)
35
+
36
+ self.left_panel_import_panel_widget = QWidget()
37
+ self.left_panel_import_panel_widget.setProperty('class', 'transparent_panel')
38
+ self.left_panel_import_panel_widget.setObjectName('left_panel_import_panel_widget')
39
+ self.left_panel_import_panel_widget.setLayout(QVBoxLayout())
40
+ self.left_panel_import_panel_widget.layout().setContentsMargins(0, 0, 0, 0)
41
+ left_panel_import_panel_scroll.setWidget(self.left_panel_import_panel_widget)
42
+
43
+ self.global_subtitlesvideo_import_button = QPushButton(parent=self.left_panel_import_panel_widget)
44
+ self.global_subtitlesvideo_import_button.setProperty('class', 'button')
45
+ # self.global_subtitlesvideo_import_button.setCheckable(True)
46
+ self.global_subtitlesvideo_import_button.clicked.connect(lambda: global_subtitlesvideo_import_button_clicked(self))
47
+
48
+
49
+ update(self)
50
+
51
+ def global_subtitlesvideo_import_button_clicked(self):
52
+ """Function to import file"""
53
+ # if self.global_subtitlesvideo_import_button.isChecked():
54
+ # self.global_subtitlesvideo_export_button.setGeometry(20, 200, self.global_panel_menu.width() - 40, 30)
55
+ # else:
56
+ # self.global_subtitlesvideo_export_button.setGeometry(20, 120, self.global_panel_menu.width() - 40, 30)
57
+ # self.global_subtitlesvideo_import_panel.setVisible(self.global_subtitlesvideo_import_button.isChecked())
58
+
59
+ supported_import_files = 'Text files' + ' ({})'.format(" ".join([" * .{}".format(fo) for fo in list_of_supported_import_extensions]))
60
+ file_to_open = QFileDialog.getOpenFileName(parent=self, caption='Select the file to import', dir=os.path.expanduser("~"), filter=supported_import_files)[0]
61
+ if file_to_open:
62
+ session.SUBTITLE['segments'] += file_io.import_file(filename=file_to_open)[0]
63
+ session.SUBTITLE['segments'].sort()
64
+ # update_widgets(self)
65
+
66
+ def show(self):
67
+ update(self)
68
+
69
+ def update(self):
70
+ pass
71
+
72
+
73
+ def hide(self):
74
+ pass
75
+
76
+
77
+ def translate(self):
78
+ self.global_subtitlesvideo_import_button.setText(_('import_panel.import'))
79
+
80
+
81
+
82
+