Skip to content

Commit

Permalink
Add localization to UI
Browse files Browse the repository at this point in the history
  • Loading branch information
ObaraEmmanuel committed Mar 27, 2024
1 parent e38445a commit 41c4c27
Show file tree
Hide file tree
Showing 38 changed files with 3,637 additions and 578 deletions.
115 changes: 115 additions & 0 deletions buildtools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import sys
import pathlib
import logging
import subprocess
import shlex
import os
import shutil
import polib

logging.basicConfig(level=logging.INFO)

locales = (
"zh_CN",
)

ROOT_DIR = pathlib.Path(__file__).parent
HOVERSET_DIR = ROOT_DIR / "hoverset"
HOVERSET_LOCALE_DIR = HOVERSET_DIR / "data" / "locale"
HOVERSET_PO = HOVERSET_LOCALE_DIR / "hoverset.po"

STUDIO_DIR = ROOT_DIR / "studio"
STUDIO_LOCALE_DIR = STUDIO_DIR / "resources" / "locale"
STUDIO_PO = STUDIO_LOCALE_DIR / "studio.po"


def extract_locale_po(pot_path, locale_dir, source_dir, appname):
logging.info(f"Extracting locales for {appname}")
files = " ".join(sorted([str(f.relative_to(ROOT_DIR).as_posix()) for f in source_dir.glob("**/*.py")]))
base_po = pot_path.relative_to(ROOT_DIR).as_posix()
cmd = (
f"xgettext --package-name {appname} -L Python {'--join-existing' if pot_path.exists() else ''} "
f"--from-code=UTF-8 --keyword=_ --output={base_po} {files}"
)
subprocess.run(shlex.split(cmd))

for locale in locales:
logging.info(f"Updating locale {locale}")
po_file = (locale_dir / locale / "LC_MESSAGES" / f"{appname}.po").relative_to(ROOT_DIR).as_posix()

# Create the po file if it does not exist
os.makedirs(os.path.dirname(po_file), exist_ok=True)
if not os.path.exists(po_file):
# copy the template file
shutil.copy(base_po, po_file)

cmd = f"msgmerge --update --verbose {po_file} {base_po}"
subprocess.run(shlex.split(cmd))


def extract_locales():
logging.info("Extracting hoverset locales")
extract_locale_po(
HOVERSET_PO,
HOVERSET_LOCALE_DIR,
HOVERSET_DIR,
"hoverset"
)
logging.info("Extracting studio locales")
extract_locale_po(
STUDIO_PO,
STUDIO_LOCALE_DIR,
STUDIO_DIR,
"studio"
)


def _compile_locales(locale_dir, appname):
for locale in locales:
po_file = (locale_dir / locale / "LC_MESSAGES" / f"{appname}.po").relative_to(ROOT_DIR).as_posix()
mo_file = (locale_dir / locale / "LC_MESSAGES" / f"{appname}.mo").relative_to(ROOT_DIR).as_posix()
logging.info(f"Compiling {po_file} to {mo_file}")
cmd = f"msgfmt --verbose -o {mo_file} {po_file}"
subprocess.run(shlex.split(cmd))


def compile_locales():
logging.info("Compiling hoverset locales")
_compile_locales(HOVERSET_LOCALE_DIR, "hoverset")
logging.info("Compiling studio locales")
_compile_locales(STUDIO_LOCALE_DIR, "studio")


def decompose_po():
po = polib.pofile(STUDIO_PO)
with open("studio-trans.txt", "w") as out:
for entry in po:
out.write(f"{entry.msgid}\n\n")

with open("hoverset-trans.txt", "w") as out:
po = polib.pofile(HOVERSET_PO)
for entry in po:
out.write(f"{entry.msgid}\n\n")


def merge_po():
pass


if __name__ == "__main__":
command_map = {
"extract_locales": extract_locales,
"extract_lc": extract_locales,
"compile_locales": compile_locales,
"compile_lc": compile_locales,
"decompose_po": decompose_po,
"merge_po": merge_po,
}

if len(sys.argv) > 1:
for arg in sys.argv[1:]:
command = command_map.get(arg)
if command:
command()
else:
print("Unknown command")
33 changes: 33 additions & 0 deletions hoverset/data/i18n.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import gettext
import functools

from hoverset.data.utils import get_resource_path

app_name = "hoverset"
locale_dir = get_resource_path('hoverset.data', "locale")

_translators_core = {}
_translators = {}


def set_locale(locale):
for appname, localedir in _translators_core.values():
translator = gettext.translation(appname, localedir, fallback=True, languages=[locale])
_translators[appname] = translator


def register_translator(appname, localedir):
global _translators
_translators_core[appname] = (appname, localedir)


def _translator(appname, message):
if appname not in _translators:
return message
return _translators[appname].gettext(message)


register_translator(app_name, locale_dir)
set_locale("en")

_ = functools.partial(_translator, app_name)
17 changes: 9 additions & 8 deletions hoverset/data/keymap.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from hoverset.ui.widgets import Frame, Label, CompoundList
from hoverset.ui.dialogs import MessageDialog
from hoverset.ui.menu import EnableIf
from hoverset.data.i18n import _


class Key:
Expand Down Expand Up @@ -317,7 +318,7 @@ def on_key_change(self, event, with_alt=False):
if self.shortcut_pane is not None:
routine = self.shortcut_pane.routine_from_shortcut(self.key)
if routine is not None and self.shortcut_pane:
self._warning['text'] = f"Key already assigned to {routine.desc}"
self._warning['text'] = _("Key already assigned to {}").format(routine.desc)
self._warning.pack(fill="x")
else:
self._warning.pack_forget()
Expand All @@ -329,7 +330,7 @@ def on_key_change(self, event, with_alt=False):
def on_key_change_alt(self, event):
self.on_key_change(event, with_alt=True)

def render(self, _):
def render(self, __):
self.detail = Label(self, **self.style.text, text=self.message)
self.detail.pack(fill="x")
warn_frame = Frame(self, **self.style.surface)
Expand All @@ -343,12 +344,12 @@ def render(self, _):
)
self.event_pad = Label(
self, **self.style.text_accent)
self._add_button(text="Cancel", value=None)
self._add_button(text="Okay", command=self.exit_with_key, focus=True)
self._add_button(text=_("Cancel"), value=None)
self._add_button(text=_("Okay"), command=self.exit_with_key, focus=True)
warn_frame.pack(side="bottom", fill="x")
self.event_pad.config(
**self.style.bright, takefocus=True,
text="Tap here to begin capturing shortcuts."
text=_("Tap here to begin capturing shortcuts.")
)
self.event_pad.bind("<Any-KeyPress>", self.on_key_change)
# for some reason alt needs to be bound separately
Expand Down Expand Up @@ -406,7 +407,7 @@ def disable(self, flag):
self.desc.config(**self.style.text)
self.key_label.config(**self.style.text_accent)

def __init__(self, master, pref: SharedPreferences, path, _, **__):
def __init__(self, master, pref: SharedPreferences, path, __, **___):
super().__init__(master)
self.config(**self.style.surface)
self.bindings = {}
Expand All @@ -419,10 +420,10 @@ def __init__(self, master, pref: SharedPreferences, path, _, **__):
self.shortcut_list.body.set_up_context((
EnableIf(
lambda: (not self.is_disabled) and self.shortcut_list.get(),
("command", "Change Shortcut", get_tk_image('edit', 14, 14), self.pick_key, {}),
("command", _("Change Shortcut"), get_tk_image('edit', 14, 14), self.pick_key, {}),
EnableIf(
lambda: self.shortcut_list.get() and self.shortcut_list.get().value[1] != BlankKey,
("command", "Remove", get_tk_image('delete', 14, 14), self.remove_key, {})
("command", _("Remove"), get_tk_image('delete', 14, 14), self.remove_key, {})
),
),
))
Expand Down
91 changes: 91 additions & 0 deletions hoverset/data/locale/hoverset.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the hoverset package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: hoverset\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-03-27 23:37+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: hoverset/ui/dialogs.py:205 hoverset/ui/dialogs.py:217
#: hoverset/data/keymap.py:347 hoverset/data/preferences.py:710
#: hoverset/data/preferences.py:715
msgid "Cancel"
msgstr ""

#: hoverset/ui/dialogs.py:206 hoverset/ui/dialogs.py:223
#: hoverset/ui/dialogs.py:228 hoverset/ui/dialogs.py:233
msgid "Ok"
msgstr ""

#: hoverset/ui/dialogs.py:211
msgid "No"
msgstr ""

#: hoverset/ui/dialogs.py:212
msgid "Yes"
msgstr ""

#: hoverset/ui/dialogs.py:218
msgid "Retry"
msgstr ""

#: hoverset/ui/panels.py:55
msgid "Pick color from anywhere"
msgstr ""

#: hoverset/ui/panels.py:134
msgid "Pick color from clipboard"
msgstr ""

#: hoverset/ui/panels.py:349
msgid "Pick Font"
msgstr ""

#: hoverset/ui/panels.py:386
msgid "No font to extract"
msgstr ""

#: hoverset/data/keymap.py:321
msgid "Key already assigned to {}"
msgstr ""

#: hoverset/data/keymap.py:348 hoverset/data/preferences.py:711
#: hoverset/data/preferences.py:716
msgid "Okay"
msgstr ""

#: hoverset/data/keymap.py:352
msgid "Tap here to begin capturing shortcuts."
msgstr ""

#: hoverset/data/keymap.py:423
msgid "Change Shortcut"
msgstr ""

#: hoverset/data/keymap.py:426
msgid "Remove"
msgstr ""

#: hoverset/data/preferences.py:577 hoverset/data/preferences.py:582
msgid "Preferences"
msgstr ""

#: hoverset/data/preferences.py:702 hoverset/data/preferences.py:707
msgid "Some changes require restart"
msgstr ""

#: hoverset/data/preferences.py:705 hoverset/data/preferences.py:707
#: hoverset/data/preferences.py:710 hoverset/data/preferences.py:712
msgid "restart"
msgstr ""
Binary file not shown.
91 changes: 91 additions & 0 deletions hoverset/data/locale/zh_CN/LC_MESSAGES/hoverset.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the hoverset package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: hoverset\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-03-27 23:37+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"Language: zh_CN \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: hoverset/ui/dialogs.py:205 hoverset/ui/dialogs.py:217
#: hoverset/data/keymap.py:347 hoverset/data/preferences.py:710
#: hoverset/data/preferences.py:715
msgid "Cancel"
msgstr "取消"

#: hoverset/ui/dialogs.py:206 hoverset/ui/dialogs.py:223
#: hoverset/ui/dialogs.py:228 hoverset/ui/dialogs.py:233
msgid "Ok"
msgstr "确定"

#: hoverset/ui/dialogs.py:211
msgid "No"
msgstr "否"

#: hoverset/ui/dialogs.py:212
msgid "Yes"
msgstr "是"

#: hoverset/ui/dialogs.py:218
msgid "Retry"
msgstr "重试"

#: hoverset/ui/panels.py:55
msgid "Pick color from anywhere"
msgstr "从任何地方选择颜色"

#: hoverset/ui/panels.py:134
msgid "Pick color from clipboard"
msgstr "从剪贴板选择颜色"

#: hoverset/ui/panels.py:349
msgid "Pick Font"
msgstr "选择字体"

#: hoverset/ui/panels.py:386
msgid "No font to extract"
msgstr "没有字体可提取"

#: hoverset/data/keymap.py:321
msgid "Key already assigned to {}"
msgstr "键已分配给 {}"

#: hoverset/data/keymap.py:348 hoverset/data/preferences.py:711
#: hoverset/data/preferences.py:716
msgid "Okay"
msgstr "好的"

#: hoverset/data/keymap.py:352
msgid "Tap here to begin capturing shortcuts."
msgstr "点击这里开始捕获快捷键。"

#: hoverset/data/keymap.py:423
msgid "Change Shortcut"
msgstr "更改快捷键"

#: hoverset/data/keymap.py:426
msgid "Remove"
msgstr "移除"

#: hoverset/data/preferences.py:577 hoverset/data/preferences.py:582
msgid "Preferences"
msgstr "偏好设置"

#: hoverset/data/preferences.py:702 hoverset/data/preferences.py:707
msgid "Some changes require restart"
msgstr "某些更改需要重启"

#: hoverset/data/preferences.py:705 hoverset/data/preferences.py:707
#: hoverset/data/preferences.py:710 hoverset/data/preferences.py:712
msgid "restart"
msgstr "重启"
Loading

0 comments on commit 41c4c27

Please sign in to comment.