Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multilingual configuration and improvements #300

Merged
merged 7 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 69 additions & 4 deletions i18n/si/msgs.jaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ config.py:
Show Welcome screen on startup: false
startup/load-crashed-workflows: false
Load crashed scratch workflows on startup: false
application/language: false
English: true
Application language: Jezik
application/last-used-language: false
If different from application/language, widget discovery is forced: false
stylesheet: false
QSS stylesheet to use: false
schemeinfo/show-at-new-scheme: false
Expand Down Expand Up @@ -433,6 +438,9 @@ application/canvasmain.py:
Save As ...: Shrani kot ...
action-save-as: false
Save current workflow as.: Shrani trenutni delotok z novi imenom
Save Workflow Image as SVG ...: Shrani sliko delotoka kot SVG...
action-save-to-svg.: false
Save workflow image as SVG.: Shrani sliko delotoka kot SVG.
Quit: Zapri
quit-action: false
Welcome: Začetno okno
Expand Down Expand Up @@ -615,10 +623,10 @@ application/canvasmain.py:
Save Changes?: Shranim spremembe?
Your changes will be lost if you do not save them.: Spremembe ne bodo ohranjene, če jih ne shranite.
def `save_scheme_as`:
mainwindow: false
last-scheme-dir: false
.ows: false
Save Orange Workflow File: Shranjevanje delotoka
save-as-ows-filedialog: false
Orange Workflow (*.ows): Orangov delotok (*.ows)
def `save_scheme_to`:
untitled: nepoimenovan
Expand Down Expand Up @@ -656,6 +664,28 @@ application/canvasmain.py:
'Could not load swp file: %r': false
Could not load restore data.: Ne morem obnoviti podatkov.
Error: Napaka
def `_settings`:
mainwindow: false
def `save_as_svg`:
save-as-svg-filedialog: false
path: false
.svg: false
untitled.svg: nepoimenovan.svg
Scalable Vector Graphics (*.svg): true
def `save`:
path: false
def `__save_as_svg`:
wt: false
utf-8: false
def `_handle_os_write_error`:
Write error: Napaka pri pisanju
'"%(path)s" could not be saved. You do not ': '"%(path)s" ni mogoče shraniti. Morda nimate '
have write permissions (%(strerror)s).: pravice pisati v direktorij (%(strerror)s).
path: false
strerror: false
'Change the file system permissions or choose ': 'Nastavite ustrezna pravice ali izberite '
another location.: drugo mesto.
'"%(path)s" could not be saved.': '"%(path)s" ni mogoče shraniti.'
def `recent_scheme`:
mainwindow/recent-items: false
title: false
Expand Down Expand Up @@ -923,6 +953,12 @@ application/settings.py:
def `__setupUi`:
General: Splošno
General Options: Splošne nastavitve
Changes will take effect on next application startup.: Spremembe bodo uveljavljene ob naslednjem zagonu programa.
combo-language: false
Select the application language.: Izberite jezik aplikacije.
currentText: false
application/language: false
Language: Jezik
nodes: false
Enable node animations: Animiraj gradnike
enable-node-animations: false
Expand Down Expand Up @@ -1609,7 +1645,6 @@ document/interactions.py:
A: false
class `NewLinkAction`:
def `mousePressEvent`:
Create a new link: Dodaj novo povezavo
<h3>Create new link</h3>: <h3>Dodaj novo povezavo</h3>
'<p>Drag a link to an existing node or release on ': '<p>Povlecite povezavo do obstoječega gradnika ali pa '
an empty spot to create a new node.</p>: na prazno mesto, da tam postavite nov gradnik.</p>
Expand Down Expand Up @@ -1654,22 +1689,27 @@ document/interactions.py:
def `__init__`:
red: false
def `start`:
Click and drag to create a new arrow: Povlecite in spustite, da narišete puščico.
<h3>New arrow annotation</h3>: <h3>Risanje oznake s puščico</h3>
<p>Click and drag to create a new arrow annotation</p>: <p>Povlecite in spustite, da ustvarite oznako s puščico.</p>
class `NewTextAnnotation`:
def `start`:
Click to create a new text annotation: Kliknite, da dodate besedilno oznako.
<h3>New text annotation</h3>: <h3>Nova besedilna oznaka</h3>
'<p>Click (and drag to resize) on the canvas to create ': <p>Kliknite (in vlecite, da določite velikost), da dodate novo besedilno oznako.</p>
a new text annotation item.</p>: ""
'<p>Right click on the annotation to change how it is ': '<p>Desni klik na oznako omogoča spreminjanje načina prikaza '
rendered (Markdown, HTML, ...).</p>: (Markdown, HTML, ...).</p>
def `createNewAnnotation`:
family: false
size: false
class `ResizeTextAnnotation`:
def `commit`:
rect: false
Edit text geometry: false
def `start`:
<h3>Edit Text Annotation</h3>: <h3>Urejanje besedilne oznake</h3>
<p>Drag control points to resize the annotation.</p>: <p>Povlecite kontrolne točke za spremembo velikosti oznake.</p>
'<p>Right click on the annotation to change how it is ': '<p>Desni klik na oznako omogoča spreminjanje načina prikaza '
rendered (Markdown, HTML, ...).</p>: (Markdown, HTML, ...).</p>
def `cancel`:
ResizeTextAnnotation.cancel(%s): false
class `ResizeArrowAnnotation`:
Expand Down Expand Up @@ -3608,3 +3648,28 @@ utils/localization/__init__.py:
aeiouAEIOU: false
ies: false
s: false
def `get_languages`:
orangecanvas: false
i18n: false
.json: false
'Invalid language file ': false
English: null
def `language_changed`:
application/language: false
application/last-used-language: false
def `update_last_used_language`:
application/language: false
English: true
application/last-used-language: false
class `Translator`:
def `__init__`:
biolab.si: false
Orange: false
application/language: false
i18n: false
{lang_eng}.json: false
{DEFAULT_LANGUAGE}.json: false
Missing language file {path}: false
def `c`:
<string>: false
eval: false
2 changes: 0 additions & 2 deletions i18n/si/trubar-config.yaml

This file was deleted.

10 changes: 4 additions & 6 deletions i18n/trans.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
if [ "$#" -ne 2 ]
if [ "$#" -ne 1 ]
then
echo "Urage: trans <language> <destination>"
echo "trans <destination>"
exit
else
lang=$1
dest=$2
trubar --conf $lang/trubar-config.yaml translate -s ../orangecanvas -d $dest/orangecanvas --static $lang/static $lang/msgs.jaml
dest=$1
trubar --conf trubar-config.yaml translate -s ../orangecanvas -d $dest/orangecanvas msgs.jaml
fi

13 changes: 13 additions & 0 deletions i18n/trubar-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
languages:
en:
name: English
original: true
si:
name: Slovenščina
international-name: Slovenian
auto-import: from orangecanvas.utils.localization.si import plsi, plsi_sz, z_besedo # pylint: disable=wrong-import-order
auto-import: |2
from orangecanvas.utils.localization import Translator # pylint: disable=wrong-import-order
_tr = Translator("orangecanvas", "biolab.si", "Orange")
del Translator
encoding: "utf-8"
2 changes: 1 addition & 1 deletion orangecanvas/application/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ def __setupUi(self):
objectName="combo-language",
toolTip=self.tr("Select the application language.")
)
cm_lang.addItems(languages)
cm_lang.addItems(list(languages))
self.bind(cm_lang, "currentText", "application/language")
cm_lang.currentTextChanged.connect(lambda: label.setHidden(False))

Expand Down
36 changes: 29 additions & 7 deletions orangecanvas/utils/localization/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from functools import lru_cache
import warnings

import os
import json
import importlib
Expand Down Expand Up @@ -37,16 +40,25 @@ def pl(n: int, forms: str) -> str: # pylint: disable=invalid-name
return word


@lru_cache
def get_languages(package=None):
if package is None:
package = "orangecanvas"
package_path = os.path.dirname(importlib.import_module(package).__file__)
msgs_path = os.path.join(package_path, "i18n")
if not os.path.exists(msgs_path):
return []
return [name
for name, ext in map(os.path.splitext, os.listdir(msgs_path))
if ext == ".json"]
return {}
names = {}
for name, ext in map(os.path.splitext, os.listdir(msgs_path)):
if ext == ".json":
try:
msgs = json.load(open(os.path.join(msgs_path, name + ext)))
except json.JSONDecodeError:
warnings.warn("Invalid language file "
+ os.path.join(msgs_path, name + ext))
else:
names[msgs[0]] = name
return names


DEFAULT_LANGUAGE = QLocale().languageToString(QLocale().language())
Expand All @@ -67,6 +79,14 @@ def update_last_used_language():
s.setValue("application/last-used-language", lang)


class _list(list):
# Accept extra argument to allow for the original string
def __getitem__(self, item):
if isinstance(item, tuple):
item = item[0]
return super().__getitem__(item)


class Translator:
e = eval

Expand All @@ -77,11 +97,13 @@ def __init__(self, package, organization="biolab.si", application="Orange"):
# For testing purposes (and potential fallback)
# lang = os.environ.get("ORANGE_LANG", "English")
package_path = os.path.dirname(importlib.import_module(package).__file__)
path = os.path.join(package_path, "i18n", f"{lang}.json")
lang_eng = get_languages().get(lang, lang)
path = os.path.join(package_path, "i18n", f"{lang_eng}.json")
if not os.path.exists(path):
path = os.path.join(package_path, "i18n", f"{DEFAULT_LANGUAGE}.json")
assert os.path.exists(path), f"Missing language file {path}"
self.m = json.load(open(path))
self.m = _list(json.load(open(path)))

def c(self, idx):
# Extra argument(s) can give the original string or any other relevant data
def c(self, idx, *_):
return compile(self.m[idx], '<string>', 'eval')
Loading