supervertaler 1.9.175__py3-none-any.whl → 1.9.176b0__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
@@ -34,7 +34,7 @@ License: MIT
34
34
  """
35
35
 
36
36
  # Version Information.
37
- __version__ = "1.9.175"
37
+ __version__ = "1.9.176-beta"
38
38
  __phase__ = "0.9"
39
39
  __release_date__ = "2026-01-28"
40
40
  __edition__ = "Qt"
@@ -6435,13 +6435,10 @@ class SupervertalerQt(QMainWindow):
6435
6435
  from PyQt6.QtCore import QTimer
6436
6436
  QTimer.singleShot(2000, lambda: self._check_for_new_models(force=False)) # 2 second delay
6437
6437
 
6438
- # First-run check - show data location dialog, then Features tab
6439
- if self._needs_data_location_dialog:
6438
+ # First-run check - show unified setup wizard
6439
+ if self._needs_data_location_dialog or not general_settings.get('first_run_completed', False):
6440
6440
  from PyQt6.QtCore import QTimer
6441
- QTimer.singleShot(300, self._show_data_location_dialog)
6442
- elif not general_settings.get('first_run_completed', False):
6443
- from PyQt6.QtCore import QTimer
6444
- QTimer.singleShot(500, self._show_first_run_welcome)
6441
+ QTimer.singleShot(300, lambda: self._show_setup_wizard(is_first_run=True))
6445
6442
 
6446
6443
  def _show_data_location_dialog(self):
6447
6444
  """Show dialog to let user choose their data folder location on first run."""
@@ -6672,7 +6669,273 @@ class SupervertalerQt(QMainWindow):
6672
6669
  self.log("✅ First-run welcome shown (will show again next time)")
6673
6670
  except Exception as e:
6674
6671
  self.log(f"⚠️ First-run welcome error: {e}")
6675
-
6672
+
6673
+ def _show_setup_wizard(self, is_first_run: bool = False):
6674
+ """
6675
+ Show unified setup wizard that combines data folder selection and features intro.
6676
+
6677
+ Args:
6678
+ is_first_run: If True, this is an automatic first-run trigger. If False, user
6679
+ manually invoked from menu (skip data folder if already configured).
6680
+ """
6681
+ try:
6682
+ from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QLabel,
6683
+ QPushButton, QLineEdit, QFileDialog, QStackedWidget,
6684
+ QWidget, QFrame, QCheckBox)
6685
+ from PyQt6.QtCore import Qt
6686
+
6687
+ dialog = QDialog(self)
6688
+ dialog.setWindowTitle("Supervertaler Setup Wizard")
6689
+ dialog.setMinimumWidth(600)
6690
+ dialog.setMinimumHeight(450)
6691
+ dialog.setModal(True)
6692
+
6693
+ main_layout = QVBoxLayout(dialog)
6694
+ main_layout.setSpacing(15)
6695
+ main_layout.setContentsMargins(20, 20, 20, 20)
6696
+
6697
+ # Stacked widget for wizard pages
6698
+ stacked = QStackedWidget()
6699
+
6700
+ # Determine if we need to show data folder page
6701
+ show_data_folder_page = is_first_run and self._needs_data_location_dialog
6702
+
6703
+ # ==================== PAGE 1: Data Folder Selection ====================
6704
+ page1 = QWidget()
6705
+ page1_layout = QVBoxLayout(page1)
6706
+ page1_layout.setSpacing(15)
6707
+
6708
+ # Step indicator
6709
+ step1_indicator = QLabel("<span style='color: #888;'>Step 1 of 2</span>")
6710
+ page1_layout.addWidget(step1_indicator)
6711
+
6712
+ # Title
6713
+ page1_title = QLabel("<h2>📁 Choose Your Data Folder</h2>")
6714
+ page1_layout.addWidget(page1_title)
6715
+
6716
+ # Explanation
6717
+ page1_msg = QLabel(
6718
+ "Supervertaler stores your data in a folder of your choice:<br><br>"
6719
+ "• <b>API keys</b> – Your LLM provider credentials<br>"
6720
+ "• <b>Translation memories</b> – Reusable translation pairs<br>"
6721
+ "• <b>Glossaries</b> – Terminology databases<br>"
6722
+ "• <b>Prompts</b> – Custom AI prompts<br>"
6723
+ "• <b>Settings</b> – Application configuration<br><br>"
6724
+ "Choose a location that's easy to find and backup."
6725
+ )
6726
+ page1_msg.setWordWrap(True)
6727
+ page1_layout.addWidget(page1_msg)
6728
+
6729
+ # Path input with browse button
6730
+ path_layout = QHBoxLayout()
6731
+ path_edit = QLineEdit()
6732
+ default_path = get_default_user_data_path()
6733
+ path_edit.setText(str(default_path))
6734
+ path_edit.setMinimumWidth(350)
6735
+ path_layout.addWidget(path_edit)
6736
+
6737
+ browse_btn = QPushButton("Browse...")
6738
+ def browse_folder():
6739
+ folder = QFileDialog.getExistingDirectory(
6740
+ dialog,
6741
+ "Choose Data Folder",
6742
+ str(Path.home())
6743
+ )
6744
+ if folder:
6745
+ folder_path = Path(folder)
6746
+ if folder_path.name != "Supervertaler":
6747
+ folder_path = folder_path / "Supervertaler"
6748
+ path_edit.setText(str(folder_path))
6749
+
6750
+ browse_btn.clicked.connect(browse_folder)
6751
+ path_layout.addWidget(browse_btn)
6752
+ page1_layout.addLayout(path_layout)
6753
+
6754
+ # Tip
6755
+ page1_tip = QLabel(
6756
+ "💡 <b>Tip:</b> The default location is in your home folder, "
6757
+ "making it easy to find and backup."
6758
+ )
6759
+ page1_tip.setWordWrap(True)
6760
+ page1_tip.setStyleSheet("color: #666;")
6761
+ page1_layout.addWidget(page1_tip)
6762
+
6763
+ page1_layout.addStretch()
6764
+ stacked.addWidget(page1)
6765
+
6766
+ # ==================== PAGE 2: Features Introduction ====================
6767
+ page2 = QWidget()
6768
+ page2_layout = QVBoxLayout(page2)
6769
+ page2_layout.setSpacing(15)
6770
+
6771
+ # Step indicator
6772
+ step2_label = "Step 2 of 2" if show_data_folder_page else "Setup"
6773
+ step2_indicator = QLabel(f"<span style='color: #888;'>{step2_label}</span>")
6774
+ page2_layout.addWidget(step2_indicator)
6775
+
6776
+ # Data folder info (shown when skipping page 1)
6777
+ if not show_data_folder_page:
6778
+ from PyQt6.QtGui import QDesktopServices
6779
+ from PyQt6.QtCore import QUrl
6780
+
6781
+ data_folder_path = str(self.user_data_path)
6782
+ data_folder_info = QLabel(
6783
+ f"<b>📁 Data Folder:</b> <a href='file:///{data_folder_path}' "
6784
+ f"style='color: #3b82f6;'>{data_folder_path}</a><br>"
6785
+ "<span style='color: #666; font-size: 0.9em;'>"
6786
+ "Your settings, TMs, glossaries and prompts are stored here. "
6787
+ "Change in Settings → General.</span>"
6788
+ )
6789
+ data_folder_info.setWordWrap(True)
6790
+ data_folder_info.setTextFormat(Qt.TextFormat.RichText)
6791
+ data_folder_info.setOpenExternalLinks(False) # Handle clicks ourselves
6792
+ data_folder_info.linkActivated.connect(
6793
+ lambda url: QDesktopServices.openUrl(QUrl.fromLocalFile(data_folder_path))
6794
+ )
6795
+ data_folder_info.setStyleSheet(
6796
+ "background: #f0f4ff; padding: 12px; border-radius: 6px; "
6797
+ "border-left: 4px solid #3b82f6; margin-bottom: 10px;"
6798
+ )
6799
+ page2_layout.addWidget(data_folder_info)
6800
+
6801
+ # Title
6802
+ page2_title = QLabel("<h2>✨ Modular Features</h2>")
6803
+ page2_layout.addWidget(page2_title)
6804
+
6805
+ # Message
6806
+ page2_msg = QLabel(
6807
+ "Supervertaler uses a <b>modular architecture</b> – you can install "
6808
+ "only the features you need.<br><br>"
6809
+ "<b>Core features</b> (always available):<br>"
6810
+ "• AI translation with OpenAI, Claude, Gemini, Ollama<br>"
6811
+ "• Translation Memory and Glossaries<br>"
6812
+ "• XLIFF, SDLXLIFF, memoQ support<br>"
6813
+ "• Basic spellchecking<br><br>"
6814
+ "<b>Optional features</b> (install via pip):<br>"
6815
+ "• <code>openai-whisper</code> – Local voice dictation (no API needed)<br><br>"
6816
+ "You can view and manage features in <b>Settings → Features</b>."
6817
+ )
6818
+ page2_msg.setWordWrap(True)
6819
+ page2_msg.setTextFormat(Qt.TextFormat.RichText)
6820
+ page2_layout.addWidget(page2_msg)
6821
+
6822
+ # Checkbox
6823
+ dont_show_checkbox = CheckmarkCheckBox("Don't show this wizard on startup")
6824
+ dont_show_checkbox.setChecked(True)
6825
+ page2_layout.addWidget(dont_show_checkbox)
6826
+
6827
+ # Open Features tab checkbox
6828
+ open_features_checkbox = CheckmarkCheckBox("Open Features tab after closing")
6829
+ open_features_checkbox.setChecked(True)
6830
+ page2_layout.addWidget(open_features_checkbox)
6831
+
6832
+ page2_layout.addStretch()
6833
+ stacked.addWidget(page2)
6834
+
6835
+ main_layout.addWidget(stacked)
6836
+
6837
+ # ==================== Navigation Buttons ====================
6838
+ nav_layout = QHBoxLayout()
6839
+
6840
+ back_btn = QPushButton("← Back")
6841
+ back_btn.setVisible(False) # Hidden on first page
6842
+
6843
+ next_btn = QPushButton("Next →")
6844
+ finish_btn = QPushButton("Finish")
6845
+ finish_btn.setVisible(False)
6846
+ finish_btn.setDefault(True)
6847
+
6848
+ # Use Default button (only on page 1)
6849
+ default_btn = QPushButton("Use Default")
6850
+ default_btn.clicked.connect(lambda: path_edit.setText(str(default_path)))
6851
+
6852
+ nav_layout.addWidget(default_btn)
6853
+ nav_layout.addStretch()
6854
+ nav_layout.addWidget(back_btn)
6855
+ nav_layout.addWidget(next_btn)
6856
+ nav_layout.addWidget(finish_btn)
6857
+
6858
+ main_layout.addLayout(nav_layout)
6859
+
6860
+ # Track chosen path for later
6861
+ chosen_path_holder = [None]
6862
+
6863
+ def go_to_page(page_index):
6864
+ stacked.setCurrentIndex(page_index)
6865
+ if page_index == 0:
6866
+ back_btn.setVisible(False)
6867
+ next_btn.setVisible(True)
6868
+ finish_btn.setVisible(False)
6869
+ default_btn.setVisible(True)
6870
+ else:
6871
+ back_btn.setVisible(show_data_folder_page)
6872
+ next_btn.setVisible(False)
6873
+ finish_btn.setVisible(True)
6874
+ default_btn.setVisible(False)
6875
+
6876
+ def on_next():
6877
+ # Save the data folder choice
6878
+ chosen_path = Path(path_edit.text())
6879
+ chosen_path_holder[0] = chosen_path
6880
+
6881
+ # Create the folder and save config
6882
+ chosen_path.mkdir(parents=True, exist_ok=True)
6883
+ save_user_data_path(chosen_path)
6884
+
6885
+ # Update our path if different
6886
+ if chosen_path != self.user_data_path:
6887
+ self.user_data_path = chosen_path
6888
+ self._reinitialize_with_new_data_path()
6889
+ else:
6890
+ if hasattr(self, 'db_manager') and self.db_manager and not self.db_manager.connection:
6891
+ self.db_manager.connect()
6892
+
6893
+ self.log(f"📁 Data folder set to: {chosen_path}")
6894
+ go_to_page(1)
6895
+
6896
+ def on_back():
6897
+ go_to_page(0)
6898
+
6899
+ def on_finish():
6900
+ # Save first_run preference
6901
+ if dont_show_checkbox.isChecked():
6902
+ settings = self.load_general_settings()
6903
+ settings['first_run_completed'] = True
6904
+ self.save_general_settings(settings)
6905
+ self.log("✅ Setup wizard completed (won't show again on startup)")
6906
+ else:
6907
+ self.log("✅ Setup wizard shown (will show again next time)")
6908
+
6909
+ dialog.accept()
6910
+
6911
+ # Navigate to Features tab if checkbox is checked
6912
+ if open_features_checkbox.isChecked():
6913
+ self.main_tabs.setCurrentIndex(4) # Settings tab
6914
+ if hasattr(self, 'settings_tabs'):
6915
+ for i in range(self.settings_tabs.count()):
6916
+ if "Features" in self.settings_tabs.tabText(i):
6917
+ self.settings_tabs.setCurrentIndex(i)
6918
+ break
6919
+
6920
+ back_btn.clicked.connect(on_back)
6921
+ next_btn.clicked.connect(on_next)
6922
+ finish_btn.clicked.connect(on_finish)
6923
+
6924
+ # Start on appropriate page
6925
+ if show_data_folder_page:
6926
+ go_to_page(0)
6927
+ else:
6928
+ # Skip to features page if data folder already configured
6929
+ go_to_page(1)
6930
+ step2_indicator.setText("<span style='color: #888;'>Supervertaler Setup</span>")
6931
+
6932
+ dialog.exec()
6933
+
6934
+ except Exception as e:
6935
+ self.log(f"⚠️ Setup wizard error: {e}")
6936
+ import traceback
6937
+ traceback.print_exc()
6938
+
6676
6939
  def _check_for_new_models(self, force: bool = False):
6677
6940
  """
6678
6941
  Check for new LLM models from providers
@@ -7936,6 +8199,11 @@ class SupervertalerQt(QMainWindow):
7936
8199
  superdocs_action.triggered.connect(lambda: self._open_url("https://supervertaler.gitbook.io/superdocs/"))
7937
8200
  help_menu.addAction(superdocs_action)
7938
8201
 
8202
+ setup_wizard_action = QAction("🚀 Setup Wizard...", self)
8203
+ setup_wizard_action.setToolTip("Run the initial setup wizard (data folder location, features overview)")
8204
+ setup_wizard_action.triggered.connect(lambda: self._show_setup_wizard(is_first_run=False))
8205
+ help_menu.addAction(setup_wizard_action)
8206
+
7939
8207
  help_menu.addSeparator()
7940
8208
 
7941
8209
  shortcuts_action = QAction("⌨️ Keyboard Shortcuts", self)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: supervertaler
3
- Version: 1.9.175
3
+ Version: 1.9.176b0
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=GSTR2FDPPN0JfSQKl8GbY1vjNeq9U5hnudZOE4WnXRs,2307421
1
+ Supervertaler.py,sha256=ABqaS7k80j4w3EiJr52ogQVIJRAFFOD3NpaeDbzWX6k,2318994
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
@@ -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.175.dist-info/licenses/LICENSE,sha256=m28u-4qL5nXIWnJ6xlQVw__H30rWFtRK3pCOais2OuY,1092
81
- supervertaler-1.9.175.dist-info/METADATA,sha256=iABI3TeYmFFqP1Ho2qd3cj0_UOjaC-7mbzrqLqHIfUw,5725
82
- supervertaler-1.9.175.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
83
- supervertaler-1.9.175.dist-info/entry_points.txt,sha256=NP4hiCvx-_30YYKqgr-jfJYQvHr1qTYBMfoVmKIXSM8,53
84
- supervertaler-1.9.175.dist-info/top_level.txt,sha256=9tUHBYUSfaE4S2E4W3eavJsDyYymkwLfeWAHHAPT6Dk,22
85
- supervertaler-1.9.175.dist-info/RECORD,,
80
+ supervertaler-1.9.176b0.dist-info/licenses/LICENSE,sha256=m28u-4qL5nXIWnJ6xlQVw__H30rWFtRK3pCOais2OuY,1092
81
+ supervertaler-1.9.176b0.dist-info/METADATA,sha256=NXnmveUpuH50y_2kAdkEavCbLiRpDYAUSIIc7YK0d-8,5727
82
+ supervertaler-1.9.176b0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
83
+ supervertaler-1.9.176b0.dist-info/entry_points.txt,sha256=NP4hiCvx-_30YYKqgr-jfJYQvHr1qTYBMfoVmKIXSM8,53
84
+ supervertaler-1.9.176b0.dist-info/top_level.txt,sha256=9tUHBYUSfaE4S2E4W3eavJsDyYymkwLfeWAHHAPT6Dk,22
85
+ supervertaler-1.9.176b0.dist-info/RECORD,,