Skip to content

Commit bc64493

Browse files
committed
Fixes #68: translation support on frozen apps (Windows)
1 parent 1d3ba7c commit bc64493

File tree

4 files changed

+45
-7
lines changed

4 files changed

+45
-7
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# Changelog #
22

3+
## Version 3.2.2 ##
4+
5+
🛠️ Bug fixes:
6+
7+
* Fixed translation support (`gettext`):
8+
* Locale detection has been fixed in 3.1.1 (deprecation of `locale.getdefaultlocale`)
9+
* However, on frozen distributions on Windows (e.g. with `pyinstaller`), function
10+
`locale.getlocale` is returning `(None, None)` instead of proper locale infos
11+
* Added a workaround: on Windows, if locale can't be detected, we now use the
12+
Windows API to retrieve it (using the `GetUserDefaultLocaleName` function)
13+
* [Issue #68](https://github.com/PlotPyStack/guidata/issues/68) - Windows: gettext translation is not working on frozen applications
14+
315
## Version 3.2.1 ##
416

517
🛠️ Bug fixes:

guidata/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
and application development tools for Qt.
99
"""
1010

11-
__version__ = "3.2.1"
11+
__version__ = "3.2.2"
1212

1313

1414
# Dear (Debian, RPM, ...) package makers, please feel free to customize the

guidata/configtools.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
from collections.abc import Callable
4444
from typing import TYPE_CHECKING
4545

46-
from guidata.utils.misc import decode_fs_string, get_module_path
46+
from guidata.utils.misc import decode_fs_string, get_module_path, get_system_lang
4747

4848
if TYPE_CHECKING: # pragma: no cover
4949
from qtpy import QtCore as QC
@@ -93,9 +93,7 @@ def get_translation(modname: str, dirname: str | None = None) -> Callable[[str],
9393
dirname = modname
9494
# fixup environment var LANG in case it's unknown
9595
if "LANG" not in os.environ:
96-
import locale # Warning: 2to3 false alarm ('import' fixer)
97-
98-
lang = locale.getlocale()[0]
96+
lang = get_system_lang()
9997
if lang is not None:
10098
os.environ["LANG"] = lang
10199
try:
@@ -459,3 +457,4 @@ def get_brush(
459457
alpha = conf.get(section, option + "/alphaF", alpha)
460458
color.setAlphaF(alpha)
461459
return QG.QBrush(color)
460+
return QG.QBrush(color)

guidata/utils/misc.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
from __future__ import annotations
3030

3131
import collections.abc
32-
import locale # Warning: 2to3 false alarm ('import' fixer)
32+
import ctypes
33+
import locale
3334
import os
3435
import os.path as osp
3536
import subprocess
@@ -40,7 +41,7 @@
4041
from guidata.userconfig import get_home_dir
4142

4243
# ==============================================================================
43-
# Strings
44+
# Strings, Locale
4445
# ==============================================================================
4546

4647

@@ -79,6 +80,31 @@ def decode_fs_string(string: str) -> str:
7980
return string.decode(charset)
8081

8182

83+
def get_system_lang() -> str | None:
84+
"""
85+
Retrieves the system language name.
86+
87+
This function uses `locale.getlocale()` to obtain the locale name based on
88+
the current user's settings. If that fails on Windows (e.g. for frozen
89+
applications), it uses the Win32 API function `GetUserDefaultLocaleName`
90+
to obtain the locale name.
91+
92+
Returns:
93+
The locale name in a format like 'en_US', or None if the function fails
94+
to retrieve the locale name.
95+
"""
96+
lang = locale.getlocale()[0]
97+
if lang is None and os.name == "nt":
98+
kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
99+
GetUserDefaultLocaleName = kernel32.GetUserDefaultLocaleName
100+
GetUserDefaultLocaleName.argtypes = [ctypes.c_wchar_p, ctypes.c_int]
101+
GetUserDefaultLocaleName.restype = ctypes.c_int
102+
locale_name = ctypes.create_unicode_buffer(85)
103+
if GetUserDefaultLocaleName(locale_name, 85):
104+
lang = locale_name.value.replace("-", "_")
105+
return lang
106+
107+
82108
# ==============================================================================
83109
# Interface checking
84110
# ==============================================================================
@@ -355,3 +381,4 @@ def convert_date_format(format_string: str) -> str:
355381
i += 1
356382

357383
return qt_format
384+
return qt_format

0 commit comments

Comments
 (0)