fixed store translation
This commit is contained in:
parent
b61d72740b
commit
b5567bf498
3 changed files with 184 additions and 19 deletions
13
database.py
13
database.py
|
|
@ -150,3 +150,16 @@ def delete_translation_record(translation_id):
|
|||
conn.commit()
|
||||
finally:
|
||||
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.
|
|
@ -15,6 +15,9 @@ class SandboxTab(QWidget):
|
|||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
# Internal tracking variable to distinguish edits vs new entries
|
||||
self.selected_translation_id = None
|
||||
|
||||
# Main layout structure
|
||||
main_layout = QVBoxLayout(self)
|
||||
main_layout.setContentsMargins(30, 20, 30, 20)
|
||||
|
|
@ -30,14 +33,17 @@ class SandboxTab(QWidget):
|
|||
self.txt_english = QLineEdit()
|
||||
self.txt_english.setPlaceholderText("Enter English phrase or word...")
|
||||
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.setPlaceholderText("Introduce la frase en español...")
|
||||
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.setPlaceholderText("e.g., Camino 2027, Café, Market conversation...")
|
||||
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.setPlaceholderText("Grammar rules, formal vs informal nuances...")
|
||||
|
|
@ -93,6 +99,7 @@ class SandboxTab(QWidget):
|
|||
|
||||
# --- SECTION 3: DATA COMMIT CONTROL BAR ---
|
||||
control_layout = QHBoxLayout()
|
||||
control_layout.setSpacing(15)
|
||||
|
||||
self.btn_save = QPushButton("Save Translation Record")
|
||||
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_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.setCursor(Qt.CursorShape.PointingHandCursor)
|
||||
self.btn_clear.setStyleSheet("""
|
||||
|
|
@ -122,9 +144,10 @@ class SandboxTab(QWidget):
|
|||
}
|
||||
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_new_record)
|
||||
control_layout.addWidget(self.btn_clear)
|
||||
control_layout.addStretch()
|
||||
|
||||
|
|
@ -137,6 +160,9 @@ class SandboxTab(QWidget):
|
|||
self.table.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows)
|
||||
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
|
||||
header = self.table.horizontalHeader()
|
||||
header.setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents)
|
||||
|
|
@ -147,7 +173,8 @@ class SandboxTab(QWidget):
|
|||
|
||||
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()
|
||||
|
||||
@pyqtSlot()
|
||||
|
|
@ -164,52 +191,175 @@ class SandboxTab(QWidget):
|
|||
if 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()
|
||||
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()
|
||||
es_text = self.txt_spanish.text().strip()
|
||||
context = self.txt_context.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:
|
||||
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)
|
||||
try:
|
||||
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
|
||||
self.clear_input_fields()
|
||||
# Clear pointer state values on successful writing commits
|
||||
self.selected_translation_id = None
|
||||
|
||||
# Sync state out across the rest of the app window elements
|
||||
self.reload_table_display()
|
||||
self.data_mutated.emit()
|
||||
# Wipe inputs cleanly and sync UI layers
|
||||
self.clear_input_fields()
|
||||
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()
|
||||
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):
|
||||
"""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_spanish.clear()
|
||||
self.txt_context.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):
|
||||
"""Refetches database rows and populates the master dashboard grid view."""
|
||||
self.table.blockSignals(True)
|
||||
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)
|
||||
|
||||
# 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)
|
||||
|
|
@ -217,3 +367,5 @@ class SandboxTab(QWidget):
|
|||
self.table.setItem(idx, 2, item_es)
|
||||
self.table.setItem(idx, 3, item_ctx)
|
||||
self.table.setItem(idx, 4, item_nts)
|
||||
|
||||
self.table.blockSignals(False)
|
||||
Loading…
Reference in a new issue