Add SRPG Studio to GUI
This commit is contained in:
parent
52e23c12aa
commit
da7b3a7bd1
4 changed files with 171 additions and 1 deletions
|
|
@ -17,6 +17,7 @@ from dotenv import load_dotenv, set_key
|
|||
from gui.rpgmaker_tab import RPGMakerTab
|
||||
from gui.wolf_tab import WolfTab
|
||||
from gui.csv_tab import CSVTab
|
||||
from gui.srpg_tab import SRPGTab
|
||||
|
||||
|
||||
def create_section_header(title):
|
||||
|
|
@ -113,6 +114,12 @@ class ConfigTab(QWidget):
|
|||
btn_csv.clicked.connect(lambda: self.switch_page(4))
|
||||
nav_layout.addWidget(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_bar.setLayout(nav_layout)
|
||||
|
|
@ -139,6 +146,10 @@ class ConfigTab(QWidget):
|
|||
# Page 5: CSV Settings
|
||||
self.csv_tab = CSVTab()
|
||||
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
|
||||
main_layout.addWidget(nav_bar)
|
||||
|
|
|
|||
155
gui/srpg_tab.py
Normal file
155
gui/srpg_tab.py
Normal 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}')
|
||||
|
|
@ -1078,6 +1078,7 @@ class TranslationTab(QWidget):
|
|||
from modules.images import handleImages
|
||||
from modules.rpgmakerplugin import handlePlugin
|
||||
from modules.aquedi4 import handleAquedi4
|
||||
from modules.srpg import handleSRPG
|
||||
|
||||
self.modules = [
|
||||
["RPG Maker MV/MZ", [".json"], handleMVMZ],
|
||||
|
|
@ -1097,6 +1098,7 @@ class TranslationTab(QWidget):
|
|||
["Images", [".png", ".jpg", ".jpeg"], handleImages],
|
||||
["RPG Maker Plugin", [".js"], handlePlugin],
|
||||
["Aquedi4 Prepared JSON", [".json"], handleAquedi4],
|
||||
["SRPG Studio", [".json"], handleSRPG],
|
||||
]
|
||||
|
||||
for module in self.modules:
|
||||
|
|
@ -1121,6 +1123,8 @@ class TranslationTab(QWidget):
|
|||
self.engine_changed.emit("wolf")
|
||||
elif "mv/mz" in lowered:
|
||||
self.engine_changed.emit("mvmz")
|
||||
elif "srpg" in lowered:
|
||||
self.engine_changed.emit("srpg")
|
||||
|
||||
# Update mode dropdown based on engine
|
||||
current_mode = self.mode_combo.currentText()
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ FIXTEXTWRAP = True
|
|||
# IGNORETLTEXT: Skip Translated Text.
|
||||
IGNORETLTEXT = False
|
||||
# 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 = False
|
||||
# Join 408 codes into a single string like 401.
|
||||
|
|
|
|||
Loading…
Reference in a new issue