supervertaler 1.9.184__py3-none-any.whl → 1.9.186__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,7 +32,7 @@ License: MIT
32
32
  """
33
33
 
34
34
  # Version Information.
35
- __version__ = "1.9.184"
35
+ __version__ = "1.9.186"
36
36
  __phase__ = "0.9"
37
37
  __release_date__ = "2026-02-01"
38
38
  __edition__ = "Qt"
@@ -8029,7 +8029,7 @@ class SupervertalerQt(QMainWindow):
8029
8029
  grid_zoom_menu = view_menu.addMenu("📊 &Grid Text Zoom")
8030
8030
 
8031
8031
  grid_zoom_in = QAction("Grid Zoom &In", self)
8032
- grid_zoom_in.setShortcut(QKeySequence.StandardKey.ZoomIn)
8032
+ grid_zoom_in.setShortcut("Ctrl+=")
8033
8033
  grid_zoom_in.triggered.connect(self.zoom_in)
8034
8034
  grid_zoom_menu.addAction(grid_zoom_in)
8035
8035
 
@@ -20565,30 +20565,80 @@ class SupervertalerQt(QMainWindow):
20565
20565
  tab_seg_info.setStyleSheet("font-weight: bold;")
20566
20566
  toolbar_layout.addWidget(tab_seg_info)
20567
20567
 
20568
- # Tag View toggle button
20569
- tag_view_btn = QPushButton("🏷️ Tags OFF")
20570
- tag_view_btn.setCheckable(True)
20571
- tag_view_btn.setChecked(False) # Default: WYSIWYG mode (tags hidden)
20572
- tag_view_btn.setStyleSheet("""
20568
+ # View mode segmented control (WYSIWYG / Tags)
20569
+ from PyQt6.QtWidgets import QButtonGroup
20570
+
20571
+ view_mode_container = QWidget()
20572
+ view_mode_layout = QHBoxLayout(view_mode_container)
20573
+ view_mode_layout.setContentsMargins(0, 0, 0, 0)
20574
+ view_mode_layout.setSpacing(0)
20575
+
20576
+ # Create button group to ensure only one is checked
20577
+ view_mode_group = QButtonGroup(self)
20578
+ view_mode_group.setExclusive(True)
20579
+
20580
+ # WYSIWYG button (left)
20581
+ wysiwyg_btn = QPushButton("WYSIWYG")
20582
+ wysiwyg_btn.setCheckable(True)
20583
+ wysiwyg_btn.setChecked(False)
20584
+ wysiwyg_btn.setToolTip("WYSIWYG View (Ctrl+Alt+T)\nShows formatted text without raw tags")
20585
+ wysiwyg_btn.setStyleSheet("""
20573
20586
  QPushButton {
20574
20587
  background-color: #757575;
20575
20588
  color: white;
20576
20589
  font-weight: bold;
20577
- padding: 4px 8px;
20578
- border-radius: 3px;
20590
+ padding: 4px 12px;
20591
+ border: none;
20592
+ border-top-left-radius: 3px;
20593
+ border-bottom-left-radius: 3px;
20579
20594
  }
20580
20595
  QPushButton:checked {
20581
20596
  background-color: #9C27B0;
20582
20597
  }
20598
+ QPushButton:hover:!checked {
20599
+ background-color: #858585;
20600
+ }
20583
20601
  """)
20584
- tag_view_btn.setToolTip("Toggle Tag View (Ctrl+Alt+T)\n\nTags OFF: Shows formatted text (WYSIWYG)\nTags ON: Shows raw tags like <b>bold</b>")
20585
- tag_view_btn.clicked.connect(lambda checked: self.toggle_tag_view(checked, tag_view_btn))
20586
- toolbar_layout.addWidget(tag_view_btn)
20587
- self.tag_view_btn = tag_view_btn # Store reference
20602
+ wysiwyg_btn.clicked.connect(lambda: self.toggle_tag_view(False, None))
20603
+ view_mode_group.addButton(wysiwyg_btn, 0)
20604
+ view_mode_layout.addWidget(wysiwyg_btn)
20605
+
20606
+ # Tags button (right)
20607
+ tags_btn = QPushButton("Tags")
20608
+ tags_btn.setCheckable(True)
20609
+ tags_btn.setChecked(True) # Default: Tags mode
20610
+ tags_btn.setToolTip("Tag View (Ctrl+Alt+T)\nShows raw tags like <b>bold</b>")
20611
+ tags_btn.setStyleSheet("""
20612
+ QPushButton {
20613
+ background-color: #757575;
20614
+ color: white;
20615
+ font-weight: bold;
20616
+ padding: 4px 12px;
20617
+ border: none;
20618
+ border-top-right-radius: 3px;
20619
+ border-bottom-right-radius: 3px;
20620
+ }
20621
+ QPushButton:checked {
20622
+ background-color: #9C27B0;
20623
+ }
20624
+ QPushButton:hover:!checked {
20625
+ background-color: #858585;
20626
+ }
20627
+ """)
20628
+ tags_btn.clicked.connect(lambda: self.toggle_tag_view(True, None))
20629
+ view_mode_group.addButton(tags_btn, 1)
20630
+ view_mode_layout.addWidget(tags_btn)
20631
+
20632
+ toolbar_layout.addWidget(view_mode_container)
20633
+
20634
+ # Store references for keyboard shortcut and programmatic access
20635
+ self.wysiwyg_btn = wysiwyg_btn
20636
+ self.tags_btn = tags_btn
20637
+ self.view_mode_group = view_mode_group
20588
20638
 
20589
20639
  # Initialize tag view state
20590
20640
  if not hasattr(self, 'show_tags'):
20591
- self.show_tags = False
20641
+ self.show_tags = True # Default: show tags
20592
20642
 
20593
20643
  # Status selector
20594
20644
  from modules.statuses import get_status, STATUSES
@@ -39560,32 +39610,30 @@ OUTPUT ONLY THE SEGMENT MARKERS. DO NOT ADD EXPLANATIONS BEFORE OR AFTER."""
39560
39610
 
39561
39611
  def _toggle_tag_view_via_shortcut(self):
39562
39612
  """Toggle tag view using keyboard shortcut (Ctrl+Alt+T)"""
39563
- if hasattr(self, 'tag_view_btn'):
39564
- # Toggle the button state (which triggers toggle_tag_view)
39565
- new_state = not self.tag_view_btn.isChecked()
39566
- self.tag_view_btn.setChecked(new_state)
39567
- self.toggle_tag_view(new_state, self.tag_view_btn)
39613
+ if hasattr(self, 'wysiwyg_btn') and hasattr(self, 'tags_btn'):
39614
+ # Toggle between the two modes
39615
+ new_state = not self.show_tags
39616
+ self.toggle_tag_view(new_state, None)
39568
39617
 
39569
39618
  def _enable_tag_view_after_import(self):
39570
39619
  """Auto-enable Tag View after importing a document with formatting tags"""
39571
- if hasattr(self, 'tag_view_btn'):
39572
- self.tag_view_btn.setChecked(True)
39573
- self.toggle_tag_view(True, self.tag_view_btn)
39620
+ if hasattr(self, 'tags_btn'):
39621
+ self.toggle_tag_view(True, None)
39574
39622
  self.log("🏷️ Tag View auto-enabled (formatting tags detected in import)")
39575
39623
 
39576
39624
  def toggle_tag_view(self, checked: bool, button: QPushButton = None):
39577
39625
  """Toggle between Tag View (showing raw tags) and WYSIWYG View (formatted display)"""
39578
39626
  self.show_tags = checked
39579
-
39580
- # Update button text
39581
- if button:
39627
+
39628
+ # Update segmented control buttons if they exist
39629
+ if hasattr(self, 'wysiwyg_btn') and hasattr(self, 'tags_btn'):
39582
39630
  if checked:
39583
- button.setText("🏷️ Tags ON")
39631
+ self.tags_btn.setChecked(True)
39584
39632
  else:
39585
- button.setText("🏷️ Tags OFF")
39586
-
39633
+ self.wysiwyg_btn.setChecked(True)
39634
+
39587
39635
  self.log(f"{'🏷️ Tag View ENABLED - showing raw tags' if checked else '✨ WYSIWYG View ENABLED - showing formatted text'}")
39588
-
39636
+
39589
39637
  # Refresh the grid to update display
39590
39638
  if hasattr(self, 'table') and self.current_project:
39591
39639
  self._refresh_grid_display_mode()
@@ -40958,45 +41006,12 @@ OUTPUT ONLY THE SEGMENT MARKERS. DO NOT ADD EXPLANATIONS BEFORE OR AFTER."""
40958
41006
  event.accept()
40959
41007
 
40960
41008
  def _cleanup_web_views(self):
40961
- """Clean up WebEngine views to prevent 'Release of profile requested' warning"""
40962
- try:
40963
- # Close any SuperBrowser tabs
40964
- if hasattr(self, 'superbrowser_tabs'):
40965
- for tab in self.superbrowser_tabs.values():
40966
- try:
40967
- if hasattr(tab, 'web_view'):
40968
- # Stop any loading/rendering
40969
- tab.web_view.stop()
40970
- # Clear page to release resources
40971
- tab.web_view.setPage(None)
40972
- tab.web_view.setUrl(QUrl('about:blank'))
40973
- tab.web_view.deleteLater()
40974
- except:
40975
- pass
40976
-
40977
- # Close Superlookup web views (from Web Resources tab)
40978
- if hasattr(self, 'web_views'):
40979
- for resource_id, web_view in list(self.web_views.items()):
40980
- try:
40981
- web_view.stop()
40982
- web_view.setPage(None)
40983
- web_view.setUrl(QUrl('about:blank'))
40984
- web_view.deleteLater()
40985
- except:
40986
- pass
40987
- self.web_views.clear()
40988
-
40989
- # Process events multiple times to ensure cleanup completes
40990
- from PyQt6.QtWidgets import QApplication
40991
- from PyQt6.QtCore import QUrl
40992
- for _ in range(3):
40993
- QApplication.processEvents()
40994
-
40995
- # Small delay to allow Qt to finish cleanup
40996
- import time
40997
- time.sleep(0.1)
40998
- except:
40999
- pass
41009
+ """Clean up WebEngine views - DISABLED to prevent crash"""
41010
+ # WebEngine cleanup has been disabled because it was causing Python crashes
41011
+ # on program exit. Qt will handle WebEngine cleanup automatically, though
41012
+ # you may see a "Release of profile requested" warning which is harmless.
41013
+ print("[WebEngine Cleanup] Skipping manual cleanup - letting Qt handle it")
41014
+ pass
41000
41015
 
41001
41016
  def _close_detached_log_windows(self):
41002
41017
  """Close all detached log windows when main window closes"""
modules/superbrowser.py CHANGED
@@ -160,6 +160,20 @@ class ChatColumn(QWidget):
160
160
  """Update URL bar when page changes"""
161
161
  self.url_input.setText(url.toString())
162
162
 
163
+ def cleanup(self):
164
+ """Clean up web engine resources before deletion"""
165
+ try:
166
+ from PyQt6.QtCore import QUrl
167
+ if hasattr(self, 'web_view'):
168
+ self.web_view.stop()
169
+ self.web_view.setPage(None)
170
+ self.web_view.setUrl(QUrl('about:blank'))
171
+ self.web_view.deleteLater()
172
+ if hasattr(self, 'profile'):
173
+ self.profile.deleteLater()
174
+ except:
175
+ pass
176
+
163
177
 
164
178
  class SuperbrowserWidget(QWidget):
165
179
  """
@@ -304,6 +318,14 @@ class SuperbrowserWidget(QWidget):
304
318
  self.claude_column.go_home()
305
319
  self.gemini_column.go_home()
306
320
 
321
+ def cleanup(self):
322
+ """Clean up all web engine resources before widget deletion"""
323
+ try:
324
+ for column in self.chat_columns:
325
+ column.cleanup()
326
+ except:
327
+ pass
328
+
307
329
 
308
330
  # ============================================================================
309
331
  # STANDALONE USAGE
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: supervertaler
3
- Version: 1.9.184
3
+ Version: 1.9.186
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=J2_iqhhPh9GFGeJxEZkGeZs-nxoB7OZAfaujHjVsF8s,2342058
1
+ Supervertaler.py,sha256=WC3nqwiY5d9QqlcSazFqSZd-S9DAPFgAsPhppK2QQaU,2342425
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
@@ -49,7 +49,7 @@ modules/spellcheck_manager.py,sha256=jwduHJ66pOKv1MtzSAltxpP8LPgz11FvF6j8h7BiRZY
49
49
  modules/statuses.py,sha256=t6TCA9pNZHDw3SbKTxT73uKezJhwWk9gFLr0NOgEufs,6911
50
50
  modules/style_guide_manager.py,sha256=QBvbygF2E-cgRuwJPWmIatwQl37voU1FErYnycv8Sac,10809
51
51
  modules/superbench_ui.py,sha256=O8pSb-R8Mul1Qz9-8gbBrFR1j7Z8b8_G0wSTSLSCf2U,55563
52
- modules/superbrowser.py,sha256=FAEaYTMiklXizYm3iPt83kp254bCGrFHRsGHduedKYI,12759
52
+ modules/superbrowser.py,sha256=jZw7jNOJyZdLTOVcbAdALH1MYiP43qi_4qGzNWxJ2Hs,13481
53
53
  modules/supercleaner.py,sha256=uRJAEh03Eu4Qtujrf_jxuIyPBbcxKAZzryhV9Chi9ro,22939
54
54
  modules/supercleaner_ui.py,sha256=sVTnYxlX9R20eWs52BKCeQ15iFVFOIQEl29L72lup1c,18812
55
55
  modules/superdocs.py,sha256=vMYyUbHU8zDkS1YMSDF7niDkT8d8FJFDcfIxSktCyGc,522
@@ -79,9 +79,9 @@ modules/unified_prompt_manager_qt.py,sha256=HkGUnH0wlfxt-hVe-nKCeWLyProYdefuuq2s
79
79
  modules/voice_commands.py,sha256=iBb-gjWxRMLhFH7-InSRjYJz1EIDBNA2Pog8V7TtJaY,38516
80
80
  modules/voice_dictation.py,sha256=QmitXfkG-vRt5hIQATjphHdhXfqmwhzcQcbXB6aRzIg,16386
81
81
  modules/voice_dictation_lite.py,sha256=jorY0BmWE-8VczbtGrWwt1zbnOctMoSlWOsQrcufBcc,9423
82
- supervertaler-1.9.184.dist-info/licenses/LICENSE,sha256=m28u-4qL5nXIWnJ6xlQVw__H30rWFtRK3pCOais2OuY,1092
83
- supervertaler-1.9.184.dist-info/METADATA,sha256=VDzAyylsZ4F4KS2d6gA9EJ-EQO-2oncJpEhgXiEiHoo,5725
84
- supervertaler-1.9.184.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
85
- supervertaler-1.9.184.dist-info/entry_points.txt,sha256=NP4hiCvx-_30YYKqgr-jfJYQvHr1qTYBMfoVmKIXSM8,53
86
- supervertaler-1.9.184.dist-info/top_level.txt,sha256=9tUHBYUSfaE4S2E4W3eavJsDyYymkwLfeWAHHAPT6Dk,22
87
- supervertaler-1.9.184.dist-info/RECORD,,
82
+ supervertaler-1.9.186.dist-info/licenses/LICENSE,sha256=m28u-4qL5nXIWnJ6xlQVw__H30rWFtRK3pCOais2OuY,1092
83
+ supervertaler-1.9.186.dist-info/METADATA,sha256=PkpuWKzW5oAa0mDFBFMvaq0Vmo6houXf0taGVT3LEaM,5725
84
+ supervertaler-1.9.186.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
85
+ supervertaler-1.9.186.dist-info/entry_points.txt,sha256=NP4hiCvx-_30YYKqgr-jfJYQvHr1qTYBMfoVmKIXSM8,53
86
+ supervertaler-1.9.186.dist-info/top_level.txt,sha256=9tUHBYUSfaE4S2E4W3eavJsDyYymkwLfeWAHHAPT6Dk,22
87
+ supervertaler-1.9.186.dist-info/RECORD,,