This commit is contained in:
dazedanon 2026-01-07 15:17:44 -06:00
parent 3c771a2b32
commit 1fc2aa3768
3 changed files with 78 additions and 61 deletions

View file

@ -376,15 +376,6 @@ class ConfigTab(QWidget):
self.note_width_spin.setFixedWidth(120) # Small
format_form.addRow(note_label, self.note_width_spin)
csv_delim_label = QLabel("CSV Delimiter:")
csv_delim_label.setFixedWidth(150)
csv_delim_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
self.csv_delimiter_combo = QComboBox()
self.csv_delimiter_combo.addItems([",", ";", "\t"])
self.csv_delimiter_combo.setItemText(2, "Tab") # Display "Tab" instead of actual tab character
self.csv_delimiter_combo.setFixedWidth(120) # Small
format_form.addRow(csv_delim_label, self.csv_delimiter_combo)
right_column.addLayout(format_form)
right_column.addWidget(create_horizontal_line())
@ -494,15 +485,6 @@ class ConfigTab(QWidget):
self.list_width_spin.setValue(int(os.getenv("listWidth", "100")))
self.note_width_spin.setValue(int(os.getenv("noteWidth", "75")))
# Load CSV delimiter
csv_delim = os.getenv("csvDelimiter", ",")
if csv_delim == "\t":
self.csv_delimiter_combo.setCurrentIndex(2) # Tab
elif csv_delim == ";":
self.csv_delimiter_combo.setCurrentIndex(1) # Semicolon
else:
self.csv_delimiter_combo.setCurrentIndex(0) # Comma (default)
# Load custom API settings
self.input_cost_spin.setValue(float(os.getenv("input_cost", "2.0")))
self.output_cost_spin.setValue(float(os.getenv("output_cost", "8.0")))
@ -535,11 +517,6 @@ class ConfigTab(QWidget):
set_key(self.env_file_path, "listWidth", str(self.list_width_spin.value()))
set_key(self.env_file_path, "noteWidth", str(self.note_width_spin.value()))
# Save CSV delimiter
csv_delim_index = self.csv_delimiter_combo.currentIndex()
csv_delim_value = [",", ";", "\t"][csv_delim_index]
set_key(self.env_file_path, "csvDelimiter", csv_delim_value)
# Save custom API settings
set_key(self.env_file_path, "input_cost", str(self.input_cost_spin.value()))
set_key(self.env_file_path, "output_cost", str(self.output_cost_spin.value()))
@ -590,7 +567,6 @@ class ConfigTab(QWidget):
self.width_spin.setValue(60)
self.list_width_spin.setValue(100)
self.note_width_spin.setValue(75)
self.csv_delimiter_combo.setCurrentIndex(0) # Comma (default)
# Custom API settings
self.input_cost_spin.setValue(2.0)
@ -618,7 +594,6 @@ class ConfigTab(QWidget):
"width": self.width_spin.value(),
"listWidth": self.list_width_spin.value(),
"noteWidth": self.note_width_spin.value(),
"csvDelimiter": [",", ";", "\t"][self.csv_delimiter_combo.currentIndex()],
"input_cost": self.input_cost_spin.value(),
"output_cost": self.output_cost_spin.value()
}

View file

@ -44,6 +44,9 @@ class CSVTab(QWidget):
# Default configuration values (0-indexed internally)
DEFAULT_CONFIG = {
# Delimiter
"CSV_DELIMITER": ",",
# Column settings (stored as 0-indexed)
"SOURCE_COLUMN": 0,
"TARGET_COLUMN": 1,
@ -105,6 +108,30 @@ class CSVTab(QWidget):
description_label.setStyleSheet("color: #888888; font-size: 10px; margin-bottom: 5px;")
main_layout.addWidget(description_label)
# Quick Presets at the top, spaced equally
main_layout.addWidget(create_section_label("⚡ Quick Presets"))
preset_layout = QHBoxLayout()
preset_layout.setSpacing(15)
preset_tpp = QPushButton("Translator++")
preset_tpp.setToolTip("Source col 1, Target col 2, skip header, use target if not empty")
preset_tpp.clicked.connect(self.apply_preset_tpp)
preset_layout.addWidget(preset_tpp, 1) # stretch factor 1 for equal spacing
preset_simple = QPushButton("Simple")
preset_simple.setToolTip("Source col 1, Target col 2, no special processing")
preset_simple.clicked.connect(self.apply_preset_simple)
preset_layout.addWidget(preset_simple, 1)
preset_speaker = QPushButton("Speaker & Text")
preset_speaker.setToolTip("Speaker col 3, Text col 10, with furigana removal")
preset_speaker.clicked.connect(self.apply_preset_speaker)
preset_layout.addWidget(preset_speaker, 1)
main_layout.addLayout(preset_layout)
main_layout.addWidget(create_horizontal_line())
# Two-column layout
columns_layout = QHBoxLayout()
columns_layout.setSpacing(40)
@ -126,7 +153,7 @@ class CSVTab(QWidget):
self.source_column_spin = QSpinBox()
self.source_column_spin.setRange(1, 100)
self.source_column_spin.setValue(1)
self.source_column_spin.setFixedWidth(80)
self.source_column_spin.setMinimumWidth(100)
column_form.addRow(source_label, self.source_column_spin)
# Target Column
@ -135,17 +162,17 @@ class CSVTab(QWidget):
self.target_column_spin = QSpinBox()
self.target_column_spin.setRange(1, 100)
self.target_column_spin.setValue(2)
self.target_column_spin.setFixedWidth(80)
self.target_column_spin.setMinimumWidth(100)
column_form.addRow(target_label, self.target_column_spin)
# Speaker Column
speaker_label = QLabel("Speaker Column:")
speaker_label.setToolTip("Which column contains speaker names (0 = none)")
speaker_label.setToolTip("Which column contains speaker names (None = disabled)")
self.speaker_column_spin = QSpinBox()
self.speaker_column_spin.setRange(0, 100)
self.speaker_column_spin.setValue(0)
self.speaker_column_spin.setSpecialValueText("None")
self.speaker_column_spin.setFixedWidth(80)
self.speaker_column_spin.setMinimumWidth(100)
column_form.addRow(speaker_label, self.speaker_column_spin)
left_column.addLayout(column_form)
@ -175,6 +202,18 @@ class CSVTab(QWidget):
self.write_next_column_cb.setToolTip("Write translation to the column after target instead of overwriting")
right_column.addWidget(self.write_next_column_cb)
# CSV Delimiter
delim_layout = QHBoxLayout()
delim_label = QLabel("Delimiter:")
delim_label.setToolTip("Character used to separate columns in the CSV file")
self.csv_delimiter_combo = QComboBox()
self.csv_delimiter_combo.addItems([",", ";", "Tab"])
self.csv_delimiter_combo.setMinimumWidth(80)
delim_layout.addWidget(delim_label)
delim_layout.addWidget(self.csv_delimiter_combo)
delim_layout.addStretch()
right_column.addLayout(delim_layout)
right_column.addWidget(create_horizontal_line())
# Special Parsing
@ -203,34 +242,6 @@ class CSVTab(QWidget):
columns_layout.addLayout(right_column, 1)
main_layout.addLayout(columns_layout)
# Preset buttons
main_layout.addWidget(create_horizontal_line())
main_layout.addWidget(create_section_label("⚡ Quick Presets"))
preset_layout = QHBoxLayout()
preset_layout.setSpacing(10)
preset_tpp = QPushButton("Translator++")
preset_tpp.setToolTip("Source col 1, Target col 2, skip header, use target if not empty")
preset_tpp.clicked.connect(self.apply_preset_tpp)
preset_tpp.setMaximumWidth(120)
preset_layout.addWidget(preset_tpp)
preset_simple = QPushButton("Simple")
preset_simple.setToolTip("Source col 1, Target col 2, no special processing")
preset_simple.clicked.connect(self.apply_preset_simple)
preset_simple.setMaximumWidth(120)
preset_layout.addWidget(preset_simple)
preset_speaker = QPushButton("Speaker & Text")
preset_speaker.setToolTip("Speaker col 3, Text col 10, with furigana removal")
preset_speaker.clicked.connect(self.apply_preset_speaker)
preset_speaker.setMaximumWidth(120)
preset_layout.addWidget(preset_speaker)
preset_layout.addStretch()
main_layout.addLayout(preset_layout)
# Bottom buttons
main_layout.addSpacing(12)
button_layout = QHBoxLayout()
@ -317,6 +328,7 @@ class CSVTab(QWidget):
self.source_column_spin.valueChanged.disconnect()
self.target_column_spin.valueChanged.disconnect()
self.speaker_column_spin.valueChanged.disconnect()
self.csv_delimiter_combo.currentIndexChanged.disconnect()
self.skip_header_cb.stateChanged.disconnect()
self.use_target_if_not_empty_cb.stateChanged.disconnect()
self.write_next_column_cb.stateChanged.disconnect()
@ -332,6 +344,7 @@ class CSVTab(QWidget):
self.source_column_spin.valueChanged.connect(lambda: self.apply_to_module(show_messages=False))
self.target_column_spin.valueChanged.connect(lambda: self.apply_to_module(show_messages=False))
self.speaker_column_spin.valueChanged.connect(lambda: self.apply_to_module(show_messages=False))
self.csv_delimiter_combo.currentIndexChanged.connect(lambda: self.apply_to_module(show_messages=False))
self.skip_header_cb.stateChanged.connect(lambda: self.apply_to_module(show_messages=False))
self.use_target_if_not_empty_cb.stateChanged.connect(lambda: self.apply_to_module(show_messages=False))
self.write_next_column_cb.stateChanged.connect(lambda: self.apply_to_module(show_messages=False))
@ -348,10 +361,16 @@ class CSVTab(QWidget):
speaker_ui = self.speaker_column_spin.value()
speaker_internal = speaker_ui - 1 if speaker_ui > 0 else -1
# Get delimiter value
delim_index = self.csv_delimiter_combo.currentIndex()
delim_values = [",", ";", "\t"]
delimiter = delim_values[delim_index] if delim_index < len(delim_values) else ","
return {
"SOURCE_COLUMN": self.source_column_spin.value() - 1,
"TARGET_COLUMN": self.target_column_spin.value() - 1,
"SPEAKER_COLUMN": speaker_internal,
"CSV_DELIMITER": delimiter,
"SKIP_HEADER_ROW": self.skip_header_cb.isChecked(),
"USE_TARGET_IF_NOT_EMPTY": self.use_target_if_not_empty_cb.isChecked(),
"WRITE_TO_NEXT_COLUMN": self.write_next_column_cb.isChecked(),
@ -372,6 +391,16 @@ class CSVTab(QWidget):
self.source_column_spin.setValue(config.get("SOURCE_COLUMN", 0) + 1)
self.target_column_spin.setValue(config.get("TARGET_COLUMN", 1) + 1)
self.speaker_column_spin.setValue(speaker_ui)
# Set delimiter
delimiter = config.get("CSV_DELIMITER", ",")
if delimiter == "\t":
self.csv_delimiter_combo.setCurrentIndex(2)
elif delimiter == ";":
self.csv_delimiter_combo.setCurrentIndex(1)
else:
self.csv_delimiter_combo.setCurrentIndex(0)
self.skip_header_cb.setChecked(config.get("SKIP_HEADER_ROW", True))
self.use_target_if_not_empty_cb.setChecked(config.get("USE_TARGET_IF_NOT_EMPTY", False))
self.write_next_column_cb.setChecked(config.get("WRITE_TO_NEXT_COLUMN", False))
@ -400,6 +429,11 @@ class CSVTab(QWidget):
"SPEAKER_COLUMN": r'^SPEAKER_COLUMN\s*=\s*(-?\d+)',
}
# Read string values (delimiter)
string_patterns = {
"CSV_DELIMITER": r'^CSV_DELIMITER\s*=\s*["\'](.+?)["\']',
}
# Read boolean values
bool_patterns = {
"SKIP_HEADER_ROW": r'^SKIP_HEADER_ROW\s*=\s*(True|False)',
@ -419,6 +453,11 @@ class CSVTab(QWidget):
if match:
config[key] = int(match.group(1))
for key, pattern in string_patterns.items():
match = re.match(pattern, line)
if match:
config[key] = match.group(1)
for key, pattern in bool_patterns.items():
match = re.match(pattern, line)
if match:
@ -487,6 +526,9 @@ class CSVTab(QWidget):
# Format value appropriately
if isinstance(value, bool):
value_str = str(value)
elif isinstance(value, str):
# String values need quotes
value_str = f'"{value}"'
else:
value_str = str(value)

View file

@ -26,7 +26,6 @@ LOCK = threading.Lock()
WIDTH = int(os.getenv("width"))
LISTWIDTH = int(os.getenv("listWidth"))
NOTEWIDTH = int(os.getenv("noteWidth"))
CSV_DELIMITER = os.getenv("csvDelimiter", ",") # CSV delimiter character (comma, semicolon, tab)
MAXHISTORY = 10
ESTIMATE = ""
TOKENS = [0, 0]
@ -40,10 +39,11 @@ FILENAME = None
BRACKETNAMES = False
# CSV Configuration Settings (configurable via GUI)
SOURCE_COLUMN = 2 # Which column has the source text to translate
TARGET_COLUMN = 3 # Which column to write translations to
CSV_DELIMITER = "," # CSV delimiter character (comma, semicolon, tab)
SOURCE_COLUMN = 0 # Which column has the source text to translate (0-indexed)
TARGET_COLUMN = 1 # Which column to write translations to
SPEAKER_COLUMN = -1 # Which column has speaker names (-1 = none)
SKIP_HEADER_ROW = True # Skip the first row (header)
SKIP_HEADER_ROW = False # Skip the first row (header)
USE_TARGET_IF_NOT_EMPTY = False # Use target column text if not empty (T++ style)
WRITE_TO_NEXT_COLUMN = False # Write to column after target instead of overwriting
PARSE_NAME_TAGS = False # Parse :name[] tags in text