Skip to content

Commit

Permalink
Qt GUI: Update translations
Browse files Browse the repository at this point in the history
  • Loading branch information
cjee21 committed Feb 17, 2025
1 parent 9006948 commit 5224098
Show file tree
Hide file tree
Showing 85 changed files with 17,292 additions and 16,860 deletions.
31 changes: 31 additions & 0 deletions Source/GUI/Qt/Qt_Translations_Updater/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Translation Update Script

This folder contains scripts to automate the process of updating Qt `.ts` translation files and generating `.qm` files for MediaInfo's Qt GUI. The process involves using `lupdate` to update the `.ts` files, a Python script to apply custom translations from MediaInfo's `Languages` CSV file, and `lrelease` to generate the final `.qm` files.

## Prerequisites

1. **Qt Tools**: Ensure you have `lupdate` and `lrelease` installed and available in your system's PATH.
2. **Python**: Ensure you have Python installed and available in your system's PATH.

## Files

### `update_Qt_translations.cmd`

This Windows Command Script automates the process of updating `.ts` files and generating `.qm` files.

### `update_Qt_translations.py`

This Python script updates the `.ts` files with translations from the CSV file and handles special cases.

## Usage

1. **Run the Windows Command Script**:
- Double-click `update_Qt_translations.cmd` or execute it from the command line.
- The script will:
- Run `lupdate` to update the `.ts` files.
- Use `update_Qt_translations.py` to apply custom translations from `Languages.csv`.
- Run `lrelease` to generate the `.qm` files.

2. **Verify the Output**:
- Check the `Source\Resource\Translations` folder to ensure that the `.ts` files have been generated/updated.
- Verify that the `.qm` files have been generated/updated in the same directory as above.
58 changes: 58 additions & 0 deletions Source/GUI/Qt/Qt_Translations_Updater/update_Qt_translations.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
@echo off
setlocal

REM Enable ANSI escape sequences
setlocal enableextensions
setlocal enabledelayedexpansion

REM ANSI escape codes for colors
set GREEN=
set YELLOW=
set RED=
set RESET=

REM Set paths
set PROJECT_FILE=%~dp0\..\..\..\..\Project\QMake\GUI\MediaInfoQt.pro
set TS_FILES_FOLDER=%~dp0\..\..\..\Resource\Translations
set CSV_FILE=%~dp0\..\..\..\Resource\Language.csv
set PYTHON_SCRIPT=%~dp0\update_Qt_translations.py

REM Step 1: Run lupdate to update .ts files
echo.
echo !YELLOW!Running lupdate...!RESET!
lupdate -noobsolete %PROJECT_FILE%
if %errorlevel% neq 0 (
echo.
echo !RED!lupdate failed!%RESET%
exit /b %errorlevel%
)
echo.
echo !GREEN!lupdate completed successfully!%RESET%
echo.

REM Step 2: Run the Python script to update .ts files
echo !YELLOW!Updating .ts files with translations...!RESET!
python %PYTHON_SCRIPT% %TS_FILES_FOLDER% %CSV_FILE%
if %errorlevel% neq 0 (
echo.
echo !RED!Python script failed!%RESET%
exit /b %errorlevel%
)
echo.
echo !GREEN!.ts files updated successfully!%RESET%
echo.

REM Step 3: Run lrelease to generate .qm files
echo !YELLOW!Running lrelease...!RESET!
lrelease %PROJECT_FILE%
if %errorlevel% neq 0 (
echo.
echo !RED!lrelease failed!%RESET%
exit /b %errorlevel%
)
echo.
echo !GREEN!lrelease completed successfully!%RESET%
echo.

echo !GREEN!All steps completed successfully!%RESET!
endlocal
105 changes: 105 additions & 0 deletions Source/GUI/Qt/Qt_Translations_Updater/update_Qt_translations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Update Qt translations .ts files with translations from MediaInfo's Languages.csv
# Script generated with Qwen2.5-Coder-32B-Instruct

import os
import csv
import xml.etree.ElementTree as ET
import sys

def load_translations(csv_file):
translations = {}
with open(csv_file, mode='r', encoding='utf-8') as file:
reader = csv.DictReader(file, delimiter=';')
for row in reader:
source = row[' Language_ISO639']
translations[source] = {lang: row[lang] for lang in row if lang != ' Language_ISO639'}
return translations

def clean_translation(translation):
if translation is not None:
return translation.replace('\\r\\n', '\n')
return translation

def update_ts_file(ts_file, translations, lang_code):
tree = ET.parse(ts_file)
root = tree.getroot()

# Update the TS tag with language and sourcelanguage attributes
root.set('language', lang_code.replace('-', '_'))
root.set('sourcelanguage', 'en')

for context in root.findall('context'):
for message in context.findall('message'):
source = message.find('source').text
translation_tag = message.find('translation')

if source in translations:
lang_translation = translations[source].get(lang_code, '')
if not lang_translation:
lang_translation = translations[source].get('en', '')

lang_translation = clean_translation(lang_translation)

if translation_tag is None:
translation_tag = ET.SubElement(message, 'translation')
translation_tag.text = lang_translation

# Remove type="unfinished" if present
if 'type' in translation_tag.attrib and translation_tag.attrib['type'] == 'unfinished':
del translation_tag.attrib['type']
elif source == 'MediaInfo v%1\nCopyright (C) 2002-2025 MediaArea.net SARL\n':
# Special case handling for Copyright
copyright_translation = translations['Copyright'].get(lang_code, '')
if not copyright_translation:
copyright_translation = translations['Copyright'].get('en', '')

copyright_translation = clean_translation(copyright_translation)

if translation_tag is None:
translation_tag = ET.SubElement(message, 'translation')

# Replace only the word "Copyright" with the translated version
translation_text = source.replace('Copyright', copyright_translation)
translation_tag.text = translation_text

# Remove type="unfinished" if present
if 'type' in translation_tag.attrib and translation_tag.attrib['type'] == 'unfinished':
del translation_tag.attrib['type']
elif source == 'Translator : Zen':
# Special case handling for Translator
translator_translation = translations['Translator'].get(lang_code, '')
if not translator_translation:
translator_translation = translations['Translator'].get('en', '')

author_name = translations[' Author_Name'].get(lang_code, 'Zen')
author_name = clean_translation(author_name)

if translation_tag is None:
translation_tag = ET.SubElement(message, 'translation')

# Replace "Translator" and "Zen" with the translated versions
translation_text = f'{translator_translation} : {author_name}'
translation_tag.text = translation_text

# Remove type="unfinished" if present
if 'type' in translation_tag.attrib and translation_tag.attrib['type'] == 'unfinished':
del translation_tag.attrib['type']

tree.write(ts_file, encoding='utf-8', xml_declaration=True)

def process_ts_files(folder, csv_file):
translations = load_translations(csv_file)
for filename in os.listdir(folder):
if filename.endswith('.ts'):
lang_code = filename[:-3] # Remove '.ts' extension
ts_file = os.path.join(folder, filename)
update_ts_file(ts_file, translations, lang_code)

if __name__ == '__main__':
if len(sys.argv) != 3:
print("Usage: python update_translations.py <ts_files_folder> <csv_file>")
sys.exit(1)

ts_files_folder = sys.argv[1]
csv_file_path = sys.argv[2]
process_ts_files(ts_files_folder, csv_file_path)
63 changes: 36 additions & 27 deletions Source/GUI/Qt/about.ui
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0">
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0">
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
Expand Down Expand Up @@ -50,30 +50,39 @@
</layout>
</item>
<item>
<widget class="QLabel" name="aboutText">
<property name="text">
<string>MediaInfo v%1
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="aboutText">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>MediaInfo v%1
Copyright (C) 2002-2025 MediaArea.net SARL

Supply very detailled information
about a multimedia file:
Matroska, OGG (including OGM)
MPEG1 (including VCD)
MPEG2 (including DVD and SVCD)
MPEG4 (including Itunes M4A)
Quicktime
RealMedia
WindowsMedia (including WMV, WMA)
Microsoft RIFF (including AVI, WAV)
Sound-only formats (AC3, DTS, AAC, AU, AIFF...)</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>MediaInfo_About</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
Expand Down Expand Up @@ -128,14 +137,14 @@ Sound-only formats (AC3, DTS, AAC, AU, AIFF...)</string>
<item>
<widget class="QPushButton" name="website">
<property name="text">
<string>Go to website</string>
<string>Go to WebSite</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="checkversion">
<property name="text">
<string>Check for new version</string>
<string>CheckNewVersion</string>
</property>
</widget>
</item>
Expand All @@ -149,7 +158,7 @@ Sound-only formats (AC3, DTS, AAC, AU, AIFF...)</string>
<item>
<widget class="QPushButton" name="mail">
<property name="text">
<string>Write mail to author</string>
<string>WriteMe</string>
</property>
</widget>
</item>
Expand Down
2 changes: 1 addition & 1 deletion Source/GUI/Qt/export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Export::Export(QString filename, int mode, QWidget *parent) :
ui->comboBoxConfig->setStyleSheet(style);
ui->comboBoxMode->setStyleSheet(style);
#else
setWindowTitle("Export");
setWindowTitle(tr("Export"));
#endif

for(int i=0;i<Export::NB_EXPORT_MODE;i++) {
Expand Down
14 changes: 7 additions & 7 deletions Source/GUI/Qt/export.ui
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@
<item>
<widget class="QGroupBox" name="formatBox">
<property name="title">
<string>Choose your desired export format</string>
<string>Choose export format</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Format:</string>
<string>Format</string>
</property>
</widget>
</item>
Expand All @@ -46,7 +46,7 @@
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Profile:</string>
<string>Profile</string>
</property>
</widget>
</item>
Expand All @@ -72,14 +72,14 @@
<item>
<widget class="QCheckBox" name="appendToFile">
<property name="text">
<string>Append to the existing file</string>
<string>File_Append</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
Expand All @@ -95,10 +95,10 @@
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
</property>
</widget>
</item>
Expand Down
2 changes: 1 addition & 1 deletion Source/GUI/Qt/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ MainWindow::MainWindow(QStringList filesnames, int viewasked, QWidget *parent) :
connect(menuItemGroup,SIGNAL(triggered(QAction*)),this,SLOT(actionView_toggled(QAction*)));

buttonView = new QToolButton();
buttonView->setText(tr("view"));
buttonView->setText("view");
buttonView->setIcon(QIcon(":/icon/view.svg"));
connect(buttonView, SIGNAL(clicked()), this, SLOT(buttonViewClicked()));
ui->toolBar->addWidget(buttonView);
Expand Down
Loading

0 comments on commit 5224098

Please sign in to comment.