From b61d72740ba2d353f91ff866956c50fcce713c6b Mon Sep 17 00:00:00 2001 From: stephen Date: Wed, 24 Jun 2026 15:37:22 +1000 Subject: [PATCH] partically working refactoring version --- anki_exporter.py | 92 ++ database.py | 152 +++ {database => database_legacy}/__init__.py | 0 {database => database_legacy}/connection.py | 0 .../trainer_backup_20260618_220043.db | Bin .../trainer_backup_20260618_224811.db | Bin main.py | 1159 ++--------------- migrate_database.py | 114 ++ spanish_trainer.db | Bin 368640 -> 212992 bytes spanish_trainer_legacy.db | Bin 0 -> 368640 bytes tabs/__init__.py | 5 + tabs/review_tab.py | 201 +++ tabs/sandbox_tab.py | 219 ++++ tabs/setting_tab.py | 0 tabs/settings_tab.py | 145 +++ 15 files changed, 1019 insertions(+), 1068 deletions(-) rename {database => database_legacy}/__init__.py (100%) rename {database => database_legacy}/connection.py (100%) rename {database => database_legacy}/trainer_backup_20260618_220043.db (100%) rename {database => database_legacy}/trainer_backup_20260618_224811.db (100%) create mode 100644 migrate_database.py create mode 100644 spanish_trainer_legacy.db delete mode 100644 tabs/setting_tab.py create mode 100644 tabs/settings_tab.py diff --git a/anki_exporter.py b/anki_exporter.py index e69de29..91efb07 100644 --- a/anki_exporter.py +++ b/anki_exporter.py @@ -0,0 +1,92 @@ +# anki_exporter.py +import os +import tempfile +import subprocess +import shutil +import genanki + +def compile_anki_package(records, output_path, deck_name): + """ + Compiles database records into an .apkg package using native macOS TTS. + Uses 'Monica' for Spanish targets and the default premium system voice for English. + """ + # Create a unique random Model ID and Deck ID for genanki + model_id = 1684329011 + deck_id = 1684329012 + + # Define the Anki Card Layout structure with audio fields + anki_model = genanki.Model( + model_id, + 'Spanish Voice Trainer Model', + fields=[ + {'name': 'EnglishText'}, + {'name': 'SpanishText'}, + {'name': 'Notes'}, + {'name': 'EnglishAudio'}, + {'name': 'SpanishAudio'} + ], + templates=[ + { + 'name': 'Card 1', + 'qfmt': '
' + 'Translate to Spanish:

{{EnglishText}}
{{EnglishAudio}}
', + 'afmt': '{{FrontSide}}
' + '
' + '{{SpanishText}}

' + '
' + '{{Notes}}

' + '
{{SpanishAudio}}
', + }, + ] + ) + + deck = genanki.Deck(deck_id, deck_name) + media_files = [] + + # Process all records inside a secure temporary directory workspace + with tempfile.TemporaryDirectory() as tmpdir: + for idx, record in enumerate(records): + en_text = record["en_text"] + es_text = record["es_text"] + notes = f"Context: {record['source_context'] or ''} | {record['notes'] or ''}".strip(" | ") + + # Generate unique filenames for the media assets + en_audio_filename = f"en_audio_{idx}.mp3" + es_audio_filename = f"es_audio_{idx}.mp3" + + en_audio_path = os.path.join(tmpdir, en_audio_filename) + es_audio_path = os.path.join(tmpdir, es_audio_filename) + + try: + # 1. Render English Audio using native macOS text-to-speech engine + subprocess.run( + ["say", "-o", en_audio_path, "--data-format=Iface", en_text], + check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL + ) + media_files.append(en_audio_path) + en_audio_field = f"[sound:{en_audio_filename}]" + except Exception: + en_audio_field = "" + + try: + # 2. Render Spanish Audio explicitly targeting the Monica voice profile + subprocess.run( + ["say", "-v", "Monica", "-o", es_audio_path, "--data-format=Iface", es_text], + check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL + ) + media_files.append(es_audio_path) + es_audio_field = f"[sound:{es_audio_filename}]" + except Exception: + es_audio_field = "" + + # Build the card note stack + note = genanki.Note( + model=anki_model, + fields=[en_text, es_text, notes, en_audio_field, es_audio_field] + ) + deck.add_note(note) + + # Build package collection mapping archive pipelines + package = genanki.Package(deck) + package.media_files = media_files + package.write_to_file(output_path) \ No newline at end of file diff --git a/database.py b/database.py index e69de29..1718b67 100644 --- a/database.py +++ b/database.py @@ -0,0 +1,152 @@ +# database.py +import sqlite3 +import os + +DB_NAME = "spanish_trainer.db" + +def get_connection(): + """Returns a connection to the SQLite database with row factory enabled.""" + conn = sqlite3.connect(DB_NAME) + conn.row_factory = sqlite3.Row + return conn + +def ensure_database_populated(): + """ + Creates empty tables using the unified schema if running + in a fresh environment without a database file. + """ + conn = get_connection() + cursor = conn.cursor() + try: + # 1. Simplified unified translations table + cursor.execute(""" + CREATE TABLE IF NOT EXISTS translations ( + translation_id INTEGER PRIMARY KEY AUTOINCREMENT, + es_text TEXT NOT NULL, + en_text TEXT NOT NULL, + source_context TEXT, + tags TEXT, + notes TEXT + ); + """) + + # 2. Key-value configuration table + cursor.execute(""" + CREATE TABLE IF NOT EXISTS settings ( + key TEXT PRIMARY KEY, + value TEXT + ); + """) + conn.commit() + finally: + conn.close() + +# ========================================== +# SETTINGS CRUD FUNCTIONS +# ========================================== + +def load_all_settings(): + """Fetches all system configuration properties into a flat Python dictionary.""" + conn = get_connection() + cursor = conn.cursor() + settings_dict = {} + try: + cursor.execute("SELECT settings.key, settings.value FROM settings;") + for row in cursor.fetchall(): + settings_dict[row["key"]] = row["value"] + finally: + conn.close() + return settings_dict + +def save_setting_to_db(key, value): + """Inserts or replaces an application configuration entry.""" + conn = get_connection() + cursor = conn.cursor() + try: + cursor.execute(""" + INSERT OR REPLACE INTO settings (key, value) + VALUES (?, ?); + """, (key, value)) + conn.commit() + finally: + conn.close() + +# ========================================== +# TRANSLATIONS CRUD FUNCTIONS +# ========================================== + +def get_all_translations_explicit(): + """ + Retrieves all 784+ records using completely explicit, + table-qualified column declarations for the engines. + """ + conn = get_connection() + cursor = conn.cursor() + try: + cursor.execute(""" + SELECT + translations.translation_id, + translations.es_text, + translations.en_text, + translations.source_context, + translations.tags, + translations.notes + FROM translations + ORDER BY translations.translation_id ASC; + """) + return [dict(row) for row in cursor.fetchall()] + finally: + conn.close() + +def get_translation_by_id(translation_id): + """Loads a single unified record row for specific inspection or editing.""" + conn = get_connection() + cursor = conn.cursor() + try: + cursor.execute(""" + SELECT + translations.translation_id, + translations.es_text, + translations.en_text, + translations.source_context, + translations.tags, + translations.notes + FROM translations + WHERE translations.translation_id = ?; + """, (translation_id,)) + row = cursor.fetchone() + return dict(row) if row else None + finally: + conn.close() + +def update_translation_record(translation_id, es_text, en_text, source_context, tags, notes): + """Saves sandbox interface edits directly back down into the table.""" + conn = get_connection() + cursor = conn.cursor() + try: + cursor.execute(""" + UPDATE translations + SET + es_text = ?, + en_text = ?, + source_context = ?, + tags = ?, + notes = ? + WHERE translation_id = ?; + """, (es_text, en_text, source_context, tags, notes, translation_id)) + conn.commit() + finally: + conn.close() + +def delete_translation_record(translation_id): + """Permanently drops a phrase card row from the data index.""" + conn = get_connection() + cursor = conn.cursor() + try: + cursor.execute(""" + DELETE FROM translations + WHERE translations.translation_id = ?; + """, (translation_id,)) + conn.commit() + finally: + conn.close() \ No newline at end of file diff --git a/database/__init__.py b/database_legacy/__init__.py similarity index 100% rename from database/__init__.py rename to database_legacy/__init__.py diff --git a/database/connection.py b/database_legacy/connection.py similarity index 100% rename from database/connection.py rename to database_legacy/connection.py diff --git a/database/trainer_backup_20260618_220043.db b/database_legacy/trainer_backup_20260618_220043.db similarity index 100% rename from database/trainer_backup_20260618_220043.db rename to database_legacy/trainer_backup_20260618_220043.db diff --git a/database/trainer_backup_20260618_224811.db b/database_legacy/trainer_backup_20260618_224811.db similarity index 100% rename from database/trainer_backup_20260618_224811.db rename to database_legacy/trainer_backup_20260618_224811.db diff --git a/main.py b/main.py index 401a433..a473be3 100644 --- a/main.py +++ b/main.py @@ -1,1106 +1,129 @@ # main.py import sys import os -import random -import hashlib -import subprocess -import json -import asyncio -import shutil -from PyQt6.QtWidgets import ( - QApplication, QMainWindow, QWidget, QTabWidget, QVBoxLayout, - QHBoxLayout, QLabel, QPushButton, QLineEdit, QComboBox, - QTableWidget, QTableWidgetItem, QSlider, QFormLayout, QTextEdit, QFrame, QMessageBox, QFileDialog -) -from PyQt6.QtCore import Qt, QUrl -from PyQt6.QtMultimedia import QMediaPlayer, QAudioOutput -from PyQt6.QtGui import QFont +from PyQt6.QtWidgets import QMainWindow, QTabWidget, QApplication, QMessageBox, QVBoxLayout, QWidget +from PyQt6.QtCore import pyqtSlot -# Third-Party Tooling -import genanki -import edge_tts -from PIL import Image, ImageDraw, ImageFont +# Import our unified data layer +import database -# Internal Project Module Imports -from database.connection import init_db, get_connection -from core.bulk_importer import BulkImporter -from core.clean_glossary import GlossaryCleaner +# Import the UI components from our sub-package +from tabs.sandbox_tab import SandboxTab +from tabs.review_tab import ReviewTab +from tabs.settings_tab import SettingsTab -class SpanishTrainerApp(QMainWindow): +# Import our background engine runners +import anki_exporter +import video_generator + +class MainWindow(QMainWindow): def __init__(self): super().__init__() - self.setWindowTitle("Castilian Voice Trainer Pro") - self.setMinimumSize(1200, 800) + self.setWindowTitle("Castilian Spanish Voice Trainer") + self.setMinimumSize(900, 650) - # 1. Initialize schema structures and check ingestion status - self.ensure_database_populated() + # 1. Ensure database structure exists on startup + database.ensure_database_populated() - # Load system persistent settings from DB (including sleep-learning fields) - self.load_system_settings() + # 2. In-memory cache for application configurations + self.app_settings = {} + self.refresh_settings_cache() - # Audio Player Architecture Setup - self.media_player = QMediaPlayer() - self.audio_output = QAudioOutput() - self.media_player.setAudioOutput(self.audio_output) + # 3. Setup central tabbed layout container + self.central_widget = QWidget() + self.setCentralWidget(self.central_widget) + self.main_layout = QVBoxLayout(self.central_widget) - # Flashcard Core State Variables - self.current_flashcard_id = None # Tracks the translation_id currently being reviewed - self.current_card_is_flipped = False # False = Front, True = Back - self.current_active_es_text = "" # Caches active Spanish string - self.current_active_en_text = "" # Caches active English string - self.flashcard_ids_pool = [] # Tracks currently filtered list of translation_ids + self.tab_widget = QTabWidget() + self.main_layout.addWidget(self.tab_widget) - self.current_sandbox_es_id = None - self.current_sandbox_en_id = None + # 4. Instantiate isolated tab modules + self.sandbox_tab = SandboxTab() + self.review_tab = ReviewTab() + self.settings_tab = SettingsTab() - # Central Main Window Tabs Interface - self.tabs = QTabWidget() - self.setCentralWidget(self.tabs) + # 5. Mount tabs with Database Sandbox on the far left (Index 0) + self.tab_widget.addTab(self.sandbox_tab, "Database Sandbox") + self.tab_widget.addTab(self.review_tab, "Flashcard Review") + self.tab_widget.addTab(self.settings_tab, "Configuration Settings") - self.init_phrase_sandbox_tab() - self.init_flashcard_reviewer_tab() - self.init_settings_tab() - - # 2. Populate table grids on initialization - self.refresh_crud_table() - self.refresh_review_table() + # 6. Wire up the cross-module communication channels (Signals) + self.wire_application_signals() - def ensure_database_populated(self): - """Forces database configuration structure and triggers pipeline execution if empty.""" - print("πŸ—„οΈ Verification Pass: Running schema configuration scripts...") - init_db() - - conn = get_connection() - cursor = conn.cursor() - - # Ensure our settings table and key columns are structurally sound - cursor.execute("CREATE TABLE IF NOT EXISTS settings (key TEXT PRIMARY KEY, value TEXT);") - - # Seamlessly inject duration column into phrases if it doesn't exist - cursor.execute("PRAGMA table_info(phrases);") - columns = [row[1] for row in cursor.fetchall()] - if "duration" not in columns: - print("πŸ”„ Modifying phrases schema to support floating-point duration tracking...") - cursor.execute("ALTER TABLE phrases ADD COLUMN duration REAL;") - conn.commit() - - try: - cursor.execute("SELECT COUNT(*) FROM translations") - count = cursor.fetchone()[0] - print(f"πŸ“Š Current Translation Pairs found in database: {count}") - except Exception as e: - print(f"⚠️ Table check encountered an issue (likely empty tables): {e}") - count = 0 - finally: - conn.close() - - if count == 0: - print("πŸ—„οΈ Database tables are empty. Triggering glossary reader pipeline...") - pdf_file = "aula_int_plus_1_glos_en_alfa.pdf" - - if os.path.exists(pdf_file): - importer = BulkImporter() - importer.import_pdf_glossary(pdf_file, "Aula Internacional Plus 1") - - cleaner = GlossaryCleaner() - cleaner.process_database_clean() - print("✨ Ingestion pipeline processing sequence successfully completed.") - else: - print(f"❌ Error: Source document '{pdf_file}' is missing from the directory root.") + def refresh_settings_cache(self): + """Loads all database settings into an easy-to-read dictionary.""" + self.app_settings = database.load_all_settings() - def load_system_settings(self): - """Loads persistent variables from the key-value settings table.""" - self.anki_export_dir = os.getcwd() - self.video_export_dir = os.getcwd() - self.video_first_lang = "English First (en -> es)" - self.video_repeats_count = "3" - self.video_pause_duration = "4.0" - self.default_deck_name = "Trainer" # Unified structural configuration fallback + def wire_application_signals(self): + """Connects tab user-actions to execution managers inside main.py.""" + # Settings Tab Signal Actions + self.settings_tab.settings_changed.connect(self.handle_settings_update) + self.settings_tab.export_anki_requested.connect(self.execute_anki_export) + self.settings_tab.generate_video_requested.connect(self.execute_video_generation) - conn = get_connection() - cursor = conn.cursor() - try: - cursor.execute("SELECT key, value FROM settings") - rows = cursor.fetchall() - for row in rows: - if row[0] == "anki_export_directory": - self.anki_export_dir = row[1] - elif row[0] == "video_export_directory": - self.video_export_dir = row[1] - elif row[0] == "video_first_language": - self.video_first_lang = row[1] - elif row[0] == "video_repeats_count": - self.video_repeats_count = row[1] - elif row[0] == "video_pause_duration": - self.video_pause_duration = row[1] - elif row[0] == "default_deck_name": - self.default_deck_name = row[1] - except Exception as e: - print(f"⚠️ Failed to read application settings from database: {e}") - finally: - conn.close() + # Sandbox / Review Tab synchronization signals + self.sandbox_tab.data_mutated.connect(self.refresh_ui_views) - def save_setting_to_db(self, key, value): - """Updates or inserts a specific system runtime variable into the database.""" - conn = get_connection() - cursor = conn.cursor() - try: - cursor.execute("INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)", (key, value)) - conn.commit() - - if key == "video_first_language": - self.video_first_lang = value - elif key == "video_repeats_count": - self.video_repeats_count = value - elif key == "video_pause_duration": - self.video_pause_duration = value - elif key == "default_deck_name": - self.default_deck_name = value - except Exception as e: - print(f"❌ Critical: Failed to save setting '{key}': {e}") - finally: - conn.close() + @pyqtSlot(str, str) + def handle_settings_update(self, key, value): + """Saves a modified setting value directly down to the database and updates memory cache.""" + database.save_setting_to_db(key, value) + self.refresh_settings_cache() - def get_or_generate_audio_duration(self, phrase_id, text_str, lang): - """ - Ensures a target audio track exists on disk, reads its run length - via ffprobe, caches the duration field inside SQLite, and returns the float timing block. - """ - if not text_str.strip(): - return 2.5 - - safe_name = "".join([c for c in text_str if c.isalnum() or c in (" ", "_")]).strip().replace(" ", "_").lower() - if not safe_name: - safe_name = hashlib.sha256(text_str.encode('utf-8')).hexdigest()[:16] - - os.makedirs("media", exist_ok=True) - target_file = f"media/{safe_name}_{lang}_female.mp3" - - if not os.path.exists(target_file): - try: - voice = "es-ES-ElviraNeural" if lang == "es" else "en-GB-SoniaNeural" - communicate = edge_tts.Communicate(text_str, voice) - asyncio.run(communicate.save(target_file)) - except Exception as tts_err: - print(f"❌ Core TTS System Exception: {tts_err}") - return 2.5 - - if phrase_id: - conn = get_connection() - cursor = conn.cursor() - cursor.execute("SELECT duration FROM phrases WHERE id = ?", (phrase_id,)) - cached_row = cursor.fetchone() - - if cached_row and cached_row[0] is not None: - conn.close() - return float(cached_row[0]) - - try: - cmd = [ - 'ffprobe', '-v', 'quiet', '-print_format', 'json', - '-show_entries', 'format=duration', target_file - ] - result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) - data = json.loads(result.stdout) - duration = float(data['format']['duration']) - - if phrase_id: - cursor.execute("UPDATE phrases SET duration = ? WHERE id = ?", (duration, phrase_id)) - conn.commit() - except Exception as e: - print(f"⚠️ Track structure analysis warning for {target_file}: {e}") - duration = 2.5 - finally: - if phrase_id and 'conn' in locals() and conn: - conn.close() - - return duration - - # ===================================================================== - # πŸ—„οΈ TAB 1: TRANSLATION-CENTRIC PHRASE SANDBOX (CRUD) - # ===================================================================== - def init_phrase_sandbox_tab(self): - tab = QWidget() - layout = QHBoxLayout(tab) + @pyqtSlot(str) + def execute_anki_export(self, full_deck_name): + """Bridges data coordinates out of SQLite to trigger the text-to-speech anki file compiler.""" + self.refresh_settings_cache() + output_dir = self.app_settings.get("anki_export_directory", os.path.expanduser("~")) + output_file = os.path.join(output_dir, f"{full_deck_name.replace('::', '_')}.apkg") - left_panel = QVBoxLayout() + # Pull all active translation records out via explicit SQL matching + records = database.get_all_translations_explicit() - filter_layout = QHBoxLayout() - filter_layout.addWidget(QLabel("πŸ” Text Filter:")) - self.search_text_input = QLineEdit() - self.search_text_input.setPlaceholderText("Search Spanish or English text blocks...") - self.search_text_input.textChanged.connect(self.refresh_crud_table) - filter_layout.addWidget(self.search_text_input) - - filter_layout.addWidget(QLabel("πŸ“‚ Context:")) - self.search_context_input = QLineEdit() - self.search_context_input.setPlaceholderText("e.g. U2") - self.search_context_input.setMaximumWidth(130) - self.search_context_input.textChanged.connect(self.refresh_crud_table) - filter_layout.addWidget(self.search_context_input) - - left_panel.addLayout(filter_layout) - - self.translation_table = QTableWidget() - self.translation_table.setColumnCount(6) - self.translation_table.setHorizontalHeaderLabels([ - "TX ID", "Spanish Phrase", "English Translation", "Type", "Source Context", "Deck Assignment" - ]) - self.translation_table.itemSelectionChanged.connect(self.handle_table_row_select) - left_panel.addWidget(self.translation_table) - - nav_layout = QHBoxLayout() - self.btn_row_up = QPushButton("πŸ”Ό Previous Pair") - self.btn_row_down = QPushButton("πŸ”½ Next Pair") - self.btn_row_up.clicked.connect(lambda: self.step_table_row(-1)) - self.btn_row_down.clicked.connect(lambda: self.step_table_row(1)) - nav_layout.addWidget(self.btn_row_up) - nav_layout.addWidget(self.btn_row_down) - left_panel.addLayout(nav_layout) - - right_panel = QVBoxLayout() - form_frame = QFrame() - form_frame.setFrameShape(QFrame.Shape.StyledPanel) - form_layout = QFormLayout(form_frame) - - self.input_tx_id = QLineEdit() - self.input_tx_id.setReadOnly(True) - self.input_tx_id.setPlaceholderText("Auto-Increment ID") - - self.input_text_es = QTextEdit() - self.input_text_es.setMaximumHeight(75) - self.input_text_es.textChanged.connect(self.clear_id_if_new_entry) - - self.input_text_en = QTextEdit() - self.input_text_en.setMaximumHeight(75) - self.input_text_en.textChanged.connect(self.clear_id_if_new_entry) - - self.combo_type = QComboBox() - self.combo_type.addItems(["phrase", "sentence", "noun", "verb", "adjective"]) - - self.input_context = QLineEdit() - self.input_context.setPlaceholderText("e.g., U8_5A") - - self.input_tags = QLineEdit() - self.input_tags.setPlaceholderText("e.g., irregular_er boots_verb") - - self.input_deck_tag = QLineEdit() - self.input_deck_tag.setPlaceholderText("Overrides System Default Workspace Deck") - - button_qss = """ - QPushButton { - background-color: #f0f0f0; - border: 1px solid #c0c0c0; - border-radius: 4px; - font-size: 11px; - font-weight: bold; - color: #333333; - } - QPushButton:hover { - background-color: #e0e0e0; - border: 1px solid #a0a0a0; - } - QPushButton:pressed { - background-color: #d0d0d0; - } - """ - - es_header_layout = QHBoxLayout() - es_header_layout.setContentsMargins(0, 5, 0, 5) - es_header_layout.addWidget(QLabel("πŸ‡ͺπŸ‡Έ Castilian Spanish Text Element:")) - - self.btn_play_sandbox_es = QPushButton("Play πŸ”Š") - self.btn_play_sandbox_es.setFixedWidth(75) - self.btn_play_sandbox_es.setFixedHeight(24) - self.btn_play_sandbox_es.setStyleSheet(button_qss) - self.btn_play_sandbox_es.clicked.connect(self.handle_sandbox_play_es) - es_header_layout.addWidget(self.btn_play_sandbox_es) - - self.combo_speed_es = QComboBox() - self.combo_speed_es.addItems(["0.50x", "0.75x", "1.00x", "1.25x", "1.50x"]) - self.combo_speed_es.setCurrentText("1.00x") - self.combo_speed_es.setFixedWidth(70) - self.combo_speed_es.setFixedHeight(24) - es_header_layout.addWidget(self.combo_speed_es) - es_header_layout.addStretch() - - en_header_layout = QHBoxLayout() - en_header_layout.setContentsMargins(0, 5, 0, 5) - en_header_layout.addWidget(QLabel("πŸ‡¬πŸ‡§ English Target Translation:")) - - self.btn_play_sandbox_en = QPushButton("Play πŸ”Š") - self.btn_play_sandbox_en.setFixedWidth(75) - self.btn_play_sandbox_en.setFixedHeight(24) - self.btn_play_sandbox_en.setStyleSheet(button_qss) - self.btn_play_sandbox_en.clicked.connect(self.handle_sandbox_play_en) - en_header_layout.addWidget(self.btn_play_sandbox_en) - - self.combo_speed_en = QComboBox() - self.combo_speed_en.addItems(["0.50x", "0.75x", "1.00x", "1.25x", "1.50x"]) - self.combo_speed_en.setCurrentText("1.00x") - self.combo_speed_en.setFixedWidth(70) - self.combo_speed_en.setFixedHeight(24) - en_header_layout.addWidget(self.combo_speed_en) - en_header_layout.addStretch() - - grammar_header_layout = QHBoxLayout() - grammar_header_layout.setContentsMargins(0, 5, 0, 5) - grammar_header_layout.addWidget(QLabel("πŸ“ Grammar / Usage Note:")) - grammar_header_layout.addStretch() - - self.input_grammar_note = QTextEdit() - self.input_grammar_note.setMaximumHeight(75) - self.input_grammar_note.setPlaceholderText("e.g., feminine variant...") - - form_layout.addRow("Translation Link ID:", self.input_tx_id) - form_layout.addRow(es_header_layout) - form_layout.addRow(self.input_text_es) - form_layout.addRow(en_header_layout) - form_layout.addRow(self.input_text_en) - form_layout.addRow(grammar_header_layout) - form_layout.addRow(self.input_grammar_note) - form_layout.addRow("Classification Profile:", self.combo_type) - form_layout.addRow("Source Context ID (Raw):", self.input_context) - form_layout.addRow("Anki Note Tags:", self.input_tags) - form_layout.addRow("Target Deck Scope (Optional):", self.input_deck_tag) - - crud_buttons = QHBoxLayout() - self.btn_save = QPushButton("βž• Create Pair") - self.btn_update = QPushButton("πŸ’Ύ Update Node") - self.btn_delete = QPushButton("πŸ—‘οΈ Sever Link") - - self.btn_save.clicked.connect(self.crud_create_pair) - self.btn_update.clicked.connect(self.crud_update_pair) - self.btn_delete.clicked.connect(self.crud_delete_pair) - - crud_buttons.addWidget(self.btn_save) - crud_buttons.addWidget(self.btn_update) - crud_buttons.addWidget(self.btn_delete) - - right_panel.addWidget(QLabel("

Translation Node Management Matrix

")) - right_panel.addWidget(form_frame) - right_panel.addLayout(crud_buttons) - right_panel.addStretch() - - layout.addLayout(left_panel, stretch=4) - layout.addLayout(right_panel, stretch=3) - - self.tabs.addTab(tab, "πŸ—„οΈ Phrase Sandbox (CRUD)") - - # ===================================================================== - # πŸƒ TAB 2: FLASHCARD STUDY MODULE - # ===================================================================== - def init_flashcard_reviewer_tab(self): - tab = QWidget() - layout = QHBoxLayout(tab) - - left_panel = QVBoxLayout() - - filter_layout = QHBoxLayout() - filter_layout.addWidget(QLabel("πŸ“‚ Context:")) - self.review_context_filter = QLineEdit() - self.review_context_filter.setPlaceholderText("Filter Context...") - self.review_context_filter.textChanged.connect(self.refresh_review_table) - filter_layout.addWidget(self.review_context_filter) - - filter_layout.addWidget(QLabel("🏷️ Tag:")) - self.review_tag_filter = QLineEdit() - self.review_tag_filter.setPlaceholderText("Filter Tag...") - self.review_tag_filter.textChanged.connect(self.refresh_review_table) - filter_layout.addWidget(self.review_tag_filter) - - left_panel.addLayout(filter_layout) - - self.review_table = QTableWidget() - self.review_table.setColumnCount(4) - self.review_table.setHorizontalHeaderLabels(["Tx ID", "Spanish Phrase", "Context", "Tags"]) - self.review_table.itemSelectionChanged.connect(self.handle_review_table_select) - left_panel.addWidget(self.review_table) - - layout.addLayout(left_panel, stretch=4) - - right_panel = QVBoxLayout() - - card_frame = QFrame() - card_frame.setStyleSheet("background-color: #ffffff; border: 2px solid #bdc3c7; border-radius: 12px;") - card_layout = QVBoxLayout(card_frame) - card_frame.setMinimumHeight(280) - - self.lbl_card_text = QLabel("Select a row or click 'Next Card' to initiate...") - self.lbl_card_text.setAlignment(Qt.AlignmentFlag.AlignCenter) - self.lbl_card_text.setFont(QFont("Arial", 20, QFont.Weight.Bold)) - self.lbl_card_text.setWordWrap(True) - self.lbl_card_text.setStyleSheet("color: #2c3e50; border: none; padding: 20px;") - - self.lbl_card_meta = QLabel("") - self.lbl_card_meta.setAlignment(Qt.AlignmentFlag.AlignCenter) - self.lbl_card_meta.setFont(QFont("Arial", 11)) - self.lbl_card_meta.setStyleSheet("color: #7f8c8d; border: none;") - - card_layout.addStretch() - card_layout.addWidget(self.lbl_card_text) - card_layout.addWidget(self.lbl_card_meta) - card_layout.addStretch() - right_panel.addWidget(card_frame, stretch=4) - - playback_layout = QHBoxLayout() - playback_layout.addWidget(QLabel("πŸ”Š Voice Speed:")) - self.slider_review_speed = QSlider(Qt.Orientation.Horizontal) - self.slider_review_speed.setMinimum(50) - self.slider_review_speed.setMaximum(150) - self.slider_review_speed.setValue(100) - self.lbl_review_speed = QLabel("1.00x") - self.slider_review_speed.valueChanged.connect(self.handle_live_speed_change) - playback_layout.addWidget(self.slider_review_speed) - playback_layout.addWidget(self.lbl_review_speed) - right_panel.addLayout(playback_layout) - - action_buttons = QHBoxLayout() - self.btn_play_voice = QPushButton("πŸ—£οΈ Play Voice Track") - self.btn_flip_card = QPushButton("πŸ‘οΈ Reveal Translation") - - self.btn_play_voice.clicked.connect(self.handle_play_voice) - self.btn_flip_card.clicked.connect(self.handle_flip_card) - - action_buttons.addWidget(self.btn_play_voice) - action_buttons.addWidget(self.btn_flip_card) - right_panel.addLayout(action_buttons) - - right_panel.addSpacing(15) - - bottom_utility_layout = QHBoxLayout() - self.btn_export_anki = QPushButton("πŸ“¦ Export Anki Deck") - self.btn_export_video = QPushButton("🎬 Export Video") - self.btn_load_next = QPushButton("➑️ Next Card") - - self.btn_export_anki.clicked.connect(self.handle_export_anki_deck) - self.btn_export_video.clicked.connect(self.handle_export_video_assets) - self.btn_load_next.clicked.connect(self.handle_load_next_card) - - utility_qss = "QPushButton { font-weight: bold; background-color: #eaf2f8; padding: 6px; border-radius: 4px; }" - self.btn_export_anki.setStyleSheet(utility_qss) - self.btn_export_video.setStyleSheet(utility_qss) - self.btn_load_next.setStyleSheet("QPushButton { font-weight: bold; background-color: #d5f5e3; padding: 6px; border-radius: 4px; }") - - bottom_utility_layout.addWidget(self.btn_export_anki) - bottom_utility_layout.addWidget(self.btn_export_video) - bottom_utility_layout.addStretch() - bottom_utility_layout.addWidget(self.btn_load_next) - right_panel.addLayout(bottom_utility_layout) - - layout.addLayout(right_panel, stretch=3) - self.tabs.addTab(tab, "πŸƒ Flashcard Review") - - # ===================================================================== - # βš™οΈ TAB 3: SYSTEM HARDWARE & EXPORT SETTINGS - # ===================================================================== - def init_settings_tab(self): - tab = QWidget() - layout = QVBoxLayout(tab) - - settings_frame = QFrame() - settings_frame.setFrameShape(QFrame.Shape.StyledPanel) - form_layout = QFormLayout(settings_frame) - - anki_layout = QHBoxLayout() - self.line_anki_dir = QLineEdit(self.anki_export_dir) - self.line_anki_dir.setReadOnly(True) - btn_browse_anki = QPushButton("Browse πŸ“‚") - btn_browse_anki.clicked.connect(self.handle_browse_anki_directory) - anki_layout.addWidget(self.line_anki_dir) - anki_layout.addWidget(btn_browse_anki) - - video_layout = QHBoxLayout() - self.line_video_dir = QLineEdit(self.video_export_dir) - self.line_video_dir.setReadOnly(True) - btn_browse_video = QPushButton("Browse πŸ“‚") - btn_browse_video.clicked.connect(self.handle_browse_video_directory) - video_layout.addWidget(self.line_video_dir) - video_layout.addWidget(btn_browse_video) - - # New Workspace Target Settings Directive Entry - self.line_default_deck = QLineEdit(self.default_deck_name) - self.line_default_deck.setPlaceholderText("e.g., Spanish::Aula_Plus_1") - self.line_default_deck.textChanged.connect(lambda v: self.save_setting_to_db("default_deck_name", v.strip())) - - self.combo_first_lang = QComboBox() - self.combo_first_lang.addItems(["English First (en -> es)", "Spanish First (es -> en)"]) - self.combo_first_lang.setCurrentText(self.video_first_lang) - self.combo_first_lang.currentTextChanged.connect(lambda v: self.save_setting_to_db("video_first_language", v)) - - self.spin_video_repeats = QLineEdit(self.video_repeats_count) - self.spin_video_repeats.setFixedWidth(60) - self.spin_video_repeats.textChanged.connect(lambda v: self.save_setting_to_db("video_repeats_count", v)) - - self.spin_pause_duration = QLineEdit(self.video_pause_duration) - self.spin_pause_duration.setFixedWidth(60) - self.spin_pause_duration.textChanged.connect(lambda v: self.save_setting_to_db("video_pause_duration", v)) - - form_layout.addRow("Anki Deck Export Destination:", anki_layout) - form_layout.addRow("Video Assembly Output Target:", video_layout) - form_layout.addRow("Default Target Deck String:", self.line_default_deck) - form_layout.addRow("Introductory Anchor Audio Language:", self.combo_first_lang) - form_layout.addRow("Target Translation Loop Multiplier (Repeats):", self.spin_video_repeats) - form_layout.addRow("User Recall Repetition Frame Intermission (Seconds):", self.spin_pause_duration) - - self.btn_sync_cache = QPushButton("⚑ Populate Audio & Timings Cache") - self.btn_sync_cache.setStyleSheet(""" - QPushButton { - font-weight: bold; - background-color: #e67e22; - color: white; - padding: 10px; - border-radius: 5px; - font-size: 13px; - } - QPushButton:hover { background-color: #d35400; } - """) - self.btn_sync_cache.clicked.connect(self.handle_bulk_populate_audio_cache) - - layout.addWidget(QLabel("

Application Preferences & Workspace Routing

")) - layout.addWidget(settings_frame) - layout.addWidget(self.btn_sync_cache) - layout.addStretch() - - self.tabs.addTab(tab, "βš™οΈ Settings") - - def handle_browse_anki_directory(self): - directory = QFileDialog.getExistingDirectory(self, "Select Anki Export Folder", self.anki_export_dir) - if directory: - self.anki_export_dir = directory - self.line_anki_dir.setText(directory) - self.save_setting_to_db("anki_export_directory", directory) - - def handle_browse_video_directory(self): - directory = QFileDialog.getExistingDirectory(self, "Select Video Export Folder", self.video_export_dir) - if directory: - self.video_export_dir = directory - self.line_video_dir.setText(directory) - self.save_setting_to_db("video_export_directory", directory) - - def handle_bulk_populate_audio_cache(self): - conn = get_connection() - cursor = conn.cursor() - cursor.execute(""" - SELECT p1.id, p1.text, p2.id, p2.text - FROM translations t - JOIN phrases p1 ON t.source_phrase_id = p1.id - JOIN phrases p2 ON t.target_phrase_id = p2.id - """) - records = cursor.fetchall() - conn.close() - if not records: - QMessageBox.information(self, "Cache Synchronizer", "No valid translation pairs exist inside the database to process.") - return - - print(f"⚑ Processing structural cache updates for {len(records)} node linkages...") - for row in records: - es_id, es_text, en_id, en_text = row[0], row[1].strip(), row[2], row[3].strip() - self.get_or_generate_audio_duration(en_id, en_text, "en") - self.get_or_generate_audio_duration(es_id, es_text, "es") - - QMessageBox.information(self, "Cache Processing Complete", "All missing speech segments successfully written. Timings cached safely.") - - # ===================================================================== - # πŸ’‘ FLASHCARD OPERATIONS LOGIC COUPLING - # ===================================================================== - def handle_live_speed_change(self): - val = self.slider_review_speed.value() - self.lbl_review_speed.setText(f"{val / 100:.2f}x") - - def load_flashcard_by_id(self, translation_id): - """Loads a translation node into memory and targets local text widgets without notes clutter.""" - conn = get_connection() - cursor = conn.cursor() - cursor.execute(""" - SELECT t.translation_id, p1.text, p2.text, p1.source_context, t.tags, t.notes - FROM translations t - JOIN phrases p1 ON t.source_phrase_id = p1.id - JOIN phrases p2 ON t.target_phrase_id = p2.id - WHERE t.translation_id = ? - """, (translation_id,)) - record = cursor.fetchone() - conn.close() - - if record: - self.current_flashcard_id = record[0] - self.current_active_es_text = str(record[1]) - self.current_active_en_text = str(record[2]) - self.current_card_is_flipped = False - - self.lbl_card_text.setText(self.current_active_en_text) - self.btn_flip_card.setText("πŸ‘οΈ Reveal Translation") - - meta_str = f"Link ID: {record[0]} | Context: {record[3] or 'N/A'}" - if record[4]: - meta_str += f" | Tags: {record[4]}" - self.lbl_card_meta.setText(meta_str) - - self.handle_play_voice() - - def handle_flip_card(self): - if not self.current_flashcard_id: + QMessageBox.warning(self, "Export Failed", "The database contains no translation records to export.") return - if not self.current_card_is_flipped: - self.lbl_card_text.setText(self.current_active_es_text) - self.btn_flip_card.setText("πŸ‘οΈ Return to Prompt") - self.current_card_is_flipped = True - else: - self.lbl_card_text.setText(self.current_active_en_text) - self.btn_flip_card.setText("πŸ‘οΈ Reveal Translation") - self.current_card_is_flipped = False - - def handle_play_voice(self): - if not self.current_flashcard_id: - return - - text_target = self.current_active_es_text if self.current_card_is_flipped else self.current_active_en_text - lang_target = "es" if self.current_card_is_flipped else "en" - speed_target = self.lbl_review_speed.text() - - self.execute_playback(text_target, lang_target, speed_target) - - def handle_load_next_card(self): - if not self.flashcard_ids_pool: - QMessageBox.information(self, "Pool Empty", "No flashcards found in the matrix matching current criteria filters.") - return - - next_tx_id = random.choice(self.flashcard_ids_pool) - - for row in range(self.review_table.rowCount()): - if int(self.review_table.item(row, 0).text()) == next_tx_id: - self.review_table.setCurrentCell(row, 0) - break - - self.load_flashcard_by_id(next_tx_id) - - # ===================================================================== - # πŸ“¦ GENANKI EXPORT ENGINE (RESTRUCTURED PURE TRANSLATION FLOW) - # ===================================================================== - def handle_export_anki_deck(self): - """ - Gathers selected records from the matching criteria pool view, builds - a dual card template layout mapping English->Spanish (Card 1) and Spanish->English - (Card 2) forward-reverse pairs cleanly. Explicitly maps 4 fields: EnglishText, - EnglishAudio, SpanishText, SpanishAudio. Context and notes are fully removed. - """ - # Architectural Fallback: If pool is empty, run an internal update pass first to grab current matrix records - if not self.flashcard_ids_pool: - self.refresh_review_table() - - targets = self.flashcard_ids_pool - if not targets: - QMessageBox.warning(self, "Export Aborted", "The active flashcard pool filter is completely empty. Nothing to export.") - return - - conn = get_connection() - cursor = conn.cursor() - - placeholders = ",".join("?" for _ in targets) - cursor.execute(f""" - SELECT t.translation_id, p1.text, p2.text, p1.source_context, t.tags, t.notes, t.deck_name - FROM translations t - JOIN phrases p1 ON t.source_phrase_id = p1.id - JOIN phrases p2 ON t.target_phrase_id = p2.id - WHERE t.translation_id IN ({placeholders}) - """, targets) - records = cursor.fetchall() - conn.close() - - if not records: - QMessageBox.information(self, "Export Processing", "No structured database entries matched your criteria indices parameters.") - return - - # Unique Identification Anchor Codes for Anki Database Integrity - MODEL_ID = 1684321095 - DECK_ID = 2026062011 - - # New Model structure aligning English Text/Audio with Spanish Text/Audio sequences - spanish_model = genanki.Model( - MODEL_ID, - 'Castilian Learning Model (Pure Text & Audio Alignment)', - fields=[ - {'name': 'EnglishText'}, - {'name': 'EnglishAudio'}, - {'name': 'SpanishText'}, - {'name': 'SpanishAudio'} - ], - templates=[ - { - 'name': 'Card 1: English -> Spanish', - 'qfmt': ( - '
πŸ‡¬πŸ‡§ ENGLISH COMPREHENSION
' - '
{{EnglishText}}
' - '
{{EnglishAudio}}
' - ), - 'afmt': ( - '{{FrontSide}}
' - '
πŸ‡ͺπŸ‡Έ SPANISH PRODUCTION
' - '
{{SpanishText}}
' - '
{{SpanishAudio}}
' - ), - }, - { - 'name': 'Card 2: Spanish -> English', - 'qfmt': ( - '
πŸ‡ͺπŸ‡Έ SPANISH PRODUCTION
' - '
{{SpanishText}}
' - '
{{SpanishAudio}}
' - ), - 'afmt': ( - '{{FrontSide}}
' - '
πŸ‡¬πŸ‡§ ENGLISH COMPREHENSION
' - '
{{EnglishText}}
' - '
{{EnglishAudio}}
' - ), - }, - ], - css='.card { font-family: arial; font-size: 20px; text-align: center; background-color: #fafafa; padding: 25px; border-radius: 8px; }' - ) - - # --- RESTRUCTURED STRINGS SAFEGUARD BLOCK --- - # Safeguard checks to normalize index 6 data entry and prevent generation string crashes - raw_deck_entry = records[0][6] - if raw_deck_entry and str(raw_deck_entry).strip(): - deck_name_fallback = str(raw_deck_entry).strip() - else: - deck_name_fallback = self.default_deck_name if self.default_deck_name else "Trainer" - - # Explicitly ensure the Anki namespace structural hierarchy sequence is intact - full_deck_string = f"Spanish::{deck_name_fallback}" if "Spanish::" not in deck_name_fallback else deck_name_fallback - - anki_deck = genanki.Deck(DECK_ID, full_deck_string) - media_files_bundle = [] - - print(f"πŸ“¦ Assembling Anki audio package for {len(records)} notes under deck: {full_deck_string}...") - - for row in records: - tx_id, es_text, en_text, context, tags, notes, deck_group = row - es_clean = es_text.strip() - en_clean = en_text.strip() - - # --- Spanish Media Track Setup --- - safe_es_name = "".join([c for c in es_clean if c.isalnum() or c in (" ", "_")]).strip().replace(" ", "_").lower() - if not safe_es_name: - safe_es_name = hashlib.sha256(es_clean.encode('utf-8')).hexdigest()[:16] - audio_es_filename = f"{safe_es_name}_es_female.mp3" - full_es_path = f"media/{audio_es_filename}" - - if not os.path.exists(full_es_path): - self.get_or_generate_audio_duration(None, es_clean, "es") - if os.path.exists(full_es_path): - media_files_bundle.append(full_es_path) - es_audio_tag = f"[sound:{audio_es_filename}]" - else: - es_audio_tag = "" - - # --- English Media Track Setup --- - safe_en_name = "".join([c for c in en_clean if c.isalnum() or c in (" ", "_")]).strip().replace(" ", "_").lower() - if not safe_en_name: - safe_en_name = hashlib.sha256(en_clean.encode('utf-8')).hexdigest()[:16] - audio_en_filename = f"{safe_en_name}_en_female.mp3" - full_en_path = f"media/{audio_en_filename}" - - if not os.path.exists(full_en_path): - self.get_or_generate_audio_duration(None, en_clean, "en") - if os.path.exists(full_en_path): - media_files_bundle.append(full_en_path) - en_audio_tag = f"[sound:{audio_en_filename}]" - else: - en_audio_tag = "" - - # Meta and Category Tag Construction - tag_list = str(tags).split() if tags else [] - if context: - tag_list.append(str(context).replace(" ", "_").replace(".", "_")) - - anki_note = genanki.Note( - model=spanish_model, - fields=[ - en_text, - en_audio_tag, - es_text, - es_audio_tag - ], - tags=tag_list - ) - anki_deck.add_note(anki_note) - - # Output file name normalization optimization to sweep unmapped character sets - safe_file_name = deck_name_fallback.replace('::', '_').replace('/', '_').strip() - export_output_path = os.path.join(self.anki_export_dir, f"{safe_file_name}.apkg") - try: - package = genanki.Package(anki_deck) - package.media_files = list(set(media_files_bundle)) - package.write_to_file(export_output_path) - - print(f"βœ… Success! Balanced text-audio cards exported cleanly: {export_output_path}") - QMessageBox.information( - self, - "Anki Package Compiled", - f"Successfully compiled {len(records)} balanced text-audio translation flashcard nodes.\n\nDestination:\n{export_output_path}" - ) - except Exception as export_err: - print(f"❌ Genanki Write Failure Exception Error: {export_err}") - QMessageBox.critical( - self, - "Export Failure Error", - f"The packaging sub-engine failed to write file to disk:\n{export_err}" - ) - - def handle_export_video_assets(self): - pass - - # ===================================================================== - # βž• CRUD ENGINE ATOMIC OPERATIONS LOGIC - # ===================================================================== - def crud_create_pair(self): - conn = get_connection() - cursor = conn.cursor() - - cursor.execute(""" - INSERT INTO phrases (text, language, word_type, source_context) VALUES (?, 'es', ?, ?) - """, (self.input_text_es.toPlainText().strip(), self.combo_type.currentText(), self.input_context.text().strip())) - es_id = cursor.lastrowid - - cursor.execute(""" - INSERT INTO phrases (text, language, word_type, source_context) VALUES (?, 'en', ?, ?) - """, (self.input_text_en.toPlainText().strip(), self.combo_type.currentText(), self.input_context.text().strip())) - en_id = cursor.lastrowid - - # Pulls from self.input_deck_tag if typed, cleanly defaults to global persistent variable self.default_deck_name - target_deck = self.input_deck_tag.text().strip() or self.default_deck_name - - cursor.execute(""" - INSERT INTO translations (source_phrase_id, target_phrase_id, deck_name, notes, tags) VALUES (?, ?, ?, ?, ?) - """, (es_id, en_id, target_deck, self.input_grammar_note.toPlainText().strip(), self.input_tags.text().strip())) - tx_id = cursor.lastrowid - - conn.commit() - conn.close() - - self.input_tx_id.setText(str(tx_id)) - self.current_sandbox_es_id = es_id - self.current_sandbox_en_id = en_id - - self.refresh_crud_table() - self.refresh_review_table() - QMessageBox.information(self, "Success", f"Isolated phrase pairs created and bound to Translation ID {tx_id}.") - - def crud_update_pair(self): - tx_id_str = self.input_tx_id.text().strip() - if not tx_id_str: - QMessageBox.warning(self, "Update Target Missing", "No Translation Link ID found. Select an existing record node or create a fresh link pair first.") - return - - if self.current_sandbox_es_id is None or self.current_sandbox_en_id is None: - QMessageBox.warning(self, "Phrase Nodes Untracked", "Underlying unique identifiers for individual language components are missing. Reselect the row from the left panel matrix grid.") - return - - conn = get_connection() - cursor = conn.cursor() - try: - cursor.execute(""" - UPDATE phrases - SET text = ?, word_type = ?, source_context = ?, duration = NULL - WHERE id = ? - """, (self.input_text_es.toPlainText().strip(), self.combo_type.currentText(), self.input_context.text().strip(), self.current_sandbox_es_id)) - - cursor.execute(""" - UPDATE phrases - SET text = ?, word_type = ?, source_context = ?, duration = NULL - WHERE id = ? - """, (self.input_text_en.toPlainText().strip(), self.combo_type.currentText(), self.input_context.text().strip(), self.current_sandbox_en_id)) - - # Updated field configuration using system preferences cache fallback assignment - target_deck = self.input_deck_tag.text().strip() or self.default_deck_name - - cursor.execute(""" - UPDATE translations - SET deck_name = ?, notes = ?, tags = ? - WHERE translation_id = ? - """, (target_deck, self.input_grammar_note.toPlainText().strip(), self.input_tags.text().strip(), int(tx_id_str))) - - conn.commit() + anki_exporter.compile_anki_package(records, output_file, full_deck_name) + QMessageBox.information(self, "Export Success", f"Successfully compiled light-weight TTS deck to:\n{output_file}") except Exception as e: - QMessageBox.critical(self, "Database Error", f"Failed to execute field modifications inside SQL engine: {e}") - finally: - conn.close() + QMessageBox.critical(self, "Export Error", f"Failed to parse or write Anki package archive:\n{str(e)}") - self.refresh_crud_table() - self.refresh_review_table() - QMessageBox.information(self, "Success", f"Node structural fields updated successfully. Translation Link ID {tx_id_str} remains active.") - - def crud_delete_pair(self): - pass - - def execute_playback(self, text_str, lang, speed_text): - txt = text_str.strip() - if not txt: - return - - self.get_or_generate_audio_duration(None, txt, lang) + @pyqtSlot() + def execute_video_generation(self): + """Coordinates data streams to invoke the independent video compilation generator.""" + self.refresh_settings_cache() + records = database.get_all_translations_explicit() - safe_name = "".join([c for c in txt if c.isalnum() or c in (" ", "_")]).strip().replace(" ", "_").lower() - if not safe_name: - safe_name = hashlib.sha256(txt.encode('utf-8')).hexdigest()[:16] - - target_file = f"media/{safe_name}_{lang}_female.mp3" - - if os.path.exists(target_file): - try: - multiplier = float(speed_text.replace("x", "")) - except ValueError: - multiplier = 1.0 - - self.media_player.stop() - self.media_player.setSource(QUrl.fromLocalFile(os.path.abspath(target_file))) - self.media_player.setLoops(1) - self.media_player.setPlaybackRate(multiplier) - self.media_player.play() - - def handle_sandbox_play_es(self): - self.execute_playback(self.input_text_es.toPlainText(), "es", self.combo_speed_es.currentText()) - - def handle_sandbox_play_en(self): - self.execute_playback(self.input_text_en.toPlainText(), "en", self.combo_speed_en.currentText()) - - # ===================================================================== - # ⚑ DATA MATRIX CONTROL & SYNCHRONIZATION VIEWS - # ===================================================================== - def refresh_crud_table(self): - conn = get_connection() - cursor = conn.cursor() - - text_filter = self.search_text_input.text().strip() - context_filter = self.search_context_input.text().strip() - - query = """ - SELECT t.translation_id, p1.text, p2.text, p1.word_type, p1.source_context, t.deck_name - FROM translations t - JOIN phrases p1 ON t.source_phrase_id = p1.id - JOIN phrases p2 ON t.target_phrase_id = p2.id - WHERE p1.language = 'es' AND p2.language = 'en' - """ - params = [] - - if text_filter: - query += " AND (p1.text LIKE ? OR p2.text LIKE ?)" - params.extend([f"%{text_filter}%", f"%{text_filter}%"]) - - if context_filter: - query += " AND p1.source_context LIKE ?" - params.append(f"%{context_filter}%") - - query += " ORDER BY t.translation_id ASC LIMIT 250" - - cursor.execute(query, params) - rows = cursor.fetchall() - conn.close() - - self.translation_table.setRowCount(0) - for row_idx, row_data in enumerate(rows): - self.translation_table.insertRow(row_idx) - for col_idx in range(6): - val = row_data[col_idx] - self.translation_table.setItem(row_idx, col_idx, QTableWidgetItem(str(val if val is not None else ""))) - - def refresh_review_table(self): - conn = get_connection() - cursor = conn.cursor() - - context_filter = self.review_context_filter.text().strip() - tag_filter = self.review_tag_filter.text().strip() - - query = """ - SELECT t.translation_id, p1.text, p1.source_context, t.tags - FROM translations t - JOIN phrases p1 ON t.source_phrase_id = p1.id - WHERE p1.language = 'es' - """ - params = [] - if context_filter: - query += " AND p1.source_context LIKE ?" - params.append(f"%{context_filter}%") - if tag_filter: - query += " AND t.tags LIKE ?" - params.append(f"%{tag_filter}%") - - query += " ORDER BY t.translation_id ASC" - - cursor.execute(query, params) - rows = cursor.fetchall() - conn.close() - - self.review_table.setRowCount(0) - self.flashcard_ids_pool = [] - - for row_idx, row_data in enumerate(rows): - self.review_table.insertRow(row_idx) - self.flashcard_ids_pool.append(row_data[0]) - for col_idx in range(4): - val = row_data[col_idx] - self.review_table.setItem(row_idx, col_idx, QTableWidgetItem(str(val if val is not None else ""))) - - def handle_table_row_select(self): - selected_ranges = self.translation_table.selectedRanges() - if not selected_ranges: - return - row = selected_ranges[0].topRow() - tx_id_item = self.translation_table.item(row, 0) - if not tx_id_item: + if not records: + QMessageBox.warning(self, "Generation Failed", "No phrases available to construct a training video playlist loops.") return - tx_id = tx_id_item.text() + # UI updates can block execution loops, so we notify before processing + self.statusBar().showMessage("Generating training video assets. Please wait...") + QApplication.processEvents() - conn = get_connection() - cursor = conn.cursor() - cursor.execute(""" - SELECT t.translation_id, p1.text, p2.text, p1.word_type, p1.source_context, t.deck_name, t.notes, t.tags, p1.id, p2.id - FROM translations t - JOIN phrases p1 ON t.source_phrase_id = p1.id - JOIN phrases p2 ON t.target_phrase_id = p2.id - WHERE t.translation_id = ? - """, (tx_id,)) - record = cursor.fetchone() - conn.close() - - if record: - self.input_tx_id.setText(str(record[0])) - self.input_text_es.setPlainText(str(record[1])) - self.input_text_en.setPlainText(str(record[2])) - self.combo_type.setCurrentText(str(record[3]) if record[3] else "phrase") - self.input_context.setText(str(record[4]) if record[4] else "") - self.input_tags.setText(str(record[7]) if record[7] is not None else "") - self.input_deck_tag.setText(str(record[5]) if record[5] else "") - self.input_grammar_note.setPlainText(str(record[6]) if record[6] is not None else "") - self.current_sandbox_es_id = record[8] - self.current_sandbox_en_id = record[9] + try: + video_generator.generate_training_video(records, self.app_settings) + QMessageBox.information(self, "Success", "MP4 Video compilation completed successfully.") + self.statusBar().showMessage("Video compilation completed.", 5000) + except Exception as e: + QMessageBox.critical(self, "Video Error", f"An error occurred during frame rendering sequences:\n{str(e)}") + self.statusBar().clearMessage() - def handle_review_table_select(self): - selected_ranges = self.review_table.selectedRanges() - if not selected_ranges: - return - row = selected_ranges[0].topRow() - if row < len(self.flashcard_ids_pool): - translation_id = self.flashcard_ids_pool[row] - self.load_flashcard_by_id(translation_id) - - def step_table_row(self, direction): - current_row = self.translation_table.currentRow() - next_row = current_row + direction - if 0 <= next_row < self.translation_table.rowCount(): - self.translation_table.setCurrentCell(next_row, 0) - - def clear_id_if_new_entry(self): - if self.input_tx_id.text() and not (self.input_text_es.hasFocus() or self.input_text_en.hasFocus()): - pass + @pyqtSlot() + def refresh_ui_views(self): + """Instructs distinct active tabs to reload data windows after database changes occur.""" + self.sandbox_tab.reload_table_display() + self.review_tab.reload_review_pool() if __name__ == "__main__": app = QApplication(sys.argv) - window = SpanishTrainerApp() + + # Modern clean styling choices for desktop applications + app.setStyle('Fusion') + + window = MainWindow() window.show() sys.exit(app.exec()) \ No newline at end of file diff --git a/migrate_database.py b/migrate_database.py new file mode 100644 index 0000000..13df5ba --- /dev/null +++ b/migrate_database.py @@ -0,0 +1,114 @@ +# migrate_database.py +import sqlite3 +import os + +OLD_DB = "spanish_trainer_legacy.db" # Your existing database renamed +NEW_DB = "spanish_trainer.db" # The fresh, simplified target database + +def migrate(): + if not os.path.exists(OLD_DB): + print(f"❌ Error: Could not find legacy database file named '{OLD_DB}'") + print("Please rename your active database file to match before running this script.") + return + + print("πŸš€ Initializing schema transformation...") + + # Connect to both databases + conn_old = sqlite3.connect(OLD_DB) + conn_old.row_factory = sqlite3.Row + cursor_old = conn_old.cursor() + + conn_new = sqlite3.connect(NEW_DB) + cursor_new = conn_new.cursor() + + # 1. Provision the clean, simplified new tables + cursor_new.execute(""" + CREATE TABLE IF NOT EXISTS translations ( + translation_id INTEGER PRIMARY KEY AUTOINCREMENT, + es_text TEXT NOT NULL, + en_text TEXT NOT NULL, + source_context TEXT, + tags TEXT, + notes TEXT + ); + """) + + cursor_new.execute(""" + CREATE TABLE IF NOT EXISTS settings ( + key TEXT PRIMARY KEY, + value TEXT + ); + """) + + # 2. Extract and pair data using explicit, table-qualified SQL queries + print("πŸ“¦ Extracting and consolidating relational text rows...") + migration_query = """ + SELECT + t.translation_id, + p1.text AS spanish_phrase, + p2.text AS english_translation, + p1.source_context AS textbook_unit, + t.tags AS metadata_tags, + t.notes AS historical_notes + FROM translations t + JOIN phrases p1 ON t.source_phrase_id = p1.id + JOIN phrases p2 ON t.target_phrase_id = p2.id + WHERE p1.language = 'es' + AND p2.language = 'en' + ORDER BY t.translation_id ASC; + """ + + try: + cursor_old.execute(migration_query) + legacy_records = cursor_old.fetchall() + except sqlite3.OperationalError as e: + print(f"❌ Legacy structure lookup failed: {e}") + print("Verify your old table structures match the schema before running.") + conn_old.close() + conn_new.close() + return + + # 3. Insert records into the new simplified table structure + inserted_count = 0 + for row in legacy_records: + cursor_new.execute(""" + INSERT INTO translations ( + translation_id, + es_text, + en_text, + source_context, + tags, + notes + ) VALUES (?, ?, ?, ?, ?, ?); + """, ( + row["translation_id"], + row["spanish_phrase"], + row["english_translation"], + row["textbook_unit"], + row["metadata_tags"], + row["historical_notes"] + )) + inserted_count += 1 + + # 4. Copy existing system configuration keys over safely + try: + cursor_old.execute("SELECT key, value FROM settings;") + settings_records = cursor_old.fetchall() + for setting in settings_records: + cursor_new.execute(""" + INSERT OR REPLACE INTO settings (key, value) + VALUES (?, ?); + """, (setting["key"], setting["value"])) + except sqlite3.OperationalError: + print("⚠️ Warning: No legacy settings table found or could not read it. Skipping settings copy.") + + # Commit changes and clean up connections + conn_new.commit() + conn_old.close() + conn_new.close() + + print(f"✨ Migration complete! Successfully converted {inserted_count} text rows.") + print(f"πŸ’Ύ Fresh database engine ready at: {NEW_DB}") + +if __name__ == "__main__": + migrate() \ No newline at end of file diff --git a/spanish_trainer.db b/spanish_trainer.db index 42db8907d2ad77386e36e6b6266ca31afe723294..71e66d577469d7746561c6914aa26208fde15270 100644 GIT binary patch delta 33040 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 U;+rzz?&Yt&IqYi17mfJ;0DCmSj{pDw literal 368640 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

=K4 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%0Ap#{Nr1&4yMz$1ZP z^-t;x)lJIJm4>nr{r{6~=lQ?jKkQ%Rdz0@9@8jNvcRj#e{d3(E>Wf*20}~y)zdTFV z8{pPqVG@KNT9Sq2@pwOO^Rsc$uymA$^kw%=!O3C{A>$ZbC^)A^X(H>>eARtZ@Ubjl z#_UQGh~Q1Tl0xqk94sr^z&I8#>k9MW6dbEdacJ`!gn)^(71ktfYA)gWdSfWO^TwiY zflr{pBv_71lz~ zVJeT>^i9EYvz(!!Y<@(>t2^Kurr^D;#2e)9Kn9LRsX%!N*Z`8$t*djdZwg+VrDnmn zhIva!dkB`bE8rWa;Kf;f43-5hjX}end8@iWkCQDR9qX`X3T~a{gAHYIO*!s0$>fEt z2d=W$DR^_1_Jo*+vhZ+4s>78Cl2dTy zETfZw=49MT-`UNiv!sGEF*V1R9imnm|$N)tiNb(|e}i@-adVpW1>tGEexqFQd7Mryufm1Qdo-Y z3YPN!OMDX^+}wA$|A+qL{!1_kU|0Je+h5(jJNC!e%TWpN`{>J~nCie<0^ALFJ7~y6tbi)_V)qAQZJ$-u2 zbJ9thcI*GvJ3c+)%j@MGq~KifB&W}a(RMLFb43kz^a(Yli$+pJ3_fhzgh+6(aijvH z#Z~O-z%$=*JfswGCG1x{|AUNjNP|}Uth&BF$_(z%ZKY{<=X

4_Yb?}R_H|}rcvUIMXgU3(Pb@_ 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 z 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

7eq5S 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�!nG~?#B8Iuq4fA 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 BMA`rV diff --git a/spanish_trainer_legacy.db b/spanish_trainer_legacy.db new file mode 100644 index 0000000000000000000000000000000000000000..42db8907d2ad77386e36e6b6266ca31afe723294 GIT binary patch literal 368640 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

=K4 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%0Ap#{Nr1&4yMz$1ZP z^-t;x)lJIJm4>nr{r{6~=lQ?jKkQ%Rdz0@9@8jNvcRj#e{d3(E>Wf*20}~y)zdTFV z8{pPqVG@KNT9Sq2@pwOO^Rsc$uymA$^kw%=!O3C{A>$ZbC^)A^X(H>>eARtZ@Ubjl z#_UQGh~Q1Tl0xqk94sr^z&I8#>k9MW6dbEdacJ`!gn)^(71ktfYA)gWdSfWO^TwiY zflr{pBv_71lz~ zVJeT>^i9EYvz(!!Y<@(>t2^Kurr^D;#2e)9Kn9LRsX%!N*Z`8$t*djdZwg+VrDnmn zhIva!dkB`bE8rWa;Kf;f43-5hjX}end8@iWkCQDR9qX`X3T~a{gAHYIO*!s0$>fEt z2d=W$DR^_1_Jo*+vhZ+4s>78Cl2dTy zETfZw=49MT-`UNiv!sGEF*V1R9imnm|$N)tiNb(|e}i@-adVpW1>tGEexqFQd7Mryufm1Qdo-Y z3YPN!OMDX^+}wA$|A+qL{!1_kU|0Je+h5(jJNC!e%TWpN`{>J~nCie<0^ALFJ7~y6tbi)_V)qAQZJ$-u2 zbJ9thcI*GvJ3c+)%j@MGq~KifB&W}a(RMLFb43kz^a(Yli$+pJ3_fhzgh+6(aijvH z#Z~O-z%$=*JfswGCG1x{|AUNjNP|}Uth&BF$_(z%ZKY{<=X

4_Yb?}R_H|}rcvUIMXgU3(Pb@_ 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 z zR*F$79ZP!(D2egXWRFEv4c&_HopOYG+qJ*2%jp5(`aZDoLolyWN_&V(05@z|L?QAp zcNcD5V7DXfn2t|{;pQQY`O@27xW#p<&;`bn`ui8i!dkDM!_rmQ>6jSo_98m9k#@%E z?^4=V*x@Mtf~_MIWk;;2)ZMC-fxU&B-6azquqZ-$z?~ezBu)i)dB>{baC-_Ul_5vA z6E03FySNZ@HN71>3)@`>pi8T=pKcLKUlHgmY-5}p&Pr1MB;5q^jf?8Np0M^5w(_aM zIG=f%_!$}6tl%e^XgahVg&W=1CuvP(#>SN8dxUd?dc;X*VT+5>;V8@$4VjG6Us{h8 zZm0?Dl=d*rRP581$w+!|6nd@r8~HL~5}NXEqytBL)eICiizFy{)g(!HZNyUDXQ+#1 zOM1wj0*YvGnwwnMIT?c@IH|ZK$+xN8bR7j0(ZI6_gv@rDE2P?P5~HsicN9=XLm?h# zvn9~)t@_8Aq`PgEbM`gzr(RqHChSNW34 z>npxf@#2c+^3RvQsJyl8TV>g@wSn&f1^+pGAM#$jiNC{1KR6mRWzsZqrUl;Ay)(G7 zynZdH1W(4|s1=%jzv|lJYgTi>bj;x15+|!rg@!ZAI5}6?YfyI2xEGf|i3CbbM871g z9W%JOypRogfI|&ZEHZnl)O%+J7ZyheY45VzUVx;Zbs!4O}oWUJM63f+ng2M_Ti%_bl#FfOmfT)~+XHFLxYgKEm9Wz|m z=_H9VMl~xPjK2G7Xa;u@otqpbM{m~@oRCA1Ubvr9DRoOBQr;lFT->8P5k_ZlPi+*B z5#oTkpYWw2T^TWF_|YP|iL0kS$@h)gXK;ae!Z8_9wkvlKD~a!(K`s~tIUV5;#AC>+ zuf!E0^%sxs8RUM6(5X1hu{}l-1FBd#`3tn=2m5D``Xy47`HqMnbVligNEA?ZrYH${ z&kWMPy!0GW8<9z)N{Xb7qVIDvgZwYCQ9POz+${-b*9_9XIEd_Qz7$e2RK-ZNXqq(m zo*8&~gfm9ygb-WG^H3JodRYA>p>GC09?y9Mw=bN^n$!+9oi+DH-wd2Qiz4=y-I5UR zpMjsplQKHm1<^R$l}*!1Lf$unB(PJd24+hLO(ao@hj`X3IIb z5dLHa0+lQHK;!rtIxDF;%Y8+aM{m~*vctq7>Fl^92EU9bDD`mq6B?O8W*D_Wy~;Un zlId|6q#X#-s`5c7x`~(`MN#z`41+UB2qTG*&xjtOdMZ2w<%^0Jcur60ok4OKopP*n z0(nG}D?qxop8DRID;CA;e{7V7w`&IJVcw~n85>9Q8j=mJ4M+f-WFj>nTcU)AK`3=+g(TTA^-6xrc+E}^?^5qe+zoioT5 z^Da_K7gAYrbT_TijUMZsLCTn?reI4)#^#?;2yjVQDgM79a9>5;2kY*wyRojk_9L|~ zuH98z7yfKGAKqH?>zX&$9IClE^tDhfbUo$(q>O=JqxA;spmnbK1#`yiG|P=Atsfaz zR(~H}f{E&Ds`giXqpGIz1C@7GZmN1i#UCr4s5n>=Du1ecwEWz%PnA7fwk`07z=s3( zIbH$$wRz4A<1%m~hk^8HByA^9IESDnVvopvSv2OeYNfrhwQbe9wzaM6=8Q00^AZE% zp9ndY@WpL&)nO5GWZz?;#|>%N15*^-pwU+3O>OkfC!y?U*d4zOa?j=733bo)TSL9#uSo3H-lqfq`%3>OF^BLn%4pbqK72fZ0UF?5VjTW3gg6< z5(A>J9OP+MFTl$6ZLO=XFPsRAj1>;~2X-Pw0wuNRe~YsY-(TEBqJ6Ux+-_TioPntY zJAWS~awNt@16@JB7Q?NDSI_nIf}xhR6#?SEod{NVFK}R<&Uxu359IFjkCi@IRZ4=b&54 z#uF7fJTbnxfVd82oLwr!n6|(ma$SWi zXT}zYn?`<@lKK|(z8B)Ml+>4s`iad-sMyHT-B~zD4stg?usbt=>nxJO^+C;Il93eB zG2H|~9j;pnw~-edxZK>E$s`VQo5pHVW+@E^Ku}MjTg2?evaKZZV`b~jg#!*@0vYH@ z#s*?Z9;7*ca)L%bmWJtu!hYw56__Sb8xtLiqPYyLb0lw!BSz($%M2xZ6_m1T3;Q^Y zn3JI?9To|pBUHhdD&gyGg}vlhb#KZ@61rqs%m;w8Wl^Jn5)fCn;j&xXx~b4l{zC7| zm|{#{rt4k*?G1%Ka)r6N+++mbh53YU`Zp!Q{k|S6&{pUr$AkOTK{4r=I$@OZw_r*z=6RrZHfh1g)Ax-D;^BDfRhtUk%rgEy-23AD{B-TNuPbyh&seE)LOsHH z3on;qG(8g6Nr%3!&{_O_^d_fJk!Xon()Y>!Z>j!dp!T!1e_Q+J+CMiQt$m>Oj@sL6 zZ>`->dqwS;nDaMibQsqeR~zRVmDT@N{jKUx*8WrYPpAm^D*6LF8Gar71Si5H;hwsm z)P1e)V|DMWJ6ShfcW2#bT`&9zEp->wS+&2$B!OFM*4JEKb4KWop&y0568cE!9ii94 zr!W;74t0la2sMQ+2pPd&1-}#g`{4V6e;F(U?+Ye^w*_|w*99*NF0=k%{j2q5>%-RD zt=Cvt>$nxQx~$FC3hR8U+We*YZS&LSQ|6n@H+f!#|5ZO_Z+W272$Yv!ICr;|uqJMX zf{zW`F$zNr0SNm>?Ea(3q8Sg4MMhIN@kX0Qqoc{D?(N%~Qd0?lg1e&W@80|Jl$h;e z!+%0ic}m|NvQty=>rpczxHR0K+kzPVoU$*!O=NIIlF7v6<+i{b?7_VrA^TKJm$cEX z*(PV(3Rn(DVejL&^^wtf%r!=WH`%cD!w~?J&GokU<{DPfP{ z91$)Zrph^JgHr;>RB!0a4VA$%n_B!DDjs*G<)U*E~YA4VX z3-n~DIUzO->H#LB$x#~DMrln0!o+sc?3-@T5C6VNm-7p%BPr!-YC_YZM zj7x7lbm{@{f!LN#)WarTVUMAXm|P%ZqSyy-z8!f5(6m?B^@EXd`ixya7MW_U5AMLR zMKn_3_!PWYh~SbzilKKyRI4yXg&}aFq)}7hSi2(rvBJhFJqFgT5L{2A@zT*LxC*TcJxx0j&E3QjCW1 z?=DEgDkkJ+UR!T3+YPjWctO!%zA-3d+hxfBBHMODY#i;9p`jm(HrnJucBvrg77{%W zje}lr5z7ino4{=P9Rw+nnP?8~6e5PrfmdhQ!f66+;z(jZJP6-H*}a{aaP%I$6}Gao z8z4&LO^FO(w?NH@cvBl+G{%J_@+*xbs5rz+_`-XxM2kmR@12=*TEjuL>+}BSbn+FR?Z+bAe4?9cj z$kE8M`){wJL&Lhvy4*Q2mfe4lL6=(f5_B7bF0pJ0I>4Zdtrtkpeg<7=T_i#K7<9gM zfduVk(7D!m64cM2<<>b8)W@K+tg|JkmqBM(XF8zl&G+vXXWm>UY?WE%4%kn8a8N^% zS!Jd}B89>zIE;tE_MxZ{8%QyQudz6Eh(~PFVVi?nn(3`+i3qv}fuCqH*x@*b#ojfLe<`En$cFD%4RAQ&XPg1}hnNhAlK!FQVz#8w z{R{^=mDZ)i)=i`w9*8v>1=6ty)|4KXvT?*Z#|aLQXtHquDt30`V2Yx_STPcaFX<{p z-^NEH^zGHnc5f<5XU|p=PaNrEcE>1e#%M~MAd~28fCma5q*z0tJ%vPLG$ytuk>H3M z^;nGVVJt{QoY}&Wk5}d-J(3wL7sL!#v!eje`3Y%q_Kdue`Lv}PZF!=llbJzrVau~o zC{0)43XH_b_M5VCWhcj@Lv6wOXP)ka>(Z4Z*uR_W?S^NbJ{ldhJGShAYKS>fkx^)g zsnq7iVAJ(>KWR3C&EQZhy*XIF9j}H<^_199>q@9`4fMUH9v~Vc%@SxRezXuZoZyYY zh1z339XEI(Ct?Luc0(78S2|xHS)`JV+oL!SV22_G0yDcl2Caz>i2B5M{iTicUO4&@ zloyo2eva71JBD9UC@NjscQi#tUHa%K8@1baG+}!!AXB{j)q zVNU`lWYngG!oB4_I~B$8fLoDv5=k>&ipW_3L5Sg0nn*yAf`UAjz-vG}fVP;>#^z=B z$M|&LXtl`$f0RM%tql@1!l1R*ItdzP&}wUq1VtItYORu>AqKTrDheF(_o!NKhw(EGsBM9SkxoQ-azV zRAp65&>jX=Sd|jAOMuKjSpf;Ul|g?n|0qGXFzDaS|B#@a4EmkZnkzv zP=Z0*t(zohoIzWyZ4xxbpe@#o5)^09X6ptCI?ABytm`G{2!l3R*E%4w|10ad19cy* z%huh2AC~?sabSr9OB`6@z!C?RIIzTlB@QfcV2J}u99ZJO5(kzzPznbws;y|b7*6;I zB9n)PqJu{djl;d#17GAe{NudpinVnVkxLw!Ab0v9Y92y9rq+$+6&rW+Z=%PkobAvM z{N_lXNKUoDdznnNAaFPVUt~NnO7rJiwjm@OPeg`NEgQ-z*6)stAB`P)uHOvejVkM2 z9jN<3-K*<9Rrh2mFSzuXB@QfcV2J}u99ZJO5(kzzu*88S4lHqCi33XYk|EUuV|7y|zF6 zyYOqm+iRY!d1KA4(62(T4BZ_3VepaQm6-ZBfxdw6#D|yuEOB6o14|rO;=mFImN>A) zfzvo}AdgW2qUoq87N_cvVYHx6m(IMpY^plmQjaV>-UE3| z6QD+bTt`YnHc`TgTATEgaz+JpvubVKrlI;!9_^W_UlwBr)re-r&@gn+d5)qDRcTMS zJ&!KUV7X?b^lWaD4|wKjyu=XtoexFvq?D@N zd@0yF^XT2|HT*(LWNPW7>`S_M1DRG&RQmF0-n>A}2Q!f&{YX|V;@&)3ID4Z^P$p=L zLQn<4w0+j;SlpLKE9V6SM+PC>%8?EwA>N%wOJ@wLW2U6Vx z-aHQ(aM~6QqNh394EQdUhtZ$Pu=UHpxyH8xb#JcgL-#+n{~rtQg8l!RnwvvE3B4Tl z|IdOiGrk>Mi`x5JQEmS!^ZL^+{3XB=2bMUn#DOIaEOB6o1OKfYh)s8f1M4xMMOab? z=wGnJof+1FJqgkE0>&~-xF}j?`Dzd7ak+Ts-6A#bz%)8Od3HVxaU6uz89Skyzb({$ zovqw6jgC;%@tBoJ2f0GgqmIX|YjtKy@3iO^<)U?oR|}w>$NgZ@q0OIEwjwkRqMm7YonE6UaNdAqxZ1Ni>rhi4360k%Ge|c^CSp;R^C3jatAQOAM0xLP2;*nD

7eq5S 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�!nG~?#B8Iuq4fA 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 BMA`rV literal 0 HcmV?d00001 diff --git a/tabs/__init__.py b/tabs/__init__.py index e69de29..551983a 100644 --- a/tabs/__init__.py +++ b/tabs/__init__.py @@ -0,0 +1,5 @@ +# tabs/__init__.py +# Leave this file empty, or just expose the tabs like this: +from .sandbox_tab import SandboxTab +from .review_tab import ReviewTab +from .settings_tab import SettingsTab \ No newline at end of file diff --git a/tabs/review_tab.py b/tabs/review_tab.py index e69de29..e189a83 100644 --- a/tabs/review_tab.py +++ b/tabs/review_tab.py @@ -0,0 +1,201 @@ +# tabs/review_tab.py +import random +from PyQt6.QtWidgets import ( + QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QPushButton, QFrame, QStackedWidget +) +from PyQt6.QtCore import Qt, pyqtSlot +import database + +class ReviewTab(QWidget): + def __init__(self, parent=None): + super().__init__(parent) + + # Core State Variables + self.review_pool = [] + self.current_index = -1 + + # Primary Layout + main_layout = QVBoxLayout(self) + main_layout.setContentsMargins(30, 20, 30, 20) + main_layout.setSpacing(20) + + # Header Status Tracker + self.lbl_status = QLabel("Session Status: No active cards loaded.") + self.lbl_status.setStyleSheet("font-size: 13px; font-weight: bold; color: #7F8C8D; letter-spacing: 0.5px;") + main_layout.addWidget(self.lbl_status) + + # --- THE CARD CANVAS AREA --- + self.card_frame = QFrame() + self.card_frame.setStyleSheet(""" + QFrame { + background-color: #FAFAFA; + border: 2px solid #E5E7E9; + border-radius: 8px; + } + """) + card_layout = QVBoxLayout(self.card_frame) + card_layout.setContentsMargins(40, 40, 40, 40) + + # Stacked display interface separating Question and Answer card views + self.card_stack = QStackedWidget() + + # View A: Card Front Layout (Prompt and Source Language Text) + self.view_front = QWidget() + front_layout = QVBoxLayout(self.view_front) + front_prompt = QLabel("TRANSLATE THIS TO SPANISH:") + front_prompt.setStyleSheet("font-size: 12px; font-weight: bold; color: #BDC3C7; letter-spacing: 1px;") + front_prompt.setAlignment(Qt.AlignmentFlag.AlignCenter) + + self.lbl_english = QLabel("English Text Layer") + self.lbl_english.setStyleSheet("font-size: 26px; color: #34495E; font-weight: 500; margin-top: 20px;") + self.lbl_english.setAlignment(Qt.AlignmentFlag.AlignCenter) + self.lbl_english.setWordWrap(True) + + front_layout.addWidget(front_prompt) + front_layout.addWidget(self.lbl_english) + front_layout.addStretch() + + # View B: Card Back Layout (Revealed target text alongside historical context notes) + self.view_back = QWidget() + back_layout = QVBoxLayout(self.view_back) + + self.lbl_spanish = QLabel("Spanish Translated Phrase") + self.lbl_spanish.setStyleSheet("font-size: 34px; font-weight: bold; color: #2980B9; margin-bottom: 10px;") + self.lbl_spanish.setAlignment(Qt.AlignmentFlag.AlignCenter) + self.lbl_spanish.setWordWrap(True) + + self.lbl_notes = QLabel("Context/Historical reference notes go here...") + self.lbl_notes.setStyleSheet(""" + QLabel { + font-size: 15px; + font-style: italic; + color: #7F8C8D; + background-color: #EAEDED; + padding: 12px; + border-radius: 4px; + margin-top: 20px; + } + """) + self.lbl_notes.setAlignment(Qt.AlignmentFlag.AlignCenter) + self.lbl_notes.setWordWrap(True) + + back_layout.addWidget(self.lbl_spanish) + back_layout.addWidget(self.lbl_notes) + back_layout.addStretch() + + # Mount the structural views into the execution layer index + self.card_stack.addWidget(self.view_front) + self.card_stack.addWidget(self.view_back) + card_layout.addWidget(self.card_stack) + + main_layout.addWidget(self.card_frame) + + # --- THE INTERACTIVE BOTTOM BAR CONTROL PIPELINE --- + self.control_stack = QStackedWidget() + + # Panel A: Contains exclusively the single full-width layout Reveal button + self.panel_reveal = QWidget() + reveal_layout = QHBoxLayout(self.panel_reveal) + reveal_layout.setContentsMargins(0, 0, 0, 0) + self.btn_reveal = QPushButton("Reveal Answer Verification") + self.btn_reveal.setStyleSheet(""" + QPushButton { background-color: #34495E; color: white; font-weight: bold; font-size: 15px; padding: 12px; border-radius: 5px; } + QPushButton:hover { background-color: #2C3E50; } + """) + self.btn_reveal.clicked.connect(self.reveal_card_answer) + reveal_layout.addWidget(self.btn_reveal) + + # Panel B: Contains the standard sequential navigation tools (Pass / Fail iteration indicators) + self.panel_navigation = QWidget() + nav_layout = QHBoxLayout(self.panel_navigation) + nav_layout.setContentsMargins(0, 0, 0, 0) + nav_layout.setSpacing(15) + + self.btn_next = QPushButton("Next Phrase βž”") + self.btn_next.setStyleSheet(""" + QPushButton { background-color: #27AE60; color: white; font-weight: bold; font-size: 15px; padding: 12px; border-radius: 5px; } + QPushButton:hover { background-color: #2ECC71; } + """) + self.btn_next.clicked.connect(self.advance_review_index) + nav_layout.addWidget(self.btn_next) + + self.control_stack.addWidget(self.panel_reveal) + self.control_stack.addWidget(self.panel_navigation) + + main_layout.addWidget(self.control_stack) + + # Load up your initial study loop deck pool array elements + self.reload_review_pool() + + @pyqtSlot() + def reload_review_pool(self): + """Fetches consolidated text entries from the database module and scrambles their indexing.""" + raw_records = database.get_all_translations_explicit() + + # Filter down records to ensure they possess safe core text parameters + self.review_pool = [r for r in raw_records if r["es_text"] and r["en_text"]] + + # Randomize review sequencing to prevent memory bias based on insertion order + random.shuffle(self.review_pool) + + if self.review_pool: + self.current_index = 0 + self.display_current_card_front() + else: + self.current_index = -1 + self.lbl_status.setText("Session Status: No usable records found inside spanish_trainer.db") + self.lbl_english.setText("The database appears to be empty.") + self.control_stack.setEnabled(False) + + def display_current_card_front(self): + """Configures the UI canvas parameters to display the prompt front.""" + if not (0 <= self.current_index < len(self.review_pool)): + return + + record = self.review_pool[self.current_index] + self.lbl_status.setText(f"Review Cycle Running: Phrase {self.current_index + 1} of {len(self.review_pool)}") + + # Render prompt text labels cleanly + self.lbl_english.setText(record["en_text"]) + + # Reset visual stack view states back to original baselines + self.card_stack.setCurrentIndex(0) # Switch to front canvas text display + self.control_stack.setCurrentIndex(0) # Toggle control element button bar back to 'Reveal' layout + + @pyqtSlot() + def reveal_card_answer(self): + """Displays translation targets on the card back.""" + if not (0 <= self.current_index < len(self.review_pool)): + return + + record = self.review_pool[self.current_index] + self.lbl_spanish.setText(record["es_text"]) + + # Show contextual notes or structural flags cleanly if populated + if record["notes"] or record["source_context"]: + context_string = record["source_context"] if record["source_context"] else "" + notes_string = f" | {record['notes']}" if record["notes"] else "" + self.lbl_notes.setText(f"Context: {context_string}{notes_string}") + self.lbl_notes.setVisible(True) + else: + self.lbl_notes.setVisible(False) + + # Toggle component visualization states + self.card_stack.setCurrentIndex(1) # Swap card panel over to the back answer layout + self.control_stack.setCurrentIndex(1) # Swap button layouts over to display 'Next Phrase' action bars + + @pyqtSlot() + def advance_review_index(self): + """Increments index counters to display a new flashcard container.""" + if not self.review_pool: + return + + self.current_index += 1 + + # Loop review cards continuously if the session index boundary thresholds overflow + if self.current_index >= len(self.review_pool): + self.current_index = 0 + random.shuffle(self.review_pool) # Re-scramble deck upon completing the pass loop + + self.display_current_card_front() \ No newline at end of file diff --git a/tabs/sandbox_tab.py b/tabs/sandbox_tab.py index e69de29..b2b19db 100644 --- a/tabs/sandbox_tab.py +++ b/tabs/sandbox_tab.py @@ -0,0 +1,219 @@ +# tabs/sandbox_tab.py +import subprocess +from PyQt6.QtWidgets import ( + QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QLineEdit, QPushButton, QTableWidget, QTableWidgetItem, + QHeaderView, QMessageBox, QFormLayout +) +from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt +import database + +class SandboxTab(QWidget): + # Signal emitted whenever data is added, modified, or deleted + data_mutated = pyqtSignal() + + def __init__(self, parent=None): + super().__init__(parent) + + # Main layout structure + main_layout = QVBoxLayout(self) + main_layout.setContentsMargins(30, 20, 30, 20) + main_layout.setSpacing(15) + + # --- SECTION 1: FORM INPUT CRADLE --- + form_container = QWidget() + form_layout = QFormLayout(form_container) + form_layout.setLabelAlignment(Qt.AlignmentFlag.AlignRight) + form_layout.setSpacing(10) + + # Input Form Fields + self.txt_english = QLineEdit() + self.txt_english.setPlaceholderText("Enter English phrase or word...") + self.txt_english.setStyleSheet("padding: 6px; font-size: 14px;") + + self.txt_spanish = QLineEdit() + self.txt_spanish.setPlaceholderText("Introduce la frase en espaΓ±ol...") + self.txt_spanish.setStyleSheet("padding: 6px; font-size: 14px;") + + self.txt_context = QLineEdit() + self.txt_context.setPlaceholderText("e.g., Camino 2027, CafΓ©, Market conversation...") + self.txt_context.setStyleSheet("padding: 6px; font-size: 14px;") + + self.txt_notes = QLineEdit() + self.txt_notes.setPlaceholderText("Grammar rules, formal vs informal nuances...") + self.txt_notes.setStyleSheet("padding: 6px; font-size: 14px;") + + # Mount fields onto Form Layout + form_layout.addRow(QLabel("English Text:"), self.txt_english) + form_layout.addRow(QLabel("Spanish Text:"), self.txt_spanish) + form_layout.addRow(QLabel("Source Context:"), self.txt_context) + form_layout.addRow(QLabel("Historical Notes:"), self.txt_notes) + + main_layout.addWidget(form_container) + + # --- SECTION 2: AUDIO PREVIEW ACTION ROW --- + audio_layout = QHBoxLayout() + audio_layout.setSpacing(15) + + self.btn_play_en = QPushButton("πŸ”Š Test English Voice") + self.btn_play_en.setCursor(Qt.CursorShape.PointingHandCursor) + self.btn_play_en.setStyleSheet(""" + QPushButton { + background-color: #E67E22; + color: white; + font-weight: bold; + font-size: 13px; + padding: 8px 16px; + border-radius: 4px; + } + QPushButton:hover { background-color: #D35400; } + """) + self.btn_play_en.clicked.connect(self.preview_english_audio) + + self.btn_play_es = QPushButton("πŸ”Š Test MΓ³nica (Spanish)") + self.btn_play_es.setCursor(Qt.CursorShape.PointingHandCursor) + self.btn_play_es.setStyleSheet(""" + QPushButton { + background-color: #9B59B6; + color: white; + font-weight: bold; + font-size: 13px; + padding: 8px 16px; + border-radius: 4px; + } + QPushButton:hover { background-color: #8E44AD; } + """) + self.btn_play_es.clicked.connect(self.preview_spanish_audio) + + audio_layout.addWidget(self.btn_play_en) + audio_layout.addWidget(self.btn_play_es) + audio_layout.addStretch() + + main_layout.addLayout(audio_layout) + + # --- SECTION 3: DATA COMMIT CONTROL BAR --- + control_layout = QHBoxLayout() + + self.btn_save = QPushButton("Save Translation Record") + self.btn_save.setCursor(Qt.CursorShape.PointingHandCursor) + self.btn_save.setStyleSheet(""" + QPushButton { + background-color: #2980B9; + color: white; + font-weight: bold; + font-size: 14px; + padding: 10px 20px; + border-radius: 5px; + } + QPushButton:hover { background-color: #1F618D; } + """) + self.btn_save.clicked.connect(self.commit_translation_record) + + self.btn_clear = QPushButton("Clear Fields") + self.btn_clear.setCursor(Qt.CursorShape.PointingHandCursor) + self.btn_clear.setStyleSheet(""" + QPushButton { + background-color: #BDC3C7; + color: #34495E; + font-weight: bold; + font-size: 14px; + padding: 10px 20px; + border-radius: 5px; + } + QPushButton:hover { background-color: #95A5A6; } + """) + self.btn_clear.clicked.connect(self.clear_input_fields) + + control_layout.addWidget(self.btn_save) + control_layout.addWidget(self.btn_clear) + control_layout.addStretch() + + main_layout.addLayout(control_layout) + + # --- SECTION 4: DATALIST DISPLAY REGION --- + self.table = QTableWidget() + self.table.setColumnCount(5) + self.table.setHorizontalHeaderLabels(["ID", "English Phrase", "Spanish Translation", "Context", "Notes"]) + self.table.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows) + self.table.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers) + + # Tweak display headers to scale nicely + header = self.table.horizontalHeader() + header.setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents) + header.setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch) + header.setSectionResizeMode(2, QHeaderView.ResizeMode.Stretch) + header.setSectionResizeMode(3, QHeaderView.ResizeMode.Interactive) + header.setSectionResizeMode(4, QHeaderView.ResizeMode.Interactive) + + main_layout.addWidget(self.table) + + # Populate live view from storage layout tracking engines + self.reload_table_display() + + @pyqtSlot() + def preview_english_audio(self): + """Auditions current text state inside the English text box field.""" + text = self.txt_english.text().strip() + if text: + subprocess.Popen(["say", text]) + + @pyqtSlot() + def preview_spanish_audio(self): + """Auditions current text state inside the Spanish text box field using MΓ³nica.""" + text = self.txt_spanish.text().strip() + if text: + subprocess.Popen(["say", "-v", "Monica", text]) + + @pyqtSlot() + def commit_translation_record(self): + """Extracts text metrics out of input wrappers and saves down to database engine storage.""" + en_text = self.txt_english.text().strip() + es_text = self.txt_spanish.text().strip() + context = self.txt_context.text().strip() + notes = self.txt_notes.text().strip() + + if not en_text or not es_text: + QMessageBox.warning(self, "Validation Alert", "Both English and Spanish base text blocks are required.") + return + + # Call explicit writing handlers down to SQLite database layer + database.insert_translation_explicit(en_text, es_text, context, notes) + + # Wipe structural field items cleanly on completions loop + self.clear_input_fields() + + # Sync state out across the rest of the app window elements + self.reload_table_display() + self.data_mutated.emit() + + @pyqtSlot() + def clear_input_fields(self): + """Flushes transient cache items out of form line elements.""" + self.txt_english.clear() + self.txt_spanish.clear() + self.txt_context.clear() + self.txt_notes.clear() + + def reload_table_display(self): + """Refetches database rows and populates the master dashboard grid view.""" + self.table.setRowCount(0) + records = database.get_all_translations_explicit() + + for idx, row in enumerate(records): + self.table.insertRow(idx) + + # Form clean mapping cell entities + item_id = QTableWidgetItem(str(row["translation_id"])) + item_en = QTableWidgetItem(row["en_text"]) + item_es = QTableWidgetItem(row["es_text"]) + item_ctx = QTableWidgetItem(row["source_context"] or "") + item_nts = QTableWidgetItem(row["notes"] or "") + + # Align center the ID key indices + item_id.setTextAlignment(Qt.AlignmentFlag.AlignCenter) + + self.table.setItem(idx, 0, item_id) + self.table.setItem(idx, 1, item_en) + self.table.setItem(idx, 2, item_es) + self.table.setItem(idx, 3, item_ctx) + self.table.setItem(idx, 4, item_nts) \ No newline at end of file diff --git a/tabs/setting_tab.py b/tabs/setting_tab.py deleted file mode 100644 index e69de29..0000000 diff --git a/tabs/settings_tab.py b/tabs/settings_tab.py new file mode 100644 index 0000000..40eec84 --- /dev/null +++ b/tabs/settings_tab.py @@ -0,0 +1,145 @@ +# tabs/settings_tab.py +import os +from PyQt6.QtWidgets import ( + QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, + QPushButton, QFileDialog, QGroupBox, QFormLayout, + QMessageBox, QFrame +) +from PyQt6.QtCore import pyqtSignal, pyqtSlot +import database + +class SettingsTab(QWidget): + # Signals to communicate up to the centralized main.py loop coordinator + settings_changed = pyqtSignal(str, str) # Emits: (key, value) + export_anki_requested = pyqtSignal(str) # Emits: (full_deck_name) + generate_video_requested = pyqtSignal() # Emits: trigger + + def __init__(self, parent=None): + super().__init__(parent) + + main_layout = QVBoxLayout(self) + main_layout.setSpacing(15) + + # --- SECTION 1: GLOBAL ANKI PACKAGING CONFIGURATIONS --- + anki_group = QGroupBox("Anki Compilation Settings") + anki_form = QFormLayout(anki_group) + anki_form.setSpacing(10) + + self.txt_root_deck = QLineEdit() + self.txt_root_deck.setPlaceholderText("e.g., Spanish::CAE_Course") + self.txt_root_deck.textChanged.connect(lambda text: self.update_setting("anki_root_deck_name", text.strip())) + + self.txt_sub_deck = QLineEdit() + self.txt_sub_deck.setPlaceholderText("e.g., Vocabulary::Unit_1") + self.txt_sub_deck.textChanged.connect(lambda text: self.update_setting("anki_sub_deck_name", text.strip())) + + # Export Destination Directory Picker + dir_picker_layout = QHBoxLayout() + self.txt_export_dir = QLineEdit() + self.txt_export_dir.setReadOnly(True) + self.txt_export_dir.setStyleSheet("background-color: #F8F9F9; color: #34495E;") + + btn_browse = QPushButton("Browse...") + btn_browse.clicked.connect(self.browse_export_directory) + dir_picker_layout.addWidget(self.txt_export_dir) + dir_picker_layout.addWidget(btn_browse) + + anki_form.addRow("Root Deck Name:", self.txt_root_deck) + anki_form.addRow("Sub-Deck Namespace Hierarchy:", self.txt_sub_deck) + anki_form.addRow("Export Target Directory:", dir_picker_layout) + + main_layout.addWidget(anki_group) + + # --- SECTION 2: AUDIO ENGINE & COMPILATION OVERRIDES --- + engine_group = QGroupBox("Voice Synthesis & Training Configuration") + engine_form = QFormLayout(engine_group) + + self.txt_tts_voice = QLineEdit() + self.txt_tts_voice.setPlaceholderText("Apple_Monica") + self.txt_tts_voice.textChanged.connect(lambda text: self.update_setting("tts_preferred_voice", text.strip())) + + self.txt_tts_speed = QLineEdit() + self.txt_tts_speed.setPlaceholderText("1.15") + self.txt_tts_speed.textChanged.connect(lambda text: self.update_setting("tts_playback_speed", text.strip())) + + engine_form.addRow("Fallback System Voice Name:", self.txt_tts_voice) + engine_form.addRow("Target Speech Playback Multiplier:", self.txt_tts_speed) + + main_layout.addWidget(engine_group) + + # Decorative divider line + divider = QFrame() + divider.setFrameShape(QFrame.Shape.HLine) + divider.setFrameShadow(QFrame.Shadow.Sunken) + main_layout.addWidget(divider) + + # --- SECTION 3: SYSTEM ACTION EXECUTION BAR --- + actions_group = QGroupBox("Execution Pipelines") + actions_layout = QHBoxLayout(actions_group) + actions_layout.setSpacing(20) + + self.btn_export_anki = QPushButton("πŸš€ Compile Lightweight Anki APKG") + self.btn_export_anki.setStyleSheet(""" + QPushButton { background-color: #2980B9; color: white; font-weight: bold; font-size: 13px; padding: 10px; border-radius: 4px; } + QPushButton:hover { background-color: #3498DB; } + """) + self.btn_export_anki.clicked.connect(self.dispatch_anki_export) + + self.btn_gen_video = QPushButton("🎬 Generate MP4 Loop Playlists") + self.btn_gen_video.setStyleSheet(""" + QPushButton { background-color: #8E44AD; color: white; font-weight: bold; font-size: 13px; padding: 10px; border-radius: 4px; } + QPushButton:hover { background-color: #9B59B6; } + """) + self.btn_gen_video.clicked.connect(self.generate_video_requested.emit) + + actions_layout.addWidget(self.btn_export_anki) + actions_layout.addWidget(self.btn_gen_video) + + main_layout.addWidget(actions_group) + main_layout.addStretch() # Push everything neatly to the top + + # Load settings from database onto inputs on initialization + self.populate_fields_from_db_state() + + def populate_fields_from_db_state(self): + """Fetches stored parameters on view load initialization.""" + # Block signals briefly so loading state doesn't trigger write-back loops + self.blockSignals(True) + + stored_settings = database.load_all_settings() + + self.txt_root_deck.setText(stored_settings.get("anki_root_deck_name", "Spanish")) + self.txt_sub_deck.setText(stored_settings.get("anki_sub_deck_name", "")) + self.txt_export_dir.setText(stored_settings.get("anki_export_directory", os.path.expanduser("~"))) + self.txt_tts_voice.setText(stored_settings.get("tts_preferred_voice", "Apple_Monica")) + self.txt_tts_speed.setText(stored_settings.get("tts_playback_speed", "1.15")) + + self.blockSignals(False) + + def update_setting(self, key, value): + """Internal helper to communicate state mutations instantly upward.""" + self.settings_changed.emit(key, value) + + def browse_export_directory(self): + """Invokes a native macOS directory finder path browser window.""" + current_dir = self.txt_export_dir.text() or os.path.expanduser("~") + selected_directory = QFileDialog.getExistingDirectory( + self, "Select Anki Export Target Location", current_dir + ) + + if selected_directory: + self.txt_export_dir.setText(selected_directory) + self.update_setting("anki_export_directory", selected_directory) + + def dispatch_anki_export(self): + """Constructs and validates the structured deck names namespace before signaling main.py.""" + root = self.txt_root_deck.text().strip() + sub = self.txt_sub_deck.text().strip() + + if not root: + QMessageBox.warning(self, "Invalid Parameters", "A root deck namespace destination must be provided.") + return + + # Combine hierarchy into standard Anki format: 'Root::SubDeck' + full_deck_name = f"{root}::{sub}" if sub else root + self.export_anki_requested.emit(full_deck_name) \ No newline at end of file