Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'release/scripts/modules/bl_i18n_utils/bl_extract_messages.py')
-rw-r--r--release/scripts/modules/bl_i18n_utils/bl_extract_messages.py148
1 files changed, 127 insertions, 21 deletions
diff --git a/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
index 319fd3396a0..21ca38bff20 100644
--- a/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
+++ b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
@@ -8,6 +8,7 @@ import datetime
import os
import re
import sys
+import glob
# XXX Relative import does not work here when used from Blender...
from bl_i18n_utils import settings as settings_i18n, utils
@@ -96,7 +97,7 @@ def check(check_ctxt, msgs, key, msgsrc, settings):
if key in py_in_rna[1]:
py_in_rna[0].add(key)
if not_capitalized is not None:
- if(key[1] not in settings.WARN_MSGID_NOT_CAPITALIZED_ALLOWED and
+ if (key[1] not in settings.WARN_MSGID_NOT_CAPITALIZED_ALLOWED and
key[1][0].isalpha() and not key[1][0].isupper()):
not_capitalized.add(key)
if end_point is not None:
@@ -206,8 +207,6 @@ def dump_rna_messages(msgs, reports, settings, verbose=False):
"Context", "Event", "Function", "UILayout", "UnknownType", "Property", "Struct",
# registerable classes
"Panel", "Menu", "Header", "RenderEngine", "Operator", "OperatorMacro", "Macro", "KeyingSetInfo",
- # window classes
- "Window",
)
}
@@ -259,11 +258,12 @@ def dump_rna_messages(msgs, reports, settings, verbose=False):
bl_rna_base_props = set()
if bl_rna_base:
bl_rna_base_props |= set(bl_rna_base.properties.values())
- for cls_base in cls.__bases__:
- bl_rna_base = getattr(cls_base, "bl_rna", None)
- if not bl_rna_base:
- continue
- bl_rna_base_props |= set(bl_rna_base.properties.values())
+ if hasattr(cls, "__bases__"):
+ for cls_base in cls.__bases__:
+ bl_rna_base = getattr(cls_base, "bl_rna", None)
+ if not bl_rna_base:
+ continue
+ bl_rna_base_props |= set(bl_rna_base.properties.values())
props = sorted(bl_rna.properties, key=lambda p: p.identifier)
for prop in props:
@@ -361,12 +361,25 @@ def dump_rna_messages(msgs, reports, settings, verbose=False):
walk_properties(cls)
+ def walk_keymap_modal_events(keyconfigs, keymap_name, msgsrc_prev, km_i18n_context):
+ for keyconfig in keyconfigs:
+ keymap = keyconfig.keymaps.get(keymap_name, None)
+ if keymap and keymap.is_modal:
+ for modal_event in keymap.modal_event_values:
+ msgsrc = msgsrc_prev + ":'{}'".format(modal_event.identifier)
+ if modal_event.name:
+ process_msg(msgs, km_i18n_context, modal_event.name, msgsrc, reports, None, settings)
+ if modal_event.description:
+ process_msg(msgs, default_context, modal_event.description, msgsrc, reports, None, settings)
+
def walk_keymap_hierarchy(hier, msgsrc_prev):
km_i18n_context = bpy.app.translations.contexts.id_windowmanager
for lvl in hier:
msgsrc = msgsrc_prev + "." + lvl[1]
if isinstance(lvl[0], str): # Can be a function too, now, with tool system...
- process_msg(msgs, km_i18n_context, lvl[0], msgsrc, reports, None, settings)
+ keymap_name = lvl[0]
+ process_msg(msgs, km_i18n_context, keymap_name, msgsrc, reports, None, settings)
+ walk_keymap_modal_events(bpy.data.window_managers[0].keyconfigs, keymap_name, msgsrc, km_i18n_context)
if lvl[3]:
walk_keymap_hierarchy(lvl[3], msgsrc)
@@ -438,6 +451,19 @@ def dump_rna_messages(msgs, reports, settings, verbose=False):
process_msg(msgs, bpy.app.translations.contexts.operator_default, cat_str, "Generated operator category",
reports, check_ctxt_rna, settings)
+ # Parse keymap preset preferences
+ for preset_filename in sorted(
+ os.listdir(os.path.join(settings.PRESETS_DIR, "keyconfig"))):
+ preset_path = os.path.join(settings.PRESETS_DIR, "keyconfig", preset_filename)
+ if not (os.path.isfile(preset_path) and preset_filename.endswith(".py")):
+ continue
+ preset_name, _ = os.path.splitext(preset_filename)
+
+ bpy.utils.keyconfig_set(preset_path)
+ preset = bpy.data.window_managers[0].keyconfigs[preset_name]
+ if preset.preferences is not None:
+ walk_properties(preset.preferences)
+
# And parse keymaps!
from bl_keymap_utils import keymap_hierarchy
walk_keymap_hierarchy(keymap_hierarchy.generate(), "KM_HIERARCHY")
@@ -803,20 +829,21 @@ def dump_src_messages(msgs, reports, settings):
line += data[pos:m.start()].count('\n')
msgsrc = rel_path + ":" + str(line)
_msgid = d.get("msg_raw")
- # First, try the "multi-contexts" stuff!
- _msgctxts = tuple(d.get("ctxt_raw{}".format(i)) for i in range(settings.PYGETTEXT_MAX_MULTI_CTXT))
- if _msgctxts[0]:
- for _msgctxt in _msgctxts:
- if not _msgctxt:
- break
+ if _msgid not in {'""', "''"}:
+ # First, try the "multi-contexts" stuff!
+ _msgctxts = tuple(d.get("ctxt_raw{}".format(i)) for i in range(settings.PYGETTEXT_MAX_MULTI_CTXT))
+ if _msgctxts[0]:
+ for _msgctxt in _msgctxts:
+ if not _msgctxt:
+ break
+ msgctxt, msgid = process_entry(_msgctxt, _msgid)
+ process_msg(msgs, msgctxt, msgid, msgsrc, reports, check_ctxt_src, settings)
+ reports["src_messages"].append((msgctxt, msgid, msgsrc))
+ else:
+ _msgctxt = d.get("ctxt_raw")
msgctxt, msgid = process_entry(_msgctxt, _msgid)
process_msg(msgs, msgctxt, msgid, msgsrc, reports, check_ctxt_src, settings)
reports["src_messages"].append((msgctxt, msgid, msgsrc))
- else:
- _msgctxt = d.get("ctxt_raw")
- msgctxt, msgid = process_entry(_msgctxt, _msgid)
- process_msg(msgs, msgctxt, msgid, msgsrc, reports, check_ctxt_src, settings)
- reports["src_messages"].append((msgctxt, msgid, msgsrc))
pos = m.end()
line += data[m.start():pos].count('\n')
@@ -852,6 +879,64 @@ def dump_src_messages(msgs, reports, settings):
dump_src_file(path, rel_path, msgs, reports, settings)
+def dump_preset_messages(msgs, reports, settings):
+ files = []
+ for dpath, _, fnames in os.walk(settings.PRESETS_DIR):
+ for fname in fnames:
+ if fname.startswith("_") or not fname.endswith(".py"):
+ continue
+ path = os.path.join(dpath, fname)
+ try: # can't always find the relative path (between drive letters on windows)
+ rel_path = os.path.relpath(path, settings.PRESETS_DIR)
+ except ValueError:
+ rel_path = path
+ files.append(rel_path)
+ for rel_path in sorted(files):
+ msgsrc, msgid = os.path.split(rel_path)
+ msgsrc = "Preset from " + msgsrc
+ msgid = bpy.path.display_name(msgid, title_case=False)
+ process_msg(msgs, settings.DEFAULT_CONTEXT, msgid, msgsrc, reports, None, settings)
+
+
+def dump_template_messages(msgs, reports, settings):
+ bfiles = [""] # General template, no name needed.
+ bfiles += glob.glob(settings.TEMPLATES_DIR + "/**/*.blend", recursive=True)
+
+ workspace_names = {}
+
+ for bfile in bfiles:
+ template = os.path.dirname(bfile)
+ template = os.path.basename(template)
+ bpy.ops.wm.read_homefile(use_factory_startup=True, app_template=template)
+ for ws in bpy.data.workspaces:
+ names = workspace_names.setdefault(ws.name, [])
+ names.append(template or "General")
+
+ from bpy.app.translations import contexts as i18n_contexts
+ msgctxt = i18n_contexts.id_workspace
+ for workspace_name in sorted(workspace_names):
+ for msgsrc in sorted(workspace_names[workspace_name]):
+ msgsrc = "Workspace from template " + msgsrc
+ process_msg(msgs, msgctxt, workspace_name, msgsrc,
+ reports, None, settings)
+
+
+def dump_addon_bl_info(msgs, reports, module, settings):
+ for prop in ('name', 'location', 'description'):
+ process_msg(
+ msgs,
+ settings.DEFAULT_CONTEXT,
+ module.bl_info[prop],
+ "Add-on " +
+ module.bl_info['name'] +
+ " info: " +
+ prop,
+ reports,
+ None,
+ settings,
+ )
+
+
##### Main functions! #####
def dump_messages(do_messages, do_checks, settings):
bl_ver = "Blender " + bpy.app.version_string
@@ -884,6 +969,19 @@ def dump_messages(do_messages, do_checks, settings):
# Get strings from C source code.
dump_src_messages(msgs, reports, settings)
+ # Get strings from presets.
+ dump_preset_messages(msgs, reports, settings)
+
+ # Get strings from startup templates.
+ dump_template_messages(msgs, reports, settings)
+
+ # Get strings from addons' bl_info.
+ import addon_utils
+ for module in addon_utils.modules():
+ if module.bl_info['support'] != 'OFFICIAL':
+ continue
+ dump_addon_bl_info(msgs, reports, module, settings)
+
# Get strings from addons' categories.
for uid, label, tip in bpy.types.WindowManager.addon_filter.keywords['items'](
bpy.context.window_manager,
@@ -961,7 +1059,12 @@ def dump_addon_messages(module_name, do_checks, settings):
# and make the diff!
for key in minus_msgs:
if key != settings.PO_HEADER_KEY:
- del msgs[key]
+ if key in msgs:
+ del msgs[key]
+ else:
+ # This should not happen, but some messages seem to have
+ # leaked on add-on unregister and register?
+ print(f"Key not found in msgs: {key}")
if check_ctxt:
_diff_check_ctxt(check_ctxt, minus_check_ctxt)
@@ -975,6 +1078,9 @@ def dump_addon_messages(module_name, do_checks, settings):
reports["check_ctxt"] = check_ctxt
dump_py_messages(msgs, reports, {addon}, settings, addons_only=True)
+ # Get strings from the addon's bl_info
+ dump_addon_bl_info(msgs, reports, addon, settings)
+
pot.unescape() # Strings gathered in py/C source code may contain escaped chars...
print_info(reports, pot)