supervertaler 1.9.179__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 +290 -149
- modules/termview_widget.py +17 -10
- modules/theme_manager.py +41 -4
- {supervertaler-1.9.179.dist-info → supervertaler-1.9.181.dist-info}/METADATA +1 -1
- {supervertaler-1.9.179.dist-info → supervertaler-1.9.181.dist-info}/RECORD +9 -9
- {supervertaler-1.9.179.dist-info → supervertaler-1.9.181.dist-info}/WHEEL +0 -0
- {supervertaler-1.9.179.dist-info → supervertaler-1.9.181.dist-info}/entry_points.txt +0 -0
- {supervertaler-1.9.179.dist-info → supervertaler-1.9.181.dist-info}/licenses/LICENSE +0 -0
- {supervertaler-1.9.179.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
|
|
@@ -6357,6 +6357,9 @@ class SupervertalerQt(QMainWindow):
|
|
|
6357
6357
|
|
|
6358
6358
|
# Initialize theme manager and apply theme
|
|
6359
6359
|
self.theme_manager = ThemeManager(self.user_data_path)
|
|
6360
|
+
# Apply saved global UI font scale
|
|
6361
|
+
saved_font_scale = self._get_global_ui_font_scale()
|
|
6362
|
+
self.theme_manager.font_scale = saved_font_scale
|
|
6360
6363
|
self.theme_manager.apply_theme(QApplication.instance())
|
|
6361
6364
|
|
|
6362
6365
|
# Update widgets that were created before theme_manager existed
|
|
@@ -6596,6 +6599,9 @@ class SupervertalerQt(QMainWindow):
|
|
|
6596
6599
|
# Update theme manager
|
|
6597
6600
|
from modules.theme_manager import ThemeManager
|
|
6598
6601
|
self.theme_manager = ThemeManager(self.user_data_path)
|
|
6602
|
+
# Apply saved global UI font scale
|
|
6603
|
+
saved_font_scale = self._get_global_ui_font_scale()
|
|
6604
|
+
self.theme_manager.font_scale = saved_font_scale
|
|
6599
6605
|
self.theme_manager.apply_theme(QApplication.instance())
|
|
6600
6606
|
|
|
6601
6607
|
# Update recent projects file path
|
|
@@ -12196,27 +12202,90 @@ class SupervertalerQt(QMainWindow):
|
|
|
12196
12202
|
f"Error testing segmentation:\n\n{e}"
|
|
12197
12203
|
)
|
|
12198
12204
|
|
|
12199
|
-
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):
|
|
12200
12206
|
"""Update all three Termview instances with the same data.
|
|
12201
|
-
|
|
12207
|
+
|
|
12202
12208
|
Termview locations:
|
|
12203
12209
|
1. Under grid (collapsible via View menu)
|
|
12204
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
|
|
12205
12219
|
"""
|
|
12206
12220
|
# Update left Termview (under grid)
|
|
12207
12221
|
if hasattr(self, 'termview_widget') and self.termview_widget:
|
|
12208
12222
|
try:
|
|
12209
|
-
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)
|
|
12210
12224
|
except Exception as e:
|
|
12211
12225
|
self.log(f"Error updating left termview: {e}")
|
|
12212
|
-
|
|
12226
|
+
|
|
12213
12227
|
# Update Match Panel Termview
|
|
12214
12228
|
if hasattr(self, 'termview_widget_match') and self.termview_widget_match:
|
|
12215
12229
|
try:
|
|
12216
|
-
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)
|
|
12217
12231
|
except Exception as e:
|
|
12218
12232
|
self.log(f"Error updating Match Panel termview: {e}")
|
|
12219
|
-
|
|
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
|
+
|
|
12220
12289
|
def _refresh_termbase_display_for_current_segment(self):
|
|
12221
12290
|
"""Refresh only termbase/glossary display for the current segment.
|
|
12222
12291
|
|
|
@@ -12276,9 +12345,12 @@ class SupervertalerQt(QMainWindow):
|
|
|
12276
12345
|
|
|
12277
12346
|
# Get NT matches
|
|
12278
12347
|
nt_matches = self.find_nt_matches_in_source(segment.source)
|
|
12279
|
-
|
|
12348
|
+
|
|
12349
|
+
# Get status hint for termbase activation
|
|
12350
|
+
status_hint = self._get_termbase_status_hint()
|
|
12351
|
+
|
|
12280
12352
|
# Update both Termview widgets (left and right)
|
|
12281
|
-
self._update_both_termviews(segment.source, termbase_list, nt_matches)
|
|
12353
|
+
self._update_both_termviews(segment.source, termbase_list, nt_matches, status_hint)
|
|
12282
12354
|
except Exception as e:
|
|
12283
12355
|
self.log(f"Error updating termview: {e}")
|
|
12284
12356
|
|
|
@@ -12770,9 +12842,12 @@ class SupervertalerQt(QMainWindow):
|
|
|
12770
12842
|
|
|
12771
12843
|
# Get NT matches
|
|
12772
12844
|
nt_matches = self.find_nt_matches_in_source(segment.source)
|
|
12773
|
-
|
|
12845
|
+
|
|
12846
|
+
# Get status hint (although after adding a term, it should be fine)
|
|
12847
|
+
status_hint = self._get_termbase_status_hint()
|
|
12848
|
+
|
|
12774
12849
|
# Update both Termview widgets (left and right)
|
|
12775
|
-
self._update_both_termviews(segment.source, termbase_list, nt_matches)
|
|
12850
|
+
self._update_both_termviews(segment.source, termbase_list, nt_matches, status_hint)
|
|
12776
12851
|
self.log(f"✅ Both TermView widgets updated instantly with new term")
|
|
12777
12852
|
|
|
12778
12853
|
# Update source cell highlighting with updated cache
|
|
@@ -15551,11 +15626,11 @@ class SupervertalerQt(QMainWindow):
|
|
|
15551
15626
|
layout.addWidget(settings_tabs)
|
|
15552
15627
|
|
|
15553
15628
|
# Apply saved UI font scale on startup
|
|
15554
|
-
saved_scale = self.
|
|
15629
|
+
saved_scale = self._get_global_ui_font_scale()
|
|
15555
15630
|
if saved_scale != 100:
|
|
15556
15631
|
# Defer application to ensure widgets are fully created
|
|
15557
15632
|
from PyQt6.QtCore import QTimer
|
|
15558
|
-
QTimer.singleShot(100, lambda: self.
|
|
15633
|
+
QTimer.singleShot(100, lambda: self._apply_global_ui_font_scale(saved_scale))
|
|
15559
15634
|
|
|
15560
15635
|
return tab
|
|
15561
15636
|
|
|
@@ -17717,26 +17792,27 @@ class SupervertalerQt(QMainWindow):
|
|
|
17717
17792
|
termview_group.setLayout(termview_layout)
|
|
17718
17793
|
layout.addWidget(termview_group)
|
|
17719
17794
|
|
|
17720
|
-
# ===== UI Font Scale
|
|
17721
|
-
ui_scale_group = QGroupBox("🖥️
|
|
17795
|
+
# ===== Global UI Font Scale =====
|
|
17796
|
+
ui_scale_group = QGroupBox("🖥️ Global UI Font Scale")
|
|
17722
17797
|
ui_scale_layout = QVBoxLayout()
|
|
17723
|
-
|
|
17798
|
+
|
|
17724
17799
|
ui_scale_info = QLabel(
|
|
17725
|
-
"Adjust the font size for
|
|
17800
|
+
"Adjust the font size for the entire application UI. Useful for Linux/macOS users where\n"
|
|
17801
|
+
"Qt applications may render with smaller fonts, or for high-DPI displays.\n"
|
|
17726
17802
|
"Changes apply immediately. Default is 100%."
|
|
17727
17803
|
)
|
|
17728
17804
|
ui_scale_info.setWordWrap(True)
|
|
17729
17805
|
ui_scale_layout.addWidget(ui_scale_info)
|
|
17730
|
-
|
|
17806
|
+
|
|
17731
17807
|
ui_scale_row = QHBoxLayout()
|
|
17732
17808
|
ui_scale_row.addWidget(QLabel("UI Font Scale:"))
|
|
17733
17809
|
ui_scale_spin = QSpinBox()
|
|
17734
|
-
ui_scale_spin.setMinimum(
|
|
17810
|
+
ui_scale_spin.setMinimum(50)
|
|
17735
17811
|
ui_scale_spin.setMaximum(200)
|
|
17736
|
-
ui_scale_spin.setValue(font_settings.get('settings_ui_font_scale', 100))
|
|
17812
|
+
ui_scale_spin.setValue(font_settings.get('global_ui_font_scale', font_settings.get('settings_ui_font_scale', 100)))
|
|
17737
17813
|
ui_scale_spin.setSuffix("%")
|
|
17738
17814
|
ui_scale_spin.setSingleStep(10)
|
|
17739
|
-
ui_scale_spin.setToolTip("Scale
|
|
17815
|
+
ui_scale_spin.setToolTip("Scale entire application UI text (50%-200%)")
|
|
17740
17816
|
ui_scale_spin.setMinimumHeight(28)
|
|
17741
17817
|
ui_scale_spin.setMinimumWidth(90)
|
|
17742
17818
|
ui_scale_spin.setStyleSheet("""
|
|
@@ -17753,11 +17829,11 @@ class SupervertalerQt(QMainWindow):
|
|
|
17753
17829
|
}
|
|
17754
17830
|
""")
|
|
17755
17831
|
ui_scale_row.addWidget(ui_scale_spin)
|
|
17756
|
-
|
|
17832
|
+
|
|
17757
17833
|
# Apply button for immediate feedback
|
|
17758
17834
|
apply_scale_btn = QPushButton("Apply")
|
|
17759
17835
|
apply_scale_btn.setToolTip("Apply font scale immediately")
|
|
17760
|
-
apply_scale_btn.clicked.connect(lambda: self.
|
|
17836
|
+
apply_scale_btn.clicked.connect(lambda: self._apply_global_ui_font_scale(ui_scale_spin.value()))
|
|
17761
17837
|
ui_scale_row.addWidget(apply_scale_btn)
|
|
17762
17838
|
|
|
17763
17839
|
ui_scale_row.addStretch()
|
|
@@ -17797,7 +17873,7 @@ class SupervertalerQt(QMainWindow):
|
|
|
17797
17873
|
def save_view_settings_with_scale():
|
|
17798
17874
|
# Save the UI scale setting first
|
|
17799
17875
|
if hasattr(self, '_ui_scale_spin'):
|
|
17800
|
-
self.
|
|
17876
|
+
self._apply_global_ui_font_scale(self._ui_scale_spin.value())
|
|
17801
17877
|
# Then save other view settings
|
|
17802
17878
|
self._save_view_settings_from_ui(
|
|
17803
17879
|
grid_font_spin, match_font_spin, compare_font_spin, show_tags_check, tag_color_btn,
|
|
@@ -19925,72 +20001,51 @@ class SupervertalerQt(QMainWindow):
|
|
|
19925
20001
|
msg.setStandardButtons(QMessageBox.StandardButton.Ok)
|
|
19926
20002
|
msg.exec()
|
|
19927
20003
|
|
|
19928
|
-
def
|
|
19929
|
-
"""Apply font scale to
|
|
19930
|
-
# Save the setting
|
|
20004
|
+
def _apply_global_ui_font_scale(self, scale_percent: int):
|
|
20005
|
+
"""Apply font scale to the entire application UI"""
|
|
19931
20006
|
general_settings = self.load_general_settings()
|
|
19932
|
-
general_settings['
|
|
20007
|
+
general_settings['global_ui_font_scale'] = scale_percent
|
|
20008
|
+
# Remove old key if present (migration)
|
|
20009
|
+
if 'settings_ui_font_scale' in general_settings:
|
|
20010
|
+
del general_settings['settings_ui_font_scale']
|
|
19933
20011
|
self.save_general_settings(general_settings)
|
|
19934
|
-
|
|
19935
|
-
#
|
|
19936
|
-
|
|
19937
|
-
|
|
19938
|
-
|
|
19939
|
-
|
|
19940
|
-
|
|
19941
|
-
|
|
19942
|
-
|
|
19943
|
-
|
|
19944
|
-
|
|
19945
|
-
|
|
19946
|
-
|
|
19947
|
-
|
|
19948
|
-
|
|
19949
|
-
|
|
19950
|
-
|
|
19951
|
-
|
|
19952
|
-
|
|
19953
|
-
|
|
19954
|
-
|
|
19955
|
-
|
|
19956
|
-
|
|
19957
|
-
|
|
19958
|
-
|
|
19959
|
-
|
|
19960
|
-
|
|
19961
|
-
|
|
19962
|
-
|
|
19963
|
-
|
|
19964
|
-
|
|
19965
|
-
|
|
19966
|
-
|
|
19967
|
-
font-size: {scaled_size}pt;
|
|
19968
|
-
}}
|
|
19969
|
-
QGroupBox QPlainTextEdit {{
|
|
19970
|
-
font-size: {scaled_size}pt;
|
|
19971
|
-
}}
|
|
19972
|
-
"""
|
|
19973
|
-
|
|
19974
|
-
# Apply to settings_tabs if it exists
|
|
19975
|
-
if hasattr(self, 'settings_tabs') and self.settings_tabs is not None:
|
|
19976
|
-
self.settings_tabs.setStyleSheet(
|
|
19977
|
-
"QTabBar::tab { outline: 0; font-size: " + str(scaled_size) + "pt; } "
|
|
19978
|
-
"QTabBar::tab:focus { outline: none; } "
|
|
19979
|
-
"QTabBar::tab:selected { border-bottom: 1px solid #2196F3; background-color: rgba(33, 150, 243, 0.08); }"
|
|
19980
|
-
)
|
|
19981
|
-
|
|
19982
|
-
# Apply to each tab's content
|
|
19983
|
-
for i in range(self.settings_tabs.count()):
|
|
19984
|
-
widget = self.settings_tabs.widget(i)
|
|
19985
|
-
if widget:
|
|
19986
|
-
widget.setStyleSheet(settings_stylesheet)
|
|
19987
|
-
|
|
19988
|
-
self.log(f"✓ Settings UI font scale set to {scale_percent}% (base: {scaled_size}pt)")
|
|
19989
|
-
|
|
19990
|
-
def _get_settings_ui_font_scale(self) -> int:
|
|
19991
|
-
"""Get the current Settings UI font scale percentage"""
|
|
20012
|
+
|
|
20013
|
+
# Update ThemeManager and reapply theme
|
|
20014
|
+
if hasattr(self, 'theme_manager') and self.theme_manager is not None:
|
|
20015
|
+
self.theme_manager.font_scale = scale_percent
|
|
20016
|
+
self.theme_manager.apply_theme(QApplication.instance())
|
|
20017
|
+
|
|
20018
|
+
# Update status bar and main tabs fonts
|
|
20019
|
+
self._update_status_bar_fonts(scale_percent)
|
|
20020
|
+
self._update_main_tabs_fonts(scale_percent)
|
|
20021
|
+
self.log(f"✓ Global UI font scale set to {scale_percent}%")
|
|
20022
|
+
|
|
20023
|
+
def _update_status_bar_fonts(self, scale_percent: int):
|
|
20024
|
+
"""Update status bar label fonts based on scale percentage"""
|
|
20025
|
+
base_size = int(9 * scale_percent / 100)
|
|
20026
|
+
small_size = max(7, base_size)
|
|
20027
|
+
style = f"font-size: {small_size}pt;"
|
|
20028
|
+
|
|
20029
|
+
# Update all status bar labels if they exist
|
|
20030
|
+
for attr_name in ['segment_count_label', 'file_label', 'tm_status_label',
|
|
20031
|
+
'termbase_status_label', 'source_lang_label', 'target_lang_label']:
|
|
20032
|
+
if hasattr(self, attr_name):
|
|
20033
|
+
label = getattr(self, attr_name)
|
|
20034
|
+
if label is not None:
|
|
20035
|
+
label.setStyleSheet(style)
|
|
20036
|
+
|
|
20037
|
+
def _update_main_tabs_fonts(self, scale_percent: int):
|
|
20038
|
+
"""Update main tab bar fonts based on scale percentage"""
|
|
20039
|
+
base_size = int(10 * scale_percent / 100)
|
|
20040
|
+
if hasattr(self, 'main_tabs') and self.main_tabs is not None:
|
|
20041
|
+
self.main_tabs.tabBar().setStyleSheet(f"font-size: {base_size}pt;")
|
|
20042
|
+
|
|
20043
|
+
def _get_global_ui_font_scale(self) -> int:
|
|
20044
|
+
"""Get the current global UI font scale percentage"""
|
|
19992
20045
|
general_settings = self.load_general_settings()
|
|
19993
|
-
|
|
20046
|
+
# Check new key first, fall back to old key for migration
|
|
20047
|
+
return general_settings.get('global_ui_font_scale',
|
|
20048
|
+
general_settings.get('settings_ui_font_scale', 100))
|
|
19994
20049
|
|
|
19995
20050
|
def create_grid_view_widget(self):
|
|
19996
20051
|
"""Create the Grid View widget (existing grid functionality)"""
|
|
@@ -21572,36 +21627,35 @@ class SupervertalerQt(QMainWindow):
|
|
|
21572
21627
|
|
|
21573
21628
|
# Source language
|
|
21574
21629
|
source_lang_combo = QComboBox()
|
|
21575
|
-
|
|
21576
|
-
|
|
21577
|
-
("
|
|
21578
|
-
("
|
|
21579
|
-
("
|
|
21580
|
-
("
|
|
21581
|
-
("
|
|
21582
|
-
("
|
|
21583
|
-
("
|
|
21584
|
-
("
|
|
21585
|
-
("
|
|
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"),
|
|
21586
21646
|
]
|
|
21587
|
-
for lang_name, lang_code in
|
|
21647
|
+
for lang_name, lang_code in available_langs:
|
|
21588
21648
|
source_lang_combo.addItem(lang_name, lang_code)
|
|
21589
21649
|
settings_layout.addRow("Source Language:", source_lang_combo)
|
|
21590
|
-
|
|
21650
|
+
|
|
21591
21651
|
# Target language
|
|
21592
21652
|
target_lang_combo = QComboBox()
|
|
21593
|
-
for lang_name, lang_code in
|
|
21653
|
+
for lang_name, lang_code in available_langs:
|
|
21594
21654
|
target_lang_combo.addItem(lang_name, lang_code)
|
|
21595
|
-
|
|
21596
|
-
# Set defaults based on global language settings
|
|
21597
|
-
|
|
21598
|
-
|
|
21599
|
-
if lang_name == self.source_language:
|
|
21600
|
-
source_lang_combo.setCurrentText(lang_name)
|
|
21601
|
-
if lang_name == self.target_language:
|
|
21602
|
-
target_lang_combo.setCurrentText(lang_name)
|
|
21603
|
-
except:
|
|
21604
|
-
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)
|
|
21605
21659
|
|
|
21606
21660
|
settings_layout.addRow("Target Language:", target_lang_combo)
|
|
21607
21661
|
|
|
@@ -21723,7 +21777,11 @@ class SupervertalerQt(QMainWindow):
|
|
|
21723
21777
|
target_lang=target_lang,
|
|
21724
21778
|
segments=[]
|
|
21725
21779
|
)
|
|
21726
|
-
|
|
21780
|
+
|
|
21781
|
+
# Sync global language settings with new project languages
|
|
21782
|
+
self.source_language = source_lang
|
|
21783
|
+
self.target_language = target_lang
|
|
21784
|
+
|
|
21727
21785
|
# Process source text if provided
|
|
21728
21786
|
source_text = text_input.toPlainText().strip()
|
|
21729
21787
|
if source_text:
|
|
@@ -21833,7 +21891,13 @@ class SupervertalerQt(QMainWindow):
|
|
|
21833
21891
|
self.current_project = Project.from_dict(data)
|
|
21834
21892
|
self.project_file_path = file_path
|
|
21835
21893
|
self.project_modified = False
|
|
21836
|
-
|
|
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
|
+
|
|
21837
21901
|
# Restore prompt settings if they exist (unified library)
|
|
21838
21902
|
if hasattr(self.current_project, 'prompt_settings') and self.current_project.prompt_settings:
|
|
21839
21903
|
prompt_settings = self.current_project.prompt_settings
|
|
@@ -23748,9 +23812,9 @@ class SupervertalerQt(QMainWindow):
|
|
|
23748
23812
|
# Initialize TM for this project
|
|
23749
23813
|
self.initialize_tm_database()
|
|
23750
23814
|
|
|
23751
|
-
# Deactivate all resources for new project
|
|
23815
|
+
# Deactivate all resources for new project, then auto-activate language-matching ones
|
|
23752
23816
|
self._deactivate_all_resources_for_new_project()
|
|
23753
|
-
|
|
23817
|
+
|
|
23754
23818
|
# Auto-resize rows for better initial display
|
|
23755
23819
|
self.auto_resize_rows()
|
|
23756
23820
|
|
|
@@ -26224,7 +26288,11 @@ class SupervertalerQt(QMainWindow):
|
|
|
26224
26288
|
|
|
26225
26289
|
# Store memoQ source path in project for persistence across saves
|
|
26226
26290
|
self.current_project.memoq_source_path = file_path
|
|
26227
|
-
|
|
26291
|
+
|
|
26292
|
+
# Sync global language settings with imported project languages
|
|
26293
|
+
self.source_language = source_lang
|
|
26294
|
+
self.target_language = target_lang
|
|
26295
|
+
|
|
26228
26296
|
# Create segments with simple sequential IDs
|
|
26229
26297
|
for idx, source_text in enumerate(source_segments):
|
|
26230
26298
|
existing_target = target_segments[idx] if idx < len(target_segments) else ""
|
|
@@ -26248,15 +26316,15 @@ class SupervertalerQt(QMainWindow):
|
|
|
26248
26316
|
self.load_segments_to_grid()
|
|
26249
26317
|
self.initialize_tm_database()
|
|
26250
26318
|
|
|
26251
|
-
# Deactivate all resources for new project
|
|
26319
|
+
# Deactivate all resources for new project, then auto-activate language-matching ones
|
|
26252
26320
|
self._deactivate_all_resources_for_new_project()
|
|
26253
|
-
|
|
26321
|
+
|
|
26254
26322
|
# Auto-resize rows for better initial display
|
|
26255
26323
|
self.auto_resize_rows()
|
|
26256
|
-
|
|
26324
|
+
|
|
26257
26325
|
# Initialize spellcheck for target language
|
|
26258
26326
|
self._initialize_spellcheck_for_target_language(target_lang)
|
|
26259
|
-
|
|
26327
|
+
|
|
26260
26328
|
# If smart formatting was used, auto-enable Tags view so user sees the tags
|
|
26261
26329
|
if self.memoq_smart_formatting:
|
|
26262
26330
|
self._enable_tag_view_after_import()
|
|
@@ -26745,7 +26813,11 @@ class SupervertalerQt(QMainWindow):
|
|
|
26745
26813
|
|
|
26746
26814
|
# Store memoQ XLIFF source path in project for persistence across saves
|
|
26747
26815
|
self.current_project.mqxliff_source_path = file_path
|
|
26748
|
-
|
|
26816
|
+
|
|
26817
|
+
# Sync global language settings with imported project languages
|
|
26818
|
+
self.source_language = source_lang
|
|
26819
|
+
self.target_language = target_lang
|
|
26820
|
+
|
|
26749
26821
|
# Update UI
|
|
26750
26822
|
self.project_file_path = None
|
|
26751
26823
|
self.project_modified = True
|
|
@@ -26753,15 +26825,15 @@ class SupervertalerQt(QMainWindow):
|
|
|
26753
26825
|
self.load_segments_to_grid()
|
|
26754
26826
|
self.initialize_tm_database()
|
|
26755
26827
|
|
|
26756
|
-
# Deactivate all resources for new project
|
|
26828
|
+
# Deactivate all resources for new project, then auto-activate language-matching ones
|
|
26757
26829
|
self._deactivate_all_resources_for_new_project()
|
|
26758
|
-
|
|
26830
|
+
|
|
26759
26831
|
# Auto-resize rows for better initial display
|
|
26760
26832
|
self.auto_resize_rows()
|
|
26761
|
-
|
|
26833
|
+
|
|
26762
26834
|
# Initialize spellcheck for target language
|
|
26763
26835
|
self._initialize_spellcheck_for_target_language(target_lang)
|
|
26764
|
-
|
|
26836
|
+
|
|
26765
26837
|
# Log success
|
|
26766
26838
|
self.log(f"✓ Imported {len(segments)} segments from memoQ XLIFF: {Path(file_path).name}")
|
|
26767
26839
|
self.log(f" Source: {source_lang}, Target: {target_lang}")
|
|
@@ -27020,7 +27092,11 @@ class SupervertalerQt(QMainWindow):
|
|
|
27020
27092
|
|
|
27021
27093
|
# Store CafeTran source path in project for persistence across saves
|
|
27022
27094
|
self.current_project.cafetran_source_path = file_path
|
|
27023
|
-
|
|
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
|
+
|
|
27024
27100
|
# Update UI
|
|
27025
27101
|
self.project_file_path = None
|
|
27026
27102
|
self.project_modified = True
|
|
@@ -27028,16 +27104,16 @@ class SupervertalerQt(QMainWindow):
|
|
|
27028
27104
|
self.load_segments_to_grid()
|
|
27029
27105
|
self.initialize_tm_database()
|
|
27030
27106
|
|
|
27031
|
-
# Deactivate all resources for new project
|
|
27107
|
+
# Deactivate all resources for new project, then auto-activate language-matching ones
|
|
27032
27108
|
self._deactivate_all_resources_for_new_project()
|
|
27033
|
-
|
|
27109
|
+
|
|
27034
27110
|
# Auto-resize rows for better initial display
|
|
27035
27111
|
self.auto_resize_rows()
|
|
27036
|
-
|
|
27112
|
+
|
|
27037
27113
|
# Initialize spellcheck for target language
|
|
27038
27114
|
target_lang = self.current_project.target_lang if self.current_project else 'nl'
|
|
27039
27115
|
self._initialize_spellcheck_for_target_language(target_lang)
|
|
27040
|
-
|
|
27116
|
+
|
|
27041
27117
|
# Log success
|
|
27042
27118
|
self.log(f"✓ Imported {len(segments)} segments from CafeTran bilingual DOCX: {Path(file_path).name}")
|
|
27043
27119
|
|
|
@@ -27244,7 +27320,11 @@ class SupervertalerQt(QMainWindow):
|
|
|
27244
27320
|
|
|
27245
27321
|
# Store Trados source path in project for persistence across saves
|
|
27246
27322
|
self.current_project.trados_source_path = file_path
|
|
27247
|
-
|
|
27323
|
+
|
|
27324
|
+
# Sync global language settings with imported project languages
|
|
27325
|
+
self.source_language = source_lang
|
|
27326
|
+
self.target_language = target_lang
|
|
27327
|
+
|
|
27248
27328
|
# Update UI
|
|
27249
27329
|
self.project_file_path = None
|
|
27250
27330
|
self.project_modified = True
|
|
@@ -27252,15 +27332,15 @@ class SupervertalerQt(QMainWindow):
|
|
|
27252
27332
|
self.load_segments_to_grid()
|
|
27253
27333
|
self.initialize_tm_database()
|
|
27254
27334
|
|
|
27255
|
-
# Deactivate all resources for new project
|
|
27335
|
+
# Deactivate all resources for new project, then auto-activate language-matching ones
|
|
27256
27336
|
self._deactivate_all_resources_for_new_project()
|
|
27257
|
-
|
|
27337
|
+
|
|
27258
27338
|
# Auto-resize rows for better initial display
|
|
27259
27339
|
self.auto_resize_rows()
|
|
27260
|
-
|
|
27340
|
+
|
|
27261
27341
|
# Initialize spellcheck for target language
|
|
27262
27342
|
self._initialize_spellcheck_for_target_language(target_lang)
|
|
27263
|
-
|
|
27343
|
+
|
|
27264
27344
|
# Count segments with tags
|
|
27265
27345
|
tagged_count = sum(1 for s in trados_segments if s.source_tags)
|
|
27266
27346
|
|
|
@@ -27604,7 +27684,11 @@ class SupervertalerQt(QMainWindow):
|
|
|
27604
27684
|
self.sdlppx_handler = handler
|
|
27605
27685
|
self.sdlppx_source_file = file_path
|
|
27606
27686
|
self.current_project.sdlppx_source_path = file_path
|
|
27607
|
-
|
|
27687
|
+
|
|
27688
|
+
# Sync global language settings with imported project languages
|
|
27689
|
+
self.source_language = source_lang
|
|
27690
|
+
self.target_language = target_lang
|
|
27691
|
+
|
|
27608
27692
|
# Update UI
|
|
27609
27693
|
self.project_file_path = None
|
|
27610
27694
|
self.project_modified = True
|
|
@@ -27937,6 +28021,10 @@ class SupervertalerQt(QMainWindow):
|
|
|
27937
28021
|
# Store Phrase source path in project for persistence across saves
|
|
27938
28022
|
self.current_project.phrase_source_path = file_path
|
|
27939
28023
|
|
|
28024
|
+
# Sync global language settings with imported project languages
|
|
28025
|
+
self.source_language = source_lang
|
|
28026
|
+
self.target_language = target_lang
|
|
28027
|
+
|
|
27940
28028
|
# Update UI
|
|
27941
28029
|
self.project_file_path = None
|
|
27942
28030
|
self.project_modified = True
|
|
@@ -28217,7 +28305,11 @@ class SupervertalerQt(QMainWindow):
|
|
|
28217
28305
|
|
|
28218
28306
|
# Store Déjà Vu source path in project for persistence
|
|
28219
28307
|
self.current_project.dejavu_source_path = file_path
|
|
28220
|
-
|
|
28308
|
+
|
|
28309
|
+
# Sync global language settings with imported project languages
|
|
28310
|
+
self.source_language = source_lang
|
|
28311
|
+
self.target_language = target_lang
|
|
28312
|
+
|
|
28221
28313
|
# Create segments
|
|
28222
28314
|
for idx, seg_data in enumerate(segments_data):
|
|
28223
28315
|
segment = Segment(
|
|
@@ -31549,9 +31641,12 @@ class SupervertalerQt(QMainWindow):
|
|
|
31549
31641
|
]
|
|
31550
31642
|
# Also get NT matches (fresh, not cached - they may have changed)
|
|
31551
31643
|
nt_matches = self.find_nt_matches_in_source(segment.source)
|
|
31552
|
-
|
|
31644
|
+
|
|
31645
|
+
# Get status hint for termbase activation
|
|
31646
|
+
status_hint = self._get_termbase_status_hint()
|
|
31647
|
+
|
|
31553
31648
|
# Update both Termview widgets (left and right)
|
|
31554
|
-
self._update_both_termviews(segment.source, termbase_matches, nt_matches)
|
|
31649
|
+
self._update_both_termviews(segment.source, termbase_matches, nt_matches, status_hint)
|
|
31555
31650
|
except Exception as e:
|
|
31556
31651
|
self.log(f"Error updating termview from cache: {e}")
|
|
31557
31652
|
|
|
@@ -31635,9 +31730,12 @@ class SupervertalerQt(QMainWindow):
|
|
|
31635
31730
|
] if stored_matches else []
|
|
31636
31731
|
# Also get NT matches
|
|
31637
31732
|
nt_matches = self.find_nt_matches_in_source(segment.source)
|
|
31638
|
-
|
|
31733
|
+
|
|
31734
|
+
# Get status hint for termbase activation
|
|
31735
|
+
status_hint = self._get_termbase_status_hint()
|
|
31736
|
+
|
|
31639
31737
|
# Update both Termview widgets (left and right)
|
|
31640
|
-
self._update_both_termviews(segment.source, termbase_matches, nt_matches)
|
|
31738
|
+
self._update_both_termviews(segment.source, termbase_matches, nt_matches, status_hint)
|
|
31641
31739
|
except Exception as e:
|
|
31642
31740
|
self.log(f"Error refreshing termview: {e}")
|
|
31643
31741
|
|
|
@@ -33779,7 +33877,8 @@ OUTPUT ONLY THE SEGMENT MARKERS. DO NOT ADD EXPLANATIONS BEFORE OR AFTER."""
|
|
|
33779
33877
|
self.nt_manager.set_list_active(list_name, False)
|
|
33780
33878
|
|
|
33781
33879
|
self.log("📋 New project: All TMs, glossaries, and NT lists deactivated (start clean)")
|
|
33782
|
-
|
|
33880
|
+
self.log("💡 Tip: Go to Resources tab to activate TMs and glossaries for this project")
|
|
33881
|
+
|
|
33783
33882
|
def search_and_display_tm_matches(self, source_text: str):
|
|
33784
33883
|
"""Search TM and Termbases and display matches with visual diff for fuzzy matches"""
|
|
33785
33884
|
self.log(f"🚨 search_and_display_tm_matches called with source_text: '{source_text[:50]}...'")
|
|
@@ -33802,11 +33901,34 @@ OUTPUT ONLY THE SEGMENT MARKERS. DO NOT ADD EXPLANATIONS BEFORE OR AFTER."""
|
|
|
33802
33901
|
try:
|
|
33803
33902
|
# Get activated TM IDs for current project
|
|
33804
33903
|
tm_ids = None
|
|
33904
|
+
no_tms_activated = False
|
|
33905
|
+
tms_wrong_language = False
|
|
33805
33906
|
if hasattr(self, 'tm_metadata_mgr') and self.tm_metadata_mgr and self.current_project:
|
|
33806
33907
|
project_id = self.current_project.id if hasattr(self.current_project, 'id') else None
|
|
33807
33908
|
if project_id:
|
|
33808
33909
|
tm_ids = self.tm_metadata_mgr.get_active_tm_ids(project_id)
|
|
33809
|
-
|
|
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
|
+
|
|
33810
33932
|
# Search for matches (using activated TMs if available)
|
|
33811
33933
|
matches = self.tm_database.search_all(source_text, tm_ids=tm_ids, max_matches=5)
|
|
33812
33934
|
|
|
@@ -33853,10 +33975,26 @@ OUTPUT ONLY THE SEGMENT MARKERS. DO NOT ADD EXPLANATIONS BEFORE OR AFTER."""
|
|
|
33853
33975
|
|
|
33854
33976
|
if not matches:
|
|
33855
33977
|
if hasattr(self, 'tm_display'):
|
|
33856
|
-
|
|
33857
|
-
|
|
33858
|
-
|
|
33859
|
-
|
|
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
|
+
)
|
|
33860
33998
|
return
|
|
33861
33999
|
|
|
33862
34000
|
# If using TranslationResultsPanel, populate it with TM and Termbase results
|
|
@@ -35508,8 +35646,11 @@ OUTPUT ONLY THE SEGMENT MARKERS. DO NOT ADD EXPLANATIONS BEFORE OR AFTER."""
|
|
|
35508
35646
|
'termbase_id': match_info.get('termbase_id'),
|
|
35509
35647
|
'notes': match_info.get('notes', '')
|
|
35510
35648
|
})
|
|
35649
|
+
# Get status hint for termbase activation
|
|
35650
|
+
status_hint = self._get_termbase_status_hint()
|
|
35651
|
+
|
|
35511
35652
|
# Update both Termview widgets
|
|
35512
|
-
self._update_both_termviews(segment.source, tb_list, nt_matches)
|
|
35653
|
+
self._update_both_termviews(segment.source, tb_list, nt_matches, status_hint)
|
|
35513
35654
|
self.log(" ✓ TermView updated")
|
|
35514
35655
|
except Exception as e:
|
|
35515
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]}
|
modules/theme_manager.py
CHANGED
|
@@ -212,7 +212,10 @@ class ThemeManager:
|
|
|
212
212
|
self.themes_file = user_data_path / "themes.json"
|
|
213
213
|
self.current_theme: Theme = self.PREDEFINED_THEMES["Light (Default)"]
|
|
214
214
|
self.custom_themes: Dict[str, Theme] = {}
|
|
215
|
-
|
|
215
|
+
|
|
216
|
+
# Global UI font scale (50-200%, default 100%)
|
|
217
|
+
self.font_scale: int = 100
|
|
218
|
+
|
|
216
219
|
# Load custom themes
|
|
217
220
|
self.load_custom_themes()
|
|
218
221
|
|
|
@@ -289,14 +292,48 @@ class ThemeManager:
|
|
|
289
292
|
def apply_theme(self, app: QApplication):
|
|
290
293
|
"""
|
|
291
294
|
Apply current theme to application
|
|
292
|
-
|
|
295
|
+
|
|
293
296
|
Args:
|
|
294
297
|
app: QApplication instance
|
|
295
298
|
"""
|
|
296
299
|
theme = self.current_theme
|
|
297
|
-
|
|
300
|
+
|
|
301
|
+
# Calculate scaled font sizes based on font_scale (default 100%)
|
|
302
|
+
base_font_size = int(10 * self.font_scale / 100) # Base: 10pt at 100%
|
|
303
|
+
small_font_size = max(7, int(9 * self.font_scale / 100)) # Small text (status bar)
|
|
304
|
+
|
|
305
|
+
# Font scaling rules (only applied if scale != 100%)
|
|
306
|
+
font_rules = ""
|
|
307
|
+
if self.font_scale != 100:
|
|
308
|
+
font_rules = f"""
|
|
309
|
+
/* Global font scaling ({self.font_scale}%) */
|
|
310
|
+
QWidget {{ font-size: {base_font_size}pt; }}
|
|
311
|
+
QMenuBar {{ font-size: {base_font_size}pt; }}
|
|
312
|
+
QMenuBar::item {{ font-size: {base_font_size}pt; }}
|
|
313
|
+
QMenu {{ font-size: {base_font_size}pt; }}
|
|
314
|
+
QMenu::item {{ font-size: {base_font_size}pt; }}
|
|
315
|
+
QStatusBar {{ font-size: {small_font_size}pt; }}
|
|
316
|
+
QTabBar::tab {{ font-size: {base_font_size}pt; }}
|
|
317
|
+
QToolBar {{ font-size: {base_font_size}pt; }}
|
|
318
|
+
QLabel {{ font-size: {base_font_size}pt; }}
|
|
319
|
+
QCheckBox {{ font-size: {base_font_size}pt; }}
|
|
320
|
+
QRadioButton {{ font-size: {base_font_size}pt; }}
|
|
321
|
+
QComboBox {{ font-size: {base_font_size}pt; }}
|
|
322
|
+
QSpinBox {{ font-size: {base_font_size}pt; }}
|
|
323
|
+
QDoubleSpinBox {{ font-size: {base_font_size}pt; }}
|
|
324
|
+
QLineEdit {{ font-size: {base_font_size}pt; }}
|
|
325
|
+
QPushButton {{ font-size: {base_font_size}pt; }}
|
|
326
|
+
QGroupBox {{ font-size: {base_font_size}pt; }}
|
|
327
|
+
QGroupBox::title {{ font-size: {base_font_size}pt; }}
|
|
328
|
+
QTextEdit {{ font-size: {base_font_size}pt; }}
|
|
329
|
+
QPlainTextEdit {{ font-size: {base_font_size}pt; }}
|
|
330
|
+
QListWidget {{ font-size: {base_font_size}pt; }}
|
|
331
|
+
QTreeWidget {{ font-size: {base_font_size}pt; }}
|
|
332
|
+
QHeaderView::section {{ font-size: {base_font_size}pt; }}
|
|
333
|
+
"""
|
|
334
|
+
|
|
298
335
|
# Create and apply stylesheet - COLORS ONLY, preserves native sizes/spacing
|
|
299
|
-
stylesheet = f"""
|
|
336
|
+
stylesheet = font_rules + f"""
|
|
300
337
|
/* Main window background */
|
|
301
338
|
QMainWindow, QWidget {{
|
|
302
339
|
background-color: {theme.window_bg};
|
|
@@ -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,8 +59,8 @@ 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=
|
|
63
|
-
modules/theme_manager.py,sha256=
|
|
62
|
+
modules/termview_widget.py,sha256=PibDY55CjBY4BSb6aMGEp4Y2JHNB67QWOQFTDNyeYy8,53968
|
|
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
|
|
66
66
|
modules/tm_metadata_manager.py,sha256=NTsaI_YjQnVOpU_scAwK9uR1Tcl9pzKD1GwLVy7sx2g,23590
|
|
@@ -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
|