Add SRPG Studio to GUI

This commit is contained in:
dazedanon 2026-03-02 01:41:10 -06:00
parent 52e23c12aa
commit da7b3a7bd1
4 changed files with 171 additions and 1 deletions

View file

@ -17,6 +17,7 @@ from dotenv import load_dotenv, set_key
from gui.rpgmaker_tab import RPGMakerTab from gui.rpgmaker_tab import RPGMakerTab
from gui.wolf_tab import WolfTab from gui.wolf_tab import WolfTab
from gui.csv_tab import CSVTab from gui.csv_tab import CSVTab
from gui.srpg_tab import SRPGTab
def create_section_header(title): def create_section_header(title):
@ -113,6 +114,12 @@ class ConfigTab(QWidget):
btn_csv.clicked.connect(lambda: self.switch_page(4)) btn_csv.clicked.connect(lambda: self.switch_page(4))
nav_layout.addWidget(btn_csv) nav_layout.addWidget(btn_csv)
self.nav_buttons.append(btn_csv) self.nav_buttons.append(btn_csv)
# SRPG Studio button
btn_srpg = self.create_nav_button("⚔️", "SRPG Studio")
btn_srpg.clicked.connect(lambda: self.switch_page(5))
nav_layout.addWidget(btn_srpg)
self.nav_buttons.append(btn_srpg)
nav_layout.addStretch() nav_layout.addStretch()
nav_bar.setLayout(nav_layout) nav_bar.setLayout(nav_layout)
@ -139,6 +146,10 @@ class ConfigTab(QWidget):
# Page 5: CSV Settings # Page 5: CSV Settings
self.csv_tab = CSVTab() self.csv_tab = CSVTab()
self.content_stack.addWidget(self.csv_tab) self.content_stack.addWidget(self.csv_tab)
# Page 6: SRPG Studio Engine
self.srpg_tab = SRPGTab()
self.content_stack.addWidget(self.srpg_tab)
# Add navigation bar and content to main layout # Add navigation bar and content to main layout
main_layout.addWidget(nav_bar) main_layout.addWidget(nav_bar)

155
gui/srpg_tab.py Normal file
View file

@ -0,0 +1,155 @@
"""SRPG Studio configuration tab.
Provides toggles for configurable flags in srpg.py so users can
enable/disable text-wrap fixing and skip-already-translated behaviour.
"""
from pathlib import Path
from PyQt5.QtWidgets import (
QWidget, QVBoxLayout, QCheckBox, QPushButton, QMessageBox, QLabel, QHBoxLayout
)
from PyQt5.QtCore import pyqtSignal
import re
try:
import set_defaults
CANONICAL_DEFAULTS = getattr(set_defaults, 'DEFAULTS', None)
except Exception:
CANONICAL_DEFAULTS = None
def create_section_label(text):
"""Create a styled section header label."""
label = QLabel(text)
label.setStyleSheet("font-size: 12px; font-weight: bold; color: #007acc; padding: 2px 0px;")
return label
class SRPGTab(QWidget):
config_changed = pyqtSignal()
DEFAULT_CONFIG = {
"FIXTEXTWRAP": True,
"IGNORETLTEXT": False,
}
def __init__(self):
super().__init__()
self.init_ui()
defaults = CANONICAL_DEFAULTS if CANONICAL_DEFAULTS is not None else self.DEFAULT_CONFIG
self.set_config(defaults)
self.connect_auto_apply()
def init_ui(self):
"""Initialize the user interface."""
main_layout = QVBoxLayout()
main_layout.setContentsMargins(15, 15, 15, 15)
main_layout.setSpacing(10)
# Title
title = QLabel("SRPG Studio Translation Settings")
title.setStyleSheet("font-size: 15px; font-weight: bold; color: #007acc;")
main_layout.addWidget(title)
description = QLabel(
"Configure translation options for SRPG Studio projects. "
"Changes are applied directly to modules/srpg.py."
)
description.setWordWrap(True)
description.setStyleSheet("color: #888888; font-size: 10px; margin-bottom: 8px;")
main_layout.addWidget(description)
# --- Text Formatting ---
main_layout.addWidget(create_section_label("📝 Text Formatting"))
self.fixtextwrap_cb = QCheckBox("Fix Text Wrap")
self.fixtextwrap_cb.setToolTip(
"Re-wrap translated text to fit the configured dialogue width (WIDTH setting)"
)
main_layout.addWidget(self.fixtextwrap_cb)
# --- Translation Behaviour ---
main_layout.addWidget(create_section_label("🔄 Translation Behaviour"))
self.ignoretltext_cb = QCheckBox("Ignore Already-Translated Text")
self.ignoretltext_cb.setToolTip(
"Skip lines that appear to have already been translated"
)
main_layout.addWidget(self.ignoretltext_cb)
main_layout.addStretch()
# Bottom buttons
button_layout = QHBoxLayout()
button_layout.setSpacing(10)
self.reset_btn = QPushButton("🔄 Reset to Defaults")
self.reset_btn.clicked.connect(self.reset_to_defaults_with_message)
self.reset_btn.setMaximumWidth(180)
self.reset_btn.setMinimumHeight(32)
button_layout.addWidget(self.reset_btn)
button_layout.addStretch()
main_layout.addLayout(button_layout)
self.setLayout(main_layout)
# ------------------------------------------------------------------
# Public API
# ------------------------------------------------------------------
def get_config(self) -> dict:
"""Return current configuration as a dictionary."""
return {
"FIXTEXTWRAP": self.fixtextwrap_cb.isChecked(),
"IGNORETLTEXT": self.ignoretltext_cb.isChecked(),
}
def set_config(self, config: dict):
"""Set configuration from dictionary (does not write to module)."""
self.fixtextwrap_cb.setChecked(config.get("FIXTEXTWRAP", True))
self.ignoretltext_cb.setChecked(config.get("IGNORETLTEXT", False))
def connect_auto_apply(self):
"""Connect widget changes to auto-apply to srpg.py."""
self.fixtextwrap_cb.stateChanged.connect(lambda: self.apply_to_module(False))
self.ignoretltext_cb.stateChanged.connect(lambda: self.apply_to_module(False))
def reset_to_defaults(self):
"""Reset all settings to defaults without showing a message."""
defaults = (
CANONICAL_DEFAULTS
if 'CANONICAL_DEFAULTS' in globals() and CANONICAL_DEFAULTS is not None
else self.DEFAULT_CONFIG
)
self.set_config(defaults)
self.apply_to_module(False)
def reset_to_defaults_with_message(self):
"""Reset to defaults and show a confirmation message."""
self.reset_to_defaults()
QMessageBox.information(
self,
"Reset Complete",
"All settings have been reset to their default values.",
)
def apply_to_module(self, show_message: bool = False):
"""Write current configuration back to modules/srpg.py."""
module_path = Path(__file__).parent.parent / 'modules' / 'srpg.py'
if not module_path.exists():
if show_message:
QMessageBox.critical(self, 'Error', 'srpg.py not found in modules directory.')
return
try:
content = module_path.read_text(encoding='utf-8')
for key, value in self.get_config().items():
pattern = rf'^{key}\s*=\s*.*$'
content = re.sub(pattern, f'{key} = {value}', content, flags=re.MULTILINE)
module_path.write_text(content, encoding='utf-8')
self.config_changed.emit()
if show_message:
QMessageBox.information(self, 'Applied', 'SRPG Studio configuration applied to srpg.py.')
except Exception as e:
if show_message:
QMessageBox.critical(self, 'Error', f'Failed to apply settings: {e}')

View file

@ -1078,6 +1078,7 @@ class TranslationTab(QWidget):
from modules.images import handleImages from modules.images import handleImages
from modules.rpgmakerplugin import handlePlugin from modules.rpgmakerplugin import handlePlugin
from modules.aquedi4 import handleAquedi4 from modules.aquedi4 import handleAquedi4
from modules.srpg import handleSRPG
self.modules = [ self.modules = [
["RPG Maker MV/MZ", [".json"], handleMVMZ], ["RPG Maker MV/MZ", [".json"], handleMVMZ],
@ -1097,6 +1098,7 @@ class TranslationTab(QWidget):
["Images", [".png", ".jpg", ".jpeg"], handleImages], ["Images", [".png", ".jpg", ".jpeg"], handleImages],
["RPG Maker Plugin", [".js"], handlePlugin], ["RPG Maker Plugin", [".js"], handlePlugin],
["Aquedi4 Prepared JSON", [".json"], handleAquedi4], ["Aquedi4 Prepared JSON", [".json"], handleAquedi4],
["SRPG Studio", [".json"], handleSRPG],
] ]
for module in self.modules: for module in self.modules:
@ -1121,6 +1123,8 @@ class TranslationTab(QWidget):
self.engine_changed.emit("wolf") self.engine_changed.emit("wolf")
elif "mv/mz" in lowered: elif "mv/mz" in lowered:
self.engine_changed.emit("mvmz") self.engine_changed.emit("mvmz")
elif "srpg" in lowered:
self.engine_changed.emit("srpg")
# Update mode dropdown based on engine # Update mode dropdown based on engine
current_mode = self.mode_combo.currentText() current_mode = self.mode_combo.currentText()

View file

@ -124,7 +124,7 @@ FIXTEXTWRAP = True
# IGNORETLTEXT: Skip Translated Text. # IGNORETLTEXT: Skip Translated Text.
IGNORETLTEXT = False IGNORETLTEXT = False
# TLSYSTEMVARIABLES: Translate System Variables. (Optional but sometimes necessary. Can break stuff.) # TLSYSTEMVARIABLES: Translate System Variables. (Optional but sometimes necessary. Can break stuff.)
TLSYSTEMVARIABLES = True TLSYSTEMVARIABLES = False
# TLSYSTEMSWITCHES: Translate System Switches. (Optional. Translates switch names in System.json.) # TLSYSTEMSWITCHES: Translate System Switches. (Optional. Translates switch names in System.json.)
TLSYSTEMSWITCHES = False TLSYSTEMSWITCHES = False
# Join 408 codes into a single string like 401. # Join 408 codes into a single string like 401.