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 CHANGED
@@ -32,9 +32,9 @@ License: MIT
32
32
  """
33
33
 
34
34
  # Version Information.
35
- __version__ = "1.9.180"
35
+ __version__ = "1.9.181"
36
36
  __phase__ = "0.9"
37
- __release_date__ = "2026-01-28"
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
- common_langs = [
21562
- ("English", "en"),
21563
- ("Dutch", "nl"),
21564
- ("German", "de"),
21565
- ("French", "fr"),
21566
- ("Spanish", "es"),
21567
- ("Italian", "it"),
21568
- ("Portuguese", "pt"),
21569
- ("Russian", "ru"),
21570
- ("Chinese", "zh"),
21571
- ("Japanese", "ja"),
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 common_langs:
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 common_langs:
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 (if in common_langs)
21583
- try:
21584
- for lang_name, lang_code in common_langs:
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 (user explicitly activates what they need)
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 (user explicitly activates what they need)
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 (user explicitly activates what they need)
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 (user explicitly activates what they need)
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 (user explicitly activates what they need)
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
- self.tm_display.setHtml(
33843
- f"<p style='color: #666;'><b>Source:</b> {source_text}</p>"
33844
- f"<p style='color: #999;'><i>No translation memory matches found</i></p>"
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}")
@@ -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
- self.info_label.setText("No terminology or NT matches for this segment")
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.180
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=D49WGFvjGTFaQ2Tmgl5jInj3qIUwzHdxPCJRv4iTjvY,2324894
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=O3ah7g-4Lb_iUctxl9sMyxh8V3A5I5PFxmy9iIH2Kgk,53484
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.180.dist-info/licenses/LICENSE,sha256=m28u-4qL5nXIWnJ6xlQVw__H30rWFtRK3pCOais2OuY,1092
81
- supervertaler-1.9.180.dist-info/METADATA,sha256=_RNcZZvz-EN-Kay2HuiR1hNQhRMVjPHZwNAjvnZ5t20,5725
82
- supervertaler-1.9.180.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
83
- supervertaler-1.9.180.dist-info/entry_points.txt,sha256=NP4hiCvx-_30YYKqgr-jfJYQvHr1qTYBMfoVmKIXSM8,53
84
- supervertaler-1.9.180.dist-info/top_level.txt,sha256=9tUHBYUSfaE4S2E4W3eavJsDyYymkwLfeWAHHAPT6Dk,22
85
- supervertaler-1.9.180.dist-info/RECORD,,
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,,