supervertaler 1.9.180__py3-none-any.whl → 1.9.181__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 +228 -73
- modules/termview_widget.py +17 -10
- {supervertaler-1.9.180.dist-info → supervertaler-1.9.181.dist-info}/METADATA +1 -1
- {supervertaler-1.9.180.dist-info → supervertaler-1.9.181.dist-info}/RECORD +8 -8
- {supervertaler-1.9.180.dist-info → supervertaler-1.9.181.dist-info}/WHEEL +0 -0
- {supervertaler-1.9.180.dist-info → supervertaler-1.9.181.dist-info}/entry_points.txt +0 -0
- {supervertaler-1.9.180.dist-info → supervertaler-1.9.181.dist-info}/licenses/LICENSE +0 -0
- {supervertaler-1.9.180.dist-info → supervertaler-1.9.181.dist-info}/top_level.txt +0 -0
Supervertaler.py
CHANGED
|
@@ -32,9 +32,9 @@ License: MIT
|
|
|
32
32
|
"""
|
|
33
33
|
|
|
34
34
|
# Version Information.
|
|
35
|
-
__version__ = "1.9.
|
|
35
|
+
__version__ = "1.9.181"
|
|
36
36
|
__phase__ = "0.9"
|
|
37
|
-
__release_date__ = "2026-01-
|
|
37
|
+
__release_date__ = "2026-01-30"
|
|
38
38
|
__edition__ = "Qt"
|
|
39
39
|
|
|
40
40
|
import sys
|
|
@@ -12202,27 +12202,90 @@ class SupervertalerQt(QMainWindow):
|
|
|
12202
12202
|
f"Error testing segmentation:\n\n{e}"
|
|
12203
12203
|
)
|
|
12204
12204
|
|
|
12205
|
-
def _update_both_termviews(self, source_text, termbase_list, nt_matches):
|
|
12205
|
+
def _update_both_termviews(self, source_text, termbase_list, nt_matches, status_hint=None):
|
|
12206
12206
|
"""Update all three Termview instances with the same data.
|
|
12207
|
-
|
|
12207
|
+
|
|
12208
12208
|
Termview locations:
|
|
12209
12209
|
1. Under grid (collapsible via View menu)
|
|
12210
12210
|
2. Match Panel tab (top section)
|
|
12211
|
+
|
|
12212
|
+
Args:
|
|
12213
|
+
source_text: The source text for the current segment
|
|
12214
|
+
termbase_list: List of termbase match dictionaries
|
|
12215
|
+
nt_matches: List of NT (Never Translate) matches
|
|
12216
|
+
status_hint: Optional hint for display when no matches:
|
|
12217
|
+
'no_termbases_activated' - no glossaries activated for project
|
|
12218
|
+
'wrong_language' - activated glossaries don't match project language
|
|
12211
12219
|
"""
|
|
12212
12220
|
# Update left Termview (under grid)
|
|
12213
12221
|
if hasattr(self, 'termview_widget') and self.termview_widget:
|
|
12214
12222
|
try:
|
|
12215
|
-
self.termview_widget.update_with_matches(source_text, termbase_list, nt_matches)
|
|
12223
|
+
self.termview_widget.update_with_matches(source_text, termbase_list, nt_matches, status_hint)
|
|
12216
12224
|
except Exception as e:
|
|
12217
12225
|
self.log(f"Error updating left termview: {e}")
|
|
12218
|
-
|
|
12226
|
+
|
|
12219
12227
|
# Update Match Panel Termview
|
|
12220
12228
|
if hasattr(self, 'termview_widget_match') and self.termview_widget_match:
|
|
12221
12229
|
try:
|
|
12222
|
-
self.termview_widget_match.update_with_matches(source_text, termbase_list, nt_matches)
|
|
12230
|
+
self.termview_widget_match.update_with_matches(source_text, termbase_list, nt_matches, status_hint)
|
|
12223
12231
|
except Exception as e:
|
|
12224
12232
|
self.log(f"Error updating Match Panel termview: {e}")
|
|
12225
|
-
|
|
12233
|
+
|
|
12234
|
+
def _get_termbase_status_hint(self) -> str:
|
|
12235
|
+
"""Check termbase activation status and return appropriate hint.
|
|
12236
|
+
|
|
12237
|
+
Returns:
|
|
12238
|
+
'no_termbases_activated' - if no glossaries are activated for this project
|
|
12239
|
+
'wrong_language' - if activated glossaries don't match project language pair
|
|
12240
|
+
None - if everything is correctly configured
|
|
12241
|
+
"""
|
|
12242
|
+
if not self.current_project:
|
|
12243
|
+
return None
|
|
12244
|
+
|
|
12245
|
+
project_id = self.current_project.id if hasattr(self.current_project, 'id') else None
|
|
12246
|
+
if not project_id:
|
|
12247
|
+
return None
|
|
12248
|
+
|
|
12249
|
+
# Check if termbase manager is available
|
|
12250
|
+
if not hasattr(self, 'termbase_mgr') or not self.termbase_mgr:
|
|
12251
|
+
return None
|
|
12252
|
+
|
|
12253
|
+
try:
|
|
12254
|
+
# Get active termbase IDs for this project
|
|
12255
|
+
active_tb_ids = self.termbase_mgr.get_active_termbase_ids(project_id)
|
|
12256
|
+
|
|
12257
|
+
# Check if no termbases are activated
|
|
12258
|
+
if not active_tb_ids or len(active_tb_ids) == 0:
|
|
12259
|
+
return 'no_termbases_activated'
|
|
12260
|
+
|
|
12261
|
+
# Check if any activated termbases match the project's language pair
|
|
12262
|
+
project_source = (self.current_project.source_lang or '').lower()
|
|
12263
|
+
project_target = (self.current_project.target_lang or '').lower()
|
|
12264
|
+
|
|
12265
|
+
# Get all termbases and check language pairs
|
|
12266
|
+
all_termbases = self.termbase_mgr.list_termbases()
|
|
12267
|
+
has_matching_language = False
|
|
12268
|
+
|
|
12269
|
+
for tb in all_termbases:
|
|
12270
|
+
if tb['id'] in active_tb_ids:
|
|
12271
|
+
tb_source = (tb.get('source_lang') or '').lower()
|
|
12272
|
+
tb_target = (tb.get('target_lang') or '').lower()
|
|
12273
|
+
# Match if: no language set, or languages match (bidirectional)
|
|
12274
|
+
if (not tb_source and not tb_target) or \
|
|
12275
|
+
(tb_source == project_source and tb_target == project_target) or \
|
|
12276
|
+
(tb_source == project_target and tb_target == project_source):
|
|
12277
|
+
has_matching_language = True
|
|
12278
|
+
break
|
|
12279
|
+
|
|
12280
|
+
if not has_matching_language:
|
|
12281
|
+
return 'wrong_language'
|
|
12282
|
+
|
|
12283
|
+
return None # All good
|
|
12284
|
+
|
|
12285
|
+
except Exception as e:
|
|
12286
|
+
self.log(f"Error checking termbase status: {e}")
|
|
12287
|
+
return None
|
|
12288
|
+
|
|
12226
12289
|
def _refresh_termbase_display_for_current_segment(self):
|
|
12227
12290
|
"""Refresh only termbase/glossary display for the current segment.
|
|
12228
12291
|
|
|
@@ -12282,9 +12345,12 @@ class SupervertalerQt(QMainWindow):
|
|
|
12282
12345
|
|
|
12283
12346
|
# Get NT matches
|
|
12284
12347
|
nt_matches = self.find_nt_matches_in_source(segment.source)
|
|
12285
|
-
|
|
12348
|
+
|
|
12349
|
+
# Get status hint for termbase activation
|
|
12350
|
+
status_hint = self._get_termbase_status_hint()
|
|
12351
|
+
|
|
12286
12352
|
# Update both Termview widgets (left and right)
|
|
12287
|
-
self._update_both_termviews(segment.source, termbase_list, nt_matches)
|
|
12353
|
+
self._update_both_termviews(segment.source, termbase_list, nt_matches, status_hint)
|
|
12288
12354
|
except Exception as e:
|
|
12289
12355
|
self.log(f"Error updating termview: {e}")
|
|
12290
12356
|
|
|
@@ -12776,9 +12842,12 @@ class SupervertalerQt(QMainWindow):
|
|
|
12776
12842
|
|
|
12777
12843
|
# Get NT matches
|
|
12778
12844
|
nt_matches = self.find_nt_matches_in_source(segment.source)
|
|
12779
|
-
|
|
12845
|
+
|
|
12846
|
+
# Get status hint (although after adding a term, it should be fine)
|
|
12847
|
+
status_hint = self._get_termbase_status_hint()
|
|
12848
|
+
|
|
12780
12849
|
# Update both Termview widgets (left and right)
|
|
12781
|
-
self._update_both_termviews(segment.source, termbase_list, nt_matches)
|
|
12850
|
+
self._update_both_termviews(segment.source, termbase_list, nt_matches, status_hint)
|
|
12782
12851
|
self.log(f"✅ Both TermView widgets updated instantly with new term")
|
|
12783
12852
|
|
|
12784
12853
|
# Update source cell highlighting with updated cache
|
|
@@ -21558,36 +21627,35 @@ class SupervertalerQt(QMainWindow):
|
|
|
21558
21627
|
|
|
21559
21628
|
# Source language
|
|
21560
21629
|
source_lang_combo = QComboBox()
|
|
21561
|
-
|
|
21562
|
-
|
|
21563
|
-
("
|
|
21564
|
-
("
|
|
21565
|
-
("
|
|
21566
|
-
("
|
|
21567
|
-
("
|
|
21568
|
-
("
|
|
21569
|
-
("
|
|
21570
|
-
("
|
|
21571
|
-
("
|
|
21630
|
+
# Full language list matching Settings → Language Pair (with ISO 639-1 codes)
|
|
21631
|
+
available_langs = [
|
|
21632
|
+
("Afrikaans", "af"), ("Albanian", "sq"), ("Arabic", "ar"), ("Armenian", "hy"),
|
|
21633
|
+
("Basque", "eu"), ("Bengali", "bn"), ("Bulgarian", "bg"), ("Catalan", "ca"),
|
|
21634
|
+
("Chinese (Simplified)", "zh-CN"), ("Chinese (Traditional)", "zh-TW"),
|
|
21635
|
+
("Croatian", "hr"), ("Czech", "cs"), ("Danish", "da"), ("Dutch", "nl"),
|
|
21636
|
+
("English", "en"), ("Estonian", "et"), ("Finnish", "fi"), ("French", "fr"),
|
|
21637
|
+
("Galician", "gl"), ("Georgian", "ka"), ("German", "de"), ("Greek", "el"),
|
|
21638
|
+
("Hebrew", "he"), ("Hindi", "hi"), ("Hungarian", "hu"), ("Icelandic", "is"),
|
|
21639
|
+
("Indonesian", "id"), ("Irish", "ga"), ("Italian", "it"), ("Japanese", "ja"),
|
|
21640
|
+
("Korean", "ko"), ("Latvian", "lv"), ("Lithuanian", "lt"), ("Macedonian", "mk"),
|
|
21641
|
+
("Malay", "ms"), ("Norwegian", "no"), ("Persian", "fa"), ("Polish", "pl"),
|
|
21642
|
+
("Portuguese", "pt"), ("Romanian", "ro"), ("Russian", "ru"), ("Serbian", "sr"),
|
|
21643
|
+
("Slovak", "sk"), ("Slovenian", "sl"), ("Spanish", "es"), ("Swahili", "sw"),
|
|
21644
|
+
("Swedish", "sv"), ("Thai", "th"), ("Turkish", "tr"), ("Ukrainian", "uk"),
|
|
21645
|
+
("Urdu", "ur"), ("Vietnamese", "vi"), ("Welsh", "cy"),
|
|
21572
21646
|
]
|
|
21573
|
-
for lang_name, lang_code in
|
|
21647
|
+
for lang_name, lang_code in available_langs:
|
|
21574
21648
|
source_lang_combo.addItem(lang_name, lang_code)
|
|
21575
21649
|
settings_layout.addRow("Source Language:", source_lang_combo)
|
|
21576
|
-
|
|
21650
|
+
|
|
21577
21651
|
# Target language
|
|
21578
21652
|
target_lang_combo = QComboBox()
|
|
21579
|
-
for lang_name, lang_code in
|
|
21653
|
+
for lang_name, lang_code in available_langs:
|
|
21580
21654
|
target_lang_combo.addItem(lang_name, lang_code)
|
|
21581
|
-
|
|
21582
|
-
# Set defaults based on global language settings
|
|
21583
|
-
|
|
21584
|
-
|
|
21585
|
-
if lang_name == self.source_language:
|
|
21586
|
-
source_lang_combo.setCurrentText(lang_name)
|
|
21587
|
-
if lang_name == self.target_language:
|
|
21588
|
-
target_lang_combo.setCurrentText(lang_name)
|
|
21589
|
-
except:
|
|
21590
|
-
target_lang_combo.setCurrentIndex(1) # Fallback to Dutch
|
|
21655
|
+
|
|
21656
|
+
# Set defaults based on global language settings
|
|
21657
|
+
source_lang_combo.setCurrentText(self.source_language)
|
|
21658
|
+
target_lang_combo.setCurrentText(self.target_language)
|
|
21591
21659
|
|
|
21592
21660
|
settings_layout.addRow("Target Language:", target_lang_combo)
|
|
21593
21661
|
|
|
@@ -21709,7 +21777,11 @@ class SupervertalerQt(QMainWindow):
|
|
|
21709
21777
|
target_lang=target_lang,
|
|
21710
21778
|
segments=[]
|
|
21711
21779
|
)
|
|
21712
|
-
|
|
21780
|
+
|
|
21781
|
+
# Sync global language settings with new project languages
|
|
21782
|
+
self.source_language = source_lang
|
|
21783
|
+
self.target_language = target_lang
|
|
21784
|
+
|
|
21713
21785
|
# Process source text if provided
|
|
21714
21786
|
source_text = text_input.toPlainText().strip()
|
|
21715
21787
|
if source_text:
|
|
@@ -21819,7 +21891,13 @@ class SupervertalerQt(QMainWindow):
|
|
|
21819
21891
|
self.current_project = Project.from_dict(data)
|
|
21820
21892
|
self.project_file_path = file_path
|
|
21821
21893
|
self.project_modified = False
|
|
21822
|
-
|
|
21894
|
+
|
|
21895
|
+
# Sync global language settings with project languages
|
|
21896
|
+
if self.current_project.source_lang:
|
|
21897
|
+
self.source_language = self.current_project.source_lang
|
|
21898
|
+
if self.current_project.target_lang:
|
|
21899
|
+
self.target_language = self.current_project.target_lang
|
|
21900
|
+
|
|
21823
21901
|
# Restore prompt settings if they exist (unified library)
|
|
21824
21902
|
if hasattr(self.current_project, 'prompt_settings') and self.current_project.prompt_settings:
|
|
21825
21903
|
prompt_settings = self.current_project.prompt_settings
|
|
@@ -23734,9 +23812,9 @@ class SupervertalerQt(QMainWindow):
|
|
|
23734
23812
|
# Initialize TM for this project
|
|
23735
23813
|
self.initialize_tm_database()
|
|
23736
23814
|
|
|
23737
|
-
# Deactivate all resources for new project
|
|
23815
|
+
# Deactivate all resources for new project, then auto-activate language-matching ones
|
|
23738
23816
|
self._deactivate_all_resources_for_new_project()
|
|
23739
|
-
|
|
23817
|
+
|
|
23740
23818
|
# Auto-resize rows for better initial display
|
|
23741
23819
|
self.auto_resize_rows()
|
|
23742
23820
|
|
|
@@ -26210,7 +26288,11 @@ class SupervertalerQt(QMainWindow):
|
|
|
26210
26288
|
|
|
26211
26289
|
# Store memoQ source path in project for persistence across saves
|
|
26212
26290
|
self.current_project.memoq_source_path = file_path
|
|
26213
|
-
|
|
26291
|
+
|
|
26292
|
+
# Sync global language settings with imported project languages
|
|
26293
|
+
self.source_language = source_lang
|
|
26294
|
+
self.target_language = target_lang
|
|
26295
|
+
|
|
26214
26296
|
# Create segments with simple sequential IDs
|
|
26215
26297
|
for idx, source_text in enumerate(source_segments):
|
|
26216
26298
|
existing_target = target_segments[idx] if idx < len(target_segments) else ""
|
|
@@ -26234,15 +26316,15 @@ class SupervertalerQt(QMainWindow):
|
|
|
26234
26316
|
self.load_segments_to_grid()
|
|
26235
26317
|
self.initialize_tm_database()
|
|
26236
26318
|
|
|
26237
|
-
# Deactivate all resources for new project
|
|
26319
|
+
# Deactivate all resources for new project, then auto-activate language-matching ones
|
|
26238
26320
|
self._deactivate_all_resources_for_new_project()
|
|
26239
|
-
|
|
26321
|
+
|
|
26240
26322
|
# Auto-resize rows for better initial display
|
|
26241
26323
|
self.auto_resize_rows()
|
|
26242
|
-
|
|
26324
|
+
|
|
26243
26325
|
# Initialize spellcheck for target language
|
|
26244
26326
|
self._initialize_spellcheck_for_target_language(target_lang)
|
|
26245
|
-
|
|
26327
|
+
|
|
26246
26328
|
# If smart formatting was used, auto-enable Tags view so user sees the tags
|
|
26247
26329
|
if self.memoq_smart_formatting:
|
|
26248
26330
|
self._enable_tag_view_after_import()
|
|
@@ -26731,7 +26813,11 @@ class SupervertalerQt(QMainWindow):
|
|
|
26731
26813
|
|
|
26732
26814
|
# Store memoQ XLIFF source path in project for persistence across saves
|
|
26733
26815
|
self.current_project.mqxliff_source_path = file_path
|
|
26734
|
-
|
|
26816
|
+
|
|
26817
|
+
# Sync global language settings with imported project languages
|
|
26818
|
+
self.source_language = source_lang
|
|
26819
|
+
self.target_language = target_lang
|
|
26820
|
+
|
|
26735
26821
|
# Update UI
|
|
26736
26822
|
self.project_file_path = None
|
|
26737
26823
|
self.project_modified = True
|
|
@@ -26739,15 +26825,15 @@ class SupervertalerQt(QMainWindow):
|
|
|
26739
26825
|
self.load_segments_to_grid()
|
|
26740
26826
|
self.initialize_tm_database()
|
|
26741
26827
|
|
|
26742
|
-
# Deactivate all resources for new project
|
|
26828
|
+
# Deactivate all resources for new project, then auto-activate language-matching ones
|
|
26743
26829
|
self._deactivate_all_resources_for_new_project()
|
|
26744
|
-
|
|
26830
|
+
|
|
26745
26831
|
# Auto-resize rows for better initial display
|
|
26746
26832
|
self.auto_resize_rows()
|
|
26747
|
-
|
|
26833
|
+
|
|
26748
26834
|
# Initialize spellcheck for target language
|
|
26749
26835
|
self._initialize_spellcheck_for_target_language(target_lang)
|
|
26750
|
-
|
|
26836
|
+
|
|
26751
26837
|
# Log success
|
|
26752
26838
|
self.log(f"✓ Imported {len(segments)} segments from memoQ XLIFF: {Path(file_path).name}")
|
|
26753
26839
|
self.log(f" Source: {source_lang}, Target: {target_lang}")
|
|
@@ -27006,7 +27092,11 @@ class SupervertalerQt(QMainWindow):
|
|
|
27006
27092
|
|
|
27007
27093
|
# Store CafeTran source path in project for persistence across saves
|
|
27008
27094
|
self.current_project.cafetran_source_path = file_path
|
|
27009
|
-
|
|
27095
|
+
|
|
27096
|
+
# Sync global language settings with imported project languages
|
|
27097
|
+
self.source_language = self.current_project.source_lang
|
|
27098
|
+
self.target_language = self.current_project.target_lang
|
|
27099
|
+
|
|
27010
27100
|
# Update UI
|
|
27011
27101
|
self.project_file_path = None
|
|
27012
27102
|
self.project_modified = True
|
|
@@ -27014,16 +27104,16 @@ class SupervertalerQt(QMainWindow):
|
|
|
27014
27104
|
self.load_segments_to_grid()
|
|
27015
27105
|
self.initialize_tm_database()
|
|
27016
27106
|
|
|
27017
|
-
# Deactivate all resources for new project
|
|
27107
|
+
# Deactivate all resources for new project, then auto-activate language-matching ones
|
|
27018
27108
|
self._deactivate_all_resources_for_new_project()
|
|
27019
|
-
|
|
27109
|
+
|
|
27020
27110
|
# Auto-resize rows for better initial display
|
|
27021
27111
|
self.auto_resize_rows()
|
|
27022
|
-
|
|
27112
|
+
|
|
27023
27113
|
# Initialize spellcheck for target language
|
|
27024
27114
|
target_lang = self.current_project.target_lang if self.current_project else 'nl'
|
|
27025
27115
|
self._initialize_spellcheck_for_target_language(target_lang)
|
|
27026
|
-
|
|
27116
|
+
|
|
27027
27117
|
# Log success
|
|
27028
27118
|
self.log(f"✓ Imported {len(segments)} segments from CafeTran bilingual DOCX: {Path(file_path).name}")
|
|
27029
27119
|
|
|
@@ -27230,7 +27320,11 @@ class SupervertalerQt(QMainWindow):
|
|
|
27230
27320
|
|
|
27231
27321
|
# Store Trados source path in project for persistence across saves
|
|
27232
27322
|
self.current_project.trados_source_path = file_path
|
|
27233
|
-
|
|
27323
|
+
|
|
27324
|
+
# Sync global language settings with imported project languages
|
|
27325
|
+
self.source_language = source_lang
|
|
27326
|
+
self.target_language = target_lang
|
|
27327
|
+
|
|
27234
27328
|
# Update UI
|
|
27235
27329
|
self.project_file_path = None
|
|
27236
27330
|
self.project_modified = True
|
|
@@ -27238,15 +27332,15 @@ class SupervertalerQt(QMainWindow):
|
|
|
27238
27332
|
self.load_segments_to_grid()
|
|
27239
27333
|
self.initialize_tm_database()
|
|
27240
27334
|
|
|
27241
|
-
# Deactivate all resources for new project
|
|
27335
|
+
# Deactivate all resources for new project, then auto-activate language-matching ones
|
|
27242
27336
|
self._deactivate_all_resources_for_new_project()
|
|
27243
|
-
|
|
27337
|
+
|
|
27244
27338
|
# Auto-resize rows for better initial display
|
|
27245
27339
|
self.auto_resize_rows()
|
|
27246
|
-
|
|
27340
|
+
|
|
27247
27341
|
# Initialize spellcheck for target language
|
|
27248
27342
|
self._initialize_spellcheck_for_target_language(target_lang)
|
|
27249
|
-
|
|
27343
|
+
|
|
27250
27344
|
# Count segments with tags
|
|
27251
27345
|
tagged_count = sum(1 for s in trados_segments if s.source_tags)
|
|
27252
27346
|
|
|
@@ -27590,7 +27684,11 @@ class SupervertalerQt(QMainWindow):
|
|
|
27590
27684
|
self.sdlppx_handler = handler
|
|
27591
27685
|
self.sdlppx_source_file = file_path
|
|
27592
27686
|
self.current_project.sdlppx_source_path = file_path
|
|
27593
|
-
|
|
27687
|
+
|
|
27688
|
+
# Sync global language settings with imported project languages
|
|
27689
|
+
self.source_language = source_lang
|
|
27690
|
+
self.target_language = target_lang
|
|
27691
|
+
|
|
27594
27692
|
# Update UI
|
|
27595
27693
|
self.project_file_path = None
|
|
27596
27694
|
self.project_modified = True
|
|
@@ -27923,6 +28021,10 @@ class SupervertalerQt(QMainWindow):
|
|
|
27923
28021
|
# Store Phrase source path in project for persistence across saves
|
|
27924
28022
|
self.current_project.phrase_source_path = file_path
|
|
27925
28023
|
|
|
28024
|
+
# Sync global language settings with imported project languages
|
|
28025
|
+
self.source_language = source_lang
|
|
28026
|
+
self.target_language = target_lang
|
|
28027
|
+
|
|
27926
28028
|
# Update UI
|
|
27927
28029
|
self.project_file_path = None
|
|
27928
28030
|
self.project_modified = True
|
|
@@ -28203,7 +28305,11 @@ class SupervertalerQt(QMainWindow):
|
|
|
28203
28305
|
|
|
28204
28306
|
# Store Déjà Vu source path in project for persistence
|
|
28205
28307
|
self.current_project.dejavu_source_path = file_path
|
|
28206
|
-
|
|
28308
|
+
|
|
28309
|
+
# Sync global language settings with imported project languages
|
|
28310
|
+
self.source_language = source_lang
|
|
28311
|
+
self.target_language = target_lang
|
|
28312
|
+
|
|
28207
28313
|
# Create segments
|
|
28208
28314
|
for idx, seg_data in enumerate(segments_data):
|
|
28209
28315
|
segment = Segment(
|
|
@@ -31535,9 +31641,12 @@ class SupervertalerQt(QMainWindow):
|
|
|
31535
31641
|
]
|
|
31536
31642
|
# Also get NT matches (fresh, not cached - they may have changed)
|
|
31537
31643
|
nt_matches = self.find_nt_matches_in_source(segment.source)
|
|
31538
|
-
|
|
31644
|
+
|
|
31645
|
+
# Get status hint for termbase activation
|
|
31646
|
+
status_hint = self._get_termbase_status_hint()
|
|
31647
|
+
|
|
31539
31648
|
# Update both Termview widgets (left and right)
|
|
31540
|
-
self._update_both_termviews(segment.source, termbase_matches, nt_matches)
|
|
31649
|
+
self._update_both_termviews(segment.source, termbase_matches, nt_matches, status_hint)
|
|
31541
31650
|
except Exception as e:
|
|
31542
31651
|
self.log(f"Error updating termview from cache: {e}")
|
|
31543
31652
|
|
|
@@ -31621,9 +31730,12 @@ class SupervertalerQt(QMainWindow):
|
|
|
31621
31730
|
] if stored_matches else []
|
|
31622
31731
|
# Also get NT matches
|
|
31623
31732
|
nt_matches = self.find_nt_matches_in_source(segment.source)
|
|
31624
|
-
|
|
31733
|
+
|
|
31734
|
+
# Get status hint for termbase activation
|
|
31735
|
+
status_hint = self._get_termbase_status_hint()
|
|
31736
|
+
|
|
31625
31737
|
# Update both Termview widgets (left and right)
|
|
31626
|
-
self._update_both_termviews(segment.source, termbase_matches, nt_matches)
|
|
31738
|
+
self._update_both_termviews(segment.source, termbase_matches, nt_matches, status_hint)
|
|
31627
31739
|
except Exception as e:
|
|
31628
31740
|
self.log(f"Error refreshing termview: {e}")
|
|
31629
31741
|
|
|
@@ -33765,7 +33877,8 @@ OUTPUT ONLY THE SEGMENT MARKERS. DO NOT ADD EXPLANATIONS BEFORE OR AFTER."""
|
|
|
33765
33877
|
self.nt_manager.set_list_active(list_name, False)
|
|
33766
33878
|
|
|
33767
33879
|
self.log("📋 New project: All TMs, glossaries, and NT lists deactivated (start clean)")
|
|
33768
|
-
|
|
33880
|
+
self.log("💡 Tip: Go to Resources tab to activate TMs and glossaries for this project")
|
|
33881
|
+
|
|
33769
33882
|
def search_and_display_tm_matches(self, source_text: str):
|
|
33770
33883
|
"""Search TM and Termbases and display matches with visual diff for fuzzy matches"""
|
|
33771
33884
|
self.log(f"🚨 search_and_display_tm_matches called with source_text: '{source_text[:50]}...'")
|
|
@@ -33788,11 +33901,34 @@ OUTPUT ONLY THE SEGMENT MARKERS. DO NOT ADD EXPLANATIONS BEFORE OR AFTER."""
|
|
|
33788
33901
|
try:
|
|
33789
33902
|
# Get activated TM IDs for current project
|
|
33790
33903
|
tm_ids = None
|
|
33904
|
+
no_tms_activated = False
|
|
33905
|
+
tms_wrong_language = False
|
|
33791
33906
|
if hasattr(self, 'tm_metadata_mgr') and self.tm_metadata_mgr and self.current_project:
|
|
33792
33907
|
project_id = self.current_project.id if hasattr(self.current_project, 'id') else None
|
|
33793
33908
|
if project_id:
|
|
33794
33909
|
tm_ids = self.tm_metadata_mgr.get_active_tm_ids(project_id)
|
|
33795
|
-
|
|
33910
|
+
# Check if no TMs are activated for this project
|
|
33911
|
+
if tm_ids is not None and len(tm_ids) == 0:
|
|
33912
|
+
no_tms_activated = True
|
|
33913
|
+
elif tm_ids and len(tm_ids) > 0:
|
|
33914
|
+
# Check if any activated TMs match the project's language pair
|
|
33915
|
+
project_source = (self.current_project.source_lang or '').lower()
|
|
33916
|
+
project_target = (self.current_project.target_lang or '').lower()
|
|
33917
|
+
all_tms = self.tm_metadata_mgr.get_all_tms()
|
|
33918
|
+
has_matching_language = False
|
|
33919
|
+
for tm in all_tms:
|
|
33920
|
+
if tm['id'] in tm_ids:
|
|
33921
|
+
tm_source = (tm.get('source_lang') or '').lower()
|
|
33922
|
+
tm_target = (tm.get('target_lang') or '').lower()
|
|
33923
|
+
# Match if languages align (bidirectional) or TM has no language set
|
|
33924
|
+
if (not tm_source and not tm_target) or \
|
|
33925
|
+
(tm_source == project_source and tm_target == project_target) or \
|
|
33926
|
+
(tm_source == project_target and tm_target == project_source):
|
|
33927
|
+
has_matching_language = True
|
|
33928
|
+
break
|
|
33929
|
+
if not has_matching_language:
|
|
33930
|
+
tms_wrong_language = True
|
|
33931
|
+
|
|
33796
33932
|
# Search for matches (using activated TMs if available)
|
|
33797
33933
|
matches = self.tm_database.search_all(source_text, tm_ids=tm_ids, max_matches=5)
|
|
33798
33934
|
|
|
@@ -33839,10 +33975,26 @@ OUTPUT ONLY THE SEGMENT MARKERS. DO NOT ADD EXPLANATIONS BEFORE OR AFTER."""
|
|
|
33839
33975
|
|
|
33840
33976
|
if not matches:
|
|
33841
33977
|
if hasattr(self, 'tm_display'):
|
|
33842
|
-
|
|
33843
|
-
|
|
33844
|
-
|
|
33845
|
-
|
|
33978
|
+
if no_tms_activated:
|
|
33979
|
+
# Show helpful message when no TMs are activated
|
|
33980
|
+
self.tm_display.setHtml(
|
|
33981
|
+
f"<p style='color: #666;'><b>Source:</b> {source_text}</p>"
|
|
33982
|
+
f"<p style='color: #E65100;'><i>No TMs activated for this project.</i></p>"
|
|
33983
|
+
f"<p style='color: #999; font-size: 9pt;'>Go to <b>Resources → TM</b> to activate translation memories.</p>"
|
|
33984
|
+
)
|
|
33985
|
+
elif tms_wrong_language:
|
|
33986
|
+
# Show message when TMs are activated but don't match project language pair
|
|
33987
|
+
project_lang_pair = f"{self.current_project.source_lang} → {self.current_project.target_lang}" if self.current_project else ""
|
|
33988
|
+
self.tm_display.setHtml(
|
|
33989
|
+
f"<p style='color: #666;'><b>Source:</b> {source_text}</p>"
|
|
33990
|
+
f"<p style='color: #E65100;'><i>Activated TMs don't match project language ({project_lang_pair}).</i></p>"
|
|
33991
|
+
f"<p style='color: #999; font-size: 9pt;'>Go to <b>Resources → TM</b> to activate TMs for this language pair.</p>"
|
|
33992
|
+
)
|
|
33993
|
+
else:
|
|
33994
|
+
self.tm_display.setHtml(
|
|
33995
|
+
f"<p style='color: #666;'><b>Source:</b> {source_text}</p>"
|
|
33996
|
+
f"<p style='color: #999;'><i>No translation memory matches found</i></p>"
|
|
33997
|
+
)
|
|
33846
33998
|
return
|
|
33847
33999
|
|
|
33848
34000
|
# If using TranslationResultsPanel, populate it with TM and Termbase results
|
|
@@ -35494,8 +35646,11 @@ OUTPUT ONLY THE SEGMENT MARKERS. DO NOT ADD EXPLANATIONS BEFORE OR AFTER."""
|
|
|
35494
35646
|
'termbase_id': match_info.get('termbase_id'),
|
|
35495
35647
|
'notes': match_info.get('notes', '')
|
|
35496
35648
|
})
|
|
35649
|
+
# Get status hint for termbase activation
|
|
35650
|
+
status_hint = self._get_termbase_status_hint()
|
|
35651
|
+
|
|
35497
35652
|
# Update both Termview widgets
|
|
35498
|
-
self._update_both_termviews(segment.source, tb_list, nt_matches)
|
|
35653
|
+
self._update_both_termviews(segment.source, tb_list, nt_matches, status_hint)
|
|
35499
35654
|
self.log(" ✓ TermView updated")
|
|
35500
35655
|
except Exception as e:
|
|
35501
35656
|
self.log(f" ⚠️ TermView update error: {e}")
|
modules/termview_widget.py
CHANGED
|
@@ -694,27 +694,28 @@ class TermviewWidget(QWidget):
|
|
|
694
694
|
font.setBold(self.current_font_bold)
|
|
695
695
|
block.source_label.setFont(font)
|
|
696
696
|
|
|
697
|
-
def update_with_matches(self, source_text: str, termbase_matches: List[Dict], nt_matches: List[Dict] = None):
|
|
697
|
+
def update_with_matches(self, source_text: str, termbase_matches: List[Dict], nt_matches: List[Dict] = None, status_hint: str = None):
|
|
698
698
|
"""
|
|
699
699
|
Update the termview display with pre-computed termbase and NT matches
|
|
700
|
-
|
|
700
|
+
|
|
701
701
|
RYS-STYLE DISPLAY: Show source text as tokens with translations underneath
|
|
702
|
-
|
|
702
|
+
|
|
703
703
|
Args:
|
|
704
704
|
source_text: Source segment text
|
|
705
705
|
termbase_matches: List of termbase match dicts from Translation Results
|
|
706
706
|
nt_matches: Optional list of NT match dicts with 'text', 'start', 'end', 'list_name' keys
|
|
707
|
+
status_hint: Optional hint about why there might be no matches (e.g., 'no_termbases_activated', 'wrong_language')
|
|
707
708
|
"""
|
|
708
709
|
self.current_source = source_text
|
|
709
|
-
|
|
710
|
+
|
|
710
711
|
# Clear existing blocks and shortcut mappings
|
|
711
712
|
self.clear_terms()
|
|
712
713
|
self.shortcut_terms = {} # Reset shortcut mappings
|
|
713
|
-
|
|
714
|
+
|
|
714
715
|
if not source_text or not source_text.strip():
|
|
715
716
|
self.info_label.setText("No segment selected")
|
|
716
717
|
return
|
|
717
|
-
|
|
718
|
+
|
|
718
719
|
# Strip HTML/XML tags from source text for display in TermView
|
|
719
720
|
# This handles CAT tool tags like <b>, </b>, <i>, </i>, <u>, </u>, <bi>, <sub>, <sup>, <li-o>, <li-b>
|
|
720
721
|
# as well as memoQ tags {1}, [2}, {3], Trados tags <1>, </1>, and Déjà Vu tags {00001}
|
|
@@ -725,16 +726,22 @@ class TermviewWidget(QWidget):
|
|
|
725
726
|
display_text = re.sub(r'\[[^\[\]]*\}', '', display_text) # Opening: [anything}
|
|
726
727
|
display_text = re.sub(r'\{[^\{\}]*\]', '', display_text) # Closing: {anything]
|
|
727
728
|
display_text = display_text.strip()
|
|
728
|
-
|
|
729
|
+
|
|
729
730
|
# If stripping tags leaves nothing, fall back to original
|
|
730
731
|
if not display_text:
|
|
731
732
|
display_text = source_text
|
|
732
|
-
|
|
733
|
+
|
|
733
734
|
has_termbase = termbase_matches and len(termbase_matches) > 0
|
|
734
735
|
has_nt = nt_matches and len(nt_matches) > 0
|
|
735
|
-
|
|
736
|
+
|
|
736
737
|
if not has_termbase and not has_nt:
|
|
737
|
-
|
|
738
|
+
# Show appropriate message based on status hint
|
|
739
|
+
if status_hint == 'no_termbases_activated':
|
|
740
|
+
self.info_label.setText("No glossaries activated. Go to Resources → Glossary to activate.")
|
|
741
|
+
elif status_hint == 'wrong_language':
|
|
742
|
+
self.info_label.setText("Activated glossaries don't match project language pair.")
|
|
743
|
+
else:
|
|
744
|
+
self.info_label.setText("No terminology or NT matches for this segment")
|
|
738
745
|
return
|
|
739
746
|
|
|
740
747
|
# Convert termbase matches to dict for easy lookup: {source_term.lower(): [translations]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: supervertaler
|
|
3
|
-
Version: 1.9.
|
|
3
|
+
Version: 1.9.181
|
|
4
4
|
Summary: Professional AI-enhanced translation workbench with multi-LLM support, glossary system, TM, spellcheck, voice commands, and PyQt6 interface. Batteries included (core).
|
|
5
5
|
Home-page: https://supervertaler.com
|
|
6
6
|
Author: Michael Beijer
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Supervertaler.py,sha256=
|
|
1
|
+
Supervertaler.py,sha256=8dvcmMQ-U7MpzzXQVLAsoB0O-yF_HMl142HfIiaMprE,2333467
|
|
2
2
|
modules/__init__.py,sha256=G58XleS-EJ2sX4Kehm-3N2m618_W2Es0Kg8CW_eBG7g,327
|
|
3
3
|
modules/ai_actions.py,sha256=i5MJcM-7Y6CAvKUwxmxrVHeoZAVtAP7aRDdWM5KLkO0,33877
|
|
4
4
|
modules/ai_attachment_manager.py,sha256=juZlrW3UPkIkcnj0SREgOQkQROLf0fcu3ShZcKXMxsI,11361
|
|
@@ -59,7 +59,7 @@ modules/term_extractor.py,sha256=qPvKNCVXFTGEGwXNvvC0cfCmdb5c3WhzE38EOgKdKUI,112
|
|
|
59
59
|
modules/termbase_entry_editor.py,sha256=iWO9CgLjMomGAqBXDsGAX7TFJvDOp2s_taS4gBL1rZY,35818
|
|
60
60
|
modules/termbase_import_export.py,sha256=16IAY04IS_rgt0GH5UOUzUI5NoqAli4JMfMquxmFBm0,23552
|
|
61
61
|
modules/termbase_manager.py,sha256=7KXEFab6y0o1EmFZwHs3ADklC95udVenxvrmN4XUoj0,48808
|
|
62
|
-
modules/termview_widget.py,sha256=
|
|
62
|
+
modules/termview_widget.py,sha256=PibDY55CjBY4BSb6aMGEp4Y2JHNB67QWOQFTDNyeYy8,53968
|
|
63
63
|
modules/theme_manager.py,sha256=Qk_jfCmfm7fjdMAOyBHpD18w3MiRfWBZk0cHTw6yAAg,18639
|
|
64
64
|
modules/tm_editor_dialog.py,sha256=AzGwq4QW641uFJdF8DljLTRRp4FLoYX3Pe4rlTjQWNg,3517
|
|
65
65
|
modules/tm_manager_qt.py,sha256=h2bvXkRuboHf_RRz9-5FX35GVRlpXgRDWeXyj1QWtPs,54406
|
|
@@ -77,9 +77,9 @@ modules/unified_prompt_manager_qt.py,sha256=U89UFGG-M7BLetoaLAlma0x-n8SIyx682DhS
|
|
|
77
77
|
modules/voice_commands.py,sha256=iBb-gjWxRMLhFH7-InSRjYJz1EIDBNA2Pog8V7TtJaY,38516
|
|
78
78
|
modules/voice_dictation.py,sha256=QmitXfkG-vRt5hIQATjphHdhXfqmwhzcQcbXB6aRzIg,16386
|
|
79
79
|
modules/voice_dictation_lite.py,sha256=jorY0BmWE-8VczbtGrWwt1zbnOctMoSlWOsQrcufBcc,9423
|
|
80
|
-
supervertaler-1.9.
|
|
81
|
-
supervertaler-1.9.
|
|
82
|
-
supervertaler-1.9.
|
|
83
|
-
supervertaler-1.9.
|
|
84
|
-
supervertaler-1.9.
|
|
85
|
-
supervertaler-1.9.
|
|
80
|
+
supervertaler-1.9.181.dist-info/licenses/LICENSE,sha256=m28u-4qL5nXIWnJ6xlQVw__H30rWFtRK3pCOais2OuY,1092
|
|
81
|
+
supervertaler-1.9.181.dist-info/METADATA,sha256=OQ1LAlPRGRyBLRAy3jX7II9VFMlrIMqy-s3o1L_NELg,5725
|
|
82
|
+
supervertaler-1.9.181.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
83
|
+
supervertaler-1.9.181.dist-info/entry_points.txt,sha256=NP4hiCvx-_30YYKqgr-jfJYQvHr1qTYBMfoVmKIXSM8,53
|
|
84
|
+
supervertaler-1.9.181.dist-info/top_level.txt,sha256=9tUHBYUSfaE4S2E4W3eavJsDyYymkwLfeWAHHAPT6Dk,22
|
|
85
|
+
supervertaler-1.9.181.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|