refactor!: rebrand product from DazedMTLTool to DazedTL

- Rename desktop launcher, window titles, About, and User-Agents
- Point QSettings at DazedTL with one-time migration from legacy app key
- Update README, Guide, skills, and launcher/script copy

BREAKING CHANGE: QSettings and desktop id now use DazedTL (legacy keys migrated once)
This commit is contained in:
DazedAnon 2026-07-22 12:27:22 -05:00
parent 41691879dc
commit 4d1b01c870
30 changed files with 4353 additions and 4311 deletions

View file

@ -1,10 +1,10 @@
[Desktop Entry] [Desktop Entry]
Type=Application Type=Application
Name=DazedMTLTool Name=DazedTL
GenericName=Translation Tool GenericName=AI Translation Tool
Comment=AI translation tool for visual novels and RPG games Comment=AI translation tool for visual novels and RPG games
Exec=bash -c 'exec "$(cd "$(dirname "%k")" && pwd)/scripts/launch.sh"' Exec=bash -c 'exec "$(cd "$(dirname "%k")" && pwd)/scripts/launch.sh"'
Icon=%k/assets/icon.png Icon=%k/assets/icon.png
Terminal=false Terminal=false
Categories=Development;Utility; Categories=Development;Utility;
StartupWMClass=DazedMTLTool StartupWMClass=DazedTL

View file

@ -1,10 +1,10 @@
# DazedMTLTool # DazedTL
An AI-powered game translation tool with a GUI. Translate RPG Maker, Ren'Py, Tyrano, Wolf RPG, Kirikiri, and other game engines from Japanese to English using GPT, Gemini, [Mistral](https://docs.mistral.ai/api), or other compatible AI models. An AI-powered game translation tool with a GUI. Translate RPG Maker, Ren'Py, Tyrano, Wolf RPG, Kirikiri, and other game engines from Japanese to English using GPT, Gemini, [Mistral](https://docs.mistral.ai/api), or other compatible AI models.
## Credits ## Credits
- **[Sinflower](https://github.com/Sinflower)** — [RV2JSON](https://github.com/Sinflower/RV2JSON) — enables RPGMaker Ace games to be translated the same way as MV/MZ by converting rvdata2 files to JSON and back. A curated copy is bundled offline in `util/ace/offline/` and updates with DazedMTLTool. - **[Sinflower](https://github.com/Sinflower)** — [RV2JSON](https://github.com/Sinflower/RV2JSON) — enables RPGMaker Ace games to be translated the same way as MV/MZ by converting rvdata2 files to JSON and back. A curated copy is bundled offline in `util/ace/offline/` and updates with DazedTL.
- **Sakura & Kao_SSS** — TL Inspector (`util/tl_inspector/`) — in-game translation source inspector and live-edit plugin for RPG Maker MV/MZ playtesting. - **Sakura & Kao_SSS** — TL Inspector (`util/tl_inspector/`) — in-game translation source inspector and live-edit plugin for RPG Maker MV/MZ playtesting.
- **Len** — [Forge](https://gitgud.io/zero64801/forge-mvmz) MV/MZ playtest plugin (`util/forge/`), Mistral API support (provider integration and adaptive rate limiting), and batch translation mode (Anthropic Message Batches API). - **Len** — [Forge](https://gitgud.io/zero64801/forge-mvmz) MV/MZ playtest plugin (`util/forge/`), Mistral API support (provider integration and adaptive rate limiting), and batch translation mode (Anthropic Message Batches API).
@ -108,7 +108,7 @@ This means Python wasn't added to your PATH. You have two options:
### 1. Download the Tool ### 1. Download the Tool
1. Click the green **Code** button at the top of this page and select **Download ZIP**. 1. Click the green **Code** button at the top of this page and select **Download ZIP**.
2. Extract the ZIP to a folder of your choice (e.g., `C:\DazedMTLTool`). 2. Extract the ZIP to a folder of your choice (e.g., `C:\DazedTL`).
### 2. Set Up Your API Key ### 2. Set Up Your API Key
@ -127,7 +127,7 @@ This means Python wasn't added to your PATH. You have two options:
**Windows:** Double-click `START.bat`. It will create a virtual environment, install dependencies, and open the GUI. **Windows:** Double-click `START.bat`. It will create a virtual environment, install dependencies, and open the GUI.
**Linux/macOS:** Run `./START.sh`, or double-click `DazedMTLTool.desktop` (choose **Allow Launching** when your file manager asks). From then on, either method works. **Linux/macOS:** Run `./START.sh`, or double-click `DazedTL.desktop` (choose **Allow Launching** when your file manager asks). From then on, either method works.
That's it! Use the same launcher each time you want to open the tool. That's it! Use the same launcher each time you want to open the tool.
@ -350,7 +350,7 @@ After Step 0 extract, the **Database** tab discovery report classifies your game
| **Classic RPG** (most dialogue in maps/common events) | Names → foundation DB → maps/events (skip narrative DB if none) | | **Classic RPG** (most dialogue in maps/common events) | Names → foundation DB → maps/events (skip narrative DB if none) |
| **Hybrid** | Names → foundation DB → narrative DB → maps/events | | **Hybrid** | Names → foundation DB → narrative DB → maps/events |
> **`wolf` binary:** Prebuilt `wolf` CLIs for Windows and Linux are bundled offline under `util/wolfdawn/bin/<platform>/`, so no toolchain or build step is needed. They update when you update DazedMTLTool. If your platform's binary is missing, update the tool or ask the maintainer to refresh the bundled copy. > **`wolf` binary:** Prebuilt `wolf` CLIs for Windows and Linux are bundled offline under `util/wolfdawn/bin/<platform>/`, so no toolchain or build step is needed. They update when you update DazedTL. If your platform's binary is missing, update the tool or ask the maintainer to refresh the bundled copy.
> **Legacy modules:** The older `Wolf RPG` / `Wolf RPG 2` modules (configured in the Engine Config tab) still exist for edge cases, but the WolfDawn workflow above is the recommended path. > **Legacy modules:** The older `Wolf RPG` / `Wolf RPG 2` modules (configured in the Engine Config tab) still exist for edge cases, but the WolfDawn workflow above is the recommended path.
@ -378,7 +378,7 @@ You can also select a block of text, right-click, and choose **Copilot → Fix /
### Modifying Tool Modules ### Modifying Tool Modules
Open the DazedMTLTool folder in VSCode and ask Copilot to make changes to the translation modules. Examples: Open the DazedTL folder in VSCode and ask Copilot to make changes to the translation modules. Examples:
- *"Add a new regex pattern to skip lines that start with //"* - *"Add a new regex pattern to skip lines that start with //"*
- *"Change the wordwrap logic to break on full-width punctuation"* - *"Change the wordwrap logic to break on full-width punctuation"*

View file

@ -2,7 +2,7 @@
setlocal EnableDelayedExpansion setlocal EnableDelayedExpansion
echo ========================================== echo ==========================================
echo DazedMTLTool Startup Script echo DazedTL Startup Script
echo ========================================== echo ==========================================
echo. echo.
@ -180,7 +180,7 @@ echo.
:: Launch the GUI :: Launch the GUI
echo ========================================== echo ==========================================
echo Launching DazedMTLTool GUI... echo Launching DazedTL GUI...
echo ========================================== echo ==========================================
echo. echo.

View file

@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# DazedMTLTool startup script for Linux/macOS # DazedTL startup script for Linux/macOS
set -o pipefail set -o pipefail
@ -150,7 +150,7 @@ ensure_vocab_file() {
} }
echo "==========================================" echo "=========================================="
echo " DazedMTLTool Startup Script" echo " DazedTL Startup Script"
echo "==========================================" echo "=========================================="
echo echo
@ -222,7 +222,7 @@ fi
echo echo
echo "==========================================" echo "=========================================="
echo " Launching DazedMTLTool GUI..." echo " Launching DazedTL GUI..."
echo "==========================================" echo "=========================================="
echo echo

View file

@ -1,6 +1,6 @@
# Welcome to DazedMTLTool # Welcome to DazedTL
DazedMTLTool translates Japanese games into English with an AI API. DazedTL translates Japanese games into English with an AI API.
It has the strongest support for **RPG Maker** (MV / MZ / Ace) and **Wolf RPG** (WolfDawn), It has the strongest support for **RPG Maker** (MV / MZ / Ace) and **Wolf RPG** (WolfDawn),
plus modules for Ren'Py, Tyrano, Kirikiri, CSV, and more. plus modules for Ren'Py, Tyrano, Kirikiri, CSV, and more.

View file

@ -69,7 +69,7 @@ Use either:
### Example: open the game in Cursor ### Example: open the game in Cursor
1. In Cursor: **File → Open Folder** and select the game root (where `Game.exe` or Wolf `Data` lives). 1. In Cursor: **File → Open Folder** and select the game root (where `Game.exe` or Wolf `Data` lives).
2. In DazedMTLTool Workflow Step 2, click **Copy Project Setup**. 2. In DazedTL Workflow Step 2, click **Copy Project Setup**.
3. Paste into Cursor chat with the game files available (or `@`-mention key JSON files). 3. Paste into Cursor chat with the game files available (or `@`-mention key JSON files).
4. Paste the agent's labeled blocks back into the Workflow editors. 4. Paste the agent's labeled blocks back into the Workflow editors.

View file

@ -14,7 +14,7 @@ You just downloaded a small MV game. You want English dialogue, menus that make
### 1. Get the tool ready ### 1. Get the tool ready
1. Launch DazedMTLTool (opens on this Guide). 1. Launch DazedTL (opens on this Guide).
2. Open **Configuration**, set your API key and model, save. 2. Open **Configuration**, set your API key and model, save.
3. Open the game folder in Cursor so the agent can read JSON later. 3. Open the game folder in Cursor so the agent can read JSON later.

View file

@ -1,6 +1,6 @@
# DazedMTLTool — Project Setup # DazedTL — Project Setup
You are analysing a Japanese game project to produce configuration artifacts for DazedMTLTool. You are analysing a Japanese game project to produce configuration artifacts for DazedTL.
Work in the game repository. Scan files; do not invent content you did not see. Work in the game repository. Scan files; do not invent content you did not see.
--- ---
@ -99,7 +99,7 @@ Output as short imperative bullets suitable to paste into `skills/quirks.md`.
### Game skill rules (for `game_skill` block) ### Game skill rules (for `game_skill` block)
Produce the per-game translation skill saved at `skills/game.md`. Produce the per-game translation skill saved at `skills/game.md`.
DazedMTLTool **merges this file into the translation system prompt** (before quirks). DazedTL **merges this file into the translation system prompt** (before quirks).
**Translation Frame only** (one compact line per field; evidence-based): **Translation Frame only** (one compact line per field; evidence-based):
- `世界観 (Theme / setting)` - genre, world type, core atmosphere - `世界観 (Theme / setting)` - genre, world type, core atmosphere
@ -195,7 +195,7 @@ Output as short imperative bullets suitable to paste into `skills/quirks.md`.
### Game skill rules (for `game_skill` block) ### Game skill rules (for `game_skill` block)
Produce the per-game translation skill saved at `skills/game.md`. Produce the per-game translation skill saved at `skills/game.md`.
DazedMTLTool **merges this file into the translation system prompt** (before quirks). DazedTL **merges this file into the translation system prompt** (before quirks).
**Translation Frame only** (one compact line per field; evidence-based): **Translation Frame only** (one compact line per field; evidence-based):
- `世界観 (Theme / setting)` - genre, world type, core atmosphere - `世界観 (Theme / setting)` - genre, world type, core atmosphere

View file

@ -2,7 +2,7 @@
setlocal EnableExtensions EnableDelayedExpansion setlocal EnableExtensions EnableDelayedExpansion
REM When deployed on a game: this file sits in the game root; patch scripts live in .\gameupdate\ REM When deployed on a game: this file sits in the game root; patch scripts live in .\gameupdate\
REM In this repo the same layout is kept for neatness: this bat is under DazedMTLTool\gameupdate\ next to a nested gameupdate\ folder with patch.ps1. REM In this repo the same layout is kept for neatness: this bat is under gameupdate\ next to a nested gameupdate\ folder with patch.ps1.
set "GU_ROOT=%~dp0" set "GU_ROOT=%~dp0"
REM Game root is this batch file's folder (not %%CD%%, so full-path launches still work). REM Game root is this batch file's folder (not %%CD%%, so full-path launches still work).
set "GAME_ROOT=!GU_ROOT!" set "GAME_ROOT=!GU_ROOT!"

View file

@ -12,7 +12,7 @@
**On an installed game (what gets copied over):** Put **`GameUpdate.bat`** in the **game root**, next to the game exe. Put **`patch.ps1`** and friends inside **`gameupdate\`** under that same root (mirror names—still **`gameupdate\`**). **`GameUpdate.bat`** finds **`gameupdate\patch.ps1`** from its own folder, so **`GameRoot`** is correct even if the console cwd is somewhere else. **On an installed game (what gets copied over):** Put **`GameUpdate.bat`** in the **game root**, next to the game exe. Put **`patch.ps1`** and friends inside **`gameupdate\`** under that same root (mirror names—still **`gameupdate\`**). **`GameUpdate.bat`** finds **`gameupdate\patch.ps1`** from its own folder, so **`GameRoot`** is correct even if the console cwd is somewhere else.
**Copy checklist:** From **`DazedMTLTool/gameupdate/`**, copy **`GameUpdate.bat`** to `<game>\`; copy everything inside **`gameupdate/gameupdate/`** into `<game>\gameupdate\`. **Copy checklist:** From the tool repo's **`gameupdate/`**, copy **`GameUpdate.bat`** to `<game>\`; copy everything inside **`gameupdate/gameupdate/`** into `<game>\gameupdate\`.
2. Optional: set `GAMEUPDATE_PROMPT_PWSH=1` before running `GameUpdate.bat` if you want users to be prompted to install PowerShell 7 via winget. 2. Optional: set `GAMEUPDATE_PROMPT_PWSH=1` before running `GameUpdate.bat` if you want users to be prompted to install PowerShell 7 via winget.
3. Optional: set `GAMEUPDATE_DL_ATTEMPTS` (default `2`) to control retries for API checks/downloads. Lower values fail faster; higher values tolerate flaky networks. 3. Optional: set `GAMEUPDATE_DL_ATTEMPTS` (default `2`) to control retries for API checks/downloads. Lower values fail faster; higher values tolerate flaky networks.
@ -21,7 +21,7 @@
Create `gameupdate/patch-config.txt` next to `patch.ps1` (see `patch-config.example.txt`). Create `gameupdate/patch-config.txt` next to `patch.ps1` (see `patch-config.example.txt`).
In DazedMTLTool, set **Config → Game Update Defaults** (forge, host, org/username, branch) once. Step 1 **Copy gameupdate/** writes those into each game's `patch-config.txt`. You still set `repo=` per game. In DazedTL, set **Config → Game Update Defaults** (forge, host, org/username, branch) once. Step 1 **Copy gameupdate/** writes those into each game's `patch-config.txt`. You still set `repo=` per game.
```txt ```txt
forge=gitlab forge=gitlab

View file

@ -1,7 +1,7 @@
# GameUpdate patch source (copy to patch-config.txt and edit). # GameUpdate patch source (copy to patch-config.txt and edit).
# Lines starting with # are comments. Keys are case-insensitive. # Lines starting with # are comments. Keys are case-insensitive.
# #
# Tip: set forge / host / username / branch once in DazedMTLTool # Tip: set forge / host / username / branch once in DazedTL
# Config → Game Update Defaults. Step 1 "Copy gameupdate/" writes # Config → Game Update Defaults. Step 1 "Copy gameupdate/" writes
# those into this file automatically (you still set repo= per game). # those into this file automatically (you still set repo= per game).

View file

@ -1,5 +1,5 @@
""" """
DazedMTLTool GUI Package DazedTL GUI Package
""" """
__version__ = "1.0.0" __version__ = "1.0.0"

View file

@ -11,6 +11,8 @@ from PyQt5.QtWidgets import (
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QSettings from PyQt5.QtCore import Qt, QThread, pyqtSignal, QSettings
import json import json
from util.paths import APP_NAME, ORG_NAME
class FileManager(QWidget): class FileManager(QWidget):
"""Widget for managing input and output files.""" """Widget for managing input and output files."""
@ -21,7 +23,7 @@ class FileManager(QWidget):
super().__init__() super().__init__()
# Persistent settings for remembering last-open directory # Persistent settings for remembering last-open directory
try: try:
self.settings = QSettings("DazedTranslations", "DazedMTLTool") self.settings = QSettings(ORG_NAME, APP_NAME)
except Exception: except Exception:
self.settings = None self.settings = None
self.input_files = [] self.input_files = []

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
""" """
DazedMTLTool GUI - Main Application DazedTL GUI - Main Application
A PyQt-based graphical user interface for the DazedMTLTool translation system. A PyQt-based graphical user interface for the DazedTL translation system.
""" """
import re import re
@ -29,7 +29,14 @@ from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer, QSettings, QCoreApplic
from PyQt5.QtGui import QIcon, QFont, QPixmap, QScreen, QGuiApplication from PyQt5.QtGui import QIcon, QFont, QPixmap, QScreen, QGuiApplication
from util.paths import PROJECT_ROOT, ICON_PATH, LAST_UPDATE_SHA_PATH from util.paths import (
APP_NAME,
ICON_PATH,
LAST_UPDATE_SHA_PATH,
ORG_NAME,
PROJECT_ROOT,
migrate_app_settings,
)
def load_application_icon() -> QIcon: def load_application_icon() -> QIcon:
@ -56,7 +63,7 @@ def check_tool_update() -> str | None:
class BackgroundUpdateCheckThread(QThread): class BackgroundUpdateCheckThread(QThread):
"""Checks for DazedMTLTool updates without blocking the UI.""" """Checks for DazedTL updates without blocking the UI."""
finished = pyqtSignal(object) # str | None — pending tool SHA when available finished = pyqtSignal(object) # str | None — pending tool SHA when available
@ -151,7 +158,7 @@ class UpdateThread(QThread):
@classmethod @classmethod
def fetch_latest_sha(cls) -> str: def fetch_latest_sha(cls) -> str:
req = urllib.request.Request( req = urllib.request.Request(
cls.branch_api_url(), headers={"User-Agent": "DazedMTLTool"} cls.branch_api_url(), headers={"User-Agent": APP_NAME}
) )
with urllib.request.urlopen(req, timeout=15) as resp: with urllib.request.urlopen(req, timeout=15) as resp:
return json.loads(resp.read())["commit"]["id"] return json.loads(resp.read())["commit"]["id"]
@ -167,7 +174,7 @@ class UpdateThread(QThread):
def _download_archive(self, zip_path: Path): def _download_archive(self, zip_path: Path):
req = urllib.request.Request( req = urllib.request.Request(
self.archive_zip_url(), headers={"User-Agent": "DazedMTLTool"} self.archive_zip_url(), headers={"User-Agent": APP_NAME}
) )
with urllib.request.urlopen(req, timeout=120) as resp, open(zip_path, "wb") as fh: with urllib.request.urlopen(req, timeout=120) as resp, open(zip_path, "wb") as fh:
total = int(resp.headers.get("Content-Length", 0) or 0) total = int(resp.headers.get("Content-Length", 0) or 0)
@ -367,7 +374,7 @@ class UpdateDialog(QDialog):
title_col = QVBoxLayout() title_col = QVBoxLayout()
title_col.setSpacing(2) title_col.setSpacing(2)
self.title_label = QLabel("DazedMTLTool Update") self.title_label = QLabel(f"{APP_NAME} Update")
self.title_label.setObjectName("updateTitle") self.title_label.setObjectName("updateTitle")
self.subtitle_label = QLabel("Stay current with the latest fixes and features.") self.subtitle_label = QLabel("Stay current with the latest fixes and features.")
self.subtitle_label.setObjectName("updateDetail") self.subtitle_label.setObjectName("updateDetail")
@ -577,7 +584,7 @@ class UpdateDialog(QDialog):
self.current_version_label.setText(sha) self.current_version_label.setText(sha)
self.headline_label.setText("Update installed successfully") self.headline_label.setText("Update installed successfully")
self.detail_label.setText( self.detail_label.setText(
"Restart DazedMTLTool to load the new version." f"Restart {APP_NAME} to load the new version."
) )
self.subtitle_label.setText("Update complete.") self.subtitle_label.setText("Update complete.")
if isinstance(self.parent(), DazedMTLGUI): if isinstance(self.parent(), DazedMTLGUI):
@ -620,7 +627,7 @@ from gui.skills_tab import SkillsTab
from gui.batch_tab import BatchTab from gui.batch_tab import BatchTab
class DazedMTLGUI(QMainWindow): class DazedMTLGUI(QMainWindow):
"""Main GUI window for the DazedMTLTool.""" """Main GUI window for DazedTL."""
PAGE_GUIDE = 0 PAGE_GUIDE = 0
PAGE_WORKFLOW = 1 PAGE_WORKFLOW = 1
@ -631,7 +638,7 @@ class DazedMTLGUI(QMainWindow):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.settings = QSettings("DazedTranslations", "DazedMTLTool") self.settings = QSettings(ORG_NAME, APP_NAME)
self._pending_tool_sha: str | None = None self._pending_tool_sha: str | None = None
self._update_check_thread = None self._update_check_thread = None
self._shutdown_started = False self._shutdown_started = False
@ -791,16 +798,16 @@ class DazedMTLGUI(QMainWindow):
# Update window title only when non-default scale is active # Update window title only when non-default scale is active
if scale_factor != 1.0: if scale_factor != 1.0:
self.setWindowTitle(f"DazedMTLTool - Visual Translation Interface (Font: {scale_factor:.1f}x)") self.setWindowTitle(f"{APP_NAME} - Visual Translation Interface (Font: {scale_factor:.1f}x)")
else: else:
self.setWindowTitle("DazedMTLTool - Visual Translation Interface") self.setWindowTitle(f"{APP_NAME} - Visual Translation Interface")
except Exception as e: except Exception as e:
print(f"Warning: Could not apply font scaling: {e}") print(f"Warning: Could not apply font scaling: {e}")
def init_ui(self): def init_ui(self):
"""Initialize the user interface.""" """Initialize the user interface."""
self.setWindowTitle("DazedMTLTool - Visual Translation Interface") self.setWindowTitle(f"{APP_NAME} - Visual Translation Interface")
# Get screen geometry and set window size more responsively # Get screen geometry and set window size more responsively
screen = QApplication.primaryScreen() screen = QApplication.primaryScreen()
@ -1012,7 +1019,7 @@ class DazedMTLGUI(QMainWindow):
return container return container
def start_background_update_check(self): def start_background_update_check(self):
"""Check for DazedMTLTool updates after the GUI is visible.""" """Check for DazedTL updates after the GUI is visible."""
if self._update_check_thread and self._update_check_thread.isRunning(): if self._update_check_thread and self._update_check_thread.isRunning():
return return
self._update_check_thread = BackgroundUpdateCheckThread(self) self._update_check_thread = BackgroundUpdateCheckThread(self)
@ -1221,15 +1228,14 @@ class DazedMTLGUI(QMainWindow):
"""Show the about dialog.""" """Show the about dialog."""
QMessageBox.about( QMessageBox.about(
self, self,
"About DazedMTLTool GUI", f"About {APP_NAME}",
""" f"""
<h3>DazedMTLTool GUI</h3> <h3>{APP_NAME}</h3>
<p>A visual interface for the DazedMTLTool translation system.</p> <p>An AI translation tool for visual novels, RPG games, and other text-based content.</p>
<p>This tool helps translate visual novels, RPG games, and other text-based content using AI translation services.</p>
<p><b>Features:</b></p> <p><b>Features:</b></p>
<ul> <ul>
<li>Guided Workflow for RPG Maker and WolfDawn</li>
<li>Visual configuration management</li> <li>Visual configuration management</li>
<li>Module-specific settings</li>
<li>Real-time translation monitoring</li> <li>Real-time translation monitoring</li>
<li>File management and organization</li> <li>File management and organization</li>
</ul> </ul>
@ -1269,10 +1275,11 @@ def main():
install_qt_message_filter() install_qt_message_filter()
ensure_linux_desktop_entry() ensure_linux_desktop_entry()
QGuiApplication.setDesktopFileName("DazedMTLTool") QGuiApplication.setDesktopFileName(APP_NAME)
QCoreApplication.setOrganizationName("DazedTranslations") QCoreApplication.setOrganizationName(ORG_NAME)
QCoreApplication.setApplicationName("DazedMTLTool") QCoreApplication.setApplicationName(APP_NAME)
migrate_app_settings()
app = QApplication(sys.argv) app = QApplication(sys.argv)
@ -1283,7 +1290,7 @@ def main():
try: try:
import ctypes import ctypes
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID( ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(
"DazedTranslations.DazedMTLTool.1" f"{ORG_NAME}.{APP_NAME}.1"
) )
except Exception: except Exception:
pass pass

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
""" """
Simple Translation Tab for DazedMTLTool GUI Simple Translation Tab for DazedTL GUI
Simple file management and translation execution with console log display. Simple file management and translation execution with console log display.
""" """
@ -33,6 +33,7 @@ from PyQt5.QtCore import Qt, QTimer, pyqtSignal, QThread, QMutex, QProcess, QEve
from PyQt5.QtGui import QFont, QColor, QBrush from PyQt5.QtGui import QFont, QColor, QBrush
from gui.log_viewer import LogViewer from gui.log_viewer import LogViewer
from gui import qt_icons from gui import qt_icons
from util.paths import APP_NAME, ORG_NAME
def _strip_ansi(text): def _strip_ansi(text):
@ -843,7 +844,7 @@ class TranslationTab(QWidget):
self.parent_window = parent self.parent_window = parent
# Persistent settings (remember last directory used in file dialogs) # Persistent settings (remember last directory used in file dialogs)
try: try:
self.settings = QSettings("DazedTranslations", "DazedMTLTool") self.settings = QSettings(ORG_NAME, APP_NAME)
except Exception: except Exception:
self.settings = None self.settings = None
# If the worker signals finished before all file progress updates # If the worker signals finished before all file progress updates

View file

@ -101,7 +101,7 @@ from util.wolfdawn import wrap_search as wolf_ws
import util.dazedwrap as dazedwrap import util.dazedwrap as dazedwrap
from gui.setup_skills_editors import SetupSkillsEditors from gui.setup_skills_editors import SetupSkillsEditors
from util.paths import PROJECT_ROOT, VOCAB_PATH from util.paths import PROJECT_ROOT, VOCAB_PATH, APP_NAME, ORG_NAME
from util.project_scanner import ( from util.project_scanner import (
detect_wolf_layout, detect_wolf_layout,
find_wolf_text_archives, find_wolf_text_archives,
@ -208,7 +208,7 @@ class WolfWorkflowTab(QWidget):
super().__init__(parent) super().__init__(parent)
self.parent_window = parent self.parent_window = parent
try: try:
self.settings = QSettings("DazedTranslations", "DazedMTLTool") self.settings = QSettings(ORG_NAME, APP_NAME)
except Exception: except Exception:
self.settings = None self.settings = None
@ -3670,7 +3670,7 @@ class WolfWorkflowTab(QWidget):
self._run_task(task, on_done=_after) self._run_task(task, on_done=_after)
def _tool_root(self) -> Path: def _tool_root(self) -> Path:
"""DazedMTLTool project root (``files/``, ``translated/``, etc.).""" """DazedTL project root (``files/``, ``translated/``, etc.)."""
return Path(__file__).resolve().parent.parent return Path(__file__).resolve().parent.parent
def _translated_path(self, json_name: str) -> Path | None: def _translated_path(self, json_name: str) -> Path | None:

View file

@ -20,7 +20,7 @@ import sys
import threading import threading
from pathlib import Path from pathlib import Path
from util.paths import VOCAB_PATH from util.paths import VOCAB_PATH, APP_NAME, ORG_NAME
from util.skills import load_project_setup from util.skills import load_project_setup
from util.vocab import BASE_SEPARATOR as _SHARED_BASE_SEPARATOR from util.vocab import BASE_SEPARATOR as _SHARED_BASE_SEPARATOR
@ -638,7 +638,7 @@ class WorkflowTab(QWidget):
super().__init__(parent) super().__init__(parent)
self.parent_window = parent self.parent_window = parent
try: try:
self.settings = QSettings("DazedTranslations", "DazedMTLTool") self.settings = QSettings(ORG_NAME, APP_NAME)
except Exception: except Exception:
self.settings = None self.settings = None

View file

@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Launcher for DazedMTLTool.desktop (finds venv, then starts the GUI). # Launcher for DazedTL.desktop (finds venv, then starts the GUI).
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT" || exit 1 cd "$ROOT" || exit 1

View file

@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Launch script for DazedMTLTool GUI.""" """Launch script for DazedTL GUI."""
import sys import sys
from pathlib import Path from pathlib import Path
@ -40,7 +40,7 @@ def check_dependencies():
def main(): def main():
"""Main entry point.""" """Main entry point."""
print("DazedMTLTool GUI Launcher") print("DazedTL GUI Launcher")
print("=" * 40) print("=" * 40)
from util.paths import ensure_vocab_file, migrate_root_data_files from util.paths import ensure_vocab_file, migrate_root_data_files

View file

@ -35,7 +35,7 @@ Or explicitly:
Manual equivalent (must run from project root, with venv activated): Manual equivalent (must run from project root, with venv activated):
```bash ```bash
cd /path/to/DazedMTLTool cd /path/to/DazedTL
source .venv/bin/activate # or: source venv/bin/activate source .venv/bin/activate # or: source venv/bin/activate
python -m unittest tests.test_mvmz_source_original -v python -m unittest tests.test_mvmz_source_original -v
``` ```

View file

@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Run DazedMTLTool unit tests using the project venv (cwd = project root). # Run DazedTL unit tests using the project venv (cwd = project root).
set -euo pipefail set -euo pipefail

View file

@ -320,7 +320,7 @@ class WolfBundledOnlyTests(unittest.TestCase):
with patch("util.wolfdawn.bundled_binary_path", return_value=missing): with patch("util.wolfdawn.bundled_binary_path", return_value=missing):
with self.assertRaises(WolfDawnError) as ctx: with self.assertRaises(WolfDawnError) as ctx:
ensure_wolf_binary() ensure_wolf_binary()
self.assertIn("Update DazedMTLTool", str(ctx.exception)) self.assertIn("Update DazedTL", str(ctx.exception))
def test_ensure_wolf_binary_never_downloads(self): def test_ensure_wolf_binary_never_downloads(self):
missing = Path("/nonexistent/wolf/missing") missing = Path("/nonexistent/wolf/missing")

View file

@ -4,7 +4,7 @@ RV2JSON.exe — https://github.com/Sinflower/RV2JSON (bin/RV2JSON.exe)
Decrypter CLI https://github.com/uuksu/RPGMakerDecrypter (release asset) Decrypter CLI https://github.com/uuksu/RPGMakerDecrypter (release asset)
End users receive curated copies via the offline bundle (``util/ace/offline/``) End users receive curated copies via the offline bundle (``util/ace/offline/``)
shipped with DazedMTLTool updates. Upstream fetches are maintainer-only shipped with DazedTL updates. Upstream fetches are maintainer-only
(``--refresh-offline`` or ``--force``). (``--refresh-offline`` or ``--force``).
""" """
@ -31,7 +31,7 @@ DECRYPTER_LOCAL = ACE_DIR / "RPGMakerDecrypter-cli.exe"
# Legacy name shipped in older DazedMTLTool commits (local only, not in git). # Legacy name shipped in older DazedMTLTool commits (local only, not in git).
DECRYPTER_LEGACY = ACE_DIR / "RPGMakerDecrypter.exe" DECRYPTER_LEGACY = ACE_DIR / "RPGMakerDecrypter.exe"
USER_AGENT = "DazedMTLTool" USER_AGENT = "DazedTL"
def _load_versions() -> dict: def _load_versions() -> dict:
@ -184,7 +184,7 @@ def ensure_rv2json(force: bool = False, log_fn=print) -> bool:
if RV2JSON_LOCAL.is_file(): if RV2JSON_LOCAL.is_file():
return True return True
_log( _log(
f"ERROR: RV2JSON.exe not found. Update DazedMTLTool or ask the maintainer " f"ERROR: RV2JSON.exe not found. Update DazedTL or ask the maintainer "
f"to refresh util/ace/offline/RV2JSON.exe.", f"to refresh util/ace/offline/RV2JSON.exe.",
log_fn, log_fn,
) )
@ -207,7 +207,7 @@ def ensure_decrypter(force: bool = False, log_fn=print) -> bool:
if DECRYPTER_LOCAL.is_file() or DECRYPTER_LEGACY.is_file(): if DECRYPTER_LOCAL.is_file() or DECRYPTER_LEGACY.is_file():
return True return True
_log( _log(
f"ERROR: {DECRYPTER_ASSET} not found. Update DazedMTLTool or ask the maintainer " f"ERROR: {DECRYPTER_ASSET} not found. Update DazedTL or ask the maintainer "
f"to refresh util/ace/offline/{DECRYPTER_ASSET}.", f"to refresh util/ace/offline/{DECRYPTER_ASSET}.",
log_fn, log_fn,
) )

View file

@ -10,7 +10,7 @@ Svelte Forge bundle. MV therefore keeps the pre-rewrite legacy plugin
Offline copies: util/forge/upstream/ Offline copies: util/forge/upstream/
Active plugins: util/forge/Forge_MZ.js (modern), util/forge/Forge_MV.js (legacy) Active plugins: util/forge/Forge_MZ.js (modern), util/forge/Forge_MV.js (legacy)
End users receive curated copies shipped with DazedMTLTool updates. End users receive curated copies shipped with DazedTL updates.
Upstream fetches are maintainer-only (``--refresh-offline`` or ``--force``) Upstream fetches are maintainer-only (``--refresh-offline`` or ``--force``)
and only refresh the MZ modern plugin. and only refresh the MZ modern plugin.
""" """
@ -36,7 +36,7 @@ FORGE_PROJECT = "zero64801/forge-mvmz"
FORGE_BRANCH = "master" FORGE_BRANCH = "master"
GITGUD_API = "https://gitgud.io/api/v4" GITGUD_API = "https://gitgud.io/api/v4"
VERSION_FILE = _PKG_ROOT / ".forge_version.json" VERSION_FILE = _PKG_ROOT / ".forge_version.json"
USER_AGENT = "DazedMTLTool" USER_AGENT = "DazedTL"
def bundled_plugin_path(engine: str) -> Path: def bundled_plugin_path(engine: str) -> Path:
@ -187,7 +187,7 @@ def ensure_forge_plugins(force: bool = False, log_fn=print) -> bool:
names = ", ".join(PLUGIN_BY_ENGINE[e] + ".js" for e in missing) names = ", ".join(PLUGIN_BY_ENGINE[e] + ".js" for e in missing)
_log( _log(
f"ERROR: Forge plugin(s) missing ({names}). " f"ERROR: Forge plugin(s) missing ({names}). "
"Update DazedMTLTool or ask the maintainer to refresh util/forge/upstream/.", "Update DazedTL or ask the maintainer to refresh util/forge/upstream/.",
log_fn, log_fn,
) )
return False return False

View file

@ -82,7 +82,7 @@ def format_patch_config(
branch = (branch or "").strip() or DEFAULT_BRANCH branch = (branch or "").strip() or DEFAULT_BRANCH
lines = [ lines = [
"# Generated by DazedMTLTool from Config → Game Update defaults.", "# Generated by DazedTL from Config → Game Update defaults.",
"# Edit repo= per game. forge/host/username usually stay the same.", "# Edit repo= per game. forge/host/username usually stay the same.",
f"forge={forge}", f"forge={forge}",
f"host={host}", f"host={host}",

View file

@ -7,9 +7,9 @@ import subprocess
import sys import sys
from pathlib import Path from pathlib import Path
from util.paths import ICON_PATH, PROJECT_ROOT from util.paths import APP_NAME, ICON_PATH, LEGACY_APP_NAME, PROJECT_ROOT
DESKTOP_ID = "DazedMTLTool" DESKTOP_ID = APP_NAME
LAUNCH_SCRIPT = PROJECT_ROOT / "scripts" / "launch.sh" LAUNCH_SCRIPT = PROJECT_ROOT / "scripts" / "launch.sh"
# Qt logs this on Wayland whenever a dialog tries to steal focus (harmless noise). # Qt logs this on Wayland whenever a dialog tries to steal focus (harmless noise).
@ -63,7 +63,7 @@ def _desktop_content(root: Path, icon: Path, launch: Path) -> str:
"[Desktop Entry]\n" "[Desktop Entry]\n"
"Type=Application\n" "Type=Application\n"
f"Name={DESKTOP_ID}\n" f"Name={DESKTOP_ID}\n"
"GenericName=Translation Tool\n" "GenericName=AI Translation Tool\n"
"Comment=AI translation tool for visual novels and RPG games\n" "Comment=AI translation tool for visual novels and RPG games\n"
f"Exec={launch}\n" f"Exec={launch}\n"
f"Icon={icon}\n" f"Icon={icon}\n"
@ -75,7 +75,7 @@ def _desktop_content(root: Path, icon: Path, launch: Path) -> str:
def ensure_linux_desktop_entry() -> None: def ensure_linux_desktop_entry() -> None:
"""Write ~/.local/share/applications/DazedMTLTool.desktop with absolute paths.""" """Write ~/.local/share/applications/DazedTL.desktop with absolute paths."""
if not sys.platform.startswith("linux"): if not sys.platform.startswith("linux"):
return return
if not LAUNCH_SCRIPT.is_file() or not ICON_PATH.is_file(): if not LAUNCH_SCRIPT.is_file() or not ICON_PATH.is_file():
@ -85,6 +85,13 @@ def ensure_linux_desktop_entry() -> None:
content = _desktop_content(PROJECT_ROOT, ICON_PATH, LAUNCH_SCRIPT) content = _desktop_content(PROJECT_ROOT, ICON_PATH, LAUNCH_SCRIPT)
try: try:
legacy = desktop_path.parent / f"{LEGACY_APP_NAME}.desktop"
if legacy.is_file() and legacy.resolve() != desktop_path.resolve():
try:
legacy.unlink()
except OSError:
pass
if desktop_path.is_file() and desktop_path.read_text(encoding="utf-8") == content: if desktop_path.is_file() and desktop_path.read_text(encoding="utf-8") == content:
return return
desktop_path.parent.mkdir(parents=True, exist_ok=True) desktop_path.parent.mkdir(parents=True, exist_ok=True)

View file

@ -4,6 +4,11 @@ from __future__ import annotations
from pathlib import Path from pathlib import Path
# Product identity (QSettings / desktop / window titles).
ORG_NAME = "DazedTranslations"
APP_NAME = "DazedTL"
LEGACY_APP_NAME = "DazedMTLTool"
PROJECT_ROOT = Path(__file__).resolve().parent.parent PROJECT_ROOT = Path(__file__).resolve().parent.parent
DATA_DIR = PROJECT_ROOT / "data" DATA_DIR = PROJECT_ROOT / "data"
VOCAB_PATH = DATA_DIR / "vocab.txt" VOCAB_PATH = DATA_DIR / "vocab.txt"
@ -55,6 +60,26 @@ def migrate_prompt_to_skills() -> None:
return return
def migrate_app_settings() -> None:
"""Copy QSettings from the legacy app name into DazedTL once."""
try:
from PyQt5.QtCore import QSettings
except ImportError:
return
new = QSettings(ORG_NAME, APP_NAME)
if str(new.value("_migrated_from_legacy_app", "")) == "1":
return
old = QSettings(ORG_NAME, LEGACY_APP_NAME)
old_keys = list(old.allKeys())
new_keys = [k for k in new.allKeys() if k != "_migrated_from_legacy_app"]
if old_keys and not new_keys:
for key in old_keys:
new.setValue(key, old.value(key))
new.setValue("_migrated_from_legacy_app", "1")
migrate_root_data_files() migrate_root_data_files()
migrate_prompt_to_skills() migrate_prompt_to_skills()

View file

@ -1,5 +1,5 @@
""" """
Shared translation utilities for DazedMTLTool. Shared translation utilities for DazedTL.
Centralized translation function used across all modules. Centralized translation function used across all modules.
""" """

View file

@ -1,10 +1,10 @@
"""WolfDawn CLI bootstrap and thin subprocess wrappers. """WolfDawn CLI bootstrap and thin subprocess wrappers.
WolfDawn is the Rust toolchain (https://gitgud.io/zero64801/wolfdawn) that WolfDawn is the Rust toolchain (https://gitgud.io/zero64801/wolfdawn) that
unpacks, extracts, injects, and repacks WOLF RPG Editor game data. DazedMTLTool unpacks, extracts, injects, and repacks WOLF RPG Editor game data. DazedTL
ships prebuilt ``wolf`` binaries offline under ``util/wolfdawn/bin/<platform>/`` ships prebuilt ``wolf`` binaries offline under ``util/wolfdawn/bin/<platform>/``
so end users never need a Rust toolchain or a live upstream fetch. Binaries are so end users never need a Rust toolchain or a live upstream fetch. Binaries are
updated when DazedMTLTool itself is updated. Everything the Wolf workflow needs updated when DazedTL itself is updated. Everything the Wolf workflow needs
goes through the helpers here so command syntax and exit-code handling live in goes through the helpers here so command syntax and exit-code handling live in
one place. one place.
@ -215,7 +215,7 @@ _RELEASE_ASSET_MATCH = {
} }
_DOWNLOAD_UA = ( _DOWNLOAD_UA = (
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) " "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) "
"DazedMTLTool WolfDawn-fetch" "DazedTL WolfDawn-fetch"
) )
PathLike = Union[str, Path] PathLike = Union[str, Path]
@ -394,7 +394,7 @@ def ensure_wolf_binary(log_fn=print) -> Path:
return bundled return bundled
raise WolfDawnError( raise WolfDawnError(
f"No bundled WolfDawn binary for '{_platform_dir()}' at {bundled}. " f"No bundled WolfDawn binary for '{_platform_dir()}' at {bundled}. "
"Update DazedMTLTool to receive a prebuilt wolf binary." "Update DazedTL to receive a prebuilt wolf binary."
) )

View file

@ -1,7 +1,7 @@
"""Check for and apply WolfDawn ``wolf`` binary updates (maintainer-only upstream fetch). """Check for and apply WolfDawn ``wolf`` binary updates (maintainer-only upstream fetch).
End users receive prebuilt binaries under ``util/wolfdawn/bin/<platform>/`` via End users receive prebuilt binaries under ``util/wolfdawn/bin/<platform>/`` via
DazedMTLTool updates. Maintainers refresh them with ``--refresh-all`` or ``--force``. DazedTL updates. Maintainers refresh them with ``--refresh-all`` or ``--force``.
""" """
from __future__ import annotations from __future__ import annotations
@ -150,7 +150,7 @@ def ensure_wolfdawn_binary(force: bool = False, log_fn=print) -> bool:
return True return True
_log( _log(
f"ERROR: no bundled WolfDawn binary for '{platform}' at {bundled}. " f"ERROR: no bundled WolfDawn binary for '{platform}' at {bundled}. "
"Update DazedMTLTool to receive a prebuilt wolf binary.", "Update DazedTL to receive a prebuilt wolf binary.",
log_fn, log_fn,
) )
return False return False