fixed store translation

This commit is contained in:
stephen 2026-06-25 22:23:11 +10:00
parent b61d72740b
commit b5567bf498
3 changed files with 184 additions and 19 deletions

View file

@ -150,3 +150,16 @@ def delete_translation_record(translation_id):
conn.commit() conn.commit()
finally: finally:
conn.close() conn.close()
def insert_translation_record(es_text, en_text, source_context, tags, notes):
"""Inserts a completely fresh record into the translations table."""
conn = get_connection()
cursor = conn.cursor()
try:
cursor.execute("""
INSERT INTO translations (es_text, en_text, source_context, tags, notes)
VALUES (?, ?, ?, ?, ?);
""", (es_text, en_text, source_context, tags, notes))
conn.commit()
finally:
conn.close()

Binary file not shown.

View file

@ -15,6 +15,9 @@ class SandboxTab(QWidget):
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
# Internal tracking variable to distinguish edits vs new entries
self.selected_translation_id = None
# Main layout structure # Main layout structure
main_layout = QVBoxLayout(self) main_layout = QVBoxLayout(self)
main_layout.setContentsMargins(30, 20, 30, 20) main_layout.setContentsMargins(30, 20, 30, 20)
@ -30,14 +33,17 @@ class SandboxTab(QWidget):
self.txt_english = QLineEdit() self.txt_english = QLineEdit()
self.txt_english.setPlaceholderText("Enter English phrase or word...") self.txt_english.setPlaceholderText("Enter English phrase or word...")
self.txt_english.setStyleSheet("padding: 6px; font-size: 14px;") self.txt_english.setStyleSheet("padding: 6px; font-size: 14px;")
self.txt_english.textChanged.connect(self.handle_live_filter)
self.txt_spanish = QLineEdit() self.txt_spanish = QLineEdit()
self.txt_spanish.setPlaceholderText("Introduce la frase en español...") self.txt_spanish.setPlaceholderText("Introduce la frase en español...")
self.txt_spanish.setStyleSheet("padding: 6px; font-size: 14px;") self.txt_spanish.setStyleSheet("padding: 6px; font-size: 14px;")
self.txt_spanish.textChanged.connect(self.handle_live_filter)
self.txt_context = QLineEdit() self.txt_context = QLineEdit()
self.txt_context.setPlaceholderText("e.g., Camino 2027, Café, Market conversation...") self.txt_context.setPlaceholderText("e.g., Camino 2027, Café, Market conversation...")
self.txt_context.setStyleSheet("padding: 6px; font-size: 14px;") self.txt_context.setStyleSheet("padding: 6px; font-size: 14px;")
self.txt_context.textChanged.connect(self.handle_live_filter)
self.txt_notes = QLineEdit() self.txt_notes = QLineEdit()
self.txt_notes.setPlaceholderText("Grammar rules, formal vs informal nuances...") self.txt_notes.setPlaceholderText("Grammar rules, formal vs informal nuances...")
@ -93,6 +99,7 @@ class SandboxTab(QWidget):
# --- SECTION 3: DATA COMMIT CONTROL BAR --- # --- SECTION 3: DATA COMMIT CONTROL BAR ---
control_layout = QHBoxLayout() control_layout = QHBoxLayout()
control_layout.setSpacing(15)
self.btn_save = QPushButton("Save Translation Record") self.btn_save = QPushButton("Save Translation Record")
self.btn_save.setCursor(Qt.CursorShape.PointingHandCursor) self.btn_save.setCursor(Qt.CursorShape.PointingHandCursor)
@ -109,6 +116,21 @@ class SandboxTab(QWidget):
""") """)
self.btn_save.clicked.connect(self.commit_translation_record) self.btn_save.clicked.connect(self.commit_translation_record)
self.btn_new_record = QPushButton("Create New Record")
self.btn_new_record.setCursor(Qt.CursorShape.PointingHandCursor)
self.btn_new_record.setStyleSheet("""
QPushButton {
background-color: #27AE60;
color: white;
font-weight: bold;
font-size: 14px;
padding: 10px 20px;
border-radius: 5px;
}
QPushButton:hover { background-color: #219653; }
""")
self.btn_new_record.clicked.connect(self.prepare_for_new_record)
self.btn_clear = QPushButton("Clear Fields") self.btn_clear = QPushButton("Clear Fields")
self.btn_clear.setCursor(Qt.CursorShape.PointingHandCursor) self.btn_clear.setCursor(Qt.CursorShape.PointingHandCursor)
self.btn_clear.setStyleSheet(""" self.btn_clear.setStyleSheet("""
@ -122,9 +144,10 @@ class SandboxTab(QWidget):
} }
QPushButton:hover { background-color: #95A5A6; } QPushButton:hover { background-color: #95A5A6; }
""") """)
self.btn_clear.clicked.connect(self.clear_input_fields) self.btn_clear.clicked.connect(self.clear_all_fields_manually)
control_layout.addWidget(self.btn_save) control_layout.addWidget(self.btn_save)
control_layout.addWidget(self.btn_new_record)
control_layout.addWidget(self.btn_clear) control_layout.addWidget(self.btn_clear)
control_layout.addStretch() control_layout.addStretch()
@ -137,6 +160,9 @@ class SandboxTab(QWidget):
self.table.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows) self.table.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows)
self.table.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers) self.table.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers)
# Wire up row selection change signals to auto-populate form
self.table.itemSelectionChanged.connect(self.handle_row_selection)
# Tweak display headers to scale nicely # Tweak display headers to scale nicely
header = self.table.horizontalHeader() header = self.table.horizontalHeader()
header.setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents) header.setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents)
@ -147,7 +173,8 @@ class SandboxTab(QWidget):
main_layout.addWidget(self.table) main_layout.addWidget(self.table)
# Populate live view from storage layout tracking engines # Master cache of unfiltered row records to enable instant filtering loops
self.all_cached_records = []
self.reload_table_display() self.reload_table_display()
@pyqtSlot() @pyqtSlot()
@ -164,52 +191,175 @@ class SandboxTab(QWidget):
if text: if text:
subprocess.Popen(["say", "-v", "Monica", text]) subprocess.Popen(["say", "-v", "Monica", text])
@pyqtSlot()
def handle_live_filter(self):
"""Filters the visible database entries based on current text input criteria."""
# Temporary block signals to prevent selection loops from fighting text changes
self.table.blockSignals(True)
filter_en = self.txt_english.text().lower().strip()
filter_es = self.txt_spanish.text().lower().strip()
filter_ctx = self.txt_context.text().lower().strip()
self.table.setRowCount(0)
visible_row_index = 0
for row in self.all_cached_records:
val_en = (row["en_text"] or "").lower()
val_es = (row["es_text"] or "").lower()
val_ctx = (row["source_context"] or "").lower()
# Look for matches across English, Spanish, and Source Context
if (filter_en in val_en) and (filter_es in val_es) and (filter_ctx in val_ctx):
self.table.insertRow(visible_row_index)
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 "")
item_id.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
self.table.setItem(visible_row_index, 0, item_id)
self.table.setItem(visible_row_index, 1, item_en)
self.table.setItem(visible_row_index, 2, item_es)
self.table.setItem(visible_row_index, 3, item_ctx)
self.table.setItem(visible_row_index, 4, item_nts)
# If we have an active editing ID, highlight that specific row during re-renders
if self.selected_translation_id == row["translation_id"]:
self.table.selectRow(visible_row_index)
visible_row_index += 1
self.table.blockSignals(False)
@pyqtSlot()
def handle_row_selection(self):
"""Populates the input forms when a user clicks a row in the table view."""
selected_ranges = self.table.selectedRanges()
if not selected_ranges:
return
row_idx = selected_ranges[0].topRow()
id_item = self.table.item(row_idx, 0)
if not id_item:
return
target_id = int(id_item.text())
# Locate item match within memory cache store elements
record = next((r for r in self.all_cached_records if r["translation_id"] == target_id), None)
if record:
# Block line edit text tracking temporarily so populating fields doesn't trigger filter loops
self.txt_english.blockSignals(True)
self.txt_spanish.blockSignals(True)
self.txt_context.blockSignals(True)
self.txt_notes.blockSignals(True)
self.selected_translation_id = record["translation_id"]
self.txt_english.setText(record["en_text"])
self.txt_spanish.setText(record["es_text"])
self.txt_context.setText(record["source_context"] or "")
self.txt_notes.setText(record["notes"] or "")
self.txt_english.blockSignals(False)
self.txt_spanish.blockSignals(False)
self.txt_context.blockSignals(False)
self.txt_notes.blockSignals(False)
@pyqtSlot()
def prepare_for_new_record(self):
"""Clears selection state so next click on 'Save' inserts fresh rows without scrubbing fields."""
self.selected_translation_id = None
self.table.blockSignals(True)
self.table.clearSelection()
self.table.blockSignals(False)
QMessageBox.information(self, "Status Shift", "Ready to insert a new record using the current field content.")
@pyqtSlot() @pyqtSlot()
def commit_translation_record(self): def commit_translation_record(self):
"""Extracts text metrics out of input wrappers and saves down to database engine storage.""" """Saves current text blocks. Dynamically detects insert vs edit based on selections."""
en_text = self.txt_english.text().strip() en_text = self.txt_english.text().strip()
es_text = self.txt_spanish.text().strip() es_text = self.txt_spanish.text().strip()
context = self.txt_context.text().strip() context = self.txt_context.text().strip()
notes = self.txt_notes.text().strip() notes = self.txt_notes.text().strip()
tags = "" # Default empty placeholder string to fit the backend DB method signature
if not en_text or not es_text: if not en_text or not es_text:
QMessageBox.warning(self, "Validation Alert", "Both English and Spanish base text blocks are required.") QMessageBox.warning(self, "Validation Alert", "Both English and Spanish base text blocks are required.")
return return
# Call explicit writing handlers down to SQLite database layer try:
database.insert_translation_explicit(en_text, es_text, context, notes) if self.selected_translation_id is not None:
# Direct match for database.update_translation_record signature:
# (translation_id, es_text, en_text, source_context, tags, notes)
database.update_translation_record(
self.selected_translation_id, es_text, en_text, context, tags, notes
)
else:
# Direct match for database.insert_translation_record signature:
# (es_text, en_text, source_context, tags, notes)
database.insert_translation_record(
es_text, en_text, context, tags, notes
)
# Wipe structural field items cleanly on completions loop # Clear pointer state values on successful writing commits
self.clear_input_fields() self.selected_translation_id = None
# Sync state out across the rest of the app window elements # Wipe inputs cleanly and sync UI layers
self.reload_table_display() self.clear_input_fields()
self.data_mutated.emit() self.reload_table_display()
self.data_mutated.emit()
except Exception as e:
QMessageBox.critical(self, "Database Commit Safeguard", f"Failed writing database operations:\n{str(e)}")
@pyqtSlot() @pyqtSlot()
def clear_all_fields_manually(self):
"""Clears explicit states alongside visual row highlights simultaneously."""
self.selected_translation_id = None
self.table.blockSignals(True)
self.table.clearSelection()
self.table.blockSignals(False)
self.clear_input_fields()
self.reload_table_display()
def clear_input_fields(self): def clear_input_fields(self):
"""Flushes transient cache items out of form line elements.""" """Flushes transient text inside line editors without running filtering rules."""
self.txt_english.blockSignals(True)
self.txt_spanish.blockSignals(True)
self.txt_context.blockSignals(True)
self.txt_notes.blockSignals(True)
self.txt_english.clear() self.txt_english.clear()
self.txt_spanish.clear() self.txt_spanish.clear()
self.txt_context.clear() self.txt_context.clear()
self.txt_notes.clear() self.txt_notes.clear()
self.txt_english.blockSignals(False)
self.txt_spanish.blockSignals(False)
self.txt_context.blockSignals(False)
self.txt_notes.blockSignals(False)
def reload_table_display(self): def reload_table_display(self):
"""Refetches database rows and populates the master dashboard grid view.""" """Refetches database rows and populates the master dashboard grid view."""
self.table.blockSignals(True)
self.table.setRowCount(0) self.table.setRowCount(0)
records = database.get_all_translations_explicit()
for idx, row in enumerate(records): # Keep internal reference arrays synced cleanly
self.all_cached_records = database.get_all_translations_explicit()
for idx, row in enumerate(self.all_cached_records):
self.table.insertRow(idx) self.table.insertRow(idx)
# Form clean mapping cell entities
item_id = QTableWidgetItem(str(row["translation_id"])) item_id = QTableWidgetItem(str(row["translation_id"]))
item_en = QTableWidgetItem(row["en_text"]) item_en = QTableWidgetItem(row["en_text"])
item_es = QTableWidgetItem(row["es_text"]) item_es = QTableWidgetItem(row["es_text"])
item_ctx = QTableWidgetItem(row["source_context"] or "") item_ctx = QTableWidgetItem(row["source_context"] or "")
item_nts = QTableWidgetItem(row["notes"] or "") item_nts = QTableWidgetItem(row["notes"] or "")
# Align center the ID key indices
item_id.setTextAlignment(Qt.AlignmentFlag.AlignCenter) item_id.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
self.table.setItem(idx, 0, item_id) self.table.setItem(idx, 0, item_id)
@ -217,3 +367,5 @@ class SandboxTab(QWidget):
self.table.setItem(idx, 2, item_es) self.table.setItem(idx, 2, item_es)
self.table.setItem(idx, 3, item_ctx) self.table.setItem(idx, 3, item_ctx)
self.table.setItem(idx, 4, item_nts) self.table.setItem(idx, 4, item_nts)
self.table.blockSignals(False)