supervertaler 1.9.153__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.
Potentially problematic release.
This version of supervertaler might be problematic. Click here for more details.
- Supervertaler.py +47886 -0
- modules/__init__.py +10 -0
- modules/ai_actions.py +964 -0
- modules/ai_attachment_manager.py +343 -0
- modules/ai_file_viewer_dialog.py +210 -0
- modules/autofingers_engine.py +466 -0
- modules/cafetran_docx_handler.py +379 -0
- modules/config_manager.py +469 -0
- modules/database_manager.py +1878 -0
- modules/database_migrations.py +417 -0
- modules/dejavurtf_handler.py +779 -0
- modules/document_analyzer.py +427 -0
- modules/docx_handler.py +689 -0
- modules/encoding_repair.py +319 -0
- modules/encoding_repair_Qt.py +393 -0
- modules/encoding_repair_ui.py +481 -0
- modules/feature_manager.py +350 -0
- modules/figure_context_manager.py +340 -0
- modules/file_dialog_helper.py +148 -0
- modules/find_replace.py +164 -0
- modules/find_replace_qt.py +457 -0
- modules/glossary_manager.py +433 -0
- modules/image_extractor.py +188 -0
- modules/keyboard_shortcuts_widget.py +571 -0
- modules/llm_clients.py +1211 -0
- modules/llm_leaderboard.py +737 -0
- modules/llm_superbench_ui.py +1401 -0
- modules/local_llm_setup.py +1104 -0
- modules/model_update_dialog.py +381 -0
- modules/model_version_checker.py +373 -0
- modules/mqxliff_handler.py +638 -0
- modules/non_translatables_manager.py +743 -0
- modules/pdf_rescue_Qt.py +1822 -0
- modules/pdf_rescue_tkinter.py +909 -0
- modules/phrase_docx_handler.py +516 -0
- modules/project_home_panel.py +209 -0
- modules/prompt_assistant.py +357 -0
- modules/prompt_library.py +689 -0
- modules/prompt_library_migration.py +447 -0
- modules/quick_access_sidebar.py +282 -0
- modules/ribbon_widget.py +597 -0
- modules/sdlppx_handler.py +874 -0
- modules/setup_wizard.py +353 -0
- modules/shortcut_manager.py +932 -0
- modules/simple_segmenter.py +128 -0
- modules/spellcheck_manager.py +727 -0
- modules/statuses.py +207 -0
- modules/style_guide_manager.py +315 -0
- modules/superbench_ui.py +1319 -0
- modules/superbrowser.py +329 -0
- modules/supercleaner.py +600 -0
- modules/supercleaner_ui.py +444 -0
- modules/superdocs.py +19 -0
- modules/superdocs_viewer_qt.py +382 -0
- modules/superlookup.py +252 -0
- modules/tag_cleaner.py +260 -0
- modules/tag_manager.py +333 -0
- modules/term_extractor.py +270 -0
- modules/termbase_entry_editor.py +842 -0
- modules/termbase_import_export.py +488 -0
- modules/termbase_manager.py +1060 -0
- modules/termview_widget.py +1172 -0
- modules/theme_manager.py +499 -0
- modules/tm_editor_dialog.py +99 -0
- modules/tm_manager_qt.py +1280 -0
- modules/tm_metadata_manager.py +545 -0
- modules/tmx_editor.py +1461 -0
- modules/tmx_editor_qt.py +2784 -0
- modules/tmx_generator.py +284 -0
- modules/tracked_changes.py +900 -0
- modules/trados_docx_handler.py +430 -0
- modules/translation_memory.py +715 -0
- modules/translation_results_panel.py +2134 -0
- modules/translation_services.py +282 -0
- modules/unified_prompt_library.py +659 -0
- modules/unified_prompt_manager_qt.py +3951 -0
- modules/voice_commands.py +920 -0
- modules/voice_dictation.py +477 -0
- modules/voice_dictation_lite.py +249 -0
- supervertaler-1.9.153.dist-info/METADATA +896 -0
- supervertaler-1.9.153.dist-info/RECORD +85 -0
- supervertaler-1.9.153.dist-info/WHEEL +5 -0
- supervertaler-1.9.153.dist-info/entry_points.txt +2 -0
- supervertaler-1.9.153.dist-info/licenses/LICENSE +21 -0
- supervertaler-1.9.153.dist-info/top_level.txt +2 -0
modules/setup_wizard.py
ADDED
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Setup Wizard for Supervertaler First Launch
|
|
3
|
+
Guides new users to select their user_data folder location.
|
|
4
|
+
|
|
5
|
+
Author: Michael Beijer
|
|
6
|
+
License: MIT
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
import tkinter as tk
|
|
11
|
+
from tkinter import filedialog, messagebox
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from typing import Optional, Tuple
|
|
14
|
+
from modules.config_manager import ConfigManager
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class SetupWizard:
|
|
18
|
+
"""
|
|
19
|
+
First-launch setup wizard for Supervertaler.
|
|
20
|
+
|
|
21
|
+
Guides users through:
|
|
22
|
+
1. Welcome and explanation
|
|
23
|
+
2. Folder selection
|
|
24
|
+
3. Migration of existing data (if applicable)
|
|
25
|
+
4. Confirmation
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(self, parent_window: Optional[tk.Tk] = None):
|
|
29
|
+
"""
|
|
30
|
+
Initialize the setup wizard.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
parent_window: Parent tkinter window (optional)
|
|
34
|
+
"""
|
|
35
|
+
self.config = ConfigManager()
|
|
36
|
+
self.parent = parent_window
|
|
37
|
+
self.selected_path = None
|
|
38
|
+
self.should_migrate = False
|
|
39
|
+
self.migration_source = None
|
|
40
|
+
|
|
41
|
+
def run(self) -> Tuple[bool, str]:
|
|
42
|
+
"""
|
|
43
|
+
Run the full setup wizard.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
Tuple of (success: bool, user_data_path: str)
|
|
47
|
+
"""
|
|
48
|
+
# Create root window if no parent
|
|
49
|
+
if self.parent is None:
|
|
50
|
+
root = tk.Tk()
|
|
51
|
+
root.withdraw() # Hide until needed
|
|
52
|
+
self.parent = root
|
|
53
|
+
cleanup_root = True
|
|
54
|
+
else:
|
|
55
|
+
cleanup_root = False
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
# Step 1: Welcome
|
|
59
|
+
self._show_welcome()
|
|
60
|
+
|
|
61
|
+
# Step 2: Select folder
|
|
62
|
+
self.selected_path = self._select_folder()
|
|
63
|
+
if self.selected_path is None:
|
|
64
|
+
# User cancelled
|
|
65
|
+
messagebox.showinfo(
|
|
66
|
+
"Setup Cancelled",
|
|
67
|
+
"Supervertaler setup was cancelled. The application will exit."
|
|
68
|
+
)
|
|
69
|
+
return False, ""
|
|
70
|
+
|
|
71
|
+
# Step 3: Check for existing data to migrate
|
|
72
|
+
existing_data = self.config.get_existing_user_data_folder()
|
|
73
|
+
if existing_data:
|
|
74
|
+
self.should_migrate = self._ask_migrate(existing_data)
|
|
75
|
+
if self.should_migrate:
|
|
76
|
+
self.migration_source = existing_data
|
|
77
|
+
|
|
78
|
+
# Step 3b: Show confirmation of what will be created
|
|
79
|
+
confirm_message = (
|
|
80
|
+
"Supervertaler will create the following structure:\n\n"
|
|
81
|
+
f"{self.selected_path}\n"
|
|
82
|
+
f" ├── api_keys.txt\n"
|
|
83
|
+
f" ├── prompt_library/\n"
|
|
84
|
+
f" │ ├── 1_System_Prompts/\n"
|
|
85
|
+
f" │ ├── 2_Domain_Prompts/\n"
|
|
86
|
+
f" │ ├── 3_Project_Prompts/\n"
|
|
87
|
+
f" │ └── 4_Style_Guides/\n"
|
|
88
|
+
f" ├── resources/\n"
|
|
89
|
+
f" │ ├── TMs/\n"
|
|
90
|
+
f" │ ├── Glossaries/\n"
|
|
91
|
+
f" │ ├── non_translatables/\n"
|
|
92
|
+
f" │ └── segmentation_rules/\n"
|
|
93
|
+
f" └── projects/\n\n"
|
|
94
|
+
"Is this correct?"
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
if not messagebox.askyesno("Confirm Folder Location", confirm_message):
|
|
98
|
+
# User wants to go back and select again
|
|
99
|
+
self.selected_path = self._select_folder()
|
|
100
|
+
if self.selected_path is None:
|
|
101
|
+
messagebox.showinfo("Setup Cancelled", "Supervertaler setup was cancelled.")
|
|
102
|
+
return False, ""
|
|
103
|
+
# Loop back to confirmation by recursing (or just continue with the new path)
|
|
104
|
+
|
|
105
|
+
# Step 4: Validate and create folder structure
|
|
106
|
+
success, message = self.config.ensure_user_data_exists(self.selected_path)
|
|
107
|
+
if not success:
|
|
108
|
+
messagebox.showerror("Setup Error", f"Failed to create folder structure:\n{message}")
|
|
109
|
+
return False, ""
|
|
110
|
+
|
|
111
|
+
# Step 5: Perform migration if needed
|
|
112
|
+
if self.should_migrate and self.migration_source:
|
|
113
|
+
success, message = self.config.migrate_user_data(
|
|
114
|
+
self.migration_source,
|
|
115
|
+
self.selected_path
|
|
116
|
+
)
|
|
117
|
+
if not success:
|
|
118
|
+
messagebox.showwarning(
|
|
119
|
+
"Migration Incomplete",
|
|
120
|
+
f"Partial migration occurred.\n{message}"
|
|
121
|
+
)
|
|
122
|
+
else:
|
|
123
|
+
messagebox.showinfo("Migration Complete", message)
|
|
124
|
+
|
|
125
|
+
# Step 5b: Migrate api_keys.txt from installation folder if needed
|
|
126
|
+
success, message = self.config.migrate_api_keys_from_installation(self.selected_path)
|
|
127
|
+
if success and "Migrated" in message:
|
|
128
|
+
messagebox.showinfo("API Keys Migrated", message)
|
|
129
|
+
|
|
130
|
+
# Step 6: Save configuration
|
|
131
|
+
success, message = self.config.set_user_data_path(self.selected_path)
|
|
132
|
+
if not success:
|
|
133
|
+
messagebox.showerror("Configuration Error", f"Failed to save configuration:\n{message}")
|
|
134
|
+
return False, ""
|
|
135
|
+
|
|
136
|
+
# Success!
|
|
137
|
+
messagebox.showinfo(
|
|
138
|
+
"Setup Complete",
|
|
139
|
+
f"✅ Supervertaler is ready!\n\n"
|
|
140
|
+
f"Your data folder: {self.selected_path}\n\n"
|
|
141
|
+
f"Created:\n"
|
|
142
|
+
f" • api_keys.txt (add your API keys here)\n"
|
|
143
|
+
f" • prompt_library/ (your prompts)\n"
|
|
144
|
+
f" • resources/ (TMs, glossaries)\n"
|
|
145
|
+
f" • projects/ (your work)\n\n"
|
|
146
|
+
f"All your translation memories, prompts, and projects\n"
|
|
147
|
+
f"will be stored in this location."
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
return True, self.selected_path
|
|
151
|
+
|
|
152
|
+
finally:
|
|
153
|
+
if cleanup_root:
|
|
154
|
+
self.parent.destroy()
|
|
155
|
+
|
|
156
|
+
def _show_welcome(self):
|
|
157
|
+
"""Show welcome dialog explaining what's happening."""
|
|
158
|
+
welcome_message = (
|
|
159
|
+
"Welcome to Supervertaler!\n\n"
|
|
160
|
+
"This is your first launch. We need to set up your data folder.\n\n"
|
|
161
|
+
"This folder is where Supervertaler will store:\n"
|
|
162
|
+
" • api_keys.txt (your API credentials)\n"
|
|
163
|
+
" • Translation Memories (TMs)\n"
|
|
164
|
+
" • Glossaries and Non-translatables\n"
|
|
165
|
+
" • System Prompts and Custom Instructions\n"
|
|
166
|
+
" • Your translation projects\n"
|
|
167
|
+
" • Segmentation rules\n"
|
|
168
|
+
" • Session reports and configuration\n\n"
|
|
169
|
+
"IMPORTANT: Select a NEW or EMPTY folder location.\n"
|
|
170
|
+
"Examples: Documents/Supervertaler_Data or Desktop/Supervertaler\n\n"
|
|
171
|
+
"Supervertaler will automatically create the full folder\n"
|
|
172
|
+
"structure inside the location you select.\n\n"
|
|
173
|
+
"Click OK to browse for your folder location."
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
messagebox.showinfo("First Time Setup", welcome_message)
|
|
177
|
+
|
|
178
|
+
def _select_folder(self) -> Optional[str]:
|
|
179
|
+
"""
|
|
180
|
+
Show folder browser dialog and return selected path.
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
Selected folder path, or None if cancelled
|
|
184
|
+
"""
|
|
185
|
+
default_path = self.config._get_default_user_data_path()
|
|
186
|
+
|
|
187
|
+
folder_selected = filedialog.askdirectory(
|
|
188
|
+
title="Select WHERE to create your Supervertaler Data Folder\n(e.g., Documents or Desktop - NOT the program folder)",
|
|
189
|
+
initialdir=str(Path.home()),
|
|
190
|
+
mustexist=False
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
if not folder_selected:
|
|
194
|
+
return None
|
|
195
|
+
|
|
196
|
+
# Normalize path
|
|
197
|
+
return os.path.normpath(folder_selected)
|
|
198
|
+
|
|
199
|
+
def _ask_migrate(self, existing_data_path: str) -> bool:
|
|
200
|
+
"""
|
|
201
|
+
Ask user if they want to migrate existing data.
|
|
202
|
+
|
|
203
|
+
Args:
|
|
204
|
+
existing_data_path: Path to existing user_data
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
True if user wants to migrate, False otherwise
|
|
208
|
+
"""
|
|
209
|
+
migrate_message = (
|
|
210
|
+
"We found your existing Supervertaler data!\n\n"
|
|
211
|
+
f"Location: {existing_data_path}\n\n"
|
|
212
|
+
"Would you like to move this data to your new location?\n\n"
|
|
213
|
+
"Click YES to migrate your data to the new folder.\n"
|
|
214
|
+
"Click NO to start fresh (data will remain in old location)."
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
result = messagebox.askyesno(
|
|
218
|
+
"Migrate Existing Data?",
|
|
219
|
+
migrate_message,
|
|
220
|
+
default=True
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
return result
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
class SetupWizardWindow:
|
|
227
|
+
"""
|
|
228
|
+
Alternative: Full window-based setup wizard (more elegant, optional).
|
|
229
|
+
Can be used instead of dialog-based approach.
|
|
230
|
+
"""
|
|
231
|
+
|
|
232
|
+
def __init__(self, on_complete_callback=None):
|
|
233
|
+
"""
|
|
234
|
+
Initialize window-based setup wizard.
|
|
235
|
+
|
|
236
|
+
Args:
|
|
237
|
+
on_complete_callback: Function to call when setup completes
|
|
238
|
+
Receives (success: bool, path: str)
|
|
239
|
+
"""
|
|
240
|
+
self.config = ConfigManager()
|
|
241
|
+
self.on_complete = on_complete_callback
|
|
242
|
+
self.window = None
|
|
243
|
+
self.selected_path = None
|
|
244
|
+
self.current_step = 1
|
|
245
|
+
|
|
246
|
+
def run(self) -> Tuple[bool, str]:
|
|
247
|
+
"""Run the window-based wizard."""
|
|
248
|
+
self.window = tk.Tk()
|
|
249
|
+
self.window.title("Supervertaler - First Time Setup")
|
|
250
|
+
self.window.geometry("600x400")
|
|
251
|
+
self.window.resizable(False, False)
|
|
252
|
+
|
|
253
|
+
# Center window on screen
|
|
254
|
+
self.window.update_idletasks()
|
|
255
|
+
x = (self.window.winfo_screenwidth() // 2) - (300)
|
|
256
|
+
y = (self.window.winfo_screenheight() // 2) - (200)
|
|
257
|
+
self.window.geometry(f"+{x}+{y}")
|
|
258
|
+
|
|
259
|
+
self._show_step_1()
|
|
260
|
+
self.window.mainloop()
|
|
261
|
+
|
|
262
|
+
return getattr(self, '_result', (False, ""))
|
|
263
|
+
|
|
264
|
+
def _show_step_1(self):
|
|
265
|
+
"""Show welcome/explanation step."""
|
|
266
|
+
for widget in self.window.winfo_children():
|
|
267
|
+
widget.destroy()
|
|
268
|
+
|
|
269
|
+
frame = tk.Frame(self.window, padx=20, pady=20)
|
|
270
|
+
frame.pack(fill=tk.BOTH, expand=True)
|
|
271
|
+
|
|
272
|
+
title = tk.Label(
|
|
273
|
+
frame,
|
|
274
|
+
text="Welcome to Supervertaler!",
|
|
275
|
+
font=("Arial", 16, "bold")
|
|
276
|
+
)
|
|
277
|
+
title.pack(pady=10)
|
|
278
|
+
|
|
279
|
+
explanation = tk.Label(
|
|
280
|
+
frame,
|
|
281
|
+
text=(
|
|
282
|
+
"This is your first launch.\n\n"
|
|
283
|
+
"Supervertaler needs to know where to store your data:\n"
|
|
284
|
+
"• Translation Memories\n"
|
|
285
|
+
"• Glossaries\n"
|
|
286
|
+
"• Prompts and Instructions\n"
|
|
287
|
+
"• Projects\n\n"
|
|
288
|
+
"You can choose any location you prefer.\n"
|
|
289
|
+
"Popular choices: Documents folder or Desktop."
|
|
290
|
+
),
|
|
291
|
+
font=("Arial", 11),
|
|
292
|
+
justify=tk.LEFT
|
|
293
|
+
)
|
|
294
|
+
explanation.pack(pady=20, anchor=tk.W)
|
|
295
|
+
|
|
296
|
+
button_frame = tk.Frame(frame)
|
|
297
|
+
button_frame.pack(side=tk.BOTTOM, fill=tk.X, pady=10)
|
|
298
|
+
|
|
299
|
+
tk.Button(
|
|
300
|
+
button_frame,
|
|
301
|
+
text="Cancel",
|
|
302
|
+
command=self._cancel,
|
|
303
|
+
width=10
|
|
304
|
+
).pack(side=tk.LEFT, padx=5)
|
|
305
|
+
|
|
306
|
+
tk.Button(
|
|
307
|
+
button_frame,
|
|
308
|
+
text="Continue →",
|
|
309
|
+
command=self._show_step_2,
|
|
310
|
+
width=10
|
|
311
|
+
).pack(side=tk.RIGHT, padx=5)
|
|
312
|
+
|
|
313
|
+
def _show_step_2(self):
|
|
314
|
+
"""Show folder selection step."""
|
|
315
|
+
# Implementation similar to dialog version
|
|
316
|
+
# For brevity, using standard filedialog
|
|
317
|
+
folder = filedialog.askdirectory(
|
|
318
|
+
title="Select User Data Folder"
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
if folder:
|
|
322
|
+
self.selected_path = os.path.normpath(folder)
|
|
323
|
+
self._show_step_3()
|
|
324
|
+
else:
|
|
325
|
+
self._cancel()
|
|
326
|
+
|
|
327
|
+
def _show_step_3(self):
|
|
328
|
+
"""Show confirmation and complete setup."""
|
|
329
|
+
# Create folders and save config
|
|
330
|
+
success, message = self.config.ensure_user_data_exists(self.selected_path)
|
|
331
|
+
if success:
|
|
332
|
+
self.config.set_user_data_path(self.selected_path)
|
|
333
|
+
self._result = (True, self.selected_path)
|
|
334
|
+
|
|
335
|
+
messagebox.showinfo(
|
|
336
|
+
"Setup Complete",
|
|
337
|
+
f"Your data folder is ready!\n{self.selected_path}"
|
|
338
|
+
)
|
|
339
|
+
else:
|
|
340
|
+
messagebox.showerror("Setup Error", message)
|
|
341
|
+
self._result = (False, "")
|
|
342
|
+
|
|
343
|
+
if self.on_complete:
|
|
344
|
+
self.on_complete(*self._result)
|
|
345
|
+
|
|
346
|
+
self.window.quit()
|
|
347
|
+
|
|
348
|
+
def _cancel(self):
|
|
349
|
+
"""Cancel setup."""
|
|
350
|
+
self._result = (False, "")
|
|
351
|
+
if self.on_complete:
|
|
352
|
+
self.on_complete(*self._result)
|
|
353
|
+
self.window.quit()
|