GameSentenceMiner 2.12.12.post1__py3-none-any.whl → 2.13.1__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.
- GameSentenceMiner/config_gui.py +1092 -857
- GameSentenceMiner/gametext.py +2 -0
- GameSentenceMiner/locales/en_us.json +592 -0
- GameSentenceMiner/locales/ja_jp.json +591 -0
- GameSentenceMiner/locales/zh_cn.json +592 -0
- GameSentenceMiner/util/configuration.py +41 -1
- GameSentenceMiner/wip/get_overlay_coords.py +1 -1
- gamesentenceminer-2.13.1.dist-info/METADATA +42 -0
- {gamesentenceminer-2.12.12.post1.dist-info → gamesentenceminer-2.13.1.dist-info}/RECORD +13 -10
- gamesentenceminer-2.12.12.post1.dist-info/METADATA +0 -157
- {gamesentenceminer-2.12.12.post1.dist-info → gamesentenceminer-2.13.1.dist-info}/WHEEL +0 -0
- {gamesentenceminer-2.12.12.post1.dist-info → gamesentenceminer-2.13.1.dist-info}/entry_points.txt +0 -0
- {gamesentenceminer-2.12.12.post1.dist-info → gamesentenceminer-2.13.1.dist-info}/licenses/LICENSE +0 -0
- {gamesentenceminer-2.12.12.post1.dist-info → gamesentenceminer-2.13.1.dist-info}/top_level.txt +0 -0
GameSentenceMiner/config_gui.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import asyncio
|
2
|
+
import json
|
2
3
|
import subprocess
|
3
4
|
import time
|
4
5
|
import tkinter as tk
|
@@ -19,6 +20,21 @@ on_save = []
|
|
19
20
|
exit_func = None
|
20
21
|
|
21
22
|
|
23
|
+
# It's assumed that a file named 'en_us.json' exists in the same directory
|
24
|
+
# or a path that Python can find.
|
25
|
+
def load_localization(locale=Locale.English):
|
26
|
+
"""Loads the localization file."""
|
27
|
+
try:
|
28
|
+
# Use a path relative to this script file
|
29
|
+
script_dir = os.path.dirname(os.path.abspath(__file__))
|
30
|
+
lang_file = os.path.join(script_dir, 'locales', f'{locale.value}.json')
|
31
|
+
with open(lang_file, 'r', encoding='utf-8') as f:
|
32
|
+
return json.load(f)['python']['config']
|
33
|
+
except (FileNotFoundError, json.JSONDecodeError) as e:
|
34
|
+
print(f"Warning: Could not load localization file '{locale.value}.json'. Error: {e}. Falling back to empty dict.")
|
35
|
+
return {}
|
36
|
+
|
37
|
+
|
22
38
|
def new_tab(func):
|
23
39
|
def wrapper(self, *args, **kwargs):
|
24
40
|
self.current_row = 0 # Resetting row for the new tab
|
@@ -35,6 +51,15 @@ class HoverInfoWidget:
|
|
35
51
|
self.info_icon.bind("<Enter>", lambda e: self.show_info_box(text))
|
36
52
|
self.info_icon.bind("<Leave>", lambda e: self.hide_info_box())
|
37
53
|
self.tooltip = None
|
54
|
+
|
55
|
+
def change_text(self, text):
|
56
|
+
"""
|
57
|
+
Change the text of the info icon.
|
58
|
+
"""
|
59
|
+
if self.tooltip:
|
60
|
+
self.tooltip.destroy()
|
61
|
+
self.tooltip = None
|
62
|
+
self.info_icon.config(text=text)
|
38
63
|
|
39
64
|
def show_info_box(self, text):
|
40
65
|
x, y, _, _ = self.info_icon.bbox("insert")
|
@@ -55,9 +80,10 @@ class HoverInfoWidget:
|
|
55
80
|
|
56
81
|
class HoverInfoLabelWidget:
|
57
82
|
def __init__(self, parent, text, tooltip, row, column, padx=5, pady=2, foreground="white", sticky='W',
|
58
|
-
bootstyle=None, font=("Arial", 10, "normal")):
|
59
|
-
self.
|
60
|
-
self.label.
|
83
|
+
bootstyle=None, font=("Arial", 10, "normal"), apply_to_parent=False, columnspan=1):
|
84
|
+
self.label_text_value = ttk.StringVar(value=text)
|
85
|
+
self.label = ttk.Label(parent, textvariable=self.label_text_value, foreground=foreground, cursor="hand2", bootstyle=bootstyle, font=font)
|
86
|
+
self.label.grid(row=row, column=column, padx=(0, padx), pady=0, sticky=sticky, columnspan=columnspan)
|
61
87
|
self.label.bind("<Enter>", lambda e: self.show_info_box(tooltip))
|
62
88
|
self.label.bind("<Leave>", lambda e: self.hide_info_box())
|
63
89
|
self.tooltip = None
|
@@ -80,8 +106,9 @@ class HoverInfoLabelWidget:
|
|
80
106
|
|
81
107
|
|
82
108
|
class ResetToDefaultButton(ttk.Button):
|
83
|
-
def __init__(self, parent, command, text="Reset to Default", bootstyle="danger", **kwargs):
|
109
|
+
def __init__(self, parent, command, text="Reset to Default", tooltip_text="Reset settings", bootstyle="danger", **kwargs):
|
84
110
|
super().__init__(parent, text=text, command=command, bootstyle=bootstyle, **kwargs)
|
111
|
+
self.tooltip_text = tooltip_text
|
85
112
|
self.tooltip = None
|
86
113
|
self.bind("<Enter>", self.show_tooltip)
|
87
114
|
self.bind("<Leave>", self.hide_tooltip)
|
@@ -93,7 +120,7 @@ class ResetToDefaultButton(ttk.Button):
|
|
93
120
|
self.tooltip = tk.Toplevel(self)
|
94
121
|
self.tooltip.wm_overrideredirect(True)
|
95
122
|
self.tooltip.wm_geometry(f"+{x}+{y}")
|
96
|
-
label = ttk.Label(self.tooltip, text=
|
123
|
+
label = ttk.Label(self.tooltip, text=self.tooltip_text, relief="solid",
|
97
124
|
borderwidth=1,
|
98
125
|
font=("tahoma", "12", "normal"))
|
99
126
|
label.pack(ipadx=1)
|
@@ -109,16 +136,16 @@ class ConfigApp:
|
|
109
136
|
self.window = root
|
110
137
|
self.on_exit = None
|
111
138
|
self.window.tk.call('tk', 'scaling', 1.5) # Set DPI scaling factor
|
112
|
-
# self.window = ttk.Window(themename='darkly')
|
113
|
-
self.window.title('GameSentenceMiner Configuration')
|
114
139
|
self.window.protocol("WM_DELETE_WINDOW", self.hide)
|
115
140
|
self.obs_scene_listbox_changed = False
|
116
141
|
self.test_func = None
|
117
142
|
|
118
|
-
# self.window.geometry("800x500")
|
119
143
|
self.current_row = 0
|
120
144
|
|
121
145
|
self.master_config: Config = configuration.load_config()
|
146
|
+
self.i18n = load_localization(self.master_config.locale)
|
147
|
+
|
148
|
+
self.window.title(self.i18n.get('app', {}).get('title', 'GameSentenceMiner Configuration'))
|
122
149
|
|
123
150
|
self.settings = self.master_config.get_config()
|
124
151
|
self.default_master_settings = Config.new()
|
@@ -126,7 +153,9 @@ class ConfigApp:
|
|
126
153
|
|
127
154
|
self.notebook = ttk.Notebook(self.window)
|
128
155
|
self.notebook.pack(pady=10, expand=True, fill='both')
|
129
|
-
|
156
|
+
|
157
|
+
self.required_settings_frame = None
|
158
|
+
self.starter_tab = None
|
130
159
|
self.general_tab = None
|
131
160
|
self.paths_tab = None
|
132
161
|
self.anki_tab = None
|
@@ -144,40 +173,195 @@ class ConfigApp:
|
|
144
173
|
try:
|
145
174
|
import mss as mss
|
146
175
|
self.monitors = [f"Monitor {i}: width: {monitor['width']}, height: {monitor['height']}" for i, monitor in enumerate(mss.mss().monitors[1:], start=1)]
|
147
|
-
print(self.monitors)
|
148
176
|
if len(self.monitors) == 0:
|
149
177
|
self.monitors = [1]
|
150
178
|
except ImportError:
|
151
179
|
self.monitors = []
|
152
180
|
|
181
|
+
self.create_vars()
|
153
182
|
self.create_tabs()
|
154
|
-
|
155
|
-
# self.create_help_tab()
|
156
|
-
|
157
183
|
self.notebook.bind("<<NotebookTabChanged>>", self.on_profiles_tab_selected)
|
158
184
|
|
159
185
|
button_frame = ttk.Frame(self.window)
|
160
186
|
button_frame.pack(side="bottom", pady=20, anchor="center")
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
187
|
+
|
188
|
+
buttons_i18n = self.i18n.get('buttons', {})
|
189
|
+
self.save_button = ttk.Button(button_frame, text=buttons_i18n.get('save', 'Save Settings'), command=self.save_settings, bootstyle="success")
|
190
|
+
self.save_button.grid(row=0, column=0, padx=10)
|
191
|
+
|
165
192
|
if len(self.master_config.configs) > 1:
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
193
|
+
self.sync_changes_var = tk.BooleanVar(value=False)
|
194
|
+
sync_btn_i18n = buttons_i18n.get('sync_changes', {})
|
195
|
+
self.sync_changes_checkbutton = ttk.Checkbutton(
|
196
|
+
button_frame,
|
197
|
+
text=sync_btn_i18n.get('label', 'Sync Changes to Profiles'),
|
198
|
+
variable=self.sync_changes_var,
|
199
|
+
bootstyle="info"
|
200
|
+
)
|
201
|
+
self.sync_changes_checkbutton.grid(row=0, column=1, padx=10)
|
202
|
+
self.sync_changes_hover_info = HoverInfoWidget(
|
203
|
+
button_frame,
|
204
|
+
sync_btn_i18n.get('tooltip', 'Syncs CHANGED SETTINGS to all profiles.'),
|
205
|
+
row=0,
|
206
|
+
column=2
|
207
|
+
)
|
172
208
|
|
173
209
|
self.window.update_idletasks()
|
174
210
|
self.window.geometry("")
|
175
211
|
self.window.withdraw()
|
212
|
+
|
213
|
+
def change_locale(self):
|
214
|
+
"""Change the locale of the application."""
|
215
|
+
if self.locale_value.get() == self.master_config.locale.name:
|
216
|
+
return
|
217
|
+
self.i18n = load_localization(Locale[self.locale_value.get()])
|
218
|
+
self.save_settings()
|
219
|
+
self.reload_settings(force_refresh=True)
|
176
220
|
|
221
|
+
self.window.title(self.i18n.get('app', {}).get('title', 'GameSentenceMiner Configuration'))
|
222
|
+
self.save_button.config(text=self.i18n.get('buttons', {}).get('save', 'Save Settings'))
|
223
|
+
if hasattr(self, 'sync_changes_checkbutton'):
|
224
|
+
self.sync_changes_checkbutton.config(text=self.i18n.get('buttons', {}).get('sync_changes', {}).get('label', 'Sync Changes to Profiles'))
|
225
|
+
|
226
|
+
logger.info(f"Locale changed to {self.locale_value.get()}.")
|
227
|
+
|
177
228
|
def set_test_func(self, func):
|
178
229
|
self.test_func = func
|
230
|
+
|
231
|
+
def create_vars(self):
|
232
|
+
"""
|
233
|
+
Initializes all the tkinter variables used in the configuration GUI.
|
234
|
+
"""
|
235
|
+
# General Settings
|
236
|
+
self.websocket_enabled_value = tk.BooleanVar(value=self.settings.general.use_websocket)
|
237
|
+
self.clipboard_enabled_value = tk.BooleanVar(value=self.settings.general.use_clipboard)
|
238
|
+
self.use_both_clipboard_and_websocket_value = tk.BooleanVar(value=self.settings.general.use_both_clipboard_and_websocket)
|
239
|
+
self.merge_matching_sequential_text_value = tk.BooleanVar(value=self.settings.general.merge_matching_sequential_text)
|
240
|
+
self.websocket_uri_value = tk.StringVar(value=self.settings.general.websocket_uri)
|
241
|
+
self.texthook_replacement_regex_value = tk.StringVar(value=self.settings.general.texthook_replacement_regex)
|
242
|
+
self.open_config_on_startup_value = tk.BooleanVar(value=self.settings.general.open_config_on_startup)
|
243
|
+
self.open_multimine_on_startup_value = tk.BooleanVar(value=self.settings.general.open_multimine_on_startup)
|
244
|
+
self.texthooker_port_value = tk.StringVar(value=str(self.settings.general.texthooker_port))
|
245
|
+
self.native_language_value = tk.StringVar(value=CommonLanguages.from_code(self.settings.general.native_language).name.replace('_', ' ').title())
|
246
|
+
|
247
|
+
# OBS Settings
|
248
|
+
self.obs_enabled_value = tk.BooleanVar(value=self.settings.obs.enabled)
|
249
|
+
self.obs_websocket_port_value = tk.StringVar(value=str(self.settings.obs.port))
|
250
|
+
self.obs_host_value = tk.StringVar(value=self.settings.obs.host)
|
251
|
+
self.obs_port_value = tk.StringVar(value=str(self.settings.obs.port))
|
252
|
+
self.obs_password_value = tk.StringVar(value=self.settings.obs.password)
|
253
|
+
self.obs_open_obs_value = tk.BooleanVar(value=self.settings.obs.open_obs)
|
254
|
+
self.obs_close_obs_value = tk.BooleanVar(value=self.settings.obs.close_obs)
|
255
|
+
self.obs_get_game_from_scene_name_value = tk.BooleanVar(value=self.settings.obs.get_game_from_scene)
|
256
|
+
self.obs_minimum_replay_size_value = tk.StringVar(value=str(self.settings.obs.minimum_replay_size))
|
257
|
+
|
258
|
+
# Paths Settings
|
259
|
+
self.folder_to_watch_value = tk.StringVar(value=self.settings.paths.folder_to_watch)
|
260
|
+
self.audio_destination_value = tk.StringVar(value=self.settings.paths.audio_destination)
|
261
|
+
self.screenshot_destination_value = tk.StringVar(value=self.settings.paths.screenshot_destination)
|
262
|
+
self.remove_video_value = tk.BooleanVar(value=self.settings.paths.remove_video)
|
263
|
+
self.remove_audio_value = tk.BooleanVar(value=self.settings.paths.remove_audio)
|
264
|
+
self.remove_screenshot_value = tk.BooleanVar(value=self.settings.paths.remove_screenshot)
|
265
|
+
|
266
|
+
# Anki Settings
|
267
|
+
self.update_anki_value = tk.BooleanVar(value=self.settings.anki.update_anki)
|
268
|
+
self.anki_url_value = tk.StringVar(value=self.settings.anki.url)
|
269
|
+
self.sentence_field_value = tk.StringVar(value=self.settings.anki.sentence_field)
|
270
|
+
self.sentence_audio_field_value = tk.StringVar(value=self.settings.anki.sentence_audio_field)
|
271
|
+
self.picture_field_value = tk.StringVar(value=self.settings.anki.picture_field)
|
272
|
+
self.word_field_value = tk.StringVar(value=self.settings.anki.word_field)
|
273
|
+
self.previous_sentence_field_value = tk.StringVar(value=self.settings.anki.previous_sentence_field)
|
274
|
+
self.previous_image_field_value = tk.StringVar(value=self.settings.anki.previous_image_field)
|
275
|
+
self.custom_tags_value = tk.StringVar(value=', '.join(self.settings.anki.custom_tags))
|
276
|
+
self.tags_to_check_value = tk.StringVar(value=', '.join(self.settings.anki.tags_to_check))
|
277
|
+
self.add_game_tag_value = tk.BooleanVar(value=self.settings.anki.add_game_tag)
|
278
|
+
self.polling_rate_value = tk.StringVar(value=str(self.settings.anki.polling_rate))
|
279
|
+
self.overwrite_audio_value = tk.BooleanVar(value=self.settings.anki.overwrite_audio)
|
280
|
+
self.overwrite_picture_value = tk.BooleanVar(value=self.settings.anki.overwrite_picture)
|
281
|
+
self.multi_overwrites_sentence_value = tk.BooleanVar(value=self.settings.anki.multi_overwrites_sentence)
|
282
|
+
self.parent_tag_value = tk.StringVar(value=self.settings.anki.parent_tag)
|
283
|
+
|
284
|
+
# Features Settings
|
285
|
+
self.full_auto_value = tk.BooleanVar(value=self.settings.features.full_auto)
|
286
|
+
self.notify_on_update_value = tk.BooleanVar(value=self.settings.features.notify_on_update)
|
287
|
+
self.open_anki_edit_value = tk.BooleanVar(value=self.settings.features.open_anki_edit)
|
288
|
+
self.open_anki_browser_value = tk.BooleanVar(value=self.settings.features.open_anki_in_browser)
|
289
|
+
self.backfill_audio_value = tk.BooleanVar(value=self.settings.features.backfill_audio)
|
290
|
+
self.browser_query_value = tk.StringVar(value=self.settings.features.browser_query)
|
291
|
+
|
292
|
+
# Screenshot Settings
|
293
|
+
self.screenshot_enabled_value = tk.BooleanVar(value=self.settings.screenshot.enabled)
|
294
|
+
self.screenshot_width_value = tk.StringVar(value=str(self.settings.screenshot.width))
|
295
|
+
self.screenshot_height_value = tk.StringVar(value=str(self.settings.screenshot.height))
|
296
|
+
self.screenshot_quality_value = tk.StringVar(value=str(self.settings.screenshot.quality))
|
297
|
+
self.screenshot_extension_value = tk.StringVar(value=self.settings.screenshot.extension)
|
298
|
+
self.screenshot_custom_ffmpeg_settings_value = tk.StringVar(value=self.settings.screenshot.custom_ffmpeg_settings)
|
299
|
+
self.screenshot_hotkey_update_anki_value = tk.BooleanVar(value=self.settings.screenshot.screenshot_hotkey_updates_anki)
|
300
|
+
self.seconds_after_line_value = tk.StringVar(value=str(self.settings.screenshot.seconds_after_line))
|
301
|
+
self.screenshot_timing_value = tk.StringVar(value=self.settings.screenshot.screenshot_timing_setting)
|
302
|
+
self.use_screenshot_selector_value = tk.BooleanVar(value=self.settings.screenshot.use_screenshot_selector)
|
303
|
+
|
304
|
+
# Audio Settings
|
305
|
+
self.audio_enabled_value = tk.BooleanVar(value=self.settings.audio.enabled)
|
306
|
+
self.audio_extension_value = tk.StringVar(value=self.settings.audio.extension)
|
307
|
+
self.beginning_offset_value = tk.StringVar(value=str(self.settings.audio.beginning_offset))
|
308
|
+
self.end_offset_value = tk.StringVar(value=str(self.settings.audio.end_offset))
|
309
|
+
self.audio_ffmpeg_reencode_options_value = tk.StringVar(value=self.settings.audio.ffmpeg_reencode_options)
|
310
|
+
self.external_tool_value = tk.StringVar(value=self.settings.audio.external_tool)
|
311
|
+
self.anki_media_collection_value = tk.StringVar(value=self.settings.audio.anki_media_collection)
|
312
|
+
self.external_tool_enabled_value = tk.BooleanVar(value=self.settings.audio.external_tool_enabled)
|
313
|
+
self.pre_vad_audio_offset_value = tk.StringVar(value=str(self.settings.audio.pre_vad_end_offset))
|
314
|
+
|
315
|
+
# Hotkeys Settings
|
316
|
+
self.reset_line_hotkey_value = tk.StringVar(value=self.settings.hotkeys.reset_line)
|
317
|
+
self.take_screenshot_hotkey_value = tk.StringVar(value=self.settings.hotkeys.take_screenshot)
|
318
|
+
self.play_latest_audio_hotkey_value = tk.StringVar(value=self.settings.hotkeys.play_latest_audio)
|
319
|
+
|
320
|
+
# VAD Settings
|
321
|
+
self.whisper_model_value = tk.StringVar(value=self.settings.vad.whisper_model)
|
322
|
+
self.do_vad_postprocessing_value = tk.BooleanVar(value=self.settings.vad.do_vad_postprocessing)
|
323
|
+
self.selected_vad_model_value = tk.StringVar(value=self.settings.vad.selected_vad_model)
|
324
|
+
self.backup_vad_model_value = tk.StringVar(value=self.settings.vad.backup_vad_model)
|
325
|
+
self.vad_trim_beginning_value = tk.BooleanVar(value=self.settings.vad.trim_beginning)
|
326
|
+
self.vad_beginning_offset_value = tk.StringVar(value=str(self.settings.vad.beginning_offset))
|
327
|
+
self.add_audio_on_no_results_value = tk.BooleanVar(value=self.settings.vad.add_audio_on_no_results)
|
328
|
+
self.language_value = tk.StringVar(value=self.settings.vad.language)
|
329
|
+
self.cut_and_splice_segments_value = tk.BooleanVar(value=self.settings.vad.cut_and_splice_segments)
|
330
|
+
self.splice_padding_value = tk.StringVar(value=str(self.settings.vad.splice_padding) if self.settings.vad.splice_padding else "")
|
331
|
+
|
332
|
+
# Advanced Settings
|
333
|
+
self.audio_player_path_value = tk.StringVar(value=self.settings.advanced.audio_player_path)
|
334
|
+
self.video_player_path_value = tk.StringVar(value=self.settings.advanced.video_player_path)
|
335
|
+
self.multi_line_line_break_value = tk.StringVar(value=self.settings.advanced.multi_line_line_break)
|
336
|
+
self.multi_line_sentence_storage_field_value = tk.StringVar(value=self.settings.advanced.multi_line_sentence_storage_field)
|
337
|
+
self.ocr_websocket_port_value = tk.StringVar(value=str(self.settings.advanced.ocr_websocket_port))
|
338
|
+
self.texthooker_communication_websocket_port_value = tk.StringVar(value=str(self.settings.advanced.texthooker_communication_websocket_port))
|
339
|
+
self.plaintext_websocket_export_port_value = tk.StringVar(value=str(self.settings.advanced.plaintext_websocket_port))
|
340
|
+
|
341
|
+
# AI Settings
|
342
|
+
self.ai_enabled_value = tk.BooleanVar(value=self.settings.ai.enabled)
|
343
|
+
self.ai_provider_value = tk.StringVar(value=self.settings.ai.provider)
|
344
|
+
self.gemini_model_value = tk.StringVar(value=self.settings.ai.gemini_model)
|
345
|
+
self.groq_model_value = tk.StringVar(value=self.settings.ai.groq_model)
|
346
|
+
self.gemini_api_key_value = tk.StringVar(value=self.settings.ai.gemini_api_key)
|
347
|
+
self.groq_api_key_value = tk.StringVar(value=self.settings.ai.groq_api_key)
|
348
|
+
self.local_ai_model_value = tk.StringVar(value=self.settings.ai.local_model)
|
349
|
+
self.ai_anki_field_value = tk.StringVar(value=self.settings.ai.anki_field)
|
350
|
+
self.use_canned_translation_prompt_value = tk.BooleanVar(value=self.settings.ai.use_canned_translation_prompt)
|
351
|
+
self.use_canned_context_prompt_value = tk.BooleanVar(value=self.settings.ai.use_canned_context_prompt)
|
352
|
+
self.ai_dialogue_context_length_value = tk.StringVar(value=str(self.settings.ai.dialogue_context_length))
|
353
|
+
|
354
|
+
# WIP Settings
|
355
|
+
self.overlay_websocket_port_value = tk.StringVar(value=str(self.settings.wip.overlay_websocket_port))
|
356
|
+
self.overlay_websocket_send_value = tk.BooleanVar(value=self.settings.wip.overlay_websocket_send)
|
357
|
+
|
358
|
+
# Master Config Settings
|
359
|
+
self.switch_to_default_if_not_found_value = tk.BooleanVar(value=self.master_config.switch_to_default_if_not_found)
|
360
|
+
self.locale_value = tk.StringVar(value=self.master_config.locale.name)
|
361
|
+
|
179
362
|
|
180
363
|
def create_tabs(self):
|
364
|
+
self.create_required_settings_tab()
|
181
365
|
self.create_general_tab()
|
182
366
|
self.create_paths_tab()
|
183
367
|
self.create_anki_tab()
|
@@ -195,18 +379,20 @@ class ConfigApp:
|
|
195
379
|
"""
|
196
380
|
Adds a reset button to the given frame that resets the settings in the frame to default values.
|
197
381
|
"""
|
382
|
+
reset_btn_i18n = self.i18n.get('buttons', {}).get('reset_to_default', {})
|
198
383
|
reset_button = ResetToDefaultButton(frame, command=lambda: self.reset_to_default(category, recreate_tab),
|
199
|
-
text=
|
384
|
+
text=reset_btn_i18n.get('text', 'Reset to Default'),
|
385
|
+
tooltip_text=reset_btn_i18n.get('tooltip', 'Reset current tab to default.'))
|
200
386
|
reset_button.grid(row=row, column=column, sticky='W', padx=5, pady=5)
|
201
387
|
return reset_button
|
202
388
|
|
203
|
-
# Category is the dataclass name of the settings being reset, default is a default instance of that dataclass
|
204
389
|
def reset_to_default(self, category, recreate_tab):
|
205
390
|
"""
|
206
391
|
Resets the settings in the current tab to default values.
|
207
392
|
"""
|
208
|
-
|
209
|
-
|
393
|
+
dialog_i18n = self.i18n.get('dialogs', {}).get('reset_to_default', {})
|
394
|
+
if not messagebox.askyesno(dialog_i18n.get('title', 'Reset to Default'),
|
395
|
+
dialog_i18n.get('message', 'Are you sure you want to reset all settings in this tab to default?')):
|
210
396
|
return
|
211
397
|
|
212
398
|
default_category_config = getattr(self.default_settings, category)
|
@@ -219,22 +405,25 @@ class ConfigApp:
|
|
219
405
|
def show_scene_selection(self, matched_configs):
|
220
406
|
selected_scene = None
|
221
407
|
if matched_configs:
|
408
|
+
dialog_i18n = self.i18n.get('dialogs', {}).get('select_profile', {})
|
409
|
+
buttons_i18n = self.i18n.get('buttons', {})
|
410
|
+
|
222
411
|
selection_window = tk.Toplevel(self.window)
|
223
|
-
selection_window.title(
|
224
|
-
selection_window.transient(self.window)
|
225
|
-
selection_window.grab_set()
|
412
|
+
selection_window.title(dialog_i18n.get('title', 'Select Profile'))
|
413
|
+
selection_window.transient(self.window)
|
414
|
+
selection_window.grab_set()
|
226
415
|
|
227
416
|
ttk.Label(selection_window,
|
228
|
-
text=
|
417
|
+
text=dialog_i18n.get('message', 'Multiple profiles match... Please select:')).pack(pady=10)
|
229
418
|
profile_var = tk.StringVar(value=matched_configs[0])
|
230
419
|
profile_dropdown = ttk.Combobox(selection_window, textvariable=profile_var, values=matched_configs,
|
231
420
|
state="readonly")
|
232
421
|
profile_dropdown.pack(pady=5)
|
233
|
-
ttk.Button(selection_window, text=
|
422
|
+
ttk.Button(selection_window, text=buttons_i18n.get('ok', 'OK'),
|
234
423
|
command=lambda: [selection_window.destroy(), setattr(self, 'selected_scene', profile_var.get())],
|
235
424
|
bootstyle="primary").pack(pady=10)
|
236
425
|
|
237
|
-
self.window.wait_window(selection_window)
|
426
|
+
self.window.wait_window(selection_window)
|
238
427
|
selected_scene = self.selected_scene
|
239
428
|
return selected_scene
|
240
429
|
|
@@ -257,165 +446,176 @@ class ConfigApp:
|
|
257
446
|
|
258
447
|
def save_settings(self, profile_change=False, sync_changes=False):
|
259
448
|
global settings_saved
|
449
|
+
|
450
|
+
sync_changes = self.sync_changes_checkbutton.instate(['selected']) if hasattr(self, 'sync_changes_checkbutton') else sync_changes
|
451
|
+
# reset checkbox
|
452
|
+
if hasattr(self, 'sync_changes_checkbutton'):
|
453
|
+
self.sync_changes_checkbutton.state(['!selected'])
|
260
454
|
|
261
455
|
# Create a new Config instance
|
262
456
|
config = ProfileConfig(
|
263
457
|
scenes=self.settings.scenes,
|
264
458
|
general=General(
|
265
|
-
use_websocket=self.
|
266
|
-
use_clipboard=self.
|
267
|
-
websocket_uri=self.
|
268
|
-
merge_matching_sequential_text= self.
|
269
|
-
open_config_on_startup=self.
|
270
|
-
open_multimine_on_startup=self.
|
271
|
-
texthook_replacement_regex=self.
|
272
|
-
use_both_clipboard_and_websocket=self.
|
273
|
-
texthooker_port=int(self.
|
274
|
-
native_language=CommonLanguages.from_name(self.
|
459
|
+
use_websocket=self.websocket_enabled_value.get(),
|
460
|
+
use_clipboard=self.clipboard_enabled_value.get(),
|
461
|
+
websocket_uri=self.websocket_uri_value.get(),
|
462
|
+
merge_matching_sequential_text= self.merge_matching_sequential_text_value.get(),
|
463
|
+
open_config_on_startup=self.open_config_on_startup_value.get(),
|
464
|
+
open_multimine_on_startup=self.open_multimine_on_startup_value.get(),
|
465
|
+
texthook_replacement_regex=self.texthook_replacement_regex_value.get(),
|
466
|
+
use_both_clipboard_and_websocket=self.use_both_clipboard_and_websocket_value.get(),
|
467
|
+
texthooker_port=int(self.texthooker_port_value.get()),
|
468
|
+
native_language=CommonLanguages.from_name(self.native_language_value.get()) if self.native_language_value.get() else CommonLanguages.ENGLISH.value,
|
275
469
|
),
|
276
470
|
paths=Paths(
|
277
|
-
folder_to_watch=self.
|
278
|
-
audio_destination=self.
|
279
|
-
screenshot_destination=self.
|
280
|
-
remove_video=self.
|
281
|
-
remove_audio=self.
|
282
|
-
remove_screenshot=self.
|
471
|
+
folder_to_watch=self.folder_to_watch_value.get(),
|
472
|
+
audio_destination=self.audio_destination_value.get(),
|
473
|
+
screenshot_destination=self.screenshot_destination_value.get(),
|
474
|
+
remove_video=self.remove_video_value.get(),
|
475
|
+
remove_audio=self.remove_audio_value.get(),
|
476
|
+
remove_screenshot=self.remove_screenshot_value.get()
|
283
477
|
),
|
284
478
|
anki=Anki(
|
285
|
-
update_anki=self.
|
286
|
-
url=self.
|
287
|
-
sentence_field=self.
|
288
|
-
sentence_audio_field=self.
|
289
|
-
picture_field=self.
|
290
|
-
word_field=self.
|
291
|
-
previous_sentence_field=self.
|
292
|
-
previous_image_field=self.
|
293
|
-
custom_tags=[tag.strip() for tag in self.
|
294
|
-
tags_to_check=[tag.strip().lower() for tag in self.
|
295
|
-
add_game_tag=self.
|
296
|
-
polling_rate=int(self.
|
297
|
-
overwrite_audio=self.
|
298
|
-
overwrite_picture=self.
|
299
|
-
multi_overwrites_sentence=self.
|
300
|
-
parent_tag=self.
|
479
|
+
update_anki=self.update_anki_value.get(),
|
480
|
+
url=self.anki_url_value.get(),
|
481
|
+
sentence_field=self.sentence_field_value.get(),
|
482
|
+
sentence_audio_field=self.sentence_audio_field_value.get(),
|
483
|
+
picture_field=self.picture_field_value.get(),
|
484
|
+
word_field=self.word_field_value.get(),
|
485
|
+
previous_sentence_field=self.previous_sentence_field_value.get(),
|
486
|
+
previous_image_field=self.previous_image_field_value.get(),
|
487
|
+
custom_tags=[tag.strip() for tag in self.custom_tags_value.get().split(',') if tag.strip()],
|
488
|
+
tags_to_check=[tag.strip().lower() for tag in self.tags_to_check_value.get().split(',') if tag.strip()],
|
489
|
+
add_game_tag=self.add_game_tag_value.get(),
|
490
|
+
polling_rate=int(self.polling_rate_value.get()),
|
491
|
+
overwrite_audio=self.overwrite_audio_value.get(),
|
492
|
+
overwrite_picture=self.overwrite_picture_value.get(),
|
493
|
+
multi_overwrites_sentence=self.multi_overwrites_sentence_value.get(),
|
494
|
+
parent_tag=self.parent_tag_value.get(),
|
301
495
|
),
|
302
496
|
features=Features(
|
303
|
-
full_auto=self.
|
304
|
-
notify_on_update=self.
|
305
|
-
open_anki_edit=self.
|
306
|
-
open_anki_in_browser=self.
|
307
|
-
backfill_audio=self.
|
308
|
-
browser_query=self.
|
497
|
+
full_auto=self.full_auto_value.get(),
|
498
|
+
notify_on_update=self.notify_on_update_value.get(),
|
499
|
+
open_anki_edit=self.open_anki_edit_value.get(),
|
500
|
+
open_anki_in_browser=self.open_anki_browser_value.get(),
|
501
|
+
backfill_audio=self.backfill_audio_value.get(),
|
502
|
+
browser_query=self.browser_query_value.get(),
|
309
503
|
),
|
310
504
|
screenshot=Screenshot(
|
311
|
-
enabled=self.
|
312
|
-
width=self.
|
313
|
-
height=self.
|
314
|
-
quality=self.
|
315
|
-
extension=self.
|
316
|
-
custom_ffmpeg_settings=self.
|
317
|
-
screenshot_hotkey_updates_anki=self.
|
318
|
-
seconds_after_line=float(self.
|
319
|
-
screenshot_timing_setting=self.
|
320
|
-
use_screenshot_selector=self.
|
505
|
+
enabled=self.screenshot_enabled_value.get(),
|
506
|
+
width=self.screenshot_width_value.get(),
|
507
|
+
height=self.screenshot_height_value.get(),
|
508
|
+
quality=self.screenshot_quality_value.get(),
|
509
|
+
extension=self.screenshot_extension_value.get(),
|
510
|
+
custom_ffmpeg_settings=self.screenshot_custom_ffmpeg_settings_value.get(),
|
511
|
+
screenshot_hotkey_updates_anki=self.screenshot_hotkey_update_anki_value.get(),
|
512
|
+
seconds_after_line=float(self.seconds_after_line_value.get()) if self.seconds_after_line_value.get() else 0.0,
|
513
|
+
screenshot_timing_setting=self.screenshot_timing_value.get(),
|
514
|
+
use_screenshot_selector=self.use_screenshot_selector_value.get(),
|
321
515
|
),
|
322
516
|
audio=Audio(
|
323
|
-
enabled=self.
|
324
|
-
extension=self.
|
325
|
-
beginning_offset=float(self.
|
326
|
-
end_offset=float(self.
|
327
|
-
ffmpeg_reencode_options=self.
|
328
|
-
external_tool=self.
|
329
|
-
anki_media_collection=self.
|
330
|
-
external_tool_enabled=self.
|
331
|
-
pre_vad_end_offset=float(self.
|
517
|
+
enabled=self.audio_enabled_value.get(),
|
518
|
+
extension=self.audio_extension_value.get(),
|
519
|
+
beginning_offset=float(self.beginning_offset_value.get()),
|
520
|
+
end_offset=float(self.end_offset_value.get()),
|
521
|
+
ffmpeg_reencode_options=self.audio_ffmpeg_reencode_options_value.get(),
|
522
|
+
external_tool=self.external_tool_value.get(),
|
523
|
+
anki_media_collection=self.anki_media_collection_value.get(),
|
524
|
+
external_tool_enabled=self.external_tool_enabled_value.get(),
|
525
|
+
pre_vad_end_offset=float(self.pre_vad_audio_offset_value.get()),
|
332
526
|
),
|
333
527
|
obs=OBS(
|
334
|
-
enabled=self.
|
335
|
-
open_obs=self.
|
336
|
-
close_obs=self.
|
337
|
-
host=self.
|
338
|
-
port=int(self.
|
339
|
-
password=self.
|
340
|
-
get_game_from_scene=self.
|
341
|
-
minimum_replay_size=int(self.
|
528
|
+
enabled=self.obs_enabled_value.get(),
|
529
|
+
open_obs=self.obs_open_obs_value.get(),
|
530
|
+
close_obs=self.obs_close_obs_value.get(),
|
531
|
+
host=self.obs_host_value.get(),
|
532
|
+
port=int(self.obs_port_value.get()),
|
533
|
+
password=self.obs_password_value.get(),
|
534
|
+
get_game_from_scene=self.obs_get_game_from_scene_name_value.get(),
|
535
|
+
minimum_replay_size=int(self.obs_minimum_replay_size_value.get())
|
342
536
|
),
|
343
537
|
hotkeys=Hotkeys(
|
344
|
-
reset_line=self.
|
345
|
-
take_screenshot=self.
|
346
|
-
|
347
|
-
play_latest_audio=self.play_latest_audio_hotkey.get()
|
538
|
+
reset_line=self.reset_line_hotkey_value.get(),
|
539
|
+
take_screenshot=self.take_screenshot_hotkey_value.get(),
|
540
|
+
play_latest_audio=self.play_latest_audio_hotkey_value.get()
|
348
541
|
),
|
349
542
|
vad=VAD(
|
350
|
-
whisper_model=self.
|
351
|
-
do_vad_postprocessing=self.
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
splice_padding=float(self.splice_padding.get()) if self.splice_padding.get() else 0.0,
|
543
|
+
whisper_model=self.whisper_model_value.get(),
|
544
|
+
do_vad_postprocessing=self.do_vad_postprocessing_value.get(),
|
545
|
+
selected_vad_model=self.selected_vad_model_value.get(),
|
546
|
+
backup_vad_model=self.backup_vad_model_value.get(),
|
547
|
+
trim_beginning=self.vad_trim_beginning_value.get(),
|
548
|
+
beginning_offset=float(self.vad_beginning_offset_value.get()),
|
549
|
+
add_audio_on_no_results=self.add_audio_on_no_results_value.get(),
|
550
|
+
language=self.language_value.get(),
|
551
|
+
cut_and_splice_segments=self.cut_and_splice_segments_value.get(),
|
552
|
+
splice_padding=float(self.splice_padding_value.get()) if self.splice_padding_value.get() else 0.0,
|
361
553
|
),
|
362
554
|
advanced=Advanced(
|
363
|
-
audio_player_path=self.
|
364
|
-
video_player_path=self.
|
365
|
-
multi_line_line_break=self.
|
366
|
-
multi_line_sentence_storage_field=self.
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
plaintext_websocket_port=int(self.plaintext_websocket_export_port.get()),
|
555
|
+
audio_player_path=self.audio_player_path_value.get(),
|
556
|
+
video_player_path=self.video_player_path_value.get(),
|
557
|
+
multi_line_line_break=self.multi_line_line_break_value.get(),
|
558
|
+
multi_line_sentence_storage_field=self.multi_line_sentence_storage_field_value.get(),
|
559
|
+
ocr_websocket_port=int(self.ocr_websocket_port_value.get()),
|
560
|
+
texthooker_communication_websocket_port=int(self.texthooker_communication_websocket_port_value.get()),
|
561
|
+
plaintext_websocket_port=int(self.plaintext_websocket_export_port_value.get()),
|
371
562
|
),
|
372
563
|
ai=Ai(
|
373
|
-
enabled=self.
|
374
|
-
provider=self.
|
375
|
-
gemini_model=self.
|
376
|
-
groq_model=self.
|
377
|
-
gemini_api_key=self.
|
378
|
-
api_key=self.
|
379
|
-
groq_api_key=self.
|
380
|
-
local_model=self.
|
381
|
-
anki_field=self.
|
382
|
-
use_canned_translation_prompt=self.
|
383
|
-
use_canned_context_prompt=self.
|
384
|
-
custom_prompt=self.custom_prompt.get("1.0", tk.END),
|
385
|
-
dialogue_context_length=int(self.
|
564
|
+
enabled=self.ai_enabled_value.get(),
|
565
|
+
provider=self.ai_provider_value.get(),
|
566
|
+
gemini_model=self.gemini_model_value.get(),
|
567
|
+
groq_model=self.groq_model_value.get(),
|
568
|
+
gemini_api_key=self.gemini_api_key_value.get(),
|
569
|
+
api_key=self.gemini_api_key_value.get(),
|
570
|
+
groq_api_key=self.groq_api_key_value.get(),
|
571
|
+
local_model=self.local_ai_model_value.get(),
|
572
|
+
anki_field=self.ai_anki_field_value.get(),
|
573
|
+
use_canned_translation_prompt=self.use_canned_translation_prompt_value.get(),
|
574
|
+
use_canned_context_prompt=self.use_canned_context_prompt_value.get(),
|
575
|
+
custom_prompt=self.custom_prompt.get("1.0", tk.END).strip(),
|
576
|
+
dialogue_context_length=int(self.ai_dialogue_context_length_value.get()),
|
386
577
|
),
|
387
578
|
wip=WIP(
|
388
|
-
overlay_websocket_port=int(self.
|
389
|
-
overlay_websocket_send=self.
|
390
|
-
monitor_to_capture=self.monitor_to_capture.current()
|
579
|
+
overlay_websocket_port=int(self.overlay_websocket_port_value.get()),
|
580
|
+
overlay_websocket_send=self.overlay_websocket_send_value.get(),
|
581
|
+
monitor_to_capture=self.monitor_to_capture.current() if self.monitors else 0
|
391
582
|
)
|
392
583
|
)
|
393
584
|
|
394
|
-
|
395
|
-
|
585
|
+
# Find the display name for "Custom" to check against
|
586
|
+
audio_i18n = self.i18n.get('tabs', {}).get('audio', {})
|
587
|
+
ffmpeg_preset_i18n = audio_i18n.get('ffmpeg_preset', {}).get('options', {})
|
588
|
+
custom_display_name = ffmpeg_preset_i18n.get('custom', 'Custom')
|
589
|
+
|
590
|
+
if self.ffmpeg_audio_preset_options.get() == custom_display_name:
|
591
|
+
config.audio.custom_encode_settings = self.audio_ffmpeg_reencode_options_value.get()
|
592
|
+
|
593
|
+
dialog_i18n = self.i18n.get('dialogs', {}).get('config_error', {})
|
594
|
+
error_title = dialog_i18n.get('title', 'Configuration Error')
|
396
595
|
|
397
596
|
if config.features.backfill_audio and config.features.full_auto:
|
398
|
-
messagebox.showerror(
|
399
|
-
|
597
|
+
messagebox.showerror(error_title,
|
598
|
+
dialog_i18n.get('full_auto_and_backfill', 'Cannot have Full Auto and Backfill...'))
|
400
599
|
return
|
401
600
|
|
402
601
|
if not config.general.use_websocket and not config.general.use_clipboard:
|
403
|
-
messagebox.showerror(
|
602
|
+
messagebox.showerror(error_title, dialog_i18n.get('no_input_method', 'Cannot have both...'))
|
404
603
|
return
|
405
604
|
|
406
605
|
current_profile = self.profile_combobox.get()
|
407
606
|
prev_config = self.master_config.get_config()
|
408
|
-
self.master_config.switch_to_default_if_not_found = self.
|
607
|
+
self.master_config.switch_to_default_if_not_found = self.switch_to_default_if_not_found_value.get()
|
409
608
|
if profile_change:
|
410
609
|
self.master_config.current_profile = current_profile
|
411
610
|
else:
|
412
611
|
self.master_config.current_profile = current_profile
|
413
612
|
self.master_config.set_config_for_profile(current_profile, config)
|
613
|
+
|
614
|
+
self.master_config.locale = Locale[self.locale_value.get()].value
|
414
615
|
|
415
616
|
|
416
617
|
config_backup_folder = os.path.join(get_app_directory(), "backup", "config")
|
417
618
|
os.makedirs(config_backup_folder, exist_ok=True)
|
418
|
-
# write a timesstamped backup of the current config before saving
|
419
619
|
timestamp = time.strftime("%Y-%m-%d_%H-%M-%S")
|
420
620
|
with open(os.path.join(config_backup_folder, f"config_backup_{timestamp}.json"), 'w') as backup_file:
|
421
621
|
backup_file.write(self.master_config.to_json(indent=4))
|
@@ -425,7 +625,6 @@ class ConfigApp:
|
|
425
625
|
if sync_changes:
|
426
626
|
self.master_config.sync_changed_fields(prev_config)
|
427
627
|
|
428
|
-
# Serialize the config instance to JSON
|
429
628
|
with open(get_config_path(), 'w') as file:
|
430
629
|
file.write(self.master_config.to_json(indent=4))
|
431
630
|
|
@@ -445,7 +644,8 @@ class ConfigApp:
|
|
445
644
|
new_config = configuration.load_config()
|
446
645
|
current_config = new_config.get_config()
|
447
646
|
|
448
|
-
self.
|
647
|
+
title_template = self.i18n.get('app', {}).get('title_with_profile', 'GameSentenceMiner Configuration - {profile_name}')
|
648
|
+
self.window.title(title_template.format(profile_name=current_config.name))
|
449
649
|
|
450
650
|
if current_config.name != self.settings.name or self.settings.config_changed(current_config) or force_refresh:
|
451
651
|
logger.info("Config changed, reloading settings.")
|
@@ -454,7 +654,7 @@ class ConfigApp:
|
|
454
654
|
for frame in self.notebook.winfo_children():
|
455
655
|
frame.destroy()
|
456
656
|
|
457
|
-
|
657
|
+
self.required_settings_frame = None
|
458
658
|
self.general_tab = None
|
459
659
|
self.paths_tab = None
|
460
660
|
self.anki_tab = None
|
@@ -466,161 +666,138 @@ class ConfigApp:
|
|
466
666
|
self.profiles_tab = None
|
467
667
|
self.ai_tab = None
|
468
668
|
self.advanced_tab = None
|
669
|
+
self.wip_tab = None
|
469
670
|
|
671
|
+
self.create_vars()
|
470
672
|
self.create_tabs()
|
471
673
|
|
472
674
|
def increment_row(self):
|
473
|
-
"""Increment the current row index and return the new value."""
|
474
675
|
self.current_row += 1
|
475
676
|
return self.current_row
|
476
677
|
|
477
|
-
def add_label_and_increment_row(self, root, label, row=0, column=0):
|
478
|
-
HoverInfoWidget(root, label, row=self.current_row, column=column)
|
479
|
-
self.increment_row()
|
480
|
-
|
481
|
-
def add_label_without_row_increment(self, root, label, row=0, column=0):
|
482
|
-
HoverInfoWidget(root, label, row=self.current_row, column=column)
|
483
|
-
|
484
678
|
@new_tab
|
485
679
|
def create_general_tab(self):
|
486
680
|
if self.general_tab is None:
|
681
|
+
general_i18n = self.i18n.get('tabs', {}).get('general', {})
|
487
682
|
self.general_tab = ttk.Frame(self.notebook, padding=15)
|
488
|
-
self.notebook.add(self.general_tab, text='General')
|
683
|
+
self.notebook.add(self.general_tab, text=general_i18n.get('title', 'General'))
|
489
684
|
else:
|
490
685
|
for widget in self.general_tab.winfo_children():
|
491
686
|
widget.destroy()
|
492
687
|
|
493
|
-
|
688
|
+
general_i18n = self.i18n.get('tabs', {}).get('general', {})
|
689
|
+
|
690
|
+
ws_i18n = general_i18n.get('websocket_enabled', {})
|
691
|
+
HoverInfoLabelWidget(self.general_tab, text=ws_i18n.get('label', 'Websocket Enabled:'),
|
494
692
|
foreground="dark orange", font=("Helvetica", 10, "bold"),
|
495
|
-
tooltip=
|
693
|
+
tooltip=ws_i18n.get('tooltip', '...'),
|
496
694
|
row=self.current_row, column=0)
|
497
|
-
self.
|
498
|
-
|
499
|
-
row=self.current_row, column=1,
|
500
|
-
sticky='W', pady=2)
|
695
|
+
ttk.Checkbutton(self.general_tab, variable=self.websocket_enabled_value, bootstyle="round-toggle").grid(
|
696
|
+
row=self.current_row, column=1, sticky='W', pady=2)
|
501
697
|
self.current_row += 1
|
502
698
|
|
503
|
-
|
699
|
+
clip_i18n = general_i18n.get('clipboard_enabled', {})
|
700
|
+
HoverInfoLabelWidget(self.general_tab, text=clip_i18n.get('label', 'Clipboard Enabled:'),
|
504
701
|
foreground="dark orange", font=("Helvetica", 10, "bold"),
|
505
|
-
tooltip=
|
506
|
-
self.
|
507
|
-
|
508
|
-
row=self.current_row, column=1,
|
509
|
-
sticky='W', pady=2)
|
702
|
+
tooltip=clip_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
703
|
+
ttk.Checkbutton(self.general_tab, variable=self.clipboard_enabled_value, bootstyle="round-toggle").grid(
|
704
|
+
row=self.current_row, column=1, sticky='W', pady=2)
|
510
705
|
self.current_row += 1
|
511
706
|
|
512
|
-
|
707
|
+
both_i18n = general_i18n.get('allow_both_simultaneously', {})
|
708
|
+
HoverInfoLabelWidget(self.general_tab, text=both_i18n.get('label', 'Allow Both Simultaneously:'),
|
513
709
|
foreground="red", font=("Helvetica", 10, "bold"),
|
514
|
-
tooltip=
|
710
|
+
tooltip=both_i18n.get('tooltip', '...'),
|
515
711
|
row=self.current_row, column=0)
|
516
|
-
self.
|
517
|
-
|
518
|
-
ttk.Checkbutton(self.general_tab, variable=self.use_both_clipboard_and_websocket,
|
519
|
-
bootstyle="round-toggle").grid(
|
520
|
-
row=self.current_row, column=1,
|
521
|
-
sticky='W', pady=2)
|
712
|
+
ttk.Checkbutton(self.general_tab, variable=self.use_both_clipboard_and_websocket_value, bootstyle="round-toggle").grid(
|
713
|
+
row=self.current_row, column=1, sticky='W', pady=2)
|
522
714
|
self.current_row += 1
|
523
715
|
|
524
|
-
|
716
|
+
merge_i18n = general_i18n.get('merge_sequential_text', {})
|
717
|
+
HoverInfoLabelWidget(self.general_tab, text=merge_i18n.get('label', 'Merge Matching Sequential Text:'),
|
525
718
|
foreground="red", font=("Helvetica", 10, "bold"),
|
526
|
-
tooltip=
|
719
|
+
tooltip=merge_i18n.get('tooltip', '...'),
|
527
720
|
row=self.current_row, column=0)
|
528
|
-
|
529
|
-
|
530
|
-
value=self.settings.general.merge_matching_sequential_text)
|
531
|
-
ttk.Checkbutton(self.general_tab, variable=self.merge_matching_sequential_text,
|
532
|
-
bootstyle="round-toggle").grid(
|
533
|
-
row=self.current_row, column=1,
|
534
|
-
sticky='W', pady=2)
|
721
|
+
ttk.Checkbutton(self.general_tab, variable=self.merge_matching_sequential_text_value, bootstyle="round-toggle").grid(
|
722
|
+
row=self.current_row, column=1, sticky='W', pady=2)
|
535
723
|
self.current_row += 1
|
536
724
|
|
537
|
-
|
538
|
-
|
725
|
+
uri_i18n = general_i18n.get('websocket_uri', {})
|
726
|
+
HoverInfoLabelWidget(self.general_tab, text=uri_i18n.get('label', 'Websocket URI(s):'),
|
727
|
+
tooltip=uri_i18n.get('tooltip', '...'),
|
539
728
|
row=self.current_row, column=0)
|
540
|
-
|
541
|
-
self.websocket_uri.insert(0, self.settings.general.websocket_uri)
|
542
|
-
self.websocket_uri.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
729
|
+
ttk.Entry(self.general_tab, width=50, textvariable=self.websocket_uri_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
543
730
|
self.current_row += 1
|
544
731
|
|
545
|
-
|
546
|
-
|
732
|
+
regex_i18n = general_i18n.get('texthook_regex', {})
|
733
|
+
HoverInfoLabelWidget(self.general_tab, text=regex_i18n.get('label', 'TextHook Replacement Regex:'),
|
734
|
+
tooltip=regex_i18n.get('tooltip', '...'),
|
547
735
|
row=self.current_row, column=0)
|
548
|
-
self.
|
549
|
-
self.texthook_replacement_regex.insert(0, self.settings.general.texthook_replacement_regex)
|
550
|
-
self.texthook_replacement_regex.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
736
|
+
ttk.Entry(self.general_tab, textvariable=self.texthook_replacement_regex_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
551
737
|
self.current_row += 1
|
552
738
|
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
ttk.Checkbutton(self.general_tab, variable=self.
|
557
|
-
row=self.current_row, column=1,
|
558
|
-
sticky='W', pady=2)
|
739
|
+
open_config_i18n = general_i18n.get('open_config_on_startup', {})
|
740
|
+
HoverInfoLabelWidget(self.general_tab, text=open_config_i18n.get('label', 'Open Config on Startup:'),
|
741
|
+
tooltip=open_config_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
742
|
+
ttk.Checkbutton(self.general_tab, variable=self.open_config_on_startup_value, bootstyle="round-toggle").grid(
|
743
|
+
row=self.current_row, column=1, sticky='W', pady=2)
|
559
744
|
self.current_row += 1
|
560
745
|
|
561
|
-
|
562
|
-
|
563
|
-
column=0)
|
564
|
-
self.
|
565
|
-
|
566
|
-
row=self.current_row, column=1,
|
567
|
-
sticky='W', pady=2)
|
746
|
+
open_texthooker_i18n = general_i18n.get('open_texthooker_on_startup', {})
|
747
|
+
HoverInfoLabelWidget(self.general_tab, text=open_texthooker_i18n.get('label', 'Open GSM Texthooker on Startup:'),
|
748
|
+
tooltip=open_texthooker_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
749
|
+
ttk.Checkbutton(self.general_tab, variable=self.open_multimine_on_startup_value, bootstyle="round-toggle").grid(
|
750
|
+
row=self.current_row, column=1, sticky='W', pady=2)
|
568
751
|
self.current_row += 1
|
569
752
|
|
570
|
-
|
571
|
-
|
753
|
+
port_i18n = general_i18n.get('texthooker_port', {})
|
754
|
+
HoverInfoLabelWidget(self.general_tab, text=port_i18n.get('label', 'GSM Texthooker Port:'),
|
755
|
+
tooltip=port_i18n.get('tooltip', '...'),
|
572
756
|
row=self.current_row, column=0)
|
573
|
-
self.
|
574
|
-
self.texthooker_port.insert(0, str(self.settings.general.texthooker_port))
|
575
|
-
self.texthooker_port.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
576
|
-
self.current_row += 1
|
577
|
-
|
578
|
-
HoverInfoLabelWidget(self.general_tab, text="Current Version:", bootstyle="secondary",
|
579
|
-
tooltip="The current version of the application.", row=self.current_row, column=0)
|
580
|
-
self.current_version = ttk.Label(self.general_tab, text=get_current_version(), bootstyle="secondary")
|
581
|
-
self.current_version.grid(row=self.current_row, column=1, sticky='W', pady=2)
|
582
|
-
self.current_row += 1
|
583
|
-
|
584
|
-
HoverInfoLabelWidget(self.general_tab, text="Latest Version:", bootstyle="secondary",
|
585
|
-
tooltip="The latest available version of the application.", row=self.current_row, column=0)
|
586
|
-
self.latest_version = ttk.Label(self.general_tab, text=get_latest_version(), bootstyle="secondary")
|
587
|
-
self.latest_version.grid(row=self.current_row, column=1, sticky='W', pady=2)
|
757
|
+
ttk.Entry(self.general_tab, textvariable=self.texthooker_port_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
588
758
|
self.current_row += 1
|
589
759
|
|
590
|
-
#
|
591
|
-
HoverInfoLabelWidget(self.general_tab, text=
|
592
|
-
|
760
|
+
# locale_i18n = general_i18n.get('locale', {})
|
761
|
+
# HoverInfoLabelWidget(self.general_tab, text=locale_i18n.get('label', 'Locale:'),
|
762
|
+
# tooltip=locale_i18n.get('tooltip', '...'),
|
763
|
+
# row=self.current_row, column=0)
|
764
|
+
# locale_combobox = ttk.Combobox(self.general_tab, textvariable=self.locale_value, values=[Locale.English.name, Locale.日本語.name, Locale.中文.name], state="readonly")
|
765
|
+
# locale_combobox.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
766
|
+
# locale_combobox.bind("<<ComboboxSelected>>", lambda e: self.change_locale())
|
767
|
+
# self.current_row += 1
|
768
|
+
|
769
|
+
lang_i18n = general_i18n.get('native_language', {})
|
770
|
+
HoverInfoLabelWidget(self.general_tab, text=lang_i18n.get('label', 'Native Language:'),
|
771
|
+
tooltip=lang_i18n.get('tooltip', '...'),
|
593
772
|
row=self.current_row, column=0)
|
594
|
-
|
595
|
-
self.native_language.set(CommonLanguages.from_code(self.settings.general.native_language).name.replace('_', ' ').title())
|
596
|
-
self.native_language.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
773
|
+
ttk.Combobox(self.general_tab, textvariable=self.native_language_value, values=CommonLanguages.get_all_names_pretty(), state="readonly").grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
597
774
|
self.current_row += 1
|
598
775
|
|
599
|
-
|
776
|
+
legend_i18n = general_i18n.get('legend', {})
|
777
|
+
ttk.Label(self.general_tab, text=legend_i18n.get('important', '...'), foreground="dark orange",
|
600
778
|
font=("Helvetica", 10, "bold")).grid(row=self.current_row, column=0, columnspan=2, sticky='W', pady=2)
|
601
779
|
self.current_row += 1
|
602
|
-
ttk.Label(self.general_tab, text=
|
780
|
+
ttk.Label(self.general_tab, text=legend_i18n.get('advanced', '...'), foreground="red",
|
603
781
|
font=("Helvetica", 10, "bold")).grid(row=self.current_row, column=0, columnspan=2, sticky='W', pady=2)
|
604
782
|
self.current_row += 1
|
605
|
-
ttk.Label(self.general_tab, text=
|
783
|
+
ttk.Label(self.general_tab, text=legend_i18n.get('recommended', '...'), foreground="green",
|
606
784
|
font=("Helvetica", 10, "bold")).grid(row=self.current_row, column=0, columnspan=2, sticky='W', pady=2)
|
607
785
|
self.current_row += 1
|
608
786
|
ttk.Label(self.general_tab,
|
609
|
-
text=
|
787
|
+
text=legend_i18n.get('tooltip_info', '...'),
|
610
788
|
font=("Helvetica", 10, "bold")).grid(row=self.current_row, column=0, columnspan=2, sticky='W', pady=2)
|
611
789
|
self.current_row += 1
|
612
790
|
|
613
791
|
if is_beangate:
|
614
|
-
ttk.Button(self.general_tab, text=
|
792
|
+
ttk.Button(self.general_tab, text=self.i18n.get('buttons', {}).get('run_function', 'Run Function'), command=self.test_func, bootstyle="info").grid(
|
615
793
|
row=self.current_row, column=0, pady=5
|
616
794
|
)
|
617
795
|
self.current_row += 1
|
618
796
|
|
619
|
-
# Add Reset to Default button
|
620
797
|
self.add_reset_button(self.general_tab, "general", self.current_row, column=0, recreate_tab=self.create_general_tab)
|
621
798
|
|
622
|
-
self.general_tab.grid_columnconfigure(0, weight=0)
|
623
|
-
self.general_tab.grid_columnconfigure(1, weight=0)
|
799
|
+
self.general_tab.grid_columnconfigure(0, weight=0)
|
800
|
+
self.general_tab.grid_columnconfigure(1, weight=0)
|
624
801
|
for row in range(self.current_row):
|
625
802
|
self.general_tab.grid_rowconfigure(row, minsize=30)
|
626
803
|
|
@@ -628,351 +805,484 @@ class ConfigApp:
|
|
628
805
|
|
629
806
|
@new_tab
|
630
807
|
def create_required_settings_tab(self):
|
631
|
-
required_settings_frame
|
632
|
-
|
808
|
+
if self.required_settings_frame is None:
|
809
|
+
self.required_settings_frame = ttk.Frame(self.notebook, padding=15)
|
810
|
+
self.notebook.add(self.required_settings_frame, text=self.i18n.get('tabs', {}).get('key_settings', {}).get('title', 'Key Settings'))
|
811
|
+
else:
|
812
|
+
for widget in self.required_settings_frame.winfo_children():
|
813
|
+
widget.destroy()
|
814
|
+
required_settings_frame = self.required_settings_frame
|
815
|
+
|
816
|
+
simple_i18n = self.i18n.get('tabs', {}).get('simple', {})
|
817
|
+
|
818
|
+
# key_settings_i18n = simple_i18n.get('key_settings', {})
|
819
|
+
# HoverInfoLabelWidget(required_settings_frame, text=key_settings_i18n.get('label', 'Key Settings'),
|
820
|
+
# tooltip=key_settings_i18n.get('tooltip', "These settings are important..."),
|
821
|
+
# row=self.current_row, column=0, columnspan=4, font=("Helvetica", 12, "bold"))
|
822
|
+
# self.current_row += 1
|
823
|
+
|
824
|
+
# --- General Settings ---
|
825
|
+
general_i18n = self.i18n.get('tabs', {}).get('general', {})
|
826
|
+
input_frame = ttk.Frame(required_settings_frame)
|
827
|
+
input_frame.grid(row=self.current_row, column=0, columnspan=4, sticky='W', pady=2)
|
828
|
+
|
829
|
+
ws_i18n = general_i18n.get('websocket_enabled', {})
|
830
|
+
HoverInfoLabelWidget(input_frame, text=ws_i18n.get('label', '...'),
|
831
|
+
tooltip=ws_i18n.get('tooltip', '...'), row=0, column=0)
|
832
|
+
ttk.Checkbutton(input_frame, variable=self.websocket_enabled_value, bootstyle="round-toggle").grid(row=0, column=1, sticky='W', pady=2)
|
833
|
+
|
834
|
+
clip_i18n = general_i18n.get('clipboard_enabled', {})
|
835
|
+
HoverInfoLabelWidget(input_frame, text=clip_i18n.get('label', '...'),
|
836
|
+
tooltip=clip_i18n.get('tooltip', '...'), row=0, column=2, padx=5)
|
837
|
+
ttk.Checkbutton(input_frame, variable=self.clipboard_enabled_value, bootstyle="round-toggle").grid(row=0, column=3, sticky='W', pady=2)
|
838
|
+
self.current_row += 1
|
839
|
+
|
840
|
+
uri_i18n = general_i18n.get('websocket_uri', {})
|
841
|
+
HoverInfoLabelWidget(required_settings_frame, text=uri_i18n.get('label', '...'),
|
842
|
+
tooltip=uri_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
843
|
+
ttk.Entry(required_settings_frame, width=50, textvariable=self.websocket_uri_value).grid(row=self.current_row, column=1, columnspan=3, sticky='EW', pady=2)
|
844
|
+
self.current_row += 1
|
845
|
+
|
846
|
+
locale_i18n = general_i18n.get('locale', {})
|
847
|
+
HoverInfoLabelWidget(required_settings_frame, text=locale_i18n.get('label', '...'),
|
848
|
+
tooltip=locale_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
849
|
+
locale_combobox_simple = ttk.Combobox(required_settings_frame, textvariable=self.locale_value, values=[Locale.English.name, Locale.日本語.name, Locale.中文.name], state="readonly")
|
850
|
+
locale_combobox_simple.grid(row=self.current_row, column=1, columnspan=3, sticky='EW', pady=2)
|
851
|
+
locale_combobox_simple.bind("<<ComboboxSelected>>", lambda e: self.change_locale())
|
852
|
+
self.current_row += 1
|
853
|
+
|
854
|
+
# --- Paths Settings ---
|
855
|
+
paths_i18n = self.i18n.get('tabs', {}).get('paths', {})
|
856
|
+
browse_text = self.i18n.get('buttons', {}).get('browse', 'Browse')
|
857
|
+
watch_i18n = paths_i18n.get('folder_to_watch', {})
|
858
|
+
HoverInfoLabelWidget(required_settings_frame, text=watch_i18n.get('label', '...'),
|
859
|
+
tooltip=watch_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
860
|
+
folder_watch_entry = ttk.Entry(required_settings_frame, width=50, textvariable=self.folder_to_watch_value)
|
861
|
+
folder_watch_entry.grid(row=self.current_row, column=1, columnspan=2, sticky='EW', pady=2)
|
862
|
+
ttk.Button(required_settings_frame, text=browse_text, command=lambda: self.browse_folder(folder_watch_entry),
|
863
|
+
bootstyle="outline").grid(row=self.current_row, column=3, padx=5, pady=2)
|
864
|
+
self.current_row += 1
|
865
|
+
|
866
|
+
# --- Anki Settings ---
|
867
|
+
anki_i18n = self.i18n.get('tabs', {}).get('anki', {})
|
868
|
+
sentence_i18n = anki_i18n.get('sentence_field', {})
|
869
|
+
HoverInfoLabelWidget(required_settings_frame, text=sentence_i18n.get('label', '...'),
|
870
|
+
tooltip=sentence_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
871
|
+
ttk.Entry(required_settings_frame, textvariable=self.sentence_field_value).grid(row=self.current_row, column=1, columnspan=3, sticky='EW', pady=2)
|
872
|
+
self.current_row += 1
|
873
|
+
|
874
|
+
audio_i18n = anki_i18n.get('sentence_audio_field', {})
|
875
|
+
HoverInfoLabelWidget(required_settings_frame, text=audio_i18n.get('label', '...'),
|
876
|
+
tooltip=audio_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
877
|
+
ttk.Entry(required_settings_frame, textvariable=self.sentence_audio_field_value).grid(row=self.current_row, column=1, columnspan=3, sticky='EW', pady=2)
|
878
|
+
self.current_row += 1
|
879
|
+
|
880
|
+
pic_i18n = anki_i18n.get('picture_field', {})
|
881
|
+
HoverInfoLabelWidget(required_settings_frame, text=pic_i18n.get('label', '...'),
|
882
|
+
tooltip=pic_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
883
|
+
ttk.Entry(required_settings_frame, textvariable=self.picture_field_value).grid(row=self.current_row, column=1, columnspan=3, sticky='EW', pady=2)
|
884
|
+
self.current_row += 1
|
885
|
+
|
886
|
+
word_i18n = anki_i18n.get('word_field', {})
|
887
|
+
HoverInfoLabelWidget(required_settings_frame, text=word_i18n.get('label', '...'),
|
888
|
+
tooltip=word_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
889
|
+
ttk.Entry(required_settings_frame, textvariable=self.word_field_value).grid(row=self.current_row, column=1, columnspan=3, sticky='EW', pady=2)
|
890
|
+
self.current_row += 1
|
891
|
+
|
892
|
+
# --- Audio Settings ---
|
893
|
+
audio_tab_i18n = self.i18n.get('tabs', {}).get('audio', {})
|
894
|
+
begin_offset_i18n = audio_tab_i18n.get('beginning_offset', {})
|
895
|
+
HoverInfoLabelWidget(required_settings_frame, text=begin_offset_i18n.get('label', '...'),
|
896
|
+
tooltip=begin_offset_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
897
|
+
ttk.Entry(required_settings_frame, textvariable=self.beginning_offset_value).grid(row=self.current_row, column=1, columnspan=3, sticky='EW', pady=2)
|
898
|
+
self.current_row += 1
|
899
|
+
|
900
|
+
# Vad end offset
|
901
|
+
|
902
|
+
vad_i18n = self.i18n.get('tabs', {}).get('vad', {})
|
903
|
+
vad_end_offset_i18n = vad_i18n.get('audio_end_offset', {})
|
904
|
+
HoverInfoLabelWidget(required_settings_frame, text=vad_end_offset_i18n.get('label', '...'),
|
905
|
+
tooltip=vad_end_offset_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
906
|
+
ttk.Entry(required_settings_frame, textvariable=self.end_offset_value).grid(row=self.current_row, column=1, columnspan=3, sticky='EW', pady=2)
|
907
|
+
self.current_row += 1
|
908
|
+
|
909
|
+
# --- Features Settings ---
|
910
|
+
features_i18n = self.i18n.get('tabs', {}).get('features', {})
|
911
|
+
# action_frame = ttk.Frame(required_settings_frame)
|
912
|
+
# action_frame.grid(row=self.current_row, column=0, columnspan=4, sticky='W', pady=2)
|
913
|
+
|
914
|
+
# Feature Toggles, Anki, OBS, Audio, VAD, AI, WIP
|
915
|
+
feature_frame = ttk.Frame(required_settings_frame)
|
916
|
+
feature_frame.grid(row=self.current_row, column=0, columnspan=5, sticky='W', pady=2)
|
917
|
+
|
918
|
+
# anki_enabled_i18n = simple_i18n.get('anki_enabled', {})
|
919
|
+
# HoverInfoLabelWidget(feature_frame, text=anki_enabled_i18n.get('label', '...'),
|
920
|
+
# tooltip=anki_enabled_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
921
|
+
# ttk.Checkbutton(feature_frame, variable=self.update_anki_value, bootstyle="round-toggle").grid(
|
922
|
+
# row=self.current_row, column=1, sticky='W', pady=2)
|
923
|
+
|
924
|
+
open_edit_i18n = features_i18n.get('open_anki_edit', {})
|
925
|
+
HoverInfoLabelWidget(feature_frame, text=open_edit_i18n.get('label', '...'),
|
926
|
+
tooltip=open_edit_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
927
|
+
ttk.Checkbutton(feature_frame, variable=self.open_anki_edit_value, bootstyle="round-toggle").grid(
|
928
|
+
row=self.current_row, column=1, sticky='W', pady=2)
|
929
|
+
|
930
|
+
open_browser_i18n = features_i18n.get('open_anki_browser', {})
|
931
|
+
HoverInfoLabelWidget(feature_frame, text=open_browser_i18n.get('label', '...'),
|
932
|
+
tooltip=open_browser_i18n.get('tooltip', '...'), row=self.current_row, column=2, padx=5)
|
933
|
+
ttk.Checkbutton(feature_frame, variable=self.open_anki_browser_value, bootstyle="round-toggle").grid(
|
934
|
+
row=self.current_row, column=3, sticky='W', pady=2)
|
935
|
+
self.current_row += 1
|
936
|
+
|
937
|
+
# obs_enabled_i18n = simple_i18n.get('obs_enabled', {})
|
938
|
+
# HoverInfoLabelWidget(feature_frame, text=obs_enabled_i18n.get('label', '...'),
|
939
|
+
# tooltip=obs_enabled_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
940
|
+
# ttk.Checkbutton(feature_frame, variable=self.obs_enabled_value, bootstyle="round-toggle").grid(
|
941
|
+
# row=self.current_row, column=1, sticky='W', pady=2)
|
942
|
+
# self.current_row += 1
|
943
|
+
|
944
|
+
# screenshot_i18n = simple_i18n.get('screenshot_enabled', {})
|
945
|
+
# HoverInfoLabelWidget(feature_frame, text=screenshot_i18n.get('label', '...'),
|
946
|
+
# tooltip=screenshot_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
947
|
+
# ttk.Checkbutton(feature_frame, variable=self.screenshot_enabled_value, bootstyle="round-toggle").grid(
|
948
|
+
# row=self.current_row, column=1, sticky='W', pady=2)
|
949
|
+
# self.current_row += 1
|
950
|
+
|
951
|
+
# audio_i18n = self.i18n.get('tabs', {}).get('audio', {})
|
952
|
+
# audio_enabled_i18n = simple_i18n.get('audio_enabled', {})
|
953
|
+
# HoverInfoLabelWidget(feature_frame, text=audio_enabled_i18n.get('label', '...'),
|
954
|
+
# tooltip=audio_enabled_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
955
|
+
# ttk.Checkbutton(feature_frame, variable=self.audio_enabled_value, bootstyle="round-toggle").grid(
|
956
|
+
# row=self.current_row, column=1, sticky='W', pady=2)
|
957
|
+
# self.current_row += 1
|
958
|
+
|
959
|
+
# vad_i18n = self.i18n.get('tabs', {}).get('vad', {})
|
960
|
+
# vad_enabled_i18n = simple_i18n.get('vad_enabled', {})
|
961
|
+
# HoverInfoLabelWidget(feature_frame, text=vad_enabled_i18n.get('label', '...'),
|
962
|
+
# tooltip=vad_enabled_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
963
|
+
# ttk.Checkbutton(feature_frame, variable=self.do_vad_postprocessing_value, bootstyle="round-toggle").grid(
|
964
|
+
# row=self.current_row, column=1, sticky='W', pady=2)
|
965
|
+
# self.current_row += 1
|
966
|
+
|
967
|
+
# ai_i18n = self.i18n.get('tabs', {}).get('ai', {})
|
968
|
+
# ai_enabled_i18n = simple_i18n.get('ai_enabled', {})
|
969
|
+
# HoverInfoLabelWidget(feature_frame, text=ai_enabled_i18n.get('label', '...'),
|
970
|
+
# tooltip=ai_enabled_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
971
|
+
# ttk.Checkbutton(feature_frame, variable=self.ai_enabled_value, bootstyle="round-toggle").grid(
|
972
|
+
# row=self.current_row, column=1, sticky='W', pady=2)
|
973
|
+
|
974
|
+
required_settings_frame.grid_columnconfigure(1, weight=1)
|
975
|
+
|
633
976
|
return required_settings_frame
|
634
977
|
|
635
978
|
@new_tab
|
636
979
|
def create_vad_tab(self):
|
637
980
|
if self.vad_tab is None:
|
981
|
+
vad_i18n = self.i18n.get('tabs', {}).get('vad', {})
|
638
982
|
self.vad_tab = ttk.Frame(self.notebook, padding=15)
|
639
|
-
self.notebook.add(self.vad_tab, text='VAD')
|
983
|
+
self.notebook.add(self.vad_tab, text=vad_i18n.get('title', 'VAD'))
|
640
984
|
else:
|
641
985
|
for widget in self.vad_tab.winfo_children():
|
642
986
|
widget.destroy()
|
643
987
|
|
644
988
|
vad_frame = self.vad_tab
|
989
|
+
vad_i18n = self.i18n.get('tabs', {}).get('vad', {})
|
645
990
|
|
646
|
-
|
647
|
-
|
991
|
+
postproc_i18n = vad_i18n.get('do_postprocessing', {})
|
992
|
+
HoverInfoLabelWidget(vad_frame, text=postproc_i18n.get('label', '...'),
|
993
|
+
tooltip=postproc_i18n.get('tooltip', '...'),
|
648
994
|
row=self.current_row, column=0)
|
649
|
-
self.
|
650
|
-
value=self.settings.vad.do_vad_postprocessing)
|
651
|
-
ttk.Checkbutton(vad_frame, variable=self.do_vad_postprocessing, bootstyle="round-toggle").grid(
|
995
|
+
ttk.Checkbutton(vad_frame, variable=self.do_vad_postprocessing_value, bootstyle="round-toggle").grid(
|
652
996
|
row=self.current_row, column=1, sticky='W', pady=2)
|
653
997
|
self.current_row += 1
|
654
998
|
|
655
|
-
|
656
|
-
|
999
|
+
lang_i18n = vad_i18n.get('language', {})
|
1000
|
+
HoverInfoLabelWidget(vad_frame, text=lang_i18n.get('label', '...'),
|
1001
|
+
tooltip=lang_i18n.get('tooltip', '...'),
|
657
1002
|
row=self.current_row, column=0)
|
658
|
-
|
659
|
-
self.language.set(self.settings.vad.language)
|
660
|
-
self.language.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1003
|
+
ttk.Combobox(vad_frame, textvariable=self.language_value, values=AVAILABLE_LANGUAGES, state="readonly").grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
661
1004
|
self.current_row += 1
|
662
1005
|
|
663
|
-
|
1006
|
+
whisper_i18n = vad_i18n.get('whisper_model', {})
|
1007
|
+
HoverInfoLabelWidget(vad_frame, text=whisper_i18n.get('label', '...'), tooltip=whisper_i18n.get('tooltip', '...'),
|
664
1008
|
row=self.current_row, column=0)
|
665
|
-
|
666
|
-
WHSIPER_LARGE, WHISPER_TURBO], state="readonly")
|
667
|
-
self.whisper_model.set(self.settings.vad.whisper_model)
|
668
|
-
self.whisper_model.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1009
|
+
ttk.Combobox(vad_frame, textvariable=self.whisper_model_value, values=[WHISPER_TINY, WHISPER_BASE, WHISPER_SMALL, WHISPER_MEDIUM,
|
1010
|
+
WHSIPER_LARGE, WHISPER_TURBO], state="readonly").grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
669
1011
|
self.current_row += 1
|
670
1012
|
|
671
|
-
|
1013
|
+
selected_model_i18n = vad_i18n.get('selected_model', {})
|
1014
|
+
HoverInfoLabelWidget(vad_frame, text=selected_model_i18n.get('label', '...'), tooltip=selected_model_i18n.get('tooltip', '...'),
|
672
1015
|
foreground="dark orange", font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
673
|
-
|
674
|
-
self.selected_vad_model.set(self.settings.vad.selected_vad_model)
|
675
|
-
self.selected_vad_model.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1016
|
+
ttk.Combobox(vad_frame, textvariable=self.selected_vad_model_value, values=[SILERO, WHISPER], state="readonly").grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
676
1017
|
self.current_row += 1
|
677
1018
|
|
678
|
-
|
679
|
-
|
1019
|
+
backup_model_i18n = vad_i18n.get('backup_model', {})
|
1020
|
+
HoverInfoLabelWidget(vad_frame, text=backup_model_i18n.get('label', '...'),
|
1021
|
+
tooltip=backup_model_i18n.get('tooltip', '...'),
|
680
1022
|
row=self.current_row, column=0)
|
681
|
-
|
682
|
-
self.backup_vad_model.set(self.settings.vad.backup_vad_model)
|
683
|
-
self.backup_vad_model.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1023
|
+
ttk.Combobox(vad_frame, textvariable=self.backup_vad_model_value, values=[OFF, SILERO, WHISPER], state="readonly").grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
684
1024
|
self.current_row += 1
|
685
1025
|
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
ttk.Checkbutton(vad_frame, variable=self.
|
1026
|
+
no_results_i18n = vad_i18n.get('add_on_no_results', {})
|
1027
|
+
HoverInfoLabelWidget(vad_frame, text=no_results_i18n.get('label', '...'),
|
1028
|
+
tooltip=no_results_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
1029
|
+
ttk.Checkbutton(vad_frame, variable=self.add_audio_on_no_results_value, bootstyle="round-toggle").grid(
|
690
1030
|
row=self.current_row, column=1, sticky='W', pady=2)
|
691
1031
|
self.current_row += 1
|
692
1032
|
|
693
|
-
|
694
|
-
|
1033
|
+
end_offset_i18n = vad_i18n.get('audio_end_offset', {})
|
1034
|
+
HoverInfoLabelWidget(vad_frame, text=end_offset_i18n.get('label', '...'),
|
1035
|
+
tooltip=end_offset_i18n.get('tooltip', '...'), foreground="dark orange",
|
695
1036
|
font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
696
|
-
|
697
|
-
self.end_offset.insert(0, str(self.settings.audio.end_offset))
|
698
|
-
self.end_offset.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1037
|
+
ttk.Entry(vad_frame, textvariable=self.end_offset_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
699
1038
|
self.current_row += 1
|
700
1039
|
|
701
|
-
|
702
|
-
|
1040
|
+
trim_begin_i18n = vad_i18n.get('trim_beginning', {})
|
1041
|
+
HoverInfoLabelWidget(vad_frame, text=trim_begin_i18n.get('label', '...'),
|
1042
|
+
tooltip=trim_begin_i18n.get('tooltip', '...'),
|
703
1043
|
row=self.current_row, column=0)
|
704
|
-
self.
|
705
|
-
value=self.settings.vad.trim_beginning)
|
706
|
-
ttk.Checkbutton(vad_frame, variable=self.vad_trim_beginning, bootstyle="round-toggle").grid(
|
1044
|
+
ttk.Checkbutton(vad_frame, variable=self.vad_trim_beginning_value, bootstyle="round-toggle").grid(
|
707
1045
|
row=self.current_row, column=1, sticky='W', pady=2)
|
708
1046
|
|
709
|
-
|
710
|
-
|
1047
|
+
begin_offset_i18n = vad_i18n.get('beginning_offset', {})
|
1048
|
+
HoverInfoLabelWidget(vad_frame, text=begin_offset_i18n.get('label', '...'),
|
1049
|
+
tooltip=begin_offset_i18n.get('tooltip', '...'),
|
711
1050
|
row=self.current_row, column=2)
|
712
|
-
|
713
|
-
self.vad_beginning_offset.insert(0, str(self.settings.vad.beginning_offset))
|
714
|
-
self.vad_beginning_offset.grid(row=self.current_row, column=3, sticky='EW', pady=2)
|
1051
|
+
ttk.Entry(vad_frame, textvariable=self.vad_beginning_offset_value).grid(row=self.current_row, column=3, sticky='EW', pady=2)
|
715
1052
|
self.current_row += 1
|
716
1053
|
|
717
|
-
|
718
|
-
|
1054
|
+
splice_i18n = vad_i18n.get('cut_and_splice', {})
|
1055
|
+
HoverInfoLabelWidget(vad_frame, text=splice_i18n.get('label', '...'),
|
1056
|
+
tooltip=splice_i18n.get('tooltip', '...'),
|
719
1057
|
row=self.current_row, column=0)
|
720
|
-
self.
|
721
|
-
ttk.Checkbutton(vad_frame, variable=self.cut_and_splice_segments, bootstyle="round-toggle").grid(
|
1058
|
+
ttk.Checkbutton(vad_frame, variable=self.cut_and_splice_segments_value, bootstyle="round-toggle").grid(
|
722
1059
|
row=self.current_row, column=1, sticky='W', pady=2)
|
723
|
-
|
724
|
-
|
1060
|
+
|
1061
|
+
padding_i18n = vad_i18n.get('splice_padding', {})
|
1062
|
+
HoverInfoLabelWidget(vad_frame, text=padding_i18n.get('label', '...'),
|
1063
|
+
tooltip=padding_i18n.get('tooltip', '...'),
|
725
1064
|
row=self.current_row, column=2)
|
726
|
-
|
727
|
-
self.splice_padding.insert(0, str(self.settings.vad.splice_padding))
|
728
|
-
self.splice_padding.grid(row=self.current_row, column=3, sticky='EW', pady=2)
|
1065
|
+
ttk.Entry(vad_frame, textvariable=self.splice_padding_value).grid(row=self.current_row, column=3, sticky='EW', pady=2)
|
729
1066
|
self.current_row += 1
|
730
1067
|
|
731
1068
|
self.add_reset_button(vad_frame, "vad", self.current_row, 0, self.create_vad_tab)
|
732
1069
|
|
733
|
-
for col in range(5):
|
734
|
-
|
735
|
-
|
736
|
-
for row in range(self.current_row):
|
737
|
-
vad_frame.grid_rowconfigure(row, minsize=30)
|
1070
|
+
for col in range(5): vad_frame.grid_columnconfigure(col, weight=0)
|
1071
|
+
for row in range(self.current_row): vad_frame.grid_rowconfigure(row, minsize=30)
|
738
1072
|
|
739
1073
|
return vad_frame
|
740
1074
|
|
741
1075
|
@new_tab
|
742
1076
|
def create_paths_tab(self):
|
743
1077
|
if self.paths_tab is None:
|
1078
|
+
paths_i18n = self.i18n.get('tabs', {}).get('paths', {})
|
744
1079
|
self.paths_tab = ttk.Frame(self.notebook, padding=15)
|
745
|
-
self.notebook.add(self.paths_tab, text='Paths')
|
1080
|
+
self.notebook.add(self.paths_tab, text=paths_i18n.get('title', 'Paths'))
|
746
1081
|
else:
|
747
1082
|
for widget in self.paths_tab.winfo_children():
|
748
1083
|
widget.destroy()
|
749
1084
|
|
750
1085
|
paths_frame = self.paths_tab
|
1086
|
+
paths_i18n = self.i18n.get('tabs', {}).get('paths', {})
|
1087
|
+
browse_text = self.i18n.get('buttons', {}).get('browse', 'Browse')
|
751
1088
|
|
752
|
-
|
1089
|
+
watch_i18n = paths_i18n.get('folder_to_watch', {})
|
1090
|
+
HoverInfoLabelWidget(paths_frame, text=watch_i18n.get('label', '...'), tooltip=watch_i18n.get('tooltip', '...'),
|
753
1091
|
foreground="dark orange", font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
754
|
-
|
755
|
-
self.
|
756
|
-
|
757
|
-
|
758
|
-
bootstyle="outline").grid(
|
759
|
-
row=self.current_row,
|
760
|
-
column=2, padx=5, pady=2)
|
1092
|
+
folder_watch_entry = ttk.Entry(paths_frame, width=50, textvariable=self.folder_to_watch_value)
|
1093
|
+
folder_watch_entry.grid(row=self.current_row, column=1, sticky='W', pady=2)
|
1094
|
+
ttk.Button(paths_frame, text=browse_text, command=lambda: self.browse_folder(folder_watch_entry),
|
1095
|
+
bootstyle="outline").grid(row=self.current_row, column=2, padx=5, pady=2)
|
761
1096
|
self.current_row += 1
|
762
1097
|
|
763
|
-
|
1098
|
+
audio_dest_i18n = paths_i18n.get('audio_destination', {})
|
1099
|
+
HoverInfoLabelWidget(paths_frame, text=audio_dest_i18n.get('label', '...'), tooltip=audio_dest_i18n.get('tooltip', '...'),
|
764
1100
|
foreground="dark orange", font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
765
|
-
|
766
|
-
self.
|
767
|
-
|
768
|
-
|
769
|
-
bootstyle="outline").grid(
|
770
|
-
row=self.current_row,
|
771
|
-
column=2, padx=5, pady=2)
|
1101
|
+
audio_dest_entry = ttk.Entry(paths_frame, width=50, textvariable=self.audio_destination_value)
|
1102
|
+
audio_dest_entry.grid(row=self.current_row, column=1, sticky='W', pady=2)
|
1103
|
+
ttk.Button(paths_frame, text=browse_text, command=lambda: self.browse_folder(audio_dest_entry),
|
1104
|
+
bootstyle="outline").grid(row=self.current_row, column=2, padx=5, pady=2)
|
772
1105
|
self.current_row += 1
|
773
1106
|
|
774
|
-
|
775
|
-
|
1107
|
+
ss_dest_i18n = paths_i18n.get('screenshot_destination', {})
|
1108
|
+
HoverInfoLabelWidget(paths_frame, text=ss_dest_i18n.get('label', '...'),
|
1109
|
+
tooltip=ss_dest_i18n.get('tooltip', '...'), foreground="dark orange",
|
776
1110
|
font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
777
|
-
|
778
|
-
self.
|
779
|
-
|
780
|
-
|
781
|
-
bootstyle="outline").grid(
|
782
|
-
row=self.current_row, column=2, padx=5, pady=2)
|
1111
|
+
ss_dest_entry = ttk.Entry(paths_frame, width=50, textvariable=self.screenshot_destination_value)
|
1112
|
+
ss_dest_entry.grid(row=self.current_row, column=1, sticky='W', pady=2)
|
1113
|
+
ttk.Button(paths_frame, text=browse_text, command=lambda: self.browse_folder(ss_dest_entry),
|
1114
|
+
bootstyle="outline").grid(row=self.current_row, column=2, padx=5, pady=2)
|
783
1115
|
self.current_row += 1
|
784
1116
|
|
785
|
-
|
1117
|
+
rm_vid_i18n = paths_i18n.get('remove_video', {})
|
1118
|
+
HoverInfoLabelWidget(paths_frame, text=rm_vid_i18n.get('label', '...'), tooltip=rm_vid_i18n.get('tooltip', '...'),
|
786
1119
|
row=self.current_row, column=0)
|
787
|
-
self.
|
788
|
-
|
789
|
-
column=1, sticky='W',
|
790
|
-
pady=2)
|
1120
|
+
ttk.Checkbutton(paths_frame, variable=self.remove_video_value, bootstyle="round-toggle").grid(row=self.current_row,
|
1121
|
+
column=1, sticky='W', pady=2)
|
791
1122
|
self.current_row += 1
|
792
1123
|
|
793
|
-
|
1124
|
+
rm_audio_i18n = paths_i18n.get('remove_audio', {})
|
1125
|
+
HoverInfoLabelWidget(paths_frame, text=rm_audio_i18n.get('label', '...'), tooltip=rm_audio_i18n.get('tooltip', '...'),
|
794
1126
|
row=self.current_row, column=0)
|
795
|
-
self.
|
796
|
-
|
797
|
-
column=1, sticky='W',
|
798
|
-
pady=2)
|
1127
|
+
ttk.Checkbutton(paths_frame, variable=self.remove_audio_value, bootstyle="round-toggle").grid(row=self.current_row,
|
1128
|
+
column=1, sticky='W', pady=2)
|
799
1129
|
self.current_row += 1
|
800
1130
|
|
801
|
-
|
1131
|
+
rm_ss_i18n = paths_i18n.get('remove_screenshot', {})
|
1132
|
+
HoverInfoLabelWidget(paths_frame, text=rm_ss_i18n.get('label', '...'), tooltip=rm_ss_i18n.get('tooltip', '...'),
|
802
1133
|
row=self.current_row, column=0)
|
803
|
-
self.
|
804
|
-
ttk.Checkbutton(paths_frame, variable=self.remove_screenshot, bootstyle="round-toggle").grid(
|
1134
|
+
ttk.Checkbutton(paths_frame, variable=self.remove_screenshot_value, bootstyle="round-toggle").grid(
|
805
1135
|
row=self.current_row, column=1, sticky='W', pady=2)
|
806
1136
|
self.current_row += 1
|
807
1137
|
|
808
1138
|
self.add_reset_button(paths_frame, "paths", self.current_row, 0, self.create_paths_tab)
|
809
1139
|
|
810
|
-
paths_frame.grid_columnconfigure(
|
811
|
-
paths_frame.
|
812
|
-
paths_frame.grid_columnconfigure(2, weight=0)
|
813
|
-
|
814
|
-
for row in range(self.current_row):
|
815
|
-
paths_frame.grid_rowconfigure(row, minsize=30)
|
1140
|
+
for col in range(3): paths_frame.grid_columnconfigure(col, weight=0)
|
1141
|
+
for row in range(self.current_row): paths_frame.grid_rowconfigure(row, minsize=30)
|
816
1142
|
|
817
1143
|
return paths_frame
|
818
1144
|
|
819
1145
|
def browse_file(self, entry_widget):
|
820
1146
|
file_selected = filedialog.askopenfilename()
|
821
1147
|
if file_selected:
|
1148
|
+
# The entry widget's textvariable will be updated automatically
|
822
1149
|
entry_widget.delete(0, tk.END)
|
823
1150
|
entry_widget.insert(0, file_selected)
|
824
1151
|
|
825
1152
|
def browse_folder(self, entry_widget):
|
826
1153
|
folder_selected = filedialog.askdirectory()
|
827
1154
|
if folder_selected:
|
1155
|
+
# The entry widget's textvariable will be updated automatically
|
828
1156
|
entry_widget.delete(0, tk.END)
|
829
1157
|
entry_widget.insert(0, folder_selected)
|
830
1158
|
|
831
1159
|
@new_tab
|
832
1160
|
def create_anki_tab(self):
|
833
1161
|
if self.anki_tab is None:
|
1162
|
+
anki_i18n = self.i18n.get('tabs', {}).get('anki', {})
|
834
1163
|
self.anki_tab = ttk.Frame(self.notebook, padding=15)
|
835
|
-
self.notebook.add(self.anki_tab, text='Anki')
|
1164
|
+
self.notebook.add(self.anki_tab, text=anki_i18n.get('title', 'Anki'))
|
836
1165
|
else:
|
837
1166
|
for widget in self.anki_tab.winfo_children():
|
838
1167
|
widget.destroy()
|
839
1168
|
|
840
1169
|
anki_frame = self.anki_tab
|
1170
|
+
anki_i18n = self.i18n.get('tabs', {}).get('anki', {})
|
841
1171
|
|
842
|
-
|
1172
|
+
update_i18n = anki_i18n.get('update_anki', {})
|
1173
|
+
HoverInfoLabelWidget(anki_frame, text=update_i18n.get('label', '...'), tooltip=update_i18n.get('tooltip', '...'),
|
843
1174
|
row=self.current_row, column=0)
|
844
|
-
self.
|
845
|
-
|
846
|
-
column=1, sticky='W',
|
847
|
-
pady=2)
|
1175
|
+
ttk.Checkbutton(anki_frame, variable=self.update_anki_value, bootstyle="round-toggle").grid(row=self.current_row,
|
1176
|
+
column=1, sticky='W', pady=2)
|
848
1177
|
self.current_row += 1
|
849
1178
|
|
850
|
-
|
1179
|
+
url_i18n = anki_i18n.get('url', {})
|
1180
|
+
HoverInfoLabelWidget(anki_frame, text=url_i18n.get('label', '...'), tooltip=url_i18n.get('tooltip', '...'),
|
851
1181
|
foreground="dark orange", font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
852
|
-
|
853
|
-
self.anki_url.insert(0, self.settings.anki.url)
|
854
|
-
self.anki_url.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1182
|
+
ttk.Entry(anki_frame, width=50, textvariable=self.anki_url_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
855
1183
|
self.current_row += 1
|
856
1184
|
|
857
|
-
|
1185
|
+
sentence_i18n = anki_i18n.get('sentence_field', {})
|
1186
|
+
HoverInfoLabelWidget(anki_frame, text=sentence_i18n.get('label', '...'), tooltip=sentence_i18n.get('tooltip', '...'),
|
858
1187
|
foreground="dark orange", font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
859
|
-
|
860
|
-
self.sentence_field.insert(0, self.settings.anki.sentence_field)
|
861
|
-
self.sentence_field.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1188
|
+
ttk.Entry(anki_frame, textvariable=self.sentence_field_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
862
1189
|
self.current_row += 1
|
863
1190
|
|
864
|
-
|
865
|
-
|
1191
|
+
audio_i18n = anki_i18n.get('sentence_audio_field', {})
|
1192
|
+
HoverInfoLabelWidget(anki_frame, text=audio_i18n.get('label', '...'),
|
1193
|
+
tooltip=audio_i18n.get('tooltip', '...'),
|
866
1194
|
foreground="dark orange", font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
867
|
-
|
868
|
-
self.sentence_audio_field.insert(0, self.settings.anki.sentence_audio_field)
|
869
|
-
self.sentence_audio_field.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1195
|
+
ttk.Entry(anki_frame, textvariable=self.sentence_audio_field_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
870
1196
|
self.current_row += 1
|
871
1197
|
|
872
|
-
|
1198
|
+
pic_i18n = anki_i18n.get('picture_field', {})
|
1199
|
+
HoverInfoLabelWidget(anki_frame, text=pic_i18n.get('label', '...'), tooltip=pic_i18n.get('tooltip', '...'),
|
873
1200
|
foreground="dark orange", font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
874
|
-
|
875
|
-
self.picture_field.insert(0, self.settings.anki.picture_field)
|
876
|
-
self.picture_field.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1201
|
+
ttk.Entry(anki_frame, textvariable=self.picture_field_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
877
1202
|
self.current_row += 1
|
878
1203
|
|
879
|
-
|
1204
|
+
word_i18n = anki_i18n.get('word_field', {})
|
1205
|
+
HoverInfoLabelWidget(anki_frame, text=word_i18n.get('label', '...'), tooltip=word_i18n.get('tooltip', '...'),
|
880
1206
|
foreground="dark orange", font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
881
|
-
|
882
|
-
self.word_field.insert(0, self.settings.anki.word_field)
|
883
|
-
self.word_field.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1207
|
+
ttk.Entry(anki_frame, textvariable=self.word_field_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
884
1208
|
self.current_row += 1
|
885
1209
|
|
886
|
-
|
887
|
-
|
1210
|
+
prev_sent_i18n = anki_i18n.get('previous_sentence_field', {})
|
1211
|
+
HoverInfoLabelWidget(anki_frame, text=prev_sent_i18n.get('label', '...'),
|
1212
|
+
tooltip=prev_sent_i18n.get('tooltip', '...'),
|
888
1213
|
row=self.current_row, column=0)
|
889
|
-
|
890
|
-
self.previous_sentence_field.insert(0, self.settings.anki.previous_sentence_field)
|
891
|
-
self.previous_sentence_field.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1214
|
+
ttk.Entry(anki_frame, textvariable=self.previous_sentence_field_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
892
1215
|
self.current_row += 1
|
893
1216
|
|
894
|
-
|
895
|
-
|
1217
|
+
prev_img_i18n = anki_i18n.get('previous_image_field', {})
|
1218
|
+
HoverInfoLabelWidget(anki_frame, text=prev_img_i18n.get('label', '...'),
|
1219
|
+
tooltip=prev_img_i18n.get('tooltip', '...'),
|
896
1220
|
row=self.current_row, column=0)
|
897
|
-
|
898
|
-
self.previous_image_field.insert(0, self.settings.anki.previous_image_field)
|
899
|
-
self.previous_image_field.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1221
|
+
ttk.Entry(anki_frame, textvariable=self.previous_image_field_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
900
1222
|
self.current_row += 1
|
901
1223
|
|
902
|
-
|
1224
|
+
tags_i18n = anki_i18n.get('custom_tags', {})
|
1225
|
+
HoverInfoLabelWidget(anki_frame, text=tags_i18n.get('label', '...'), tooltip=tags_i18n.get('tooltip', '...'),
|
903
1226
|
row=self.current_row, column=0)
|
904
|
-
|
905
|
-
self.custom_tags.insert(0, ', '.join(self.settings.anki.custom_tags))
|
906
|
-
self.custom_tags.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1227
|
+
ttk.Entry(anki_frame, width=50, textvariable=self.custom_tags_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
907
1228
|
self.current_row += 1
|
908
1229
|
|
909
|
-
|
910
|
-
|
1230
|
+
tags_check_i18n = anki_i18n.get('tags_to_check', {})
|
1231
|
+
HoverInfoLabelWidget(anki_frame, text=tags_check_i18n.get('label', '...'),
|
1232
|
+
tooltip=tags_check_i18n.get('tooltip', '...'),
|
911
1233
|
foreground="green", font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
912
|
-
|
913
|
-
self.tags_to_check.insert(0, ', '.join(self.settings.anki.tags_to_check))
|
914
|
-
self.tags_to_check.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1234
|
+
ttk.Entry(anki_frame, width=50, textvariable=self.tags_to_check_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
915
1235
|
self.current_row += 1
|
916
1236
|
|
917
|
-
|
918
|
-
|
1237
|
+
game_tag_i18n = anki_i18n.get('add_game_tag', {})
|
1238
|
+
HoverInfoLabelWidget(anki_frame, text=game_tag_i18n.get('label', '...'),
|
1239
|
+
tooltip=game_tag_i18n.get('tooltip', '...'), foreground="green",
|
919
1240
|
font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
920
|
-
self.
|
921
|
-
|
922
|
-
column=1, sticky='W',
|
923
|
-
pady=2)
|
924
|
-
|
1241
|
+
ttk.Checkbutton(anki_frame, variable=self.add_game_tag_value, bootstyle="round-toggle").grid(row=self.current_row,
|
1242
|
+
column=1, sticky='W', pady=2)
|
925
1243
|
self.current_row += 1
|
926
1244
|
|
927
|
-
|
1245
|
+
parent_tag_i18n = anki_i18n.get('parent_tag', {})
|
1246
|
+
HoverInfoLabelWidget(anki_frame, text=parent_tag_i18n.get('label', '...'),
|
928
1247
|
foreground="green", font=("Helvetica", 10, "bold"),
|
929
|
-
tooltip=
|
1248
|
+
tooltip=parent_tag_i18n.get('tooltip', '...'),
|
930
1249
|
row=self.current_row, column=0)
|
931
|
-
|
932
|
-
self.parent_tag.insert(0, self.settings.anki.parent_tag)
|
933
|
-
self.parent_tag.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
934
|
-
|
1250
|
+
ttk.Entry(anki_frame, width=50, textvariable=self.parent_tag_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
935
1251
|
self.current_row += 1
|
936
1252
|
|
937
|
-
|
1253
|
+
ow_audio_i18n = anki_i18n.get('overwrite_audio', {})
|
1254
|
+
HoverInfoLabelWidget(anki_frame, text=ow_audio_i18n.get('label', '...'), tooltip=ow_audio_i18n.get('tooltip', '...'),
|
938
1255
|
row=self.current_row, column=0)
|
939
|
-
self.
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
tooltip="Overwrite existing pictures in Anki cards.", row=self.current_row, column=0)
|
948
|
-
self.overwrite_picture = tk.BooleanVar(
|
949
|
-
value=self.settings.anki.overwrite_picture)
|
950
|
-
ttk.Checkbutton(anki_frame, variable=self.overwrite_picture, bootstyle="round-toggle").grid(
|
1256
|
+
ttk.Checkbutton(anki_frame, variable=self.overwrite_audio_value, bootstyle="round-toggle").grid(row=self.current_row,
|
1257
|
+
column=1, sticky='W', pady=2)
|
1258
|
+
self.current_row += 1
|
1259
|
+
|
1260
|
+
ow_pic_i18n = anki_i18n.get('overwrite_picture', {})
|
1261
|
+
HoverInfoLabelWidget(anki_frame, text=ow_pic_i18n.get('label', '...'),
|
1262
|
+
tooltip=ow_pic_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
1263
|
+
ttk.Checkbutton(anki_frame, variable=self.overwrite_picture_value, bootstyle="round-toggle").grid(
|
951
1264
|
row=self.current_row, column=1, sticky='W', pady=2)
|
952
1265
|
self.current_row += 1
|
953
1266
|
|
954
|
-
|
955
|
-
|
1267
|
+
multi_ow_i18n = anki_i18n.get('multi_overwrites_sentence', {})
|
1268
|
+
HoverInfoLabelWidget(anki_frame, text=multi_ow_i18n.get('label', '...'),
|
1269
|
+
tooltip=multi_ow_i18n.get('tooltip', '...'),
|
956
1270
|
row=self.current_row, column=0)
|
957
|
-
self.
|
958
|
-
value=self.settings.anki.multi_overwrites_sentence)
|
959
|
-
ttk.Checkbutton(anki_frame, variable=self.multi_overwrites_sentence, bootstyle="round-toggle").grid(
|
1271
|
+
ttk.Checkbutton(anki_frame, variable=self.multi_overwrites_sentence_value, bootstyle="round-toggle").grid(
|
960
1272
|
row=self.current_row, column=1, sticky='W', pady=2)
|
961
1273
|
self.current_row += 1
|
962
1274
|
|
963
1275
|
self.add_reset_button(anki_frame, "anki", self.current_row, 0, self.create_anki_tab)
|
964
1276
|
|
965
|
-
anki_frame.grid_columnconfigure(
|
966
|
-
anki_frame.
|
967
|
-
|
968
|
-
for row in range(self.current_row):
|
969
|
-
anki_frame.grid_rowconfigure(row, minsize=30)
|
1277
|
+
for col in range(2): anki_frame.grid_columnconfigure(col, weight=0)
|
1278
|
+
for row in range(self.current_row): anki_frame.grid_rowconfigure(row, minsize=30)
|
970
1279
|
|
971
1280
|
return anki_frame
|
972
1281
|
|
973
1282
|
def on_profiles_tab_selected(self, event):
|
974
1283
|
try:
|
975
|
-
|
1284
|
+
profiles_i18n = self.i18n.get('tabs', {}).get('profiles', {})
|
1285
|
+
if self.window.state() != "withdrawn" and self.notebook.tab(self.notebook.select(), "text") == profiles_i18n.get('title', 'Profiles'):
|
976
1286
|
self.refresh_obs_scenes()
|
977
1287
|
except Exception as e:
|
978
1288
|
logger.debug(e)
|
@@ -980,342 +1290,305 @@ class ConfigApp:
|
|
980
1290
|
@new_tab
|
981
1291
|
def create_features_tab(self):
|
982
1292
|
if self.features_tab is None:
|
1293
|
+
features_i18n = self.i18n.get('tabs', {}).get('features', {})
|
983
1294
|
self.features_tab = ttk.Frame(self.notebook, padding=15)
|
984
|
-
self.notebook.add(self.features_tab, text='Features')
|
1295
|
+
self.notebook.add(self.features_tab, text=features_i18n.get('title', 'Features'))
|
985
1296
|
else:
|
986
1297
|
for widget in self.features_tab.winfo_children():
|
987
1298
|
widget.destroy()
|
988
1299
|
|
989
1300
|
features_frame = self.features_tab
|
1301
|
+
features_i18n = self.i18n.get('tabs', {}).get('features', {})
|
990
1302
|
|
991
|
-
|
1303
|
+
notify_i18n = features_i18n.get('notify_on_update', {})
|
1304
|
+
HoverInfoLabelWidget(features_frame, text=notify_i18n.get('label', '...'), tooltip=notify_i18n.get('tooltip', '...'),
|
992
1305
|
row=self.current_row, column=0)
|
993
|
-
self.
|
994
|
-
ttk.Checkbutton(features_frame, variable=self.notify_on_update, bootstyle="round-toggle").grid(
|
1306
|
+
ttk.Checkbutton(features_frame, variable=self.notify_on_update_value, bootstyle="round-toggle").grid(
|
995
1307
|
row=self.current_row, column=1, sticky='W', pady=2)
|
996
1308
|
self.current_row += 1
|
997
1309
|
|
998
|
-
|
999
|
-
|
1000
|
-
column=0)
|
1001
|
-
self.
|
1002
|
-
ttk.Checkbutton(features_frame, variable=self.open_anki_edit, bootstyle="round-toggle").grid(
|
1310
|
+
open_edit_i18n = features_i18n.get('open_anki_edit', {})
|
1311
|
+
HoverInfoLabelWidget(features_frame, text=open_edit_i18n.get('label', '...'),
|
1312
|
+
tooltip=open_edit_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
1313
|
+
ttk.Checkbutton(features_frame, variable=self.open_anki_edit_value, bootstyle="round-toggle").grid(
|
1003
1314
|
row=self.current_row, column=1, sticky='W', pady=2)
|
1004
1315
|
self.current_row += 1
|
1005
1316
|
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
ttk.Checkbutton(features_frame, variable=self.
|
1317
|
+
open_browser_i18n = features_i18n.get('open_anki_browser', {})
|
1318
|
+
HoverInfoLabelWidget(features_frame, text=open_browser_i18n.get('label', '...'),
|
1319
|
+
tooltip=open_browser_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
1320
|
+
ttk.Checkbutton(features_frame, variable=self.open_anki_browser_value, bootstyle="round-toggle").grid(
|
1010
1321
|
row=self.current_row, column=1, sticky='W', pady=2)
|
1011
1322
|
self.current_row += 1
|
1012
1323
|
|
1013
|
-
|
1014
|
-
|
1324
|
+
query_i18n = features_i18n.get('browser_query', {})
|
1325
|
+
HoverInfoLabelWidget(features_frame, text=query_i18n.get('label', '...'),
|
1326
|
+
tooltip=query_i18n.get('tooltip', '...'),
|
1015
1327
|
row=self.current_row, column=0)
|
1016
|
-
|
1017
|
-
self.browser_query.insert(0, self.settings.features.browser_query)
|
1018
|
-
self.browser_query.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1328
|
+
ttk.Entry(features_frame, width=50, textvariable=self.browser_query_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1019
1329
|
self.current_row += 1
|
1020
1330
|
|
1021
|
-
|
1331
|
+
backfill_i18n = features_i18n.get('backfill_audio', {})
|
1332
|
+
HoverInfoLabelWidget(features_frame, text=backfill_i18n.get('label', '...'), tooltip=backfill_i18n.get('tooltip', '...'),
|
1022
1333
|
row=self.current_row, column=0)
|
1023
|
-
self.
|
1024
|
-
ttk.Checkbutton(features_frame, variable=self.backfill_audio, bootstyle="round-toggle").grid(
|
1334
|
+
ttk.Checkbutton(features_frame, variable=self.backfill_audio_value, bootstyle="round-toggle").grid(
|
1025
1335
|
row=self.current_row, column=1, sticky='W', pady=2)
|
1026
1336
|
self.current_row += 1
|
1027
1337
|
|
1028
|
-
|
1338
|
+
full_auto_i18n = features_i18n.get('full_auto', {})
|
1339
|
+
HoverInfoLabelWidget(features_frame, text=full_auto_i18n.get('label', '...'), tooltip=full_auto_i18n.get('tooltip', '...'),
|
1029
1340
|
row=self.current_row, column=0)
|
1030
|
-
self.
|
1031
|
-
|
1032
|
-
ttk.Checkbutton(features_frame, variable=self.full_auto, bootstyle="round-toggle").grid(row=self.current_row,
|
1033
|
-
column=1, sticky='W',
|
1034
|
-
pady=2)
|
1341
|
+
ttk.Checkbutton(features_frame, variable=self.full_auto_value, bootstyle="round-toggle").grid(row=self.current_row,
|
1342
|
+
column=1, sticky='W', pady=2)
|
1035
1343
|
self.current_row += 1
|
1036
1344
|
|
1037
1345
|
self.add_reset_button(features_frame, "features", self.current_row, 0, self.create_features_tab)
|
1038
1346
|
|
1039
|
-
for col in range(3):
|
1040
|
-
|
1041
|
-
|
1042
|
-
for row in range(self.current_row):
|
1043
|
-
features_frame.grid_rowconfigure(row, minsize=30)
|
1347
|
+
for col in range(3): features_frame.grid_columnconfigure(col, weight=0)
|
1348
|
+
for row in range(self.current_row): features_frame.grid_rowconfigure(row, minsize=30)
|
1044
1349
|
|
1045
1350
|
return features_frame
|
1046
1351
|
|
1047
1352
|
@new_tab
|
1048
1353
|
def create_screenshot_tab(self):
|
1049
1354
|
if self.screenshot_tab is None:
|
1355
|
+
ss_i18n = self.i18n.get('tabs', {}).get('screenshot', {})
|
1050
1356
|
self.screenshot_tab = ttk.Frame(self.notebook, padding=15)
|
1051
|
-
self.notebook.add(self.screenshot_tab, text='Screenshot')
|
1357
|
+
self.notebook.add(self.screenshot_tab, text=ss_i18n.get('title', 'Screenshot'))
|
1052
1358
|
else:
|
1053
1359
|
for widget in self.screenshot_tab.winfo_children():
|
1054
1360
|
widget.destroy()
|
1055
1361
|
|
1056
1362
|
screenshot_frame = self.screenshot_tab
|
1363
|
+
ss_i18n = self.i18n.get('tabs', {}).get('screenshot', {})
|
1057
1364
|
|
1058
|
-
|
1365
|
+
enabled_i18n = ss_i18n.get('enabled', {})
|
1366
|
+
HoverInfoLabelWidget(screenshot_frame, text=enabled_i18n.get('label', '...'), tooltip=enabled_i18n.get('tooltip', '...'),
|
1059
1367
|
row=self.current_row, column=0)
|
1060
|
-
self.
|
1061
|
-
ttk.Checkbutton(screenshot_frame, variable=self.screenshot_enabled, bootstyle="round-toggle").grid(
|
1368
|
+
ttk.Checkbutton(screenshot_frame, variable=self.screenshot_enabled_value, bootstyle="round-toggle").grid(
|
1062
1369
|
row=self.current_row, column=1, sticky='W', pady=2)
|
1063
1370
|
self.current_row += 1
|
1064
1371
|
|
1065
|
-
|
1372
|
+
width_i18n = ss_i18n.get('width', {})
|
1373
|
+
HoverInfoLabelWidget(screenshot_frame, text=width_i18n.get('label', '...'), tooltip=width_i18n.get('tooltip', '...'),
|
1066
1374
|
row=self.current_row, column=0)
|
1067
|
-
|
1068
|
-
self.screenshot_width.insert(0, str(self.settings.screenshot.width))
|
1069
|
-
self.screenshot_width.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1375
|
+
ttk.Entry(screenshot_frame, textvariable=self.screenshot_width_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1070
1376
|
self.current_row += 1
|
1071
1377
|
|
1072
|
-
|
1378
|
+
height_i18n = ss_i18n.get('height', {})
|
1379
|
+
HoverInfoLabelWidget(screenshot_frame, text=height_i18n.get('label', '...'), tooltip=height_i18n.get('tooltip', '...'),
|
1073
1380
|
row=self.current_row, column=0)
|
1074
|
-
|
1075
|
-
self.screenshot_height.insert(0, str(self.settings.screenshot.height))
|
1076
|
-
self.screenshot_height.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1381
|
+
ttk.Entry(screenshot_frame, textvariable=self.screenshot_height_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1077
1382
|
self.current_row += 1
|
1078
1383
|
|
1079
|
-
|
1384
|
+
quality_i18n = ss_i18n.get('quality', {})
|
1385
|
+
HoverInfoLabelWidget(screenshot_frame, text=quality_i18n.get('label', '...'), tooltip=quality_i18n.get('tooltip', '...'),
|
1080
1386
|
row=self.current_row, column=0)
|
1081
|
-
|
1082
|
-
self.screenshot_quality.insert(0, str(self.settings.screenshot.quality))
|
1083
|
-
self.screenshot_quality.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1387
|
+
ttk.Entry(screenshot_frame, textvariable=self.screenshot_quality_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1084
1388
|
self.current_row += 1
|
1085
1389
|
|
1086
|
-
|
1390
|
+
ext_i18n = ss_i18n.get('extension', {})
|
1391
|
+
HoverInfoLabelWidget(screenshot_frame, text=ext_i18n.get('label', '...'), tooltip=ext_i18n.get('tooltip', '...'),
|
1087
1392
|
row=self.current_row, column=0)
|
1088
|
-
|
1089
|
-
state="readonly")
|
1090
|
-
self.screenshot_extension.set(self.settings.screenshot.extension)
|
1091
|
-
self.screenshot_extension.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1393
|
+
ttk.Combobox(screenshot_frame, textvariable=self.screenshot_extension_value, values=['webp', 'avif', 'png', 'jpeg'],
|
1394
|
+
state="readonly").grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1092
1395
|
self.current_row += 1
|
1093
1396
|
|
1094
|
-
|
1095
|
-
|
1397
|
+
ffmpeg_i18n = ss_i18n.get('ffmpeg_options', {})
|
1398
|
+
HoverInfoLabelWidget(screenshot_frame, text=ffmpeg_i18n.get('label', '...'),
|
1399
|
+
tooltip=ffmpeg_i18n.get('tooltip', '...'), foreground="red",
|
1096
1400
|
font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
1097
|
-
|
1098
|
-
self.screenshot_custom_ffmpeg_settings.insert(0, self.settings.screenshot.custom_ffmpeg_settings)
|
1099
|
-
self.screenshot_custom_ffmpeg_settings.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1401
|
+
ttk.Entry(screenshot_frame, width=50, textvariable=self.screenshot_custom_ffmpeg_settings_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1100
1402
|
self.current_row += 1
|
1101
1403
|
|
1102
|
-
|
1103
|
-
|
1404
|
+
timing_i18n = ss_i18n.get('timing', {})
|
1405
|
+
HoverInfoLabelWidget(screenshot_frame, text=timing_i18n.get('label', '...'),
|
1406
|
+
tooltip=timing_i18n.get('tooltip', '...'),
|
1104
1407
|
row=self.current_row, column=0)
|
1105
|
-
|
1106
|
-
self.screenshot_timing.set(self.settings.screenshot.screenshot_timing_setting)
|
1107
|
-
self.screenshot_timing.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1408
|
+
ttk.Combobox(screenshot_frame, textvariable=self.screenshot_timing_value, values=['beginning', 'middle', 'end'], state="readonly").grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1108
1409
|
self.current_row += 1
|
1109
1410
|
|
1110
|
-
|
1111
|
-
|
1411
|
+
offset_i18n = ss_i18n.get('offset', {})
|
1412
|
+
HoverInfoLabelWidget(screenshot_frame, text=offset_i18n.get('label', '...'),
|
1413
|
+
tooltip=offset_i18n.get('tooltip', '...'),
|
1112
1414
|
foreground="dark orange", font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
1113
|
-
|
1114
|
-
self.seconds_after_line.insert(0, str(self.settings.screenshot.seconds_after_line))
|
1115
|
-
self.seconds_after_line.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1415
|
+
ttk.Entry(screenshot_frame, textvariable=self.seconds_after_line_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1116
1416
|
self.current_row += 1
|
1117
1417
|
|
1118
|
-
|
1119
|
-
|
1418
|
+
selector_i18n = ss_i18n.get('use_selector', {})
|
1419
|
+
HoverInfoLabelWidget(screenshot_frame, text=selector_i18n.get('label', '...'),
|
1420
|
+
tooltip=selector_i18n.get('tooltip', '...'),
|
1120
1421
|
row=self.current_row, column=0)
|
1121
|
-
self.
|
1122
|
-
ttk.Checkbutton(screenshot_frame, variable=self.use_screenshot_selector, bootstyle="round-toggle").grid(
|
1422
|
+
ttk.Checkbutton(screenshot_frame, variable=self.use_screenshot_selector_value, bootstyle="round-toggle").grid(
|
1123
1423
|
row=self.current_row, column=1, sticky='W', pady=2)
|
1124
1424
|
self.current_row += 1
|
1125
1425
|
|
1126
|
-
|
1426
|
+
hotkey_i18n = ss_i18n.get('hotkey', {})
|
1427
|
+
HoverInfoLabelWidget(screenshot_frame, text=hotkey_i18n.get('label', '...'), tooltip=hotkey_i18n.get('tooltip', '...'),
|
1127
1428
|
row=self.current_row, column=0)
|
1128
|
-
|
1129
|
-
self.take_screenshot_hotkey.insert(0, self.settings.hotkeys.take_screenshot)
|
1130
|
-
self.take_screenshot_hotkey.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1429
|
+
ttk.Entry(screenshot_frame, textvariable=self.take_screenshot_hotkey_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1131
1430
|
self.current_row += 1
|
1132
1431
|
|
1133
|
-
|
1134
|
-
|
1432
|
+
hotkey_update_i18n = ss_i18n.get('hotkey_updates_anki', {})
|
1433
|
+
HoverInfoLabelWidget(screenshot_frame, text=hotkey_update_i18n.get('label', '...'),
|
1434
|
+
tooltip=hotkey_update_i18n.get('tooltip', '...'),
|
1135
1435
|
row=self.current_row, column=0)
|
1136
|
-
self.
|
1137
|
-
value=self.settings.screenshot.screenshot_hotkey_updates_anki)
|
1138
|
-
ttk.Checkbutton(screenshot_frame, variable=self.screenshot_hotkey_update_anki, bootstyle="round-toggle").grid(
|
1436
|
+
ttk.Checkbutton(screenshot_frame, variable=self.screenshot_hotkey_update_anki_value, bootstyle="round-toggle").grid(
|
1139
1437
|
row=self.current_row, column=1, sticky='W', pady=2)
|
1140
1438
|
self.current_row += 1
|
1141
1439
|
|
1142
1440
|
self.add_reset_button(screenshot_frame, "screenshot", self.current_row, 0, self.create_screenshot_tab)
|
1143
1441
|
|
1144
|
-
for col in range(3):
|
1145
|
-
|
1146
|
-
|
1147
|
-
for row in range(self.current_row):
|
1148
|
-
screenshot_frame.grid_rowconfigure(row, minsize=30)
|
1442
|
+
for col in range(3): screenshot_frame.grid_columnconfigure(col, weight=0)
|
1443
|
+
for row in range(self.current_row): screenshot_frame.grid_rowconfigure(row, minsize=30)
|
1149
1444
|
|
1150
1445
|
return screenshot_frame
|
1151
1446
|
|
1152
1447
|
def update_audio_ffmpeg_settings(self, event):
|
1153
1448
|
selected_option = self.ffmpeg_audio_preset_options.get()
|
1154
1449
|
if selected_option in self.ffmpeg_audio_preset_options_map:
|
1155
|
-
self.
|
1156
|
-
self.audio_ffmpeg_reencode_options.insert(0, self.ffmpeg_audio_preset_options_map[selected_option])
|
1450
|
+
self.audio_ffmpeg_reencode_options_value.set(self.ffmpeg_audio_preset_options_map[selected_option])
|
1157
1451
|
else:
|
1158
|
-
self.
|
1159
|
-
self.audio_ffmpeg_reencode_options.insert(0, "")
|
1452
|
+
self.audio_ffmpeg_reencode_options_value.set("")
|
1160
1453
|
|
1161
1454
|
@new_tab
|
1162
1455
|
def create_audio_tab(self):
|
1163
1456
|
if self.audio_tab is None:
|
1457
|
+
audio_i18n = self.i18n.get('tabs', {}).get('audio', {})
|
1164
1458
|
self.audio_tab = ttk.Frame(self.notebook, padding=15)
|
1165
|
-
self.notebook.add(self.audio_tab, text='Audio')
|
1459
|
+
self.notebook.add(self.audio_tab, text=audio_i18n.get('title', 'Audio'))
|
1166
1460
|
else:
|
1167
1461
|
for widget in self.audio_tab.winfo_children():
|
1168
1462
|
widget.destroy()
|
1169
1463
|
|
1170
1464
|
audio_frame = self.audio_tab
|
1465
|
+
audio_i18n = self.i18n.get('tabs', {}).get('audio', {})
|
1171
1466
|
|
1172
|
-
|
1467
|
+
enabled_i18n = audio_i18n.get('enabled', {})
|
1468
|
+
HoverInfoLabelWidget(audio_frame, text=enabled_i18n.get('label', '...'), tooltip=enabled_i18n.get('tooltip', '...'),
|
1173
1469
|
row=self.current_row, column=0)
|
1174
|
-
self.
|
1175
|
-
|
1176
|
-
column=1, sticky='W',
|
1177
|
-
pady=2)
|
1470
|
+
ttk.Checkbutton(audio_frame, variable=self.audio_enabled_value, bootstyle="round-toggle").grid(row=self.current_row,
|
1471
|
+
column=1, sticky='W', pady=2)
|
1178
1472
|
self.current_row += 1
|
1179
1473
|
|
1180
|
-
|
1474
|
+
ext_i18n = audio_i18n.get('extension', {})
|
1475
|
+
HoverInfoLabelWidget(audio_frame, text=ext_i18n.get('label', '...'), tooltip=ext_i18n.get('tooltip', '...'),
|
1181
1476
|
row=self.current_row, column=0)
|
1182
|
-
|
1183
|
-
self.audio_extension.set(self.settings.audio.extension)
|
1184
|
-
self.audio_extension.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1477
|
+
ttk.Combobox(audio_frame, textvariable=self.audio_extension_value, values=['opus', 'mp3', 'ogg', 'aac', 'm4a'], state="readonly").grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1185
1478
|
self.current_row += 1
|
1186
1479
|
|
1187
|
-
|
1188
|
-
|
1480
|
+
begin_offset_i18n = audio_i18n.get('beginning_offset', {})
|
1481
|
+
HoverInfoLabelWidget(audio_frame, text=begin_offset_i18n.get('label', '...'),
|
1482
|
+
tooltip=begin_offset_i18n.get('tooltip', '...'),
|
1189
1483
|
foreground="dark orange", font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
1190
|
-
|
1191
|
-
self.beginning_offset.insert(0, str(self.settings.audio.beginning_offset))
|
1192
|
-
self.beginning_offset.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1193
|
-
|
1194
|
-
ttk.Button(audio_frame, text="Find Offset (WIP)", command=self.call_audio_offset_selector,
|
1195
|
-
bootstyle="info").grid(
|
1196
|
-
row=self.current_row, column=2, sticky='EW', pady=2, padx=5)
|
1484
|
+
ttk.Entry(audio_frame, textvariable=self.beginning_offset_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1197
1485
|
|
1486
|
+
ttk.Button(audio_frame, text=audio_i18n.get('find_offset_button', 'Find Offset (WIP)'), command=self.call_audio_offset_selector,
|
1487
|
+
bootstyle="info").grid(row=self.current_row, column=2, sticky='EW', pady=2, padx=5)
|
1198
1488
|
self.current_row += 1
|
1199
1489
|
|
1200
|
-
|
1201
|
-
|
1490
|
+
end_offset_i18n = audio_i18n.get('end_offset', {})
|
1491
|
+
HoverInfoLabelWidget(audio_frame, text=end_offset_i18n.get('label', '...'),
|
1492
|
+
tooltip=end_offset_i18n.get('tooltip', '...'),
|
1202
1493
|
foreground="red", font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
1203
|
-
|
1204
|
-
self.pre_vad_audio_offset.insert(0, str(self.settings.audio.pre_vad_end_offset))
|
1205
|
-
self.pre_vad_audio_offset.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1494
|
+
ttk.Entry(audio_frame, textvariable=self.pre_vad_audio_offset_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1206
1495
|
self.current_row += 1
|
1207
1496
|
|
1208
|
-
|
1209
|
-
|
1210
|
-
column=0)
|
1497
|
+
ffmpeg_preset_i18n = audio_i18n.get('ffmpeg_preset', {})
|
1498
|
+
HoverInfoLabelWidget(audio_frame, text=ffmpeg_preset_i18n.get('label', '...'),
|
1499
|
+
tooltip=ffmpeg_preset_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
1211
1500
|
|
1212
|
-
|
1501
|
+
preset_options_i18n = ffmpeg_preset_i18n.get('options', {})
|
1213
1502
|
self.ffmpeg_audio_preset_options_map = {
|
1214
|
-
"No Re-encode": "",
|
1215
|
-
"Simple Fade-in
|
1216
|
-
"Simple loudness
|
1217
|
-
"Downmix to mono
|
1218
|
-
"Downmix to mono, 30kbps
|
1219
|
-
"Custom": get_config().audio.custom_encode_settings,
|
1503
|
+
preset_options_i18n.get('no_reencode', "No Re-encode"): "",
|
1504
|
+
preset_options_i18n.get('fade_in', "Simple Fade-in..."): "-c:a {encoder} -f {format} -af \"afade=t=in:d=0.10\"",
|
1505
|
+
preset_options_i18n.get('loudness_norm', "Simple loudness..."): "-c:a {encoder} -f {format} -af \"loudnorm=I=-23:TP=-2,afade=t=in:d=0.10\"",
|
1506
|
+
preset_options_i18n.get('downmix_norm', "Downmix to mono..."): "-c:a {encoder} -ac 1 -f {format} -af \"loudnorm=I=-23:TP=-2:dual_mono=true,afade=t=in:d=0.10\"",
|
1507
|
+
preset_options_i18n.get('downmix_norm_low_bitrate', "Downmix to mono, 30kbps..."): "-c:a {encoder} -b:a 30k -ac 1 -f {format} -af \"loudnorm=I=-23:TP=-2:dual_mono=true,afade=t=in:d=0.10\"",
|
1508
|
+
preset_options_i18n.get('custom', "Custom"): get_config().audio.custom_encode_settings,
|
1220
1509
|
}
|
1221
1510
|
|
1222
|
-
# Create a Combobox with display names
|
1223
1511
|
self.ffmpeg_audio_preset_options = ttk.Combobox(audio_frame,
|
1224
1512
|
values=list(self.ffmpeg_audio_preset_options_map.keys()),
|
1225
1513
|
width=50, state="readonly")
|
1226
|
-
# self.ffmpeg_preset_options.set("Downmix to mono with normalization") # Set default display name
|
1227
1514
|
self.ffmpeg_audio_preset_options.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1228
|
-
|
1229
|
-
# Bind selection to update settings
|
1230
1515
|
self.ffmpeg_audio_preset_options.bind("<<ComboboxSelected>>", self.update_audio_ffmpeg_settings)
|
1231
1516
|
self.current_row += 1
|
1232
1517
|
|
1233
|
-
|
1234
|
-
|
1518
|
+
ffmpeg_options_i18n = audio_i18n.get('ffmpeg_options', {})
|
1519
|
+
HoverInfoLabelWidget(audio_frame, text=ffmpeg_options_i18n.get('label', '...'),
|
1520
|
+
tooltip=ffmpeg_options_i18n.get('tooltip', '...'), foreground="red",
|
1235
1521
|
font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
1236
|
-
|
1237
|
-
self.audio_ffmpeg_reencode_options.insert(0, self.settings.audio.ffmpeg_reencode_options)
|
1238
|
-
self.audio_ffmpeg_reencode_options.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1522
|
+
ttk.Entry(audio_frame, width=50, textvariable=self.audio_ffmpeg_reencode_options_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1239
1523
|
self.current_row += 1
|
1240
1524
|
|
1241
|
-
|
1242
|
-
|
1525
|
+
anki_media_i18n = audio_i18n.get('anki_media_collection', {})
|
1526
|
+
HoverInfoLabelWidget(audio_frame, text=anki_media_i18n.get('label', '...'),
|
1527
|
+
tooltip=anki_media_i18n.get('tooltip', '...'),
|
1243
1528
|
foreground="green", font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
1244
|
-
self.
|
1245
|
-
self.
|
1246
|
-
self.anki_media_collection.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1529
|
+
self.anki_media_collection_entry = ttk.Entry(audio_frame, textvariable=self.anki_media_collection_value)
|
1530
|
+
self.anki_media_collection_entry.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1247
1531
|
self.current_row += 1
|
1248
1532
|
|
1249
|
-
|
1250
|
-
|
1533
|
+
ext_tool_i18n = audio_i18n.get('external_tool', {})
|
1534
|
+
HoverInfoLabelWidget(audio_frame, text=ext_tool_i18n.get('label', '...'),
|
1535
|
+
tooltip=ext_tool_i18n.get('tooltip', '...'),
|
1251
1536
|
foreground="green", font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
1252
|
-
self.
|
1253
|
-
self.
|
1254
|
-
|
1255
|
-
|
1256
|
-
HoverInfoLabelWidget(audio_frame, text=
|
1537
|
+
self.external_tool_entry = ttk.Entry(audio_frame, textvariable=self.external_tool_value)
|
1538
|
+
self.external_tool_entry.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1539
|
+
|
1540
|
+
ext_tool_enabled_i18n = audio_i18n.get('external_tool_enabled', {})
|
1541
|
+
HoverInfoLabelWidget(audio_frame, text=ext_tool_enabled_i18n.get('label', '...'), tooltip=ext_tool_enabled_i18n.get('tooltip', '...'),
|
1257
1542
|
row=self.current_row, column=2, foreground="green", font=("Helvetica", 10, "bold"))
|
1258
|
-
ttk.Checkbutton(audio_frame, variable=self.
|
1543
|
+
ttk.Checkbutton(audio_frame, variable=self.external_tool_enabled_value, bootstyle="round-toggle").grid(
|
1259
1544
|
row=self.current_row, column=3, sticky='W', padx=10, pady=5)
|
1260
1545
|
self.current_row += 1
|
1261
1546
|
|
1262
|
-
ttk.Button(audio_frame, text=
|
1263
|
-
bootstyle="info").grid(
|
1264
|
-
|
1265
|
-
ttk.Button(audio_frame, text="Get Anki Media Collection",
|
1547
|
+
ttk.Button(audio_frame, text=audio_i18n.get('install_ocenaudio_button', 'Install Ocenaudio'), command=self.download_and_install_ocen,
|
1548
|
+
bootstyle="info").grid(row=self.current_row, column=0, pady=5)
|
1549
|
+
ttk.Button(audio_frame, text=audio_i18n.get('get_anki_media_button', 'Get Anki Media Collection'),
|
1266
1550
|
command=self.set_default_anki_media_collection, bootstyle="info").grid(row=self.current_row,
|
1267
1551
|
column=1, pady=5)
|
1268
1552
|
self.current_row += 1
|
1269
1553
|
|
1270
1554
|
self.add_reset_button(audio_frame, "audio", self.current_row, 0, self.create_audio_tab)
|
1271
1555
|
|
1272
|
-
for col in range(5):
|
1273
|
-
|
1274
|
-
|
1275
|
-
for row in range(self.current_row):
|
1276
|
-
audio_frame.grid_rowconfigure(row, minsize=30)
|
1556
|
+
for col in range(5): audio_frame.grid_columnconfigure(col, weight=0)
|
1557
|
+
for row in range(self.current_row): audio_frame.grid_rowconfigure(row, minsize=30)
|
1277
1558
|
|
1278
1559
|
return audio_frame
|
1279
1560
|
|
1280
1561
|
def call_audio_offset_selector(self):
|
1281
1562
|
try:
|
1282
|
-
# if is_dev:
|
1283
|
-
# path, beginning_offset, end_offset = r"C:\Users\Beangate\GSM\Electron App\test\tmphd01whan_untrimmed.opus", 500, 0
|
1284
|
-
# else:
|
1285
1563
|
path, beginning_offset, end_offset = gsm_state.previous_trim_args
|
1286
|
-
# Get the directory of the current script
|
1287
1564
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
1288
|
-
|
1289
|
-
script_path = os.path.join(current_dir,
|
1290
|
-
"audio_offset_selector.py") # Replace with the actual script name if different
|
1565
|
+
script_path = os.path.join(current_dir, "audio_offset_selector.py")
|
1291
1566
|
|
1292
1567
|
logger.info(' '.join([sys.executable, "-m", "GameSentenceMiner.util.audio_offset_selector",
|
1293
|
-
"--path", path, "--beginning_offset", str(beginning_offset), "--end_offset",
|
1294
|
-
str(end_offset)]))
|
1568
|
+
"--path", path, "--beginning_offset", str(beginning_offset), "--end_offset", str(end_offset)]))
|
1295
1569
|
|
1296
|
-
# Run the script using subprocess.run()
|
1297
1570
|
result = subprocess.run(
|
1298
1571
|
[sys.executable, "-m", "GameSentenceMiner.util.audio_offset_selector",
|
1299
1572
|
"--path", path, "--beginning_offset", str(beginning_offset), "--end_offset", str(end_offset)],
|
1300
|
-
capture_output=True,
|
1301
|
-
text=True, # Get output as text
|
1302
|
-
check=False # Raise an exception for non-zero exit codes
|
1573
|
+
capture_output=True, text=True, check=False
|
1303
1574
|
)
|
1304
1575
|
if result.returncode != 0:
|
1305
1576
|
logger.error(f"Script failed with return code: {result.returncode}")
|
1306
1577
|
return None
|
1578
|
+
|
1307
1579
|
logger.info(result)
|
1308
1580
|
logger.info(f"Audio offset selector script output: {result.stdout.strip()}")
|
1309
|
-
pyperclip.copy(result.stdout.strip())
|
1310
|
-
|
1311
|
-
|
1581
|
+
pyperclip.copy(result.stdout.strip())
|
1582
|
+
|
1583
|
+
dialog_i18n = self.i18n.get('dialogs', {}).get('offset_copied', {})
|
1584
|
+
messagebox.showinfo(dialog_i18n.get('title', 'Clipboard'), dialog_i18n.get('message', 'Offset copied!'))
|
1585
|
+
return result.stdout.strip()
|
1312
1586
|
|
1313
1587
|
except subprocess.CalledProcessError as e:
|
1314
|
-
logger.error(f"Error calling script: {e}")
|
1315
|
-
logger.error(f"Script output (stderr): {e.stderr.strip()}")
|
1588
|
+
logger.error(f"Error calling script: {e}\nStderr: {e.stderr.strip()}")
|
1316
1589
|
return None
|
1317
1590
|
except FileNotFoundError:
|
1318
|
-
logger.error(f"Error: Script not found at {script_path}.
|
1591
|
+
logger.error(f"Error: Script not found at {script_path}.")
|
1319
1592
|
return None
|
1320
1593
|
except Exception as e:
|
1321
1594
|
logger.error(f"An unexpected error occurred: {e}")
|
@@ -1324,95 +1597,91 @@ class ConfigApp:
|
|
1324
1597
|
@new_tab
|
1325
1598
|
def create_obs_tab(self):
|
1326
1599
|
if self.obs_tab is None:
|
1600
|
+
obs_i18n = self.i18n.get('tabs', {}).get('obs', {})
|
1327
1601
|
self.obs_tab = ttk.Frame(self.notebook, padding=15)
|
1328
|
-
self.notebook.add(self.obs_tab, text='OBS')
|
1602
|
+
self.notebook.add(self.obs_tab, text=obs_i18n.get('title', 'OBS'))
|
1329
1603
|
else:
|
1330
1604
|
for widget in self.obs_tab.winfo_children():
|
1331
1605
|
widget.destroy()
|
1332
1606
|
|
1333
1607
|
obs_frame = self.obs_tab
|
1608
|
+
obs_i18n = self.i18n.get('tabs', {}).get('obs', {})
|
1334
1609
|
|
1335
|
-
|
1610
|
+
enabled_i18n = obs_i18n.get('enabled', {})
|
1611
|
+
HoverInfoLabelWidget(obs_frame, text=enabled_i18n.get('label', '...'), tooltip=enabled_i18n.get('tooltip', '...'),
|
1336
1612
|
row=self.current_row, column=0)
|
1337
|
-
self.
|
1338
|
-
|
1339
|
-
column=1, sticky='W',
|
1340
|
-
pady=2)
|
1613
|
+
ttk.Checkbutton(obs_frame, variable=self.obs_enabled_value, bootstyle="round-toggle").grid(row=self.current_row,
|
1614
|
+
column=1, sticky='W', pady=2)
|
1341
1615
|
self.current_row += 1
|
1342
1616
|
|
1343
|
-
|
1617
|
+
open_i18n = obs_i18n.get('open_obs', {})
|
1618
|
+
HoverInfoLabelWidget(obs_frame, text=open_i18n.get('label', '...'), tooltip=open_i18n.get('tooltip', '...'), row=self.current_row,
|
1344
1619
|
column=0)
|
1345
|
-
self.
|
1346
|
-
ttk.Checkbutton(obs_frame, variable=self.open_obs, bootstyle="round-toggle").grid(row=self.current_row,
|
1620
|
+
ttk.Checkbutton(obs_frame, variable=self.obs_open_obs_value, bootstyle="round-toggle").grid(row=self.current_row,
|
1347
1621
|
column=1, sticky='W', pady=2)
|
1348
1622
|
self.current_row += 1
|
1349
1623
|
|
1350
|
-
|
1624
|
+
close_i18n = obs_i18n.get('close_obs', {})
|
1625
|
+
HoverInfoLabelWidget(obs_frame, text=close_i18n.get('label', '...'), tooltip=close_i18n.get('tooltip', '...'),
|
1351
1626
|
row=self.current_row, column=0)
|
1352
|
-
self.
|
1353
|
-
ttk.Checkbutton(obs_frame, variable=self.close_obs, bootstyle="round-toggle").grid(row=self.current_row,
|
1627
|
+
ttk.Checkbutton(obs_frame, variable=self.obs_close_obs_value, bootstyle="round-toggle").grid(row=self.current_row,
|
1354
1628
|
column=1, sticky='W', pady=2)
|
1355
1629
|
self.current_row += 1
|
1356
1630
|
|
1357
|
-
|
1631
|
+
host_i18n = obs_i18n.get('host', {})
|
1632
|
+
HoverInfoLabelWidget(obs_frame, text=host_i18n.get('label', '...'), tooltip=host_i18n.get('tooltip', '...'),
|
1358
1633
|
row=self.current_row, column=0)
|
1359
|
-
|
1360
|
-
self.obs_host.insert(0, self.settings.obs.host)
|
1361
|
-
self.obs_host.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1634
|
+
ttk.Entry(obs_frame, textvariable=self.obs_host_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1362
1635
|
self.current_row += 1
|
1363
1636
|
|
1364
|
-
|
1637
|
+
port_i18n = obs_i18n.get('port', {})
|
1638
|
+
HoverInfoLabelWidget(obs_frame, text=port_i18n.get('label', '...'), tooltip=port_i18n.get('tooltip', '...'),
|
1365
1639
|
row=self.current_row, column=0)
|
1366
|
-
|
1367
|
-
self.obs_port.insert(0, str(self.settings.obs.port))
|
1368
|
-
self.obs_port.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1640
|
+
ttk.Entry(obs_frame, textvariable=self.obs_port_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1369
1641
|
self.current_row += 1
|
1370
1642
|
|
1371
|
-
|
1643
|
+
pass_i18n = obs_i18n.get('password', {})
|
1644
|
+
HoverInfoLabelWidget(obs_frame, text=pass_i18n.get('label', '...'), tooltip=pass_i18n.get('tooltip', '...'),
|
1372
1645
|
row=self.current_row, column=0)
|
1373
|
-
|
1374
|
-
self.obs_password.insert(0, self.settings.obs.password)
|
1375
|
-
self.obs_password.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1646
|
+
ttk.Entry(obs_frame, show="*", textvariable=self.obs_password_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1376
1647
|
self.current_row += 1
|
1377
1648
|
|
1378
|
-
|
1649
|
+
game_scene_i18n = obs_i18n.get('game_from_scene', {})
|
1650
|
+
HoverInfoLabelWidget(obs_frame, text=game_scene_i18n.get('label', '...'), tooltip=game_scene_i18n.get('tooltip', '...'),
|
1379
1651
|
row=self.current_row, column=0)
|
1380
|
-
self.
|
1381
|
-
|
1382
|
-
row=self.current_row, column=1,
|
1383
|
-
sticky='W', pady=2)
|
1652
|
+
ttk.Checkbutton(obs_frame, variable=self.obs_get_game_from_scene_name_value, bootstyle="round-toggle").grid(
|
1653
|
+
row=self.current_row, column=1, sticky='W', pady=2)
|
1384
1654
|
self.current_row += 1
|
1385
1655
|
|
1386
|
-
|
1387
|
-
|
1656
|
+
min_size_i18n = obs_i18n.get('min_replay_size', {})
|
1657
|
+
HoverInfoLabelWidget(obs_frame, text=min_size_i18n.get('label', '...'),
|
1658
|
+
tooltip=min_size_i18n.get('tooltip', '...'),
|
1388
1659
|
row=self.current_row, column=0)
|
1389
|
-
|
1390
|
-
self.minimum_replay_size.insert(0, str(self.settings.obs.minimum_replay_size))
|
1391
|
-
self.minimum_replay_size.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1660
|
+
ttk.Entry(obs_frame, textvariable=self.obs_minimum_replay_size_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1392
1661
|
self.current_row += 1
|
1393
1662
|
|
1394
1663
|
self.add_reset_button(obs_frame, "obs", self.current_row, 0, self.create_obs_tab)
|
1395
1664
|
|
1396
|
-
for col in range(3):
|
1397
|
-
|
1398
|
-
|
1399
|
-
for row in range(self.current_row):
|
1400
|
-
obs_frame.grid_rowconfigure(row, minsize=30)
|
1665
|
+
for col in range(3): obs_frame.grid_columnconfigure(col, weight=0)
|
1666
|
+
for row in range(self.current_row): obs_frame.grid_rowconfigure(row, minsize=30)
|
1401
1667
|
|
1402
1668
|
return obs_frame
|
1403
1669
|
|
1404
1670
|
@new_tab
|
1405
1671
|
def create_profiles_tab(self):
|
1406
1672
|
if self.profiles_tab is None:
|
1673
|
+
profiles_i18n = self.i18n.get('tabs', {}).get('profiles', {})
|
1407
1674
|
self.profiles_tab = ttk.Frame(self.notebook, padding=15)
|
1408
|
-
self.notebook.add(self.profiles_tab, text='Profiles')
|
1675
|
+
self.notebook.add(self.profiles_tab, text=profiles_i18n.get('title', 'Profiles'))
|
1409
1676
|
else:
|
1410
1677
|
for widget in self.profiles_tab.winfo_children():
|
1411
1678
|
widget.destroy()
|
1412
1679
|
|
1413
1680
|
profiles_frame = self.profiles_tab
|
1681
|
+
profiles_i18n = self.i18n.get('tabs', {}).get('profiles', {})
|
1414
1682
|
|
1415
|
-
|
1683
|
+
select_i18n = profiles_i18n.get('select_profile', {})
|
1684
|
+
HoverInfoLabelWidget(profiles_frame, text=select_i18n.get('label', '...'), tooltip=select_i18n.get('tooltip', '...'),
|
1416
1685
|
row=self.current_row, column=0)
|
1417
1686
|
self.profile_var = tk.StringVar(value=self.settings.name)
|
1418
1687
|
self.profile_combobox = ttk.Combobox(profiles_frame, textvariable=self.profile_var,
|
@@ -1422,11 +1691,11 @@ class ConfigApp:
|
|
1422
1691
|
self.current_row += 1
|
1423
1692
|
|
1424
1693
|
button_row = self.current_row
|
1425
|
-
ttk.Button(profiles_frame, text=
|
1694
|
+
ttk.Button(profiles_frame, text=profiles_i18n.get('add_button', 'Add Profile'), command=self.add_profile, bootstyle="primary").grid(
|
1426
1695
|
row=button_row, column=0, pady=5)
|
1427
|
-
ttk.Button(profiles_frame, text=
|
1696
|
+
ttk.Button(profiles_frame, text=profiles_i18n.get('copy_button', 'Copy Profile'), command=self.copy_profile, bootstyle="secondary").grid(
|
1428
1697
|
row=button_row, column=1, pady=5)
|
1429
|
-
self.delete_profile_button = ttk.Button(profiles_frame, text=
|
1698
|
+
self.delete_profile_button = ttk.Button(profiles_frame, text=profiles_i18n.get('delete_button', 'Delete Config'), command=self.delete_profile,
|
1430
1699
|
bootstyle="danger")
|
1431
1700
|
if self.master_config.current_profile != DEFAULT_CONFIG:
|
1432
1701
|
self.delete_profile_button.grid(row=button_row, column=2, pady=5)
|
@@ -1434,31 +1703,29 @@ class ConfigApp:
|
|
1434
1703
|
self.delete_profile_button.grid_remove()
|
1435
1704
|
self.current_row += 1
|
1436
1705
|
|
1437
|
-
|
1438
|
-
|
1706
|
+
scene_i18n = profiles_i18n.get('obs_scene', {})
|
1707
|
+
HoverInfoLabelWidget(profiles_frame, text=scene_i18n.get('label', '...'),
|
1708
|
+
tooltip=scene_i18n.get('tooltip', '...'),
|
1439
1709
|
row=self.current_row, column=0)
|
1440
1710
|
self.obs_scene_var = tk.StringVar(value="")
|
1441
1711
|
self.obs_scene_listbox = tk.Listbox(profiles_frame, listvariable=self.obs_scene_var, selectmode=tk.MULTIPLE,
|
1442
1712
|
height=10, width=50, selectbackground=ttk.Style().colors.primary)
|
1443
1713
|
self.obs_scene_listbox.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1444
1714
|
self.obs_scene_listbox.bind("<<ListboxSelect>>", self.on_obs_scene_select)
|
1445
|
-
ttk.Button(profiles_frame, text=
|
1715
|
+
ttk.Button(profiles_frame, text=profiles_i18n.get('refresh_scenes_button', 'Refresh Scenes'), command=self.refresh_obs_scenes, bootstyle="outline").grid(
|
1446
1716
|
row=self.current_row, column=2, pady=5)
|
1447
1717
|
self.current_row += 1
|
1448
1718
|
|
1449
|
-
|
1450
|
-
|
1719
|
+
switch_i18n = profiles_i18n.get('switch_to_default', {})
|
1720
|
+
HoverInfoLabelWidget(profiles_frame, text=switch_i18n.get('label', '...'),
|
1721
|
+
tooltip=switch_i18n.get('tooltip', '...'),
|
1451
1722
|
row=self.current_row, column=0)
|
1452
|
-
self.
|
1453
|
-
ttk.Checkbutton(profiles_frame, variable=self.switch_to_default_if_not_found, bootstyle="round-toggle").grid(
|
1723
|
+
ttk.Checkbutton(profiles_frame, variable=self.switch_to_default_if_not_found_value, bootstyle="round-toggle").grid(
|
1454
1724
|
row=self.current_row, column=1, sticky='W', pady=2)
|
1455
1725
|
self.current_row += 1
|
1456
1726
|
|
1457
|
-
for col in range(4):
|
1458
|
-
|
1459
|
-
|
1460
|
-
for row in range(self.current_row):
|
1461
|
-
profiles_frame.grid_rowconfigure(row, minsize=30)
|
1727
|
+
for col in range(4): profiles_frame.grid_columnconfigure(col, weight=0)
|
1728
|
+
for row in range(self.current_row): profiles_frame.grid_rowconfigure(row, minsize=30)
|
1462
1729
|
|
1463
1730
|
return profiles_frame
|
1464
1731
|
|
@@ -1470,328 +1737,295 @@ class ConfigApp:
|
|
1470
1737
|
def refresh_obs_scenes(self):
|
1471
1738
|
scenes = obs.get_obs_scenes()
|
1472
1739
|
obs_scene_names = [scene['sceneName'] for scene in scenes]
|
1473
|
-
self.obs_scene_listbox.delete(0, tk.END)
|
1740
|
+
self.obs_scene_listbox.delete(0, tk.END)
|
1474
1741
|
for scene_name in obs_scene_names:
|
1475
|
-
self.obs_scene_listbox.insert(tk.END, scene_name)
|
1476
|
-
for i, scene in enumerate(obs_scene_names):
|
1477
|
-
if scene.strip() in self.settings.scenes:
|
1478
|
-
self.obs_scene_listbox.select_set(i)
|
1742
|
+
self.obs_scene_listbox.insert(tk.END, scene_name)
|
1743
|
+
for i, scene in enumerate(obs_scene_names):
|
1744
|
+
if scene.strip() in self.settings.scenes:
|
1745
|
+
self.obs_scene_listbox.select_set(i)
|
1479
1746
|
self.obs_scene_listbox.activate(i)
|
1480
|
-
self.obs_scene_listbox.update_idletasks()
|
1747
|
+
self.obs_scene_listbox.update_idletasks()
|
1481
1748
|
|
1482
1749
|
@new_tab
|
1483
1750
|
def create_advanced_tab(self):
|
1484
1751
|
if self.advanced_tab is None:
|
1752
|
+
advanced_i18n = self.i18n.get('tabs', {}).get('advanced', {})
|
1485
1753
|
self.advanced_tab = ttk.Frame(self.notebook, padding=15)
|
1486
|
-
self.notebook.add(self.advanced_tab, text='Advanced')
|
1754
|
+
self.notebook.add(self.advanced_tab, text=advanced_i18n.get('title', 'Advanced'))
|
1487
1755
|
else:
|
1488
1756
|
for widget in self.advanced_tab.winfo_children():
|
1489
1757
|
widget.destroy()
|
1490
1758
|
|
1491
1759
|
advanced_frame = self.advanced_tab
|
1760
|
+
advanced_i18n = self.i18n.get('tabs', {}).get('advanced', {})
|
1761
|
+
browse_text = self.i18n.get('buttons', {}).get('browse', 'Browse')
|
1492
1762
|
|
1493
|
-
ttk.Label(advanced_frame, text=
|
1763
|
+
ttk.Label(advanced_frame, text=advanced_i18n.get('player_note', '...'),
|
1494
1764
|
foreground="red", font=("Helvetica", 10, "bold")).grid(row=self.current_row, column=0, columnspan=3,
|
1495
1765
|
sticky='W', pady=5)
|
1496
1766
|
self.current_row += 1
|
1497
1767
|
|
1498
|
-
|
1499
|
-
|
1768
|
+
audio_player_i18n = advanced_i18n.get('audio_player_path', {})
|
1769
|
+
HoverInfoLabelWidget(advanced_frame, text=audio_player_i18n.get('label', '...'),
|
1770
|
+
tooltip=audio_player_i18n.get('tooltip', '...'),
|
1500
1771
|
row=self.current_row, column=0)
|
1501
|
-
|
1502
|
-
self.
|
1503
|
-
|
1504
|
-
ttk.Button(advanced_frame, text="Browse", command=lambda: self.browse_file(self.audio_player_path),
|
1772
|
+
audio_player_entry = ttk.Entry(advanced_frame, width=50, textvariable=self.audio_player_path_value)
|
1773
|
+
audio_player_entry.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1774
|
+
ttk.Button(advanced_frame, text=browse_text, command=lambda: self.browse_file(audio_player_entry),
|
1505
1775
|
bootstyle="outline").grid(row=self.current_row, column=2, padx=5, pady=2)
|
1506
1776
|
self.current_row += 1
|
1507
1777
|
|
1508
|
-
|
1509
|
-
|
1778
|
+
video_player_i18n = advanced_i18n.get('video_player_path', {})
|
1779
|
+
HoverInfoLabelWidget(advanced_frame, text=video_player_i18n.get('label', '...'),
|
1780
|
+
tooltip=video_player_i18n.get('tooltip', '...'),
|
1510
1781
|
row=self.current_row, column=0)
|
1511
|
-
|
1512
|
-
self.
|
1513
|
-
|
1514
|
-
ttk.Button(advanced_frame, text="Browse", command=lambda: self.browse_file(self.video_player_path),
|
1782
|
+
video_player_entry = ttk.Entry(advanced_frame, width=50, textvariable=self.video_player_path_value)
|
1783
|
+
video_player_entry.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1784
|
+
ttk.Button(advanced_frame, text=browse_text, command=lambda: self.browse_file(video_player_entry),
|
1515
1785
|
bootstyle="outline").grid(row=self.current_row, column=2, padx=5, pady=2)
|
1516
1786
|
self.current_row += 1
|
1517
1787
|
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
self.play_latest_audio_hotkey.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1788
|
+
play_hotkey_i18n = advanced_i18n.get('play_latest_hotkey', {})
|
1789
|
+
HoverInfoLabelWidget(advanced_frame, text=play_hotkey_i18n.get('label', '...'),
|
1790
|
+
tooltip=play_hotkey_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
1791
|
+
ttk.Entry(advanced_frame, textvariable=self.play_latest_audio_hotkey_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1523
1792
|
self.current_row += 1
|
1524
1793
|
|
1525
|
-
|
1526
|
-
|
1794
|
+
linebreak_i18n = advanced_i18n.get('multiline_linebreak', {})
|
1795
|
+
HoverInfoLabelWidget(advanced_frame, text=linebreak_i18n.get('label', '...'),
|
1796
|
+
tooltip=linebreak_i18n.get('tooltip', '...'),
|
1527
1797
|
row=self.current_row, column=0)
|
1528
|
-
|
1529
|
-
self.multi_line_line_break.insert(0, self.settings.advanced.multi_line_line_break)
|
1530
|
-
self.multi_line_line_break.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1798
|
+
ttk.Entry(advanced_frame, textvariable=self.multi_line_line_break_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1531
1799
|
self.current_row += 1
|
1532
1800
|
|
1533
|
-
|
1534
|
-
|
1801
|
+
storage_field_i18n = advanced_i18n.get('multiline_storage_field', {})
|
1802
|
+
HoverInfoLabelWidget(advanced_frame, text=storage_field_i18n.get('label', '...'),
|
1803
|
+
tooltip=storage_field_i18n.get('tooltip', '...'),
|
1535
1804
|
row=self.current_row, column=0)
|
1536
|
-
|
1537
|
-
self.multi_line_sentence_storage_field.insert(0, self.settings.advanced.multi_line_sentence_storage_field)
|
1538
|
-
self.multi_line_sentence_storage_field.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1805
|
+
ttk.Entry(advanced_frame, textvariable=self.multi_line_sentence_storage_field_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1539
1806
|
self.current_row += 1
|
1540
1807
|
|
1541
|
-
|
1542
|
-
|
1808
|
+
ocr_port_i18n = advanced_i18n.get('ocr_port', {})
|
1809
|
+
HoverInfoLabelWidget(advanced_frame, text=ocr_port_i18n.get('label', '...'),
|
1810
|
+
tooltip=ocr_port_i18n.get('tooltip', '...'),
|
1543
1811
|
row=self.current_row, column=0)
|
1544
|
-
|
1545
|
-
self.ocr_websocket_port.insert(0, str(self.settings.advanced.ocr_websocket_port))
|
1546
|
-
self.ocr_websocket_port.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1812
|
+
ttk.Entry(advanced_frame, textvariable=self.ocr_websocket_port_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1547
1813
|
self.current_row += 1
|
1548
1814
|
|
1549
|
-
|
1550
|
-
|
1815
|
+
comm_port_i18n = advanced_i18n.get('texthooker_comm_port', {})
|
1816
|
+
HoverInfoLabelWidget(advanced_frame, text=comm_port_i18n.get('label', '...'),
|
1817
|
+
tooltip=comm_port_i18n.get('tooltip', '...'),
|
1551
1818
|
row=self.current_row, column=0)
|
1552
|
-
|
1553
|
-
self.texthooker_communication_websocket_port.insert(0,
|
1554
|
-
str(self.settings.advanced.texthooker_communication_websocket_port))
|
1555
|
-
self.texthooker_communication_websocket_port.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1819
|
+
ttk.Entry(advanced_frame, textvariable=self.texthooker_communication_websocket_port_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1556
1820
|
self.current_row += 1
|
1557
1821
|
|
1558
|
-
|
1559
|
-
|
1822
|
+
export_port_i18n = advanced_i18n.get('plaintext_export_port', {})
|
1823
|
+
HoverInfoLabelWidget(advanced_frame, text=export_port_i18n.get('label', '...'),
|
1824
|
+
tooltip=export_port_i18n.get('tooltip', '...'),
|
1560
1825
|
row=self.current_row, column=0)
|
1561
|
-
|
1562
|
-
self.plaintext_websocket_export_port.insert(0, str(self.settings.advanced.plaintext_websocket_port))
|
1563
|
-
self.plaintext_websocket_export_port.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1826
|
+
ttk.Entry(advanced_frame, textvariable=self.plaintext_websocket_export_port_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1564
1827
|
self.current_row += 1
|
1565
1828
|
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
# ttk.Checkbutton(advanced_frame, variable=self.use_anki_note_creation_time, bootstyle="round-toggle").grid(
|
1571
|
-
# row=self.current_row, column=1, sticky='W', pady=2)
|
1572
|
-
# self.current_row += 1
|
1573
|
-
|
1574
|
-
HoverInfoLabelWidget(advanced_frame, text="Reset Line Hotkey:",
|
1575
|
-
tooltip="Hotkey to reset the current line of dialogue.", row=self.current_row, column=0)
|
1576
|
-
self.reset_line_hotkey = ttk.Entry(advanced_frame)
|
1577
|
-
self.reset_line_hotkey.insert(0, self.settings.hotkeys.reset_line)
|
1578
|
-
self.reset_line_hotkey.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1829
|
+
reset_hotkey_i18n = advanced_i18n.get('reset_line_hotkey', {})
|
1830
|
+
HoverInfoLabelWidget(advanced_frame, text=reset_hotkey_i18n.get('label', '...'),
|
1831
|
+
tooltip=reset_hotkey_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
1832
|
+
ttk.Entry(advanced_frame, textvariable=self.reset_line_hotkey_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1579
1833
|
self.current_row += 1
|
1580
1834
|
|
1581
|
-
|
1582
|
-
|
1835
|
+
polling_i18n = advanced_i18n.get('polling_rate', {})
|
1836
|
+
HoverInfoLabelWidget(advanced_frame, text=polling_i18n.get('label', '...'),
|
1837
|
+
tooltip=polling_i18n.get('tooltip', '...'),
|
1583
1838
|
row=self.current_row, column=0)
|
1584
|
-
|
1585
|
-
self.
|
1586
|
-
|
1839
|
+
ttk.Entry(advanced_frame, textvariable=self.polling_rate_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1840
|
+
self.current_row += 1
|
1841
|
+
|
1842
|
+
current_ver_i18n = advanced_i18n.get('current_version', {})
|
1843
|
+
HoverInfoLabelWidget(advanced_frame, text=current_ver_i18n.get('label', 'Current Version:'), bootstyle="secondary",
|
1844
|
+
tooltip=current_ver_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
1845
|
+
self.current_version = ttk.Label(advanced_frame, text=get_current_version(), bootstyle="secondary")
|
1846
|
+
self.current_version.grid(row=self.current_row, column=1, sticky='W', pady=2)
|
1587
1847
|
self.current_row += 1
|
1588
1848
|
|
1589
|
-
|
1590
|
-
|
1591
|
-
|
1592
|
-
|
1593
|
-
|
1594
|
-
|
1595
|
-
# self.current_row += 1
|
1849
|
+
latest_ver_i18n = advanced_i18n.get('latest_version', {})
|
1850
|
+
HoverInfoLabelWidget(advanced_frame, text=latest_ver_i18n.get('label', 'Latest Version:'), bootstyle="secondary",
|
1851
|
+
tooltip=latest_ver_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
1852
|
+
self.latest_version = ttk.Label(advanced_frame, text=get_latest_version(), bootstyle="secondary")
|
1853
|
+
self.latest_version.grid(row=self.current_row, column=1, sticky='W', pady=2)
|
1854
|
+
self.current_row += 1
|
1596
1855
|
|
1597
1856
|
self.add_reset_button(advanced_frame, "advanced", self.current_row, 0, self.create_advanced_tab)
|
1598
1857
|
|
1599
|
-
for col in range(4):
|
1600
|
-
|
1601
|
-
|
1602
|
-
for row in range(self.current_row):
|
1603
|
-
advanced_frame.grid_rowconfigure(row, minsize=30)
|
1858
|
+
for col in range(4): advanced_frame.grid_columnconfigure(col, weight=0)
|
1859
|
+
for row in range(self.current_row): advanced_frame.grid_rowconfigure(row, minsize=30)
|
1604
1860
|
|
1605
1861
|
return advanced_frame
|
1606
1862
|
|
1607
1863
|
@new_tab
|
1608
1864
|
def create_ai_tab(self):
|
1609
1865
|
if self.ai_tab is None:
|
1866
|
+
ai_i18n = self.i18n.get('tabs', {}).get('ai', {})
|
1610
1867
|
self.ai_tab = ttk.Frame(self.notebook, padding=15)
|
1611
|
-
self.notebook.add(self.ai_tab, text='AI')
|
1868
|
+
self.notebook.add(self.ai_tab, text=ai_i18n.get('title', 'AI'))
|
1612
1869
|
else:
|
1613
1870
|
for widget in self.ai_tab.winfo_children():
|
1614
1871
|
widget.destroy()
|
1615
1872
|
|
1616
1873
|
ai_frame = self.ai_tab
|
1874
|
+
ai_i18n = self.i18n.get('tabs', {}).get('ai', {})
|
1617
1875
|
|
1618
|
-
|
1876
|
+
enabled_i18n = ai_i18n.get('enabled', {})
|
1877
|
+
HoverInfoLabelWidget(ai_frame, text=enabled_i18n.get('label', '...'), tooltip=enabled_i18n.get('tooltip', '...'),
|
1619
1878
|
row=self.current_row, column=0)
|
1620
|
-
self.
|
1621
|
-
ttk.Checkbutton(ai_frame, variable=self.ai_enabled, bootstyle="round-toggle").grid(row=self.current_row,
|
1879
|
+
ttk.Checkbutton(ai_frame, variable=self.ai_enabled_value, bootstyle="round-toggle").grid(row=self.current_row,
|
1622
1880
|
column=1, sticky='W', pady=2)
|
1623
1881
|
self.current_row += 1
|
1624
1882
|
|
1625
|
-
|
1883
|
+
provider_i18n = ai_i18n.get('provider', {})
|
1884
|
+
HoverInfoLabelWidget(ai_frame, text=provider_i18n.get('label', '...'), tooltip=provider_i18n.get('tooltip', '...'), row=self.current_row,
|
1626
1885
|
column=0)
|
1627
|
-
|
1628
|
-
self.ai_provider.set(self.settings.ai.provider)
|
1629
|
-
self.ai_provider.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1886
|
+
ttk.Combobox(ai_frame, textvariable=self.ai_provider_value, values=[AI_GEMINI, AI_GROQ, AI_LOCAL], state="readonly").grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1630
1887
|
self.current_row += 1
|
1631
1888
|
|
1632
|
-
|
1889
|
+
gemini_model_i18n = ai_i18n.get('gemini_model', {})
|
1890
|
+
HoverInfoLabelWidget(ai_frame, text=gemini_model_i18n.get('label', '...'), tooltip=gemini_model_i18n.get('tooltip', '...'),
|
1633
1891
|
row=self.current_row, column=0)
|
1634
|
-
|
1635
|
-
try:
|
1636
|
-
self.gemini_model.set(self.settings.ai.gemini_model)
|
1637
|
-
except Exception:
|
1638
|
-
self.gemini_model.set('gemini-2.5-flash')
|
1639
|
-
self.gemini_model.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1892
|
+
ttk.Combobox(ai_frame, textvariable=self.gemini_model_value, values=['gemma-3n-e4b-it', 'gemini-2.5-flash-lite', 'gemini-2.5-flash','gemini-2.0-flash', 'gemini-2.0-flash-lite'], state="readonly").grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1640
1893
|
self.current_row += 1
|
1641
1894
|
|
1642
|
-
|
1643
|
-
|
1895
|
+
gemini_key_i18n = ai_i18n.get('gemini_api_key', {})
|
1896
|
+
HoverInfoLabelWidget(ai_frame, text=gemini_key_i18n.get('label', '...'),
|
1897
|
+
tooltip=gemini_key_i18n.get('tooltip', '...'),
|
1644
1898
|
foreground="green", font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
1645
|
-
|
1646
|
-
self.gemini_api_key.insert(0, self.settings.ai.gemini_api_key)
|
1647
|
-
self.gemini_api_key.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1899
|
+
ttk.Entry(ai_frame, show="*", textvariable=self.gemini_api_key_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1648
1900
|
self.current_row += 1
|
1649
1901
|
|
1650
|
-
|
1902
|
+
groq_model_i18n = ai_i18n.get('groq_model', {})
|
1903
|
+
HoverInfoLabelWidget(ai_frame, text=groq_model_i18n.get('label', '...'), tooltip=groq_model_i18n.get('tooltip', '...'),
|
1651
1904
|
row=self.current_row, column=0)
|
1652
|
-
|
1905
|
+
ttk.Combobox(ai_frame, textvariable=self.groq_model_value, values=['meta-llama/llama-4-maverick-17b-128e-instruct',
|
1653
1906
|
'meta-llama/llama-4-scout-17b-16e-instruct',
|
1654
|
-
'llama-3.1-8b-instant'], state="readonly")
|
1655
|
-
self.groq_model.set(self.settings.ai.groq_model)
|
1656
|
-
self.groq_model.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1907
|
+
'llama-3.1-8b-instant'], state="readonly").grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1657
1908
|
self.current_row += 1
|
1658
1909
|
|
1659
|
-
|
1910
|
+
groq_key_i18n = ai_i18n.get('groq_api_key', {})
|
1911
|
+
HoverInfoLabelWidget(ai_frame, text=groq_key_i18n.get('label', '...'), tooltip=groq_key_i18n.get('tooltip', '...'),
|
1660
1912
|
row=self.current_row, column=0)
|
1661
|
-
|
1662
|
-
self.groq_api_key.insert(0, self.settings.ai.groq_api_key)
|
1663
|
-
self.groq_api_key.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1913
|
+
ttk.Entry(ai_frame, show="*", textvariable=self.groq_api_key_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1664
1914
|
self.current_row += 1
|
1665
1915
|
|
1666
|
-
|
1667
|
-
HoverInfoLabelWidget(ai_frame, text=
|
1668
|
-
|
1669
|
-
|
1670
|
-
self.local_ai_model.set(self.settings.ai.local_model)
|
1671
|
-
self.local_ai_model.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1916
|
+
local_model_i18n = ai_i18n.get('local_model', {})
|
1917
|
+
HoverInfoLabelWidget(ai_frame, text=local_model_i18n.get('label', '...'), tooltip=local_model_i18n.get('tooltip', '...'),
|
1918
|
+
foreground="red", font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
1919
|
+
ttk.Combobox(ai_frame, textvariable=self.local_ai_model_value, values=[OFF, 'facebook/nllb-200-distilled-600M', 'facebook/nllb-200-1.3B', 'facebook/nllb-200-3.3B']).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1672
1920
|
self.current_row += 1
|
1673
1921
|
|
1674
|
-
|
1922
|
+
anki_field_i18n = ai_i18n.get('anki_field', {})
|
1923
|
+
HoverInfoLabelWidget(ai_frame, text=anki_field_i18n.get('label', '...'), tooltip=anki_field_i18n.get('tooltip', '...'),
|
1675
1924
|
row=self.current_row, column=0)
|
1676
|
-
|
1677
|
-
self.ai_anki_field.insert(0, self.settings.ai.anki_field)
|
1678
|
-
self.ai_anki_field.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1925
|
+
ttk.Entry(ai_frame, textvariable=self.ai_anki_field_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1679
1926
|
self.current_row += 1
|
1680
1927
|
|
1681
|
-
|
1928
|
+
context_i18n = ai_i18n.get('context_length', {})
|
1929
|
+
HoverInfoLabelWidget(ai_frame, text=context_i18n.get('label', '...'), tooltip=context_i18n.get('tooltip', '...'),
|
1682
1930
|
foreground="red", font=("Helvetica", 10, "bold"), row=self.current_row, column=0)
|
1683
|
-
|
1684
|
-
self.ai_dialogue_context_length.insert(0, str(self.settings.ai.dialogue_context_length))
|
1685
|
-
self.ai_dialogue_context_length.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1931
|
+
ttk.Entry(ai_frame, textvariable=self.ai_dialogue_context_length_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1686
1932
|
self.current_row += 1
|
1687
1933
|
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
1691
|
-
ttk.Checkbutton(ai_frame, variable=self.
|
1692
|
-
row=self.current_row, column=1,
|
1693
|
-
sticky='W', pady=2)
|
1934
|
+
canned_trans_i18n = ai_i18n.get('use_canned_translation', {})
|
1935
|
+
HoverInfoLabelWidget(ai_frame, text=canned_trans_i18n.get('label', '...'),
|
1936
|
+
tooltip=canned_trans_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
1937
|
+
ttk.Checkbutton(ai_frame, variable=self.use_canned_translation_prompt_value, bootstyle="round-toggle").grid(
|
1938
|
+
row=self.current_row, column=1, sticky='W', pady=2)
|
1694
1939
|
self.current_row += 1
|
1695
1940
|
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
ttk.Checkbutton(ai_frame, variable=self.
|
1700
|
-
row=self.current_row, column=1,
|
1701
|
-
sticky='W', pady=2)
|
1941
|
+
canned_context_i18n = ai_i18n.get('use_canned_context', {})
|
1942
|
+
HoverInfoLabelWidget(ai_frame, text=canned_context_i18n.get('label', '...'),
|
1943
|
+
tooltip=canned_context_i18n.get('tooltip', '...'), row=self.current_row, column=0)
|
1944
|
+
ttk.Checkbutton(ai_frame, variable=self.use_canned_context_prompt_value, bootstyle="round-toggle").grid(
|
1945
|
+
row=self.current_row, column=1, sticky='W', pady=2)
|
1702
1946
|
self.current_row += 1
|
1703
1947
|
|
1704
|
-
|
1948
|
+
custom_prompt_i18n = ai_i18n.get('custom_prompt', {})
|
1949
|
+
HoverInfoLabelWidget(ai_frame, text=custom_prompt_i18n.get('label', '...'), tooltip=custom_prompt_i18n.get('tooltip', '...'),
|
1705
1950
|
row=self.current_row, column=0)
|
1706
1951
|
self.custom_prompt = scrolledtext.ScrolledText(ai_frame, width=50, height=5, font=("TkDefaultFont", 9),
|
1707
1952
|
relief="solid", borderwidth=1,
|
1708
|
-
highlightbackground=ttk.Style().colors.border)
|
1953
|
+
highlightbackground=ttk.Style().colors.border)
|
1709
1954
|
self.custom_prompt.insert(tk.END, self.settings.ai.custom_prompt)
|
1710
1955
|
self.custom_prompt.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1711
1956
|
self.current_row += 1
|
1712
1957
|
|
1713
1958
|
self.add_reset_button(ai_frame, "ai", self.current_row, 0, self.create_ai_tab)
|
1714
1959
|
|
1715
|
-
for col in range(3):
|
1716
|
-
|
1717
|
-
|
1718
|
-
for row in range(self.current_row):
|
1719
|
-
ai_frame.grid_rowconfigure(row, minsize=30)
|
1960
|
+
for col in range(3): ai_frame.grid_columnconfigure(col, weight=0)
|
1961
|
+
for row in range(self.current_row): ai_frame.grid_rowconfigure(row, minsize=30)
|
1720
1962
|
|
1721
1963
|
return ai_frame
|
1722
|
-
|
1723
|
-
# @new_tab
|
1724
|
-
# def create_help_tab(self):
|
1725
|
-
# help_frame = ttk.Frame(self.notebook, padding=15)
|
1726
|
-
# self.notebook.add(help_frame, text='Help')
|
1727
|
-
#
|
1728
|
-
#
|
1729
|
-
#
|
1730
|
-
# help_frame.grid_columnconfigure(0, weight=1)
|
1731
1964
|
|
1732
1965
|
@new_tab
|
1733
1966
|
def create_wip_tab(self):
|
1734
1967
|
if self.wip_tab is None:
|
1968
|
+
wip_i18n = self.i18n.get('tabs', {}).get('wip', {})
|
1735
1969
|
self.wip_tab = ttk.Frame(self.notebook, padding=15)
|
1736
|
-
self.notebook.add(self.wip_tab, text='WIP')
|
1970
|
+
self.notebook.add(self.wip_tab, text=wip_i18n.get('title', 'WIP'))
|
1737
1971
|
else:
|
1738
1972
|
for widget in self.wip_tab.winfo_children():
|
1739
1973
|
widget.destroy()
|
1740
1974
|
|
1741
1975
|
wip_frame = self.wip_tab
|
1976
|
+
wip_i18n = self.i18n.get('tabs', {}).get('wip', {})
|
1742
1977
|
try:
|
1743
|
-
|
1744
|
-
ttk.Label(wip_frame, text="Warning: These features are experimental and may not work as expected.",
|
1978
|
+
ttk.Label(wip_frame, text=wip_i18n.get('warning_experimental', '...'),
|
1745
1979
|
foreground="red", font=("Helvetica", 10, "bold")).grid(row=self.current_row, column=0, columnspan=2,
|
1746
1980
|
sticky='W', pady=5)
|
1747
|
-
|
1748
1981
|
self.current_row += 1
|
1749
1982
|
|
1750
|
-
ttk.Label(wip_frame, text=
|
1983
|
+
ttk.Label(wip_frame, text=wip_i18n.get('warning_overlay_deps', '...'),
|
1751
1984
|
foreground="red", font=("Helvetica", 10, "bold")).grid(row=self.current_row, column=0, columnspan=2,
|
1752
1985
|
sticky='W', pady=5)
|
1753
|
-
|
1754
1986
|
self.current_row += 1
|
1755
1987
|
|
1756
|
-
|
1757
|
-
|
1988
|
+
overlay_port_i18n = wip_i18n.get('overlay_port', {})
|
1989
|
+
HoverInfoLabelWidget(wip_frame, text=overlay_port_i18n.get('label', '...'),
|
1990
|
+
tooltip=overlay_port_i18n.get('tooltip', '...'),
|
1758
1991
|
row=self.current_row, column=0)
|
1759
|
-
|
1760
|
-
self.overlay_websocket_port.insert(0, str(self.settings.wip.overlay_websocket_port))
|
1761
|
-
self.overlay_websocket_port.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1992
|
+
ttk.Entry(wip_frame, textvariable=self.overlay_websocket_port_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1762
1993
|
self.current_row += 1
|
1763
1994
|
|
1764
|
-
|
1765
|
-
|
1995
|
+
overlay_send_i18n = wip_i18n.get('overlay_send', {})
|
1996
|
+
HoverInfoLabelWidget(wip_frame, text=overlay_send_i18n.get('label', '...'),
|
1997
|
+
tooltip=overlay_send_i18n.get('tooltip', '...'),
|
1766
1998
|
row=self.current_row, column=0)
|
1767
|
-
self.
|
1768
|
-
ttk.Checkbutton(wip_frame, variable=self.overlay_websocket_send, bootstyle="round-toggle").grid(
|
1999
|
+
ttk.Checkbutton(wip_frame, variable=self.overlay_websocket_send_value, bootstyle="round-toggle").grid(
|
1769
2000
|
row=self.current_row, column=1, sticky='W', pady=2)
|
1770
2001
|
self.current_row += 1
|
1771
2002
|
|
1772
|
-
|
1773
|
-
|
2003
|
+
monitor_i18n = wip_i18n.get('monitor_capture', {})
|
2004
|
+
HoverInfoLabelWidget(wip_frame, text=monitor_i18n.get('label', '...'),
|
2005
|
+
tooltip=monitor_i18n.get('tooltip', '...'),
|
1774
2006
|
row=self.current_row, column=0)
|
1775
2007
|
self.monitor_to_capture = ttk.Combobox(wip_frame, values=self.monitors, state="readonly")
|
1776
2008
|
|
1777
|
-
# set index of monitor to capture, not the string
|
1778
2009
|
if self.monitors:
|
1779
|
-
|
2010
|
+
# Ensure the index is valid
|
2011
|
+
monitor_index = self.settings.wip.monitor_to_capture
|
2012
|
+
if 0 <= monitor_index < len(self.monitors):
|
2013
|
+
self.monitor_to_capture.current(monitor_index)
|
2014
|
+
else:
|
2015
|
+
self.monitor_to_capture.current(0)
|
1780
2016
|
else:
|
1781
|
-
self.monitor_to_capture.set("OwOCR Not Detected")
|
2017
|
+
self.monitor_to_capture.set(monitor_i18n.get('not_detected', "OwOCR Not Detected"))
|
1782
2018
|
self.monitor_to_capture.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1783
2019
|
self.current_row += 1
|
1784
2020
|
|
1785
2021
|
except Exception as e:
|
1786
2022
|
logger.error(f"Error setting up wip tab to capture: {e}")
|
1787
|
-
ttk.Label(wip_frame, text=
|
2023
|
+
ttk.Label(wip_frame, text=wip_i18n.get('error_setup', 'Error setting up WIP tab'), foreground="red").grid(row=self.current_row, column=0, columnspan=2, sticky='W', pady=5)
|
1788
2024
|
|
1789
2025
|
self.add_reset_button(wip_frame, "wip", self.current_row, 0, self.create_wip_tab)
|
1790
2026
|
|
1791
|
-
for col in range(2):
|
1792
|
-
|
1793
|
-
for row in range(self.current_row):
|
1794
|
-
wip_frame.grid_rowconfigure(row, minsize=30)
|
2027
|
+
for col in range(2): wip_frame.grid_columnconfigure(col, weight=0)
|
2028
|
+
for row in range(self.current_row): wip_frame.grid_rowconfigure(row, minsize=30)
|
1795
2029
|
|
1796
2030
|
return wip_frame
|
1797
2031
|
|
@@ -1805,7 +2039,8 @@ class ConfigApp:
|
|
1805
2039
|
self.delete_profile_button.grid_remove()
|
1806
2040
|
|
1807
2041
|
def add_profile(self):
|
1808
|
-
|
2042
|
+
dialog_i18n = self.i18n.get('dialogs', {}).get('add_profile', {})
|
2043
|
+
new_profile_name = simpledialog.askstring(dialog_i18n.get('title', 'Input'), dialog_i18n.get('prompt', 'Enter new profile name:'))
|
1809
2044
|
if new_profile_name:
|
1810
2045
|
self.master_config.configs[new_profile_name] = self.master_config.get_default_config()
|
1811
2046
|
self.profile_combobox['values'] = list(self.master_config.configs.keys())
|
@@ -1815,12 +2050,12 @@ class ConfigApp:
|
|
1815
2050
|
|
1816
2051
|
def copy_profile(self):
|
1817
2052
|
source_profile = self.profile_combobox.get()
|
1818
|
-
|
2053
|
+
dialog_i18n = self.i18n.get('dialogs', {}).get('copy_profile', {})
|
2054
|
+
new_profile_name = simpledialog.askstring(dialog_i18n.get('title', 'Input'), dialog_i18n.get('prompt', 'Enter new profile name:'), parent=self.window)
|
1819
2055
|
if new_profile_name and source_profile in self.master_config.configs:
|
1820
|
-
# Deep copy the configuration to avoid shared references
|
1821
2056
|
import copy
|
1822
2057
|
self.master_config.configs[new_profile_name] = copy.deepcopy(self.master_config.configs[source_profile])
|
1823
|
-
self.master_config.configs[new_profile_name].name = new_profile_name
|
2058
|
+
self.master_config.configs[new_profile_name].name = new_profile_name
|
1824
2059
|
self.profile_combobox['values'] = list(self.master_config.configs.keys())
|
1825
2060
|
self.profile_combobox.set(new_profile_name)
|
1826
2061
|
self.save_settings()
|
@@ -1828,13 +2063,16 @@ class ConfigApp:
|
|
1828
2063
|
|
1829
2064
|
def delete_profile(self):
|
1830
2065
|
profile_to_delete = self.profile_combobox.get()
|
2066
|
+
dialog_i18n = self.i18n.get('dialogs', {}).get('delete_profile', {})
|
2067
|
+
error_title = dialog_i18n.get('error_title', 'Error')
|
2068
|
+
|
1831
2069
|
if profile_to_delete == "Default":
|
1832
|
-
messagebox.showerror(
|
2070
|
+
messagebox.showerror(error_title, dialog_i18n.get('error_cannot_delete_default', 'Cannot delete the Default profile.'))
|
1833
2071
|
return
|
1834
2072
|
|
1835
2073
|
if profile_to_delete and profile_to_delete in self.master_config.configs:
|
1836
|
-
confirm = messagebox.askyesno(
|
1837
|
-
|
2074
|
+
confirm = messagebox.askyesno(dialog_i18n.get('title', 'Confirm Delete'),
|
2075
|
+
dialog_i18n.get('message', "Are you sure... '{profile_name}'?").format(profile_name=profile_to_delete),
|
1838
2076
|
parent=self.window, icon='warning')
|
1839
2077
|
if confirm:
|
1840
2078
|
del self.master_config.configs[profile_to_delete]
|
@@ -1844,38 +2082,35 @@ class ConfigApp:
|
|
1844
2082
|
save_full_config(self.master_config)
|
1845
2083
|
self.reload_settings()
|
1846
2084
|
|
1847
|
-
def show_error_box(self, title, message):
|
1848
|
-
messagebox.showerror(title, message)
|
1849
|
-
|
1850
2085
|
def download_and_install_ocen(self):
|
1851
|
-
|
1852
|
-
|
2086
|
+
dialog_i18n = self.i18n.get('dialogs', {}).get('install_ocenaudio', {})
|
2087
|
+
confirm = messagebox.askyesno(dialog_i18n.get('title', 'Download OcenAudio?'),
|
2088
|
+
dialog_i18n.get('message', 'Would you like to download...?'),
|
1853
2089
|
parent=self.window, icon='question')
|
1854
2090
|
if confirm:
|
1855
|
-
self.
|
1856
|
-
self.external_tool.insert(0, "Downloading OcenAudio...")
|
2091
|
+
self.external_tool_value.set(dialog_i18n.get('downloading_message', 'Downloading...'))
|
1857
2092
|
exe_path = download_ocenaudio_if_needed()
|
1858
|
-
messagebox.showinfo(
|
1859
|
-
|
2093
|
+
messagebox.showinfo(dialog_i18n.get('success_title', 'Download Complete'),
|
2094
|
+
dialog_i18n.get('success_message', 'Downloaded to {path}').format(path=exe_path),
|
1860
2095
|
parent=self.window)
|
1861
|
-
self.
|
1862
|
-
self.external_tool.insert(0, exe_path)
|
2096
|
+
self.external_tool_value.set(exe_path)
|
1863
2097
|
self.save_settings()
|
1864
2098
|
|
1865
2099
|
def set_default_anki_media_collection(self):
|
1866
|
-
|
1867
|
-
|
2100
|
+
dialog_i18n = self.i18n.get('dialogs', {}).get('set_anki_media', {})
|
2101
|
+
confirm = messagebox.askyesno(dialog_i18n.get('title', 'Set Default Path?'),
|
2102
|
+
dialog_i18n.get('message', 'Would you like to set...?'),
|
1868
2103
|
parent=self.window, icon='question')
|
1869
2104
|
if confirm:
|
1870
2105
|
default_path = get_default_anki_media_collection_path()
|
1871
|
-
if default_path != self.
|
1872
|
-
self.
|
1873
|
-
self.anki_media_collection.insert(0, default_path)
|
2106
|
+
if default_path != self.anki_media_collection_value.get():
|
2107
|
+
self.anki_media_collection_value.set(default_path)
|
1874
2108
|
self.save_settings()
|
1875
2109
|
|
1876
2110
|
|
1877
2111
|
if __name__ == '__main__':
|
2112
|
+
# Ensure 'en_us.json' is in the same directory as this script to run this example
|
1878
2113
|
root = ttk.Window(themename='darkly')
|
1879
2114
|
window = ConfigApp(root)
|
1880
2115
|
window.show()
|
1881
|
-
window.window.mainloop()
|
2116
|
+
window.window.mainloop()
|