Added translation folder + updated strings for translations
This commit is contained in:
parent
adc14d0155
commit
718401b049
|
@ -1,8 +1,14 @@
|
||||||
|
import FreeCAD as App
|
||||||
|
import FreeCADGui as Gui
|
||||||
|
|
||||||
globalGroups = []
|
globalGroups = []
|
||||||
|
|
||||||
itemGroups = None
|
itemGroups = None
|
||||||
serializedItemGroups = None
|
serializedItemGroups = None
|
||||||
|
|
||||||
|
# Define the translation
|
||||||
|
translate = App.Qt.translate
|
||||||
|
|
||||||
|
|
||||||
def onResultSelected(index, groupId):
|
def onResultSelected(index, groupId):
|
||||||
global globalGroups
|
global globalGroups
|
||||||
|
@ -17,8 +23,11 @@ def onResultSelected(index, groupId):
|
||||||
|
|
||||||
QtGui.QMessageBox.warning(
|
QtGui.QMessageBox.warning(
|
||||||
None,
|
None,
|
||||||
"Could not execute this action",
|
translate("SearchBar", "Could not execute this action"),
|
||||||
"Could not execute this action, it could be from a Mod that has been uninstalled. Try refreshing the list of tools.",
|
translate(
|
||||||
|
"SearchBar",
|
||||||
|
"Could not execute this action, it could be from a Mod that has been uninstalled. Try refreshing the list of tools.",
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,7 +40,10 @@ def getToolTip(groupId, setParent):
|
||||||
if handlerName in SearchResults.toolTipHandlers:
|
if handlerName in SearchResults.toolTipHandlers:
|
||||||
return SearchResults.toolTipHandlers[handlerName](nfo, setParent)
|
return SearchResults.toolTipHandlers[handlerName](nfo, setParent)
|
||||||
else:
|
else:
|
||||||
return "Could not load tooltip for this tool, it could be from a Mod that has been uninstalled. Try refreshing the list of tools."
|
return translate(
|
||||||
|
"SearchBar",
|
||||||
|
"Could not load tooltip for this tool, it could be from a Mod that has been uninstalled. Try refreshing the list of tools.",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def getItemGroups():
|
def getItemGroups():
|
||||||
|
|
19
InitGui.py
19
InitGui.py
|
@ -1,9 +1,20 @@
|
||||||
|
import FreeCAD as App
|
||||||
|
import FreeCADGui as Gui
|
||||||
|
|
||||||
# Avoid garbage collection by storing the action in a global variable
|
# Avoid garbage collection by storing the action in a global variable
|
||||||
wax = None
|
wax = None
|
||||||
sea = None
|
sea = None
|
||||||
tbr = None
|
tbr = None
|
||||||
|
|
||||||
|
|
||||||
|
def QT_TRANSLATE_NOOP(context, text):
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
# Define the translation
|
||||||
|
translate = App.Qt.translate
|
||||||
|
|
||||||
|
|
||||||
def addToolSearchBox():
|
def addToolSearchBox():
|
||||||
import FreeCADGui
|
import FreeCADGui
|
||||||
from PySide import QtGui
|
from PySide import QtGui
|
||||||
|
@ -24,9 +35,13 @@ def addToolSearchBox():
|
||||||
|
|
||||||
if wax is None:
|
if wax is None:
|
||||||
wax = QtGui.QWidgetAction(None)
|
wax = QtGui.QWidgetAction(None)
|
||||||
wax.setWhatsThis("Use this search bar to find tools, document objects, preferences and more")
|
wax.setWhatsThis(
|
||||||
|
translate("SearchBar", "Use this search bar to find tools, document objects, preferences and more")
|
||||||
|
)
|
||||||
|
|
||||||
sea.setWhatsThis("Use this search bar to find tools, document objects, preferences and more")
|
sea.setWhatsThis(
|
||||||
|
translate("SearchBar", "Use this search bar to find tools, document objects, preferences and more")
|
||||||
|
)
|
||||||
wax.setDefaultWidget(sea)
|
wax.setDefaultWidget(sea)
|
||||||
##mbr.addWidget(sea)
|
##mbr.addWidget(sea)
|
||||||
# mbr.addAction(wax)
|
# mbr.addAction(wax)
|
||||||
|
|
|
@ -1,17 +1,20 @@
|
||||||
import os
|
import os
|
||||||
import FreeCAD as App
|
import FreeCAD as App
|
||||||
|
|
||||||
|
# Define the translation
|
||||||
|
translate = App.Qt.translate
|
||||||
|
|
||||||
|
|
||||||
def loadAllWorkbenches():
|
def loadAllWorkbenches():
|
||||||
from PySide import QtGui
|
from PySide import QtGui
|
||||||
import FreeCADGui
|
import FreeCADGui
|
||||||
|
|
||||||
activeWorkbench = FreeCADGui.activeWorkbench().name()
|
activeWorkbench = FreeCADGui.activeWorkbench().name()
|
||||||
lbl = QtGui.QLabel("Loading workbench … (…/…)")
|
lbl = QtGui.QLabel(translate("SearchBar", "Loading workbench … (…/…)"))
|
||||||
lbl.show()
|
lbl.show()
|
||||||
lst = FreeCADGui.listWorkbenches()
|
lst = FreeCADGui.listWorkbenches()
|
||||||
for i, wb in enumerate(lst):
|
for i, wb in enumerate(lst):
|
||||||
msg = "Loading workbench " + wb + " (" + str(i) + "/" + str(len(lst)) + ")"
|
msg = translate("SearchBar", "Loading workbench ") + wb + " (" + str(i) + "/" + str(len(lst)) + ")"
|
||||||
print(msg)
|
print(msg)
|
||||||
lbl.setText(msg)
|
lbl.setText(msg)
|
||||||
geo = lbl.geometry()
|
geo = lbl.geometry()
|
||||||
|
@ -88,8 +91,11 @@ def refreshToolsAction():
|
||||||
fw.clearFocus()
|
fw.clearFocus()
|
||||||
reply = QtGui.QMessageBox.question(
|
reply = QtGui.QMessageBox.question(
|
||||||
None,
|
None,
|
||||||
"Load all workbenches?",
|
translate("SearchBar", "Load all workbenches?"),
|
||||||
'Load all workbenches? This can cause FreeCAD to become unstable, and this "reload tools" feature contained a bug that crashed freecad systematically, so please make sure you save your work before. It\'s a good idea to restart FreeCAD after this operation.',
|
translate(
|
||||||
|
"SearchBar",
|
||||||
|
'Load all workbenches? This can cause FreeCAD to become unstable, and this "reload tools" feature contained a bug that crashed freecad systematically, so please make sure you save your work before. It\'s a good idea to restart FreeCAD after this operation.',
|
||||||
|
),
|
||||||
QtGui.QMessageBox.Yes,
|
QtGui.QMessageBox.Yes,
|
||||||
QtGui.QMessageBox.No,
|
QtGui.QMessageBox.No,
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,6 +5,9 @@ import FreeCADGui
|
||||||
import SafeViewer
|
import SafeViewer
|
||||||
import SearchBox
|
import SearchBox
|
||||||
|
|
||||||
|
# Define the translation
|
||||||
|
translate = App.Qt.translate
|
||||||
|
|
||||||
|
|
||||||
def documentAction(nfo):
|
def documentAction(nfo):
|
||||||
act = nfo["action"]
|
act = nfo["action"]
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import FreeCAD as App
|
||||||
|
import FreeCADGui as Gui
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from PySide import QtGui
|
from PySide import QtGui
|
||||||
import Serialize_SearchBar
|
import Serialize_SearchBar
|
||||||
|
@ -5,6 +8,9 @@ import Parameters_SearchBar as Parameters
|
||||||
|
|
||||||
genericToolIcon = QtGui.QIcon(QtGui.QIcon(Parameters.genericToolIcon_Pixmap))
|
genericToolIcon = QtGui.QIcon(QtGui.QIcon(Parameters.genericToolIcon_Pixmap))
|
||||||
|
|
||||||
|
# Define the translation
|
||||||
|
translate = App.Qt.translate
|
||||||
|
|
||||||
|
|
||||||
def refreshToolsAction(nfo):
|
def refreshToolsAction(nfo):
|
||||||
import RefreshTools
|
import RefreshTools
|
||||||
|
@ -15,7 +21,12 @@ def refreshToolsAction(nfo):
|
||||||
def refreshToolsToolTip(nfo, setParent):
|
def refreshToolsToolTip(nfo, setParent):
|
||||||
return (
|
return (
|
||||||
Serialize_SearchBar.iconToHTML(genericToolIcon)
|
Serialize_SearchBar.iconToHTML(genericToolIcon)
|
||||||
+ "<p>Load all workbenches to refresh this list of tools. This may take a minute, depending on the number of installed workbenches.</p>"
|
+ "<p>"
|
||||||
|
+ translate(
|
||||||
|
"SearchBar",
|
||||||
|
"Load all workbenches to refresh this list of tools. This may take a minute, depending on the number of installed workbenches.",
|
||||||
|
)
|
||||||
|
+ "</p>"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
|
import FreeCAD as App
|
||||||
from PySide import QtGui
|
from PySide import QtGui
|
||||||
import FreeCADGui
|
import FreeCADGui
|
||||||
import Serialize_SearchBar
|
import Serialize_SearchBar
|
||||||
|
|
||||||
|
# Define the translation
|
||||||
|
translate = App.Qt.translate
|
||||||
|
|
||||||
|
|
||||||
def toolbarAction(nfo):
|
def toolbarAction(nfo):
|
||||||
act = nfo["action"]
|
act = nfo["action"]
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
from PySide import QtGui
|
from PySide import QtGui
|
||||||
import FreeCAD
|
import FreeCAD as App
|
||||||
|
|
||||||
|
# Define the translation
|
||||||
|
translate = App.Qt.translate
|
||||||
|
|
||||||
|
|
||||||
class SafeViewer(QtGui.QWidget):
|
class SafeViewer(QtGui.QWidget):
|
||||||
|
@ -7,7 +10,7 @@ class SafeViewer(QtGui.QWidget):
|
||||||
FreeCAD's FreeCADGui.createViewer() puts the viewer widget inside an MDI window, and detaching it without causing segfaults on exit is tricky.
|
FreeCAD's FreeCADGui.createViewer() puts the viewer widget inside an MDI window, and detaching it without causing segfaults on exit is tricky.
|
||||||
This class contains some kludges to extract the viewer as a standalone widget and destroy it safely."""
|
This class contains some kludges to extract the viewer as a standalone widget and destroy it safely."""
|
||||||
|
|
||||||
enabled = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/SearchBar").GetBool("PreviewEnabled", False)
|
enabled = App.ParamGet("User parameter:BaseApp/Preferences/Mod/SearchBar").GetBool("PreviewEnabled", False)
|
||||||
instances = []
|
instances = []
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
|
@ -27,11 +30,18 @@ class SafeViewer(QtGui.QWidget):
|
||||||
self.lbl_warning.setReadOnly(True)
|
self.lbl_warning.setReadOnly(True)
|
||||||
self.lbl_warning.setAlignment(QtCore.Qt.AlignTop)
|
self.lbl_warning.setAlignment(QtCore.Qt.AlignTop)
|
||||||
self.lbl_warning.setText(
|
self.lbl_warning.setText(
|
||||||
"Warning: the 3D preview has some stability issues. It can cause FreeCAD to crash (usually when quitting the application) and could in theory cause data loss, inside and outside of FreeCAD."
|
translate(
|
||||||
|
"SearchBar",
|
||||||
|
"Warning: the 3D preview has some stability issues. It can cause FreeCAD to crash (usually when quitting the application) and could in theory cause data loss, inside and outside of App.",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.btn_enable_for_this_session = QtGui.QPushButton(
|
||||||
|
translate("SearchBar", "Enable 3D preview for this session")
|
||||||
)
|
)
|
||||||
self.btn_enable_for_this_session = QtGui.QPushButton("Enable 3D preview for this session")
|
|
||||||
self.btn_enable_for_this_session.clicked.connect(self.enable_for_this_session)
|
self.btn_enable_for_this_session.clicked.connect(self.enable_for_this_session)
|
||||||
self.btn_enable_for_future_sessions = QtGui.QPushButton("Enable 3D preview for future sessions")
|
self.btn_enable_for_future_sessions = QtGui.QPushButton(
|
||||||
|
translate("SearchBar", "Enable 3D preview for future sessions")
|
||||||
|
)
|
||||||
self.btn_enable_for_future_sessions.clicked.connect(self.enable_for_future_sessions)
|
self.btn_enable_for_future_sessions.clicked.connect(self.enable_for_future_sessions)
|
||||||
self.setLayout(QtGui.QVBoxLayout())
|
self.setLayout(QtGui.QVBoxLayout())
|
||||||
self.layout().addWidget(self.lbl_warning)
|
self.layout().addWidget(self.lbl_warning)
|
||||||
|
@ -46,7 +56,7 @@ class SafeViewer(QtGui.QWidget):
|
||||||
def enable_for_future_sessions(self):
|
def enable_for_future_sessions(self):
|
||||||
if not SafeViewer.enabled:
|
if not SafeViewer.enabled:
|
||||||
# Store in prefs
|
# Store in prefs
|
||||||
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/SearchBar").SetBool("PreviewEnabled", True)
|
App.ParamGet("User parameter:BaseApp/Preferences/Mod/SearchBar").SetBool("PreviewEnabled", True)
|
||||||
# Then enable as usual
|
# Then enable as usual
|
||||||
self.enable_for_this_session()
|
self.enable_for_this_session()
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import FreeCADGui as Gui # just used for FreeCADGui.updateGui()
|
import FreeCAD as App
|
||||||
|
import FreeCADGui as Gui
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from PySide.QtCore import (
|
from PySide.QtCore import (
|
||||||
|
@ -44,6 +45,9 @@ genericToolIcon = QIcon(Parameters.genericToolIcon_Pixmap)
|
||||||
|
|
||||||
globalIgnoreFocusOut = False
|
globalIgnoreFocusOut = False
|
||||||
|
|
||||||
|
# Define the translation
|
||||||
|
translate = App.Qt.translate
|
||||||
|
|
||||||
|
|
||||||
def easyToolTipWidget(html):
|
def easyToolTipWidget(html):
|
||||||
foo = QTextEdit()
|
foo = QTextEdit()
|
||||||
|
@ -170,7 +174,7 @@ class SearchBox(QLineEdit):
|
||||||
mdl = QStandardItemModel()
|
mdl = QStandardItemModel()
|
||||||
mdl.appendRow(
|
mdl.appendRow(
|
||||||
[
|
[
|
||||||
QStandardItem(genericToolIcon, "Please wait, loading results from cache…"),
|
QStandardItem(genericToolIcon, translate("SearchBar", "Please wait, loading results from cache…")),
|
||||||
QStandardItem("0"),
|
QStandardItem("0"),
|
||||||
QStandardItem("-1"),
|
QStandardItem("-1"),
|
||||||
]
|
]
|
||||||
|
|
104
translations/README.md
Normal file
104
translations/README.md
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
# About translating Ribbon Addon
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> All commands **must** be run in `./translations/` directory.
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> If you want to update/release the files you need to have installed
|
||||||
|
> `lupdate` and `lrelease` from Qt6 version. Using the versions from
|
||||||
|
> Qt5 is not advised because they're buggy.
|
||||||
|
|
||||||
|
## Updating translations template file
|
||||||
|
|
||||||
|
To update the template file from source files you should use this command:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
./update_translation.sh -U
|
||||||
|
```
|
||||||
|
|
||||||
|
Once done you can commit the changes and upload the new file to CrowdIn platform
|
||||||
|
at <https://crowdin.com/project/freecad-addons> webpage and find the **Ribbon** project.
|
||||||
|
|
||||||
|
## Creating file for missing locale
|
||||||
|
|
||||||
|
### Using script
|
||||||
|
|
||||||
|
To create a file for a new language with all **Ribbon** translatable strings execute
|
||||||
|
the script with `-u` flag plus your locale:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
./update_translation.sh -u de
|
||||||
|
```
|
||||||
|
|
||||||
|
### Renaming file
|
||||||
|
|
||||||
|
Also you can rename new `SearchBar.ts` file by appending the locale code,
|
||||||
|
for example, `SearchBar_de.ts` for German and change
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<TS version="2.1">
|
||||||
|
```
|
||||||
|
|
||||||
|
to
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<TS version="2.1" language="de" sourcelanguage="en">
|
||||||
|
```
|
||||||
|
|
||||||
|
As of 2024/10/28 the supported locales on FreeCAD
|
||||||
|
(according to `FreeCADGui.supportedLocales()`) are 44:
|
||||||
|
|
||||||
|
```python
|
||||||
|
{'English': 'en', 'Afrikaans': 'af', 'Arabic': 'ar', 'Basque': 'eu',
|
||||||
|
'Belarusian': 'be', 'Bulgarian': 'bg', 'Catalan': 'ca',
|
||||||
|
'Chinese Simplified': 'zh-CN', 'Chinese Traditional': 'zh-TW', 'Croatian': 'hr',
|
||||||
|
'Czech': 'cs', 'Danish': 'da', 'Dutch': 'nl', 'Filipino': 'fil', 'Finnish': 'fi',
|
||||||
|
'French': 'fr', 'Galician': 'gl', 'Georgian': 'ka', 'German': 'de', 'Greek': 'el',
|
||||||
|
'Hungarian': 'hu', 'Indonesian': 'id', 'Italian': 'it', 'Japanese': 'ja',
|
||||||
|
'Kabyle': 'kab', 'Korean': 'ko', 'Lithuanian': 'lt', 'Norwegian': 'no',
|
||||||
|
'Polish': 'pl', 'Portuguese': 'pt-PT', 'Portuguese, Brazilian': 'pt-BR',
|
||||||
|
'Romanian': 'ro', 'Russian': 'ru', 'Serbian': 'sr', 'Serbian, Latin': 'sr-CS',
|
||||||
|
'Slovak': 'sk', 'Slovenian': 'sl', 'Spanish': 'es-ES', 'Spanish, Argentina': 'es-AR',
|
||||||
|
'Swedish': 'sv-SE', 'Turkish': 'tr', 'Ukrainian': 'uk', 'Valencian': 'val-ES',
|
||||||
|
'Vietnamese': 'vi'}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Translating
|
||||||
|
|
||||||
|
To edit your language file open your file in `Qt Linguist` from `qt5-tools`/`qt6-tools`
|
||||||
|
package or in a text editor like `xed`, `mousepad`, `gedit`, `nano`, `vim`/`nvim`,
|
||||||
|
`geany` etc. and translate it.
|
||||||
|
|
||||||
|
Alternatively you can visit the **FreeCAD-addons** project on CrowdIn platform
|
||||||
|
at <https://crowdin.com/project/freecad-addons> webpage and find your language,
|
||||||
|
once done, look for the **Ribbon** project.
|
||||||
|
|
||||||
|
## Compiling translations
|
||||||
|
|
||||||
|
To convert all `.ts` files to `.qm` files (merge) you can use this command:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
./update_translation.sh -R
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are a translator that wants to update only their language file
|
||||||
|
to test it on **FreeCAD** before doing a PR you can use this command:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
./update_translation.sh -r de
|
||||||
|
```
|
||||||
|
|
||||||
|
This will update the `.qm` file for your language (German in this case).
|
||||||
|
|
||||||
|
## Sending translations
|
||||||
|
|
||||||
|
Now you can contribute your translated `.ts` file to **Ribbon** repository,
|
||||||
|
also include the `.qm` file.
|
||||||
|
|
||||||
|
<https://github.com/APEbbers/FreeCAD-Ribbon>
|
||||||
|
|
||||||
|
## More information
|
||||||
|
|
||||||
|
You can read more about translating external workbenches here:
|
||||||
|
|
||||||
|
<https://wiki.freecad.org/Translating_an_external_workbench>
|
166
translations/update_translation.sh
Normal file
166
translations/update_translation.sh
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Create, update and release translation files.
|
||||||
|
#
|
||||||
|
# Supported locales on FreeCAD <2024-10-14, FreeCADGui.supportedLocales(), total=44>:
|
||||||
|
# {'English': 'en', 'Afrikaans': 'af', 'Arabic': 'ar', 'Basque': 'eu', 'Belarusian': 'be',
|
||||||
|
# 'Bulgarian': 'bg', 'Catalan': 'ca', 'Chinese Simplified': 'zh-CN',
|
||||||
|
# 'Chinese Traditional': 'zh-TW', 'Croatian': 'hr', 'Czech': 'cs', 'Danish': 'da',
|
||||||
|
# 'Dutch': 'nl', 'Filipino': 'fil', 'Finnish': 'fi', 'French': 'fr', 'Galician': 'gl',
|
||||||
|
# 'Georgian': 'ka', 'German': 'de', 'Greek': 'el', 'Hungarian': 'hu', 'Indonesian': 'id',
|
||||||
|
# 'Italian': 'it', 'Japanese': 'ja', 'Kabyle': 'kab', 'Korean': 'ko', 'Lithuanian': 'lt',
|
||||||
|
# 'Norwegian': 'no', 'Polish': 'pl', 'Portuguese': 'pt-PT', 'Portuguese, Brazilian': 'pt-BR',
|
||||||
|
# 'Romanian': 'ro', 'Russian': 'ru', 'Serbian': 'sr', 'Serbian, Latin': 'sr-CS', 'Slovak': 'sk',
|
||||||
|
# 'Slovenian': 'sl', 'Spanish': 'es-ES', 'Spanish, Argentina': 'es-AR', 'Swedish': 'sv-SE',
|
||||||
|
# 'Turkish': 'tr', 'Ukrainian': 'uk', 'Valencian': 'val-ES', 'Vietnamese': 'vi'}
|
||||||
|
#
|
||||||
|
# NOTE: PREPARATION
|
||||||
|
# - Install Qt tools
|
||||||
|
# Debian-based (e.g., Ubuntu): $ sudo apt-get install qttools5-dev-tools pyqt6-dev-tools
|
||||||
|
# Fedora-based: $ sudo dnf install qt6-linguist qt6-devel
|
||||||
|
# Arch-based: $ sudo pacman -S qt6-tools python-pyqt6
|
||||||
|
# - Make the script executable
|
||||||
|
# $ chmod +x update_translation.sh
|
||||||
|
# - The script has to be executed within the `translations` directory.
|
||||||
|
# Executing the script with no flags invokes the help.
|
||||||
|
# $ ./update_translation.sh
|
||||||
|
#
|
||||||
|
# NOTE: WORKFLOW TRANSLATOR (LOCAL)
|
||||||
|
# - Execute the script passing the `-u` flag plus locale code as argument
|
||||||
|
# Only update the file(s) you're translating!
|
||||||
|
# $ ./update_translation.sh -u es-ES
|
||||||
|
# - Do the translation via Qt Linguist and use `File>Release`
|
||||||
|
# - If releasing with the script execute it passing the `-r` flag
|
||||||
|
# plus locale code as argument
|
||||||
|
# $ ./update_translation.sh -r es-ES
|
||||||
|
#
|
||||||
|
# NOTE: WORKFLOW MAINTAINER (CROWDIN)
|
||||||
|
# - Execute the script passing the '-U' flag
|
||||||
|
# $ ./update_translation.sh -U
|
||||||
|
# - Once done, download the translated files, copy them to `translations`
|
||||||
|
# - Upload the updated file to CrowdIn and wait for translators do their thing ;-)
|
||||||
|
# and release all the files to update the changes
|
||||||
|
# $ ./update_translation.sh -R
|
||||||
|
#
|
||||||
|
# --------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
supported_locales=(
|
||||||
|
"en" "af" "ar" "eu" "be" "bg" "ca" "zh-CN" "zh-TW" "hr"
|
||||||
|
"cs" "da" "nl" "fil" "fi" "fr" "gl" "ka" "de" "el"
|
||||||
|
"hu" "id" "it" "ja" "kab" "ko" "lt" "no" "pl" "pt-PT"
|
||||||
|
"pt-BR" "ro" "ru" "sr" "sr-CS" "sk" "sl" "es-ES" "es-AR" "sv-SE"
|
||||||
|
"tr" "uk" "val-ES" "vi"
|
||||||
|
)
|
||||||
|
|
||||||
|
is_locale_supported() {
|
||||||
|
local locale="$1"
|
||||||
|
for supported_locale in "${supported_locales[@]}"; do
|
||||||
|
[ "$supported_locale" == "$locale" ] && return 0
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
update_locale() {
|
||||||
|
local locale="$1"
|
||||||
|
local u=${locale:+_} # Conditional underscore
|
||||||
|
FILES="../*.py ../Resources/ui/*.ui"
|
||||||
|
|
||||||
|
# NOTE: Execute the right commands depending on:
|
||||||
|
# - if it's a locale file or the main, agnostic one
|
||||||
|
[ ! -f "${WB}${u}${locale}.ts" ] && action="Creating" || action="Updating"
|
||||||
|
echo -e "\033[1;34m\n\t<<< ${action} '${WB}${u}${locale}.ts' file >>>\n\033[m"
|
||||||
|
if [ "$u" == "" ]; then
|
||||||
|
eval $LUPDATE "$FILES" -ts "${WB}.ts" # locale-agnostic file
|
||||||
|
else
|
||||||
|
eval $LUPDATE "$FILES" -source-language en_US -target-language "${locale//-/_}" \
|
||||||
|
-ts "${WB}_${locale}.ts"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
normalize_crowdin_files() {
|
||||||
|
# Rename files which locales are different on FreeCAD and delete not supported locales
|
||||||
|
crowdin_fixes=(af-ZA ar-SA be-BY bg-BG ca-ES cs-CZ da-DK de-DE el-GR eu-ES fi-FI
|
||||||
|
fil-PH fr-FR gl-ES hr-HR hu-HU it-IT ja-JP ka-GE kab-KAB ko-KR lt-LT nl-NL
|
||||||
|
no-NO pl-PL ro-RO ru-RU sk-SK sl-SI sr-SP tr-TR uk-UA vi-VN)
|
||||||
|
|
||||||
|
crowdin_deletes=(az-AZ bn-BD br-FR bs-BA en en-GB en-US eo-UY es-CO es-VE et-EE fa-IR he-IL
|
||||||
|
hi-IN hy-AM id-ID kaa lv-LV mk-MK ms-MY sat-IN si-LK ta-IN te-IN th-TH ur-PK xav yo-NG)
|
||||||
|
|
||||||
|
for pattern in "${crowdin_fixes[@]}"; do
|
||||||
|
find . -type f -name "*_${pattern}\.*" | while read -r file; do
|
||||||
|
mv -v "$file" "${file//-*./.}"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
for pattern in "${crowdin_deletes[@]}"; do
|
||||||
|
find . -type f -name "*_${pattern}\.*" -delete
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
help() {
|
||||||
|
echo -e "\nDescription:"
|
||||||
|
echo -e "\tCreate, update and release translation files."
|
||||||
|
echo -e "\nUsage:"
|
||||||
|
echo -e "\t./update_translation.sh [-R] [-U] [-r <locale>] [-u <locale>]"
|
||||||
|
echo -e "\nFlags:"
|
||||||
|
echo -e " -R\n\tRelease all translations (qm files)"
|
||||||
|
echo -e " -U\n\tUpdate all translations (ts files)"
|
||||||
|
echo -e " -r <locale>\n\tRelease the specified locale"
|
||||||
|
echo -e " -u <locale>\n\tUpdate strings for the specified locale"
|
||||||
|
echo -e " -N\n\tNormalize CrowdIn filenames"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main function ------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LUPDATE=/usr/lib/qt6/bin/lupdate # from Qt6
|
||||||
|
# LUPDATE=lupdate # from Qt5
|
||||||
|
LRELEASE=/usr/lib/qt6/bin/lrelease # from Qt6
|
||||||
|
# LRELEASE=lrelease # from Qt5
|
||||||
|
WB="SearchBar"
|
||||||
|
|
||||||
|
sed -i '3s/-/_/' ${WB}*.ts # Enforce underscore on locales
|
||||||
|
sed -i '3s/\"en\"/\"en_US\"/g' ${WB}*.ts # Use en_US
|
||||||
|
|
||||||
|
if [ $# -eq 1 ]; then
|
||||||
|
if [ "$1" == "-R" ]; then
|
||||||
|
find . -type f -name '*_*.ts' | while IFS= read -r file; do
|
||||||
|
# Release all locales
|
||||||
|
$LRELEASE -nounfinished "$file"
|
||||||
|
echo
|
||||||
|
done
|
||||||
|
elif [ "$1" == "-U" ]; then
|
||||||
|
for locale in "${supported_locales[@]}"; do
|
||||||
|
update_locale "$locale"
|
||||||
|
done
|
||||||
|
elif [ "$1" == "-u" ]; then
|
||||||
|
update_locale # Update main file (agnostic)
|
||||||
|
elif [ "$1" == "-N" ]; then
|
||||||
|
normalize_crowdin_files
|
||||||
|
else
|
||||||
|
help
|
||||||
|
fi
|
||||||
|
elif [ $# -eq 2 ]; then
|
||||||
|
LOCALE="$2"
|
||||||
|
if is_locale_supported "$LOCALE"; then
|
||||||
|
if [ "$1" == "-r" ]; then
|
||||||
|
# Release locale (creation of *.qm file from *.ts file)
|
||||||
|
$LRELEASE -nounfinished "${WB}_${LOCALE}.ts"
|
||||||
|
elif [ "$1" == "-u" ]; then
|
||||||
|
# Update main & locale files
|
||||||
|
update_locale
|
||||||
|
update_locale "$LOCALE"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Verify your language code. Case sensitive."
|
||||||
|
echo "If it's correct, ask a maintainer to add support for your language on FreeCAD."
|
||||||
|
echo -e "\nSupported locales, '\033[1;34mFreeCADGui.supportedLocales()\033[m': \033[1;33m"
|
||||||
|
for locale in $(printf "%s\n" "${supported_locales[@]}" | sort); do
|
||||||
|
echo -n "$locale "
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
help
|
||||||
|
fi
|
Loading…
Reference in New Issue
Block a user