From 04aa879c22f7b70cd514573d47b8f2bb9dd825a0 Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Sun, 12 Jan 2025 15:15:29 +0800 Subject: [PATCH] feat: finish i18n extract work - masically finish u18n extract work (most fields are extracted) --- bbp_ng/OP_ADDS_bme.py | 38 +++++++-------- bbp_ng/OP_ADDS_component.py | 15 ++++-- bbp_ng/OP_ADDS_rail.py | 28 +++++------ bbp_ng/OP_EXPORT_virtools.py | 4 +- bbp_ng/OP_IMPORT_virtools.py | 8 +++- bbp_ng/OP_MTL_fix_material.py | 4 +- bbp_ng/OP_OBJECT_legacy_align.py | 24 +++++----- bbp_ng/OP_OBJECT_naming_convention.py | 9 ++-- bbp_ng/OP_OBJECT_virtools_group.py | 4 +- bbp_ng/OP_UV_flatten_uv.py | 10 ++-- bbp_ng/OP_UV_rail_uv.py | 8 +++- bbp_ng/PROP_preferences.py | 4 +- bbp_ng/PROP_ptrprop_resolver.py | 3 +- bbp_ng/PROP_virtools_group.py | 10 ++-- bbp_ng/PROP_virtools_light.py | 16 ++++--- bbp_ng/PROP_virtools_material.py | 38 ++++++++------- bbp_ng/UTIL_file_browser.py | 2 +- bbp_ng/UTIL_ioport_shared.py | 67 ++++++++++++++------------- bbp_ng/UTIL_naming_convension.py | 25 +++++++--- bbp_ng/UTIL_translation.py | 40 ++++++++++------ bbp_ng/UTIL_virtools_types.py | 4 +- bbp_ng/__init__.py | 66 +++++++++++++++++--------- 22 files changed, 255 insertions(+), 172 deletions(-) diff --git a/bbp_ng/OP_ADDS_bme.py b/bbp_ng/OP_ADDS_bme.py index 7c78f23..ef750b9 100644 --- a/bbp_ng/OP_ADDS_bme.py +++ b/bbp_ng/OP_ADDS_bme.py @@ -55,7 +55,7 @@ class BBP_OT_add_bme_struct(bpy.types.Operator): ## Compromise used "outdated" flag. outdated_flag: bpy.props.BoolProperty( - # TR: Internal property should not have name and desc otherwise they will be written in translation. + # TR: Property not showen should not have name and desc. # name = "Outdated Type", # description = "Internal flag.", options = {'HIDDEN', 'SKIP_SAVE'}, @@ -243,49 +243,49 @@ class BBP_OT_add_bme_struct(bpy.types.Operator): op_cfgs_visitor: UTIL_functions.CollectionVisitor[BBP_PG_bme_adder_cfgs] op_cfgs_visitor = UTIL_functions.CollectionVisitor(self.bme_struct_cfgs) # visit cfgs cache list to show cfg - layout.label(text = "Prototype Configurations:") + layout.label(text="Prototype Configurations:", text_ctxt='BBP_OT_add_bme_struct/draw') for (cfg, cfg_index) in self.bme_struct_cfg_index_cache: # create box for cfgs box_layout: bpy.types.UILayout = layout.box() # draw title and description first - box_layout.label(text = cfg.get_title()) - box_layout.label(text = cfg.get_desc()) + box_layout.label(text=cfg.get_title()) # TODO: finish translation context + box_layout.label(text=cfg.get_desc()) # show prop differently by cfg type match(cfg.get_type()): case UTIL_bme.PrototypeShowcaseCfgsTypes.Integer: - box_layout.prop(op_cfgs_visitor[cfg_index], 'prop_int', text = '') + box_layout.prop(op_cfgs_visitor[cfg_index], 'prop_int', text='') case UTIL_bme.PrototypeShowcaseCfgsTypes.Float: - box_layout.prop(op_cfgs_visitor[cfg_index], 'prop_float', text = '') + box_layout.prop(op_cfgs_visitor[cfg_index], 'prop_float', text='') case UTIL_bme.PrototypeShowcaseCfgsTypes.Boolean: - box_layout.prop(op_cfgs_visitor[cfg_index], 'prop_bool', text = '') + box_layout.prop(op_cfgs_visitor[cfg_index], 'prop_bool', text='') case UTIL_bme.PrototypeShowcaseCfgsTypes.Face: # face will show a special layout (grid view) grids = box_layout.grid_flow( row_major=True, columns=3, even_columns=True, even_rows=True, align=True) grids.alignment = 'CENTER' grids.separator() - grids.prop(op_cfgs_visitor[cfg_index + 0], 'prop_bool', text = 'Top') # top - grids.prop(op_cfgs_visitor[cfg_index + 2], 'prop_bool', text = 'Front') # front - grids.prop(op_cfgs_visitor[cfg_index + 4], 'prop_bool', text = 'Left') # left - grids.label(text = '', icon = 'CUBE') # show a 3d cube as icon - grids.prop(op_cfgs_visitor[cfg_index + 5], 'prop_bool', text = 'Right') # right - grids.prop(op_cfgs_visitor[cfg_index + 3], 'prop_bool', text = 'Back') # back - grids.prop(op_cfgs_visitor[cfg_index + 1], 'prop_bool', text = 'Bottom') # bottom + grids.prop(op_cfgs_visitor[cfg_index + 0], 'prop_bool', text='Top', text_ctxt='BBP_OT_add_bme_struct/draw') # top + grids.prop(op_cfgs_visitor[cfg_index + 2], 'prop_bool', text='Front', text_ctxt='BBP_OT_add_bme_struct/draw') # front + grids.prop(op_cfgs_visitor[cfg_index + 4], 'prop_bool', text='Left', text_ctxt='BBP_OT_add_bme_struct/draw') # left + grids.label(text='', icon='CUBE') # show a 3d cube as icon + grids.prop(op_cfgs_visitor[cfg_index + 5], 'prop_bool', text='Right', text_ctxt='BBP_OT_add_bme_struct/draw') # right + grids.prop(op_cfgs_visitor[cfg_index + 3], 'prop_bool', text='Back', text_ctxt='BBP_OT_add_bme_struct/draw') # back + grids.prop(op_cfgs_visitor[cfg_index + 1], 'prop_bool', text='Bottom', text_ctxt='BBP_OT_add_bme_struct/draw') # bottom grids.separator() # show extra transform props # forcely order that each one are placed horizontally - layout.label(text = "Extra Transform") + layout.label(text="Extra Transform", text_ctxt='BBP_OT_add_bme_struct/draw') # translation - layout.label(text = 'Translation') + layout.label(text='Translation', text_ctxt='BBP_OT_add_bme_struct/draw') hbox_layout: bpy.types.UILayout = layout.row() - hbox_layout.prop(self, 'extra_translation', text = '') + hbox_layout.prop(self, 'extra_translation', text='') # rotation - layout.label(text = 'Rotation') + layout.label(text='Rotation', text_ctxt='BBP_OT_add_bme_struct/draw') hbox_layout = layout.row() - hbox_layout.prop(self, 'extra_rotation', text = '') + hbox_layout.prop(self, 'extra_rotation', text='') @classmethod def draw_blc_menu(cls, layout: bpy.types.UILayout): diff --git a/bbp_ng/OP_ADDS_component.py b/bbp_ng/OP_ADDS_component.py index f0b5c72..b8fc9fc 100644 --- a/bbp_ng/OP_ADDS_component.py +++ b/bbp_ng/OP_ADDS_component.py @@ -224,7 +224,9 @@ class BBP_OT_add_component(bpy.types.Operator, ComponentSectorParam): # check for some special components and show warning elename: str | None = _check_component_existance(_g_EnumHelper_Component.get_selection(self.component_type), self.general_get_component_sector()) if elename is not None: - layout.label(text = f'Warning: {elename} already exist.') + tr_text: str = bpy.app.translations.pgettext_iface( + 'Warning: {0} already exist.', 'BBP_OT_add_component/draw') + layout.label(text=tr_text.format(elename), translate=False) def execute(self, context): # call general creator @@ -324,7 +326,8 @@ class BBP_OT_add_nong_ventilator(bpy.types.Operator, ComponentSectorParam, Compo self.draw_component_sector_params(layout) # draw count settings by different source - layout.label(text = 'Count') + layout.separator() + layout.label(text='Count Source', text_ctxt='BBP_OT_add_nong_ventilator/draw') layout.prop(self, 'ventilator_count_source', expand = True) if (self.ventilator_count_source == 'CUSTOM'): self.draw_component_count_params(layout) @@ -551,16 +554,20 @@ class BBP_OT_add_sector_component_pair(bpy.types.Operator, ComponentSectorParam) layout = self.layout self.draw_component_sector_params(layout) + # fetch warning string + tr_text: str = bpy.app.translations.pgettext_iface( + 'Warning: {0} already exist.', 'BBP_OT_add_sector_component_pair/draw') + # check checkpoint and resetpoint name conflict and show warnings (checkp_ty, checkp_sector) = self.__get_checkpoint() elename: str | None = _check_component_existance(checkp_ty, checkp_sector) if elename is not None: - layout.label(text = f'Warning: {elename} already exist.') + layout.label(text=tr_text.format(elename), translate=False) (resetp_ty, resetp_sector) = self.__get_resetpoint() elename = _check_component_existance(resetp_ty, resetp_sector) if elename is not None: - layout.label(text = f'Warning: {elename} already exist.') + layout.label(text=tr_text.format(elename), translate=False) def execute(self, context): # create checkpoint and resetpoint individually in element context diff --git a/bbp_ng/OP_ADDS_rail.py b/bbp_ng/OP_ADDS_rail.py index ccbc4c2..1a46bc2 100644 --- a/bbp_ng/OP_ADDS_rail.py +++ b/bbp_ng/OP_ADDS_rail.py @@ -62,15 +62,15 @@ class SharedExtraTransform(): def draw_extra_transform_input(self, layout: bpy.types.UILayout) -> None: # show extra transform props # forcely order that each one are placed horizontally - layout.label(text = "Extra Transform") + layout.label(text="Extra Transform", text_ctxt='BBP/OP_ADDS_rail.SharedExtraTransform/draw') # translation - layout.label(text = 'Translation') + layout.label(text='Translation', text_ctxt='BBP/OP_ADDS_rail.SharedExtraTransform/draw') row = layout.row() - row.prop(self, 'extra_translation', text = '') + row.prop(self, 'extra_translation', text='') # rotation - layout.label(text = 'Rotation') + layout.label(text='Rotation', text_ctxt='BBP/OP_ADDS_rail.SharedExtraTransform/draw') row = layout.row() - row.prop(self, 'extra_rotation', text = '') + row.prop(self, 'extra_rotation', text='') def general_get_extra_transform(self) -> mathutils.Matrix: return mathutils.Matrix.LocRotScale( @@ -124,7 +124,7 @@ class SharedRailCapInputProperty(): ) # type: ignore def draw_rail_cap_input(self, layout: bpy.types.UILayout) -> None: - layout.label(text = "Cap Options") + layout.label(text="Cap Options", text_ctxt='BBP/OP_ADDS_rail.SharedRailCapInputProperty/draw') row = layout.row() row.prop(self, "rail_start_cap", toggle = 1) row.prop(self, "rail_end_cap", toggle = 1) @@ -209,7 +209,7 @@ class SharedScrewRailInputProperty(): def draw_screw_rail_flip_input(self, layout: bpy.types.UILayout) -> None: # flip options should placed horizontally - layout.label(text = "Flip Options") + layout.label(text="Flip Options", text_ctxt='BBP/OP_ADDS_rail.SharedScrewRailInputProperty/draw') row = layout.row() row.prop(self, "rail_screw_flip_x", toggle = 1) row.prop(self, "rail_screw_flip_y", toggle = 1) @@ -263,7 +263,7 @@ class BBP_OT_add_transition_section(bpy.types.Operator): def draw(self, context): layout = self.layout - layout.label(text = 'No Options Available') + layout.label(text='No Options Available', text_ctxt='BBP_OT_add_transition_section/draw') class BBP_OT_add_straight_rail(SharedExtraTransform, SharedRailSectionInputProperty, SharedRailCapInputProperty, SharedStraightRailInputProperty, bpy.types.Operator): """Add Straight Rail""" @@ -286,7 +286,7 @@ class BBP_OT_add_straight_rail(SharedExtraTransform, SharedRailSectionInputPrope def draw(self, context): layout = self.layout - layout.label(text = 'Straight Rail') + layout.label(text='Straight Rail', text_ctxt='BBP_OT_add_straight_rail/draw') self.draw_rail_section_input(layout) self.draw_straight_rail_input(layout) layout.separator() @@ -315,7 +315,7 @@ class BBP_OT_add_transition_rail(SharedExtraTransform, SharedRailCapInputPropert def draw(self, context): layout = self.layout - layout.label(text = 'Transition Rail') + layout.label(text='Transition Rail', text_ctxt='BBP_OT_add_transition_rail/draw') self.draw_straight_rail_input(layout) layout.separator() self.draw_rail_cap_input(layout) @@ -355,7 +355,7 @@ class BBP_OT_add_side_rail(SharedExtraTransform, SharedRailCapInputProperty, Sha def draw(self, context): layout = self.layout - layout.label(text = 'Side Rail') + layout.label(text='Side Rail', text_ctxt='BBP_OT_add_side_rail/draw') layout.prop(self, 'side_rail_type') self.draw_straight_rail_input(layout) layout.separator() @@ -395,7 +395,7 @@ class BBP_OT_add_arc_rail(SharedExtraTransform, SharedRailSectionInputProperty, def draw(self, context): layout = self.layout - layout.label(text = 'Arc Rail') + layout.label(text='Arc Rail', text_ctxt='BBP_OT_add_arc_rail/draw') self.draw_rail_section_input(layout) self.draw_screw_rail_input(layout) layout.prop(self, "rail_screw_angle") @@ -445,7 +445,7 @@ class BBP_OT_add_spiral_rail(SharedExtraTransform, SharedRailCapInputProperty, S def draw(self, context): layout = self.layout - layout.label(text = 'Spiral Rail') + layout.label(text='Spiral Rail', text_ctxt='BBP_OT_add_spiral_rail/draw') self.draw_screw_rail_input(layout) layout.prop(self, "rail_screw_screw") layout.prop(self, "rail_screw_iterations") @@ -489,7 +489,7 @@ class BBP_OT_add_side_spiral_rail(SharedExtraTransform, SharedRailSectionInputPr def draw(self, context): layout = self.layout - layout.label(text = 'Spiral Rail') + layout.label(text='Spiral Rail', text_ctxt='BBP_OT_add_side_spiral_rail/draw') self.draw_screw_rail_input(layout) layout.prop(self, "rail_screw_iterations") layout.separator() diff --git a/bbp_ng/OP_EXPORT_virtools.py b/bbp_ng/OP_EXPORT_virtools.py index cb43744..c78e363 100644 --- a/bbp_ng/OP_EXPORT_virtools.py +++ b/bbp_ng/OP_EXPORT_virtools.py @@ -79,7 +79,9 @@ def _export_virtools( # create temp folder with tempfile.TemporaryDirectory() as vt_temp_folder: - print(f'Virtools Engine Temp: {vt_temp_folder}') + tr_text: str = bpy.app.translations.pgettext_rpt( + 'Virtools Engine Temporary Directory: {0}', 'BBP_OT_export_virtools/execute') + print(tr_text.format(vt_temp_folder)) # create virtools reader context with bmap.BMFileWriter( diff --git a/bbp_ng/OP_IMPORT_virtools.py b/bbp_ng/OP_IMPORT_virtools.py index ca9d2ad..193da2c 100644 --- a/bbp_ng/OP_IMPORT_virtools.py +++ b/bbp_ng/OP_IMPORT_virtools.py @@ -43,7 +43,9 @@ class BBP_OT_import_virtools(bpy.types.Operator, UTIL_file_browser.ImportVirtool def _import_virtools(file_name_: str, encodings_: tuple[str], resolver: UTIL_ioport_shared.ConflictResolver) -> None: # create temp folder with tempfile.TemporaryDirectory() as vt_temp_folder: - print(f'Virtools Engine Temp: {vt_temp_folder}') + tr_text: str = bpy.app.translations.pgettext_rpt( + 'Virtools Engine Temporary Directory: {0}', 'BBP_OT_import_virtools/execute') + print(tr_text.format(vt_temp_folder)) # create virtools reader context with bmap.BMFileReader( @@ -82,7 +84,9 @@ def _import_virtools_textures( # create another temp folder for raw data virtools texture importing with tempfile.TemporaryDirectory() as rawdata_temp: - print(f'Texture Raw Data Temp: {rawdata_temp}') + tr_text: str = bpy.app.translations.pgettext_rpt( + 'Texture Raw Data Temporary Directory: {0}', 'BBP_OT_import_virtools/execute') + print(tr_text.format(rawdata_temp)) for vttexture in reader.get_textures(): tex_cret: typing.Callable[[], bpy.types.Image] diff --git a/bbp_ng/OP_MTL_fix_material.py b/bbp_ng/OP_MTL_fix_material.py index c8edaac..b2cc122 100644 --- a/bbp_ng/OP_MTL_fix_material.py +++ b/bbp_ng/OP_MTL_fix_material.py @@ -30,7 +30,9 @@ class BBP_OT_fix_all_material(bpy.types.Operator): counter_suc += 1 # report and return - self.report({'INFO'}, f'Fix {counter_suc}/{counter_all} materials.') + tr_text: str = bpy.app.translations.pgettext_rpt( + 'Fix {0}/{1} materials.', 'BBP_OT_fix_all_material/draw') + self.report({'INFO'}, tr_text.format(counter_suc, counter_all)) return {'FINISHED'} def register() -> None: diff --git a/bbp_ng/OP_OBJECT_legacy_align.py b/bbp_ng/OP_OBJECT_legacy_align.py index e60ab44..be99b34 100644 --- a/bbp_ng/OP_OBJECT_legacy_align.py +++ b/bbp_ng/OP_OBJECT_legacy_align.py @@ -112,22 +112,22 @@ class BBP_OT_legacy_align(bpy.types.Operator): return None apply_flag: bpy.props.BoolProperty( - name = "Apply Flag", - description = "Internal flag.", + # TR: Property not showen should not have name and desc. + # name = "Apply Flag", + # description = "Internal flag.", options = {'HIDDEN', 'SKIP_SAVE'}, default = True, # default True value to make it as a "light" button, not a grey one. - update = apply_flag_updated, - translation_context = 'BBP_OT_legacy_align/property' + update = apply_flag_updated ) # type: ignore recursive_hinder: bpy.props.BoolProperty( - # TR: internal used property should not have name and description, otherwise it will be translated. + # TR: Property not showen should not have name and desc. # name = "Recursive Hinder", # description = "An internal flag to prevent the loop calling to apply_flags's updator.", options = {'HIDDEN', 'SKIP_SAVE'}, default = False ) # type: ignore align_history : bpy.props.CollectionProperty( - # TR: same reason for no name and description. + # TR: Property not showen should not have name and desc. # name = "Historys", # description = "Align history.", type = BBP_PG_legacy_align_history @@ -179,7 +179,7 @@ class BBP_OT_legacy_align(bpy.types.Operator): col = layout.column() # show axis - col.label(text="Align Axis (Multi-selection)") + col.label(text="Align Axis (Multi-selection)", text_ctxt='BBP_OT_legacy_align/draw') row = col.row() row.prop(entry, "align_x", toggle = 1) row.prop(entry, "align_y", toggle = 1) @@ -187,9 +187,9 @@ class BBP_OT_legacy_align(bpy.types.Operator): # show mode col.separator() - col.label(text = 'Current Object (Active Object)') + col.label(text='Current Object (Active Object)', text_ctxt='BBP_OT_legacy_align/draw') col.prop(entry, "current_align_mode", expand = True) - col.label(text = 'Target Objects (Selected Objects)') + col.label(text='Target Objects (Selected Objects)', text_ctxt='BBP_OT_legacy_align/draw') col.prop(entry, "target_align_mode", expand = True) # show apply button @@ -198,8 +198,10 @@ class BBP_OT_legacy_align(bpy.types.Operator): # only allow Apply when there is a selected axis conditional_disable_area.enabled = entry.align_x == True or entry.align_y == True or entry.align_z == True # show apply and counter - conditional_disable_area.prop(self, 'apply_flag', text = 'Apply', icon = 'CHECKMARK', toggle = 1) - conditional_disable_area.label(text = f'Total {len(histories) - 1} applied alignments') + conditional_disable_area.prop(self, 'apply_flag', toggle = 1, text='Apply', icon='CHECKMARK', text_ctxt='BBP_OT_legacy_align/draw') + tr_text: str = bpy.app.translations.pgettext_iface( + 'Total {0} applied alignments', 'BBP_OT_legacy_align/draw') + conditional_disable_area.label(text=tr_text.format(len(histories) - 1), translate=False) #region Core Functions diff --git a/bbp_ng/OP_OBJECT_naming_convention.py b/bbp_ng/OP_OBJECT_naming_convention.py index d49f6a2..e34685c 100644 --- a/bbp_ng/OP_OBJECT_naming_convention.py +++ b/bbp_ng/OP_OBJECT_naming_convention.py @@ -82,11 +82,14 @@ def _rename_core( reporter.leave_object(obj) # report data + tr_text_1: str = bpy.app.translations.pgettext_rpt('View console to get more detail', 'BBP/OP_OBJECT_naming_convention._rename_core()') + tr_text_2: str = bpy.app.translations.pgettext_rpt('All: {0}', 'BBP/OP_OBJECT_naming_convention._rename_core()') + tr_text_3: str = bpy.app.translations.pgettext_rpt('Failed: {0}', 'BBP/OP_OBJECT_naming_convention._rename_core()') UTIL_functions.message_box( ( - 'View console to get more detail', - f'All: {reporter.get_all_objs_count()}', - f'Failed: {reporter.get_failed_objs_count()}' + tr_text_1, + tr_text_2.format(reporter.get_all_objs_count()), + tr_text_3.format(reporter.get_failed_objs_count()) ), 'Rename System Report', UTIL_icons_manager.BlenderPresetIcons.Info.value diff --git a/bbp_ng/OP_OBJECT_virtools_group.py b/bbp_ng/OP_OBJECT_virtools_group.py index 268c28d..a2a007e 100644 --- a/bbp_ng/OP_OBJECT_virtools_group.py +++ b/bbp_ng/OP_OBJECT_virtools_group.py @@ -60,12 +60,12 @@ class BBP_OT_select_object_by_virtools_group(bpy.types.Operator, PROP_virtools_g def draw(self, context): layout = self.layout - layout.label(text='Selection Mode') + layout.label(text='Selection Mode', text_ctxt='BBP_OT_select_object_by_virtools_group/draw') sublayout = layout.column() # make selection expand vertically, not horizontal. sublayout.prop(self, 'selection_mode', expand = True) layout.separator() - layout.label(text='Group Parameters') + layout.label(text='Group Parameters', text_ctxt='BBP_OT_select_object_by_virtools_group/draw') self.draw_group_name_input(layout) def _select_object_by_virtools_group(context: bpy.types.Context, group_name: str, mode: SelectMode) -> None: diff --git a/bbp_ng/OP_UV_flatten_uv.py b/bbp_ng/OP_UV_flatten_uv.py index 1d354fe..9f437de 100644 --- a/bbp_ng/OP_UV_flatten_uv.py +++ b/bbp_ng/OP_UV_flatten_uv.py @@ -171,24 +171,26 @@ class BBP_OT_flatten_uv(bpy.types.Operator): # do flatten uv and report failed: int = _flatten_uv_wrapper(context.active_object.data, flatten_param_) if failed != 0: - print(f'[Flatten UV] {failed} faces are not be processed correctly because process failed.') + tr_text: str = bpy.app.translations.pgettext_rpt( + '[Flatten UV] {0} faces are not be processed correctly because process failed.', 'BBP_OT_flatten_uv/execute') + print(tr_text.format(failed)) return {'FINISHED'} def draw(self, context): layout = self.layout layout.emboss = 'NORMAL' - layout.label(text = "Flatten Method") + layout.label(text="Flatten Method", text_ctxt='BBP_OT_flatten_uv/draw') sublayout = layout.row() sublayout.prop(self, "flatten_method", expand = True) layout.prop(self, "reference_edge") layout.separator() - layout.label(text = "Scale Mode") + layout.label(text="Scale Mode", text_ctxt='BBP_OT_flatten_uv/draw') sublayout = layout.row() sublayout.prop(self, "scale_mode", expand = True) layout.separator() - layout.label(text = "Scale Config") + layout.label(text="Scale Configuration", text_ctxt='BBP_OT_flatten_uv/draw') if self.scale_mode == 'NUM': layout.prop(self, "scale_number") else: diff --git a/bbp_ng/OP_UV_rail_uv.py b/bbp_ng/OP_UV_rail_uv.py index 3f51f77..d68ecac 100644 --- a/bbp_ng/OP_UV_rail_uv.py +++ b/bbp_ng/OP_UV_rail_uv.py @@ -76,8 +76,12 @@ def _get_rail_target(context: bpy.types.Context) -> tuple[bool, typing.Iterable[ if has_invalid_objs: # output to console print('') - print('========== Rail UV Report ==========') - print('Following objects are not processed by Rail UV because they do not meet the requirements of Rail UV.') + tr_text: str = bpy.app.translations.pgettext_rpt('Rail UV Report', 'BBP_OT_rail_uv/execute') + print(f'========== {tr_text} ==========') + print(bpy.app.translations.pgettext_rpt( + 'Following objects are not processed by Rail UV because they do not meet the requirements of Rail UV.', + 'BBP_OT_rail_uv/execute' + )) for objname in error_objname: print(objname) print('') diff --git a/bbp_ng/PROP_preferences.py b/bbp_ng/PROP_preferences.py index ad7eb53..3473c64 100644 --- a/bbp_ng/PROP_preferences.py +++ b/bbp_ng/PROP_preferences.py @@ -39,9 +39,9 @@ class BBPPreferences(bpy.types.AddonPreferences): row = layout.row() col = row.column() - col.label(text = "Ballance Texture Folder") + col.label(text="Ballance Texture Folder", text_ctxt='BBPPreferences/draw') col.prop(self, "ballance_texture_folder", text = "") - col.label(text = "No Component Collection") + col.label(text="No Component Collection", text_ctxt='BBPPreferences/draw') col.prop(self, "no_component_collection", text = "") def get_preferences() -> BBPPreferences: diff --git a/bbp_ng/PROP_ptrprop_resolver.py b/bbp_ng/PROP_ptrprop_resolver.py index 305d820..9c4b151 100644 --- a/bbp_ng/PROP_ptrprop_resolver.py +++ b/bbp_ng/PROP_ptrprop_resolver.py @@ -12,6 +12,7 @@ from . import UTIL_functions, UTIL_virtools_types class BBP_PG_bmap_encoding(bpy.types.PropertyGroup): encoding: bpy.props.StringProperty( name = "Encoding", + description = "The name of BMap used encoding.", default = "", translation_context = 'BBP_PG_bmap_encoding/property' ) # type: ignore @@ -42,7 +43,7 @@ class BBP_PG_ptrprop_resolver(bpy.types.PropertyGroup): translation_context = 'BBP_PG_ptrprop_resolver/property' ) # type: ignore - # TR: These encoding related items should not have explicit name and description + # TR: Properties not showen should not have name and desc. ioport_encodings: bpy.props.CollectionProperty(type = BBP_PG_bmap_encoding) # type: ignore active_ioport_encodings: bpy.props.IntProperty() # type: ignore diff --git a/bbp_ng/PROP_virtools_group.py b/bbp_ng/PROP_virtools_group.py index 6f04d7d..2c681a7 100644 --- a/bbp_ng/PROP_virtools_group.py +++ b/bbp_ng/PROP_virtools_group.py @@ -252,21 +252,21 @@ class SharedGroupNameInputProperties(): ('DEFINED', "Predefined", "Pre-defined group name."), ('CUSTOM', "Custom", "User specified group name."), ), - translation_context = 'BME/PROP_virtools_grourp.SharedGroupNameInputProperties/property' + translation_context = 'BBP/PROP_virtools_grourp.SharedGroupNameInputProperties/property' ) # type: ignore preset_group_name: bpy.props.EnumProperty( name = "Group Name", description = "Pick vanilla Ballance group name.", items = _g_EnumHelper_Group.generate_items(), - translation_context = 'BME/PROP_virtools_grourp.SharedGroupNameInputProperties/property' + translation_context = 'BBP/PROP_virtools_grourp.SharedGroupNameInputProperties/property' ) # type: ignore custom_group_name: bpy.props.StringProperty( name = "Custom Group Name", description = "Input your custom group name.", default = "", - translation_context = 'BME/PROP_virtools_grourp.SharedGroupNameInputProperties/property' + translation_context = 'BBP/PROP_virtools_grourp.SharedGroupNameInputProperties/property' ) # type: ignore def draw_group_name_input(self, layout: bpy.types.UILayout) -> None: @@ -388,7 +388,9 @@ class BBP_PT_virtools_groups(bpy.types.Panel): # notify on non-mesh object if target.type != 'MESH': - layout.label(text = 'Virtools Group is invalid on non-mesh object!', icon = 'ERROR') + layout.label( + text='Virtools Group is invalid on non-mesh object!', icon='ERROR', + text_ctxt='BBP_PT_virtools_groups/draw') # draw main body row = layout.row() diff --git a/bbp_ng/PROP_virtools_light.py b/bbp_ng/PROP_virtools_light.py index 4b9de4a..6ac6b32 100644 --- a/bbp_ng/PROP_virtools_light.py +++ b/bbp_ng/PROP_virtools_light.py @@ -283,11 +283,13 @@ class BBP_PT_virtools_light(bpy.types.Panel): rawdata: RawVirtoolsLight = get_raw_virtools_light(lit) # draw operator - layout.operator(BBP_OT_apply_virtools_light.bl_idname, text = 'Apply', icon = 'NODETREE') + layout.operator( + BBP_OT_apply_virtools_light.bl_idname, text='Apply', icon='NODETREE', + text_ctxt='BBP_PT_virtools_light/draw') # draw data layout.separator() - layout.label(text = 'Basics') + layout.label(text='Basics', text_ctxt='BBP_PT_virtools_light/draw') # all lights has type and color property sublayout = layout.row() sublayout.use_property_split = False @@ -300,15 +302,15 @@ class BBP_PT_virtools_light(bpy.types.Panel): # all light has attenuation exception directional light if rawdata.mType != UTIL_virtools_types.VXLIGHT_TYPE.VX_LIGHTDIREC: layout.separator() - layout.label(text = 'Attenuation') - layout.prop(props, 'constant_attenuation', text = 'Constant') - layout.prop(props, 'linear_attenuation', text = 'Linear') - layout.prop(props, 'quadratic_attenuation', text = 'Quadratic') + layout.label(text='Attenuation', text_ctxt='BBP_PT_virtools_light/draw') + layout.prop(props, 'constant_attenuation', text='Constant', text_ctxt='BBP_PT_virtools_light/draw') + layout.prop(props, 'linear_attenuation', text='Linear', text_ctxt='BBP_PT_virtools_light/draw') + layout.prop(props, 'quadratic_attenuation', text='Quadratic', text_ctxt='BBP_PT_virtools_light/draw') # only spot light has spot cone properties. if rawdata.mType == UTIL_virtools_types.VXLIGHT_TYPE.VX_LIGHTSPOT: layout.separator() - layout.label(text = 'Spot Cone') + layout.label(text='Spot Cone', text_ctxt='BBP_PT_virtools_light/draw') layout.prop(props, 'hot_spot') layout.prop(props, 'falloff') layout.prop(props, 'falloff_shape') diff --git a/bbp_ng/PROP_virtools_material.py b/bbp_ng/PROP_virtools_material.py index 61029ef..20e5233 100644 --- a/bbp_ng/PROP_virtools_material.py +++ b/bbp_ng/PROP_virtools_material.py @@ -907,7 +907,7 @@ class BBP_OT_apply_virtools_material(bpy.types.Operator): return context.material is not None def execute(self, context): - mtl: bpy.types.Material = context.material + mtl = typing.cast(bpy.types.Material, context.material) apply_to_blender_material(mtl) return {'FINISHED'} @@ -930,7 +930,7 @@ class BBP_OT_fix_single_material(bpy.types.Operator): def execute(self, context): # get mtl and try to fix - mtl: bpy.types.Material = context.material + mtl = typing.cast(bpy.types.Material, context.material) ret: bool = fix_material(mtl) # if suc, apply to blender mtl and show info @@ -969,7 +969,7 @@ class BBP_OT_preset_virtools_material(bpy.types.Operator): def execute(self, context): # get essential value - mtl: bpy.types.Material = context.material + mtl = typing.cast(bpy.types.Material, context.material) expected_preset: MaterialPresetType = _g_Helper_MtlPreset.get_selection(self.preset_type) # apply preset to material @@ -982,7 +982,7 @@ class BBP_OT_direct_set_virtools_texture(bpy.types.Operator, UTIL_file_browser.I """Import and Assign Texture Directly""" bl_idname = "bbp.direct_set_virtools_texture" bl_label = "Import and Assign Texture" - bl_options = {'UNDO'} + bl_options = {'UNDO', 'INTERNAL'} # NOTE: Use 'INTERNAL' to remove it from search result. bl_translation_context = 'BBP_OT_direct_set_virtools_texture' @classmethod @@ -1004,7 +1004,7 @@ class BBP_OT_direct_set_virtools_texture(bpy.types.Operator, UTIL_file_browser.I def execute(self, context): # get assoc mtl - mtl: bpy.types.Material = context.material + mtl = typing.cast(bpy.types.Material, context.material) rawmtl: RawVirtoolsMaterial = get_raw_virtools_material(mtl) # import texture according to whether it is ballance texture @@ -1045,18 +1045,22 @@ class BBP_PT_virtools_material(bpy.types.Panel): def draw(self, context): # get layout and target layout = self.layout - mtl: bpy.types.Material = context.material + mtl = typing.cast(bpy.types.Material, context.material) props: BBP_PG_virtools_material = get_virtools_material(mtl) rawdata: RawVirtoolsMaterial = get_raw_virtools_material(mtl) # draw operator row = layout.row() - row.operator(BBP_OT_preset_virtools_material.bl_idname, text = 'Preset', icon = "PRESET") - row.operator(BBP_OT_apply_virtools_material.bl_idname, text = 'Apply', icon = "NODETREE") - row.operator(BBP_OT_fix_single_material.bl_idname, text = '', icon = "MODIFIER") + row.operator( + BBP_OT_preset_virtools_material.bl_idname, text='Preset', icon = "PRESET", + text_ctxt='BBP_PT_virtools_material/draw') + row.operator( + BBP_OT_apply_virtools_material.bl_idname, text='Apply', icon = "NODETREE", + text_ctxt='BBP_PT_virtools_material/draw') + row.operator(BBP_OT_fix_single_material.bl_idname, text='', icon = "MODIFIER") # draw data - layout.label(text="Color Parameters") + layout.label(text="Color Parameters", text_ctxt='BBP_PT_virtools_material/draw') layout.prop(props, 'ambient') layout.prop(props, 'diffuse') layout.prop(props, 'specular') @@ -1064,22 +1068,22 @@ class BBP_PT_virtools_material(bpy.types.Panel): layout.prop(props, 'specular_power') layout.separator() - layout.label(text="Mode Parameters") + layout.label(text="Mode Parameters", text_ctxt='BBP_PT_virtools_material/draw') layout.prop(props, 'enable_two_sided') layout.prop(props, 'fill_mode') layout.prop(props, 'shade_mode') layout.separator() - layout.label(text="Texture Parameters") + layout.label(text="Texture Parameters", text_ctxt='BBP_PT_virtools_material/draw') # texture prop with direct importing sublay = layout.row() sublay.prop(props, 'texture', emboss = True) - sublay.operator(BBP_OT_direct_set_virtools_texture.bl_idname, text = '', icon = 'FILEBROWSER') + sublay.operator(BBP_OT_direct_set_virtools_texture.bl_idname, text='', icon='FILEBROWSER') # texture detail if rawdata.mTexture is not None: # have texture, show texture settings and enclosed by a border. boxlayout = layout.box() - boxlayout.label(text="Virtools Texture Settings") + boxlayout.label(text="Virtools Texture Settings", text_ctxt='BBP_PT_virtools_material/draw') PROP_virtools_texture.draw_virtools_texture(props.texture, boxlayout) layout.prop(props, 'texture_blend_mode') @@ -1091,21 +1095,21 @@ class BBP_PT_virtools_material(bpy.types.Panel): layout.prop(props, 'texture_border_color') layout.separator() - layout.label(text="Alpha Test Parameters") + layout.label(text="Alpha Test Parameters", text_ctxt='BBP_PT_virtools_material/draw') layout.prop(props, 'enable_alpha_test') if rawdata.mEnableAlphaTest: layout.prop(props, 'alpha_func') layout.prop(props, 'alpha_ref') layout.separator() - layout.label(text="Alpha Blend Parameters") + layout.label(text="Alpha Blend Parameters", text_ctxt='BBP_PT_virtools_material/draw') layout.prop(props, 'enable_alpha_blend') if rawdata.mEnableAlphaBlend: layout.prop(props, 'source_blend') layout.prop(props, 'dest_blend') layout.separator() - layout.label(text="Z Write Parameters") + layout.label(text="Z Write Parameters", text_ctxt='BBP_PT_virtools_material/draw') layout.prop(props, 'enable_z_write') if rawdata.mEnableZWrite: layout.prop(props, 'z_func') diff --git a/bbp_ng/UTIL_file_browser.py b/bbp_ng/UTIL_file_browser.py index c0429dd..0afdbac 100644 --- a/bbp_ng/UTIL_file_browser.py +++ b/bbp_ng/UTIL_file_browser.py @@ -88,7 +88,7 @@ class ExportVirtoolsFile(bpy_extras.io_utils.ExportHelper): class ImportDirectory(bpy_extras.io_utils.ImportHelper): # add directory prop to receive directory - directory: bpy.props.StringProperty() + directory: bpy.props.StringProperty() # type: ignore # blank filter filter_glob: bpy.props.StringProperty( diff --git a/bbp_ng/UTIL_ioport_shared.py b/bbp_ng/UTIL_ioport_shared.py index cb73a60..a426d19 100644 --- a/bbp_ng/UTIL_ioport_shared.py +++ b/bbp_ng/UTIL_ioport_shared.py @@ -159,7 +159,7 @@ class ImportParams(): items = _g_EnumHelper_ConflictStrategy.generate_items(), description = "Define how to process texture name conflict", default = _g_EnumHelper_ConflictStrategy.to_selection(ConflictStrategy.Current), - translation_context = 'BME/UTIL_ioport_shared.ImportParams/property' + translation_context = 'BBP/UTIL_ioport_shared.ImportParams/property' ) # type: ignore material_conflict_strategy: bpy.props.EnumProperty( @@ -167,7 +167,7 @@ class ImportParams(): items = _g_EnumHelper_ConflictStrategy.generate_items(), description = "Define how to process material name conflict", default = _g_EnumHelper_ConflictStrategy.to_selection(ConflictStrategy.Rename), - translation_context = 'BME/UTIL_ioport_shared.ImportParams/property' + translation_context = 'BBP/UTIL_ioport_shared.ImportParams/property' ) # type: ignore mesh_conflict_strategy: bpy.props.EnumProperty( @@ -175,7 +175,7 @@ class ImportParams(): items = _g_EnumHelper_ConflictStrategy.generate_items(), description = "Define how to process mesh name conflict", default = _g_EnumHelper_ConflictStrategy.to_selection(ConflictStrategy.Rename), - translation_context = 'BME/UTIL_ioport_shared.ImportParams/property' + translation_context = 'BBP/UTIL_ioport_shared.ImportParams/property' ) # type: ignore light_conflict_strategy: bpy.props.EnumProperty( @@ -183,7 +183,7 @@ class ImportParams(): items = _g_EnumHelper_ConflictStrategy.generate_items(), description = "Define how to process light name conflict", default = _g_EnumHelper_ConflictStrategy.to_selection(ConflictStrategy.Rename), - translation_context = 'BME/UTIL_ioport_shared.ImportParams/property' + translation_context = 'BBP/UTIL_ioport_shared.ImportParams/property' ) # type: ignore object_conflict_strategy: bpy.props.EnumProperty( @@ -191,28 +191,29 @@ class ImportParams(): items = _g_EnumHelper_ConflictStrategy.generate_items(), description = "Define how to process object name conflict", default = _g_EnumHelper_ConflictStrategy.to_selection(ConflictStrategy.Rename), - translation_context = 'BME/UTIL_ioport_shared.ImportParams/property' + translation_context = 'BBP/UTIL_ioport_shared.ImportParams/property' ) # type: ignore def draw_import_params(self, layout: bpy.types.UILayout) -> None: header: bpy.types.UILayout body: bpy.types.UILayout header, body = layout.panel("BBP_PT_ioport_shared_import_params", default_closed=False) - header.label(text = 'Import Parameters') + header.label(text='Import Parameters', text_ctxt='BBP/UTIL_ioport_shared.ImportParams/draw') + # NOTE: if panel is collapsed, body will be None. So we need check it. if body is None: return - body.label(text = 'Name Conflict Strategy') - grid = body.grid_flow(row_major = False, columns = 2) - grid.label(text = 'Object', icon = 'CUBE') - grid.label(text = 'Light', icon = 'LIGHT') - grid.label(text = 'Mesh', icon = 'MESH_DATA') - grid.label(text = 'Material', icon = 'MATERIAL') - grid.label(text = 'Texture', icon = 'TEXTURE') - grid.prop(self, 'object_conflict_strategy', text = '') - grid.prop(self, 'light_conflict_strategy', text = '') - grid.prop(self, 'mesh_conflict_strategy', text = '') - grid.prop(self, 'material_conflict_strategy', text = '') - grid.prop(self, 'texture_conflict_strategy', text = '') + body.label(text='Name Conflict Strategy', text_ctxt='BBP/UTIL_ioport_shared.ImportParams/draw') + grid = body.grid_flow(row_major=False, columns=2) + grid.label(text='Object', icon='CUBE', text_ctxt='BBP/UTIL_ioport_shared.ImportParams/draw') + grid.label(text='Light', icon='LIGHT', text_ctxt='BBP/UTIL_ioport_shared.ImportParams/draw') + grid.label(text='Mesh', icon='MESH_DATA', text_ctxt='BBP/UTIL_ioport_shared.ImportParams/draw') + grid.label(text='Material', icon='MATERIAL', text_ctxt='BBP/UTIL_ioport_shared.ImportParams/draw') + grid.label(text='Texture', icon='TEXTURE', text_ctxt='BBP/UTIL_ioport_shared.ImportParams/draw') + grid.prop(self, 'object_conflict_strategy', text='') + grid.prop(self, 'light_conflict_strategy', text='') + grid.prop(self, 'mesh_conflict_strategy', text='') + grid.prop(self, 'material_conflict_strategy', text='') + grid.prop(self, 'texture_conflict_strategy', text='') def general_get_texture_conflict_strategy(self) -> ConflictStrategy: return _g_EnumHelper_ConflictStrategy.get_selection(self.texture_conflict_strategy) @@ -245,20 +246,20 @@ class ExportParams(): ('COLLECTION', "Collection", "Export a collection", 'OUTLINER_COLLECTION', 0), ('OBJECT', "Object", "Export an object", 'OBJECT_DATA', 1), ), - translation_context = 'BME/UTIL_ioport_shared.ExportParams/property' + translation_context = 'BBP/UTIL_ioport_shared.ExportParams/property' ) # type: ignore def draw_export_params(self, context: bpy.types.Context, layout: bpy.types.UILayout) -> None: header: bpy.types.UILayout body: bpy.types.UILayout header, body = layout.panel("BBP_PT_ioport_shared_export_params", default_closed=False) - header.label(text = 'Export Parameters') + header.label(text='Export Parameters', text_ctxt='BBP/UTIL_ioport_shared.ExportParams/draw') if body is None: return # make prop expand horizontaly, not vertical. horizon_body = body.row() # draw switch - horizon_body.prop(self, "export_mode", expand = True) + horizon_body.prop(self, "export_mode", expand=True) # draw picker ptrprops = PROP_ptrprop_resolver.PropsVisitor(context.scene) @@ -291,14 +292,14 @@ class VirtoolsParams(): description = "Decide how texture saved if texture is specified as Use Global as its Save Options.", items = _g_EnumHelper_CK_TEXTURE_SAVEOPTIONS.generate_items(), default = _g_EnumHelper_CK_TEXTURE_SAVEOPTIONS.to_selection(UTIL_virtools_types.CK_TEXTURE_SAVEOPTIONS.CKTEXTURE_EXTERNAL), - translation_context = 'BME/UTIL_ioport_shared.VirtoolsParams/property' + translation_context = 'BBP/UTIL_ioport_shared.VirtoolsParams/property' ) # type: ignore use_compress: bpy.props.BoolProperty( name="Use Compress", description = "Whether use ZLib to compress result when saving composition.", default = True, - translation_context = 'BME/UTIL_ioport_shared.VirtoolsParams/property' + translation_context = 'BBP/UTIL_ioport_shared.VirtoolsParams/property' ) # type: ignore compress_level: bpy.props.IntProperty( @@ -306,29 +307,29 @@ class VirtoolsParams(): description = "The ZLib compress level used by Virtools Engine when saving composition.", min = 1, max = 9, default = 5, - translation_context = 'BME/UTIL_ioport_shared.VirtoolsParams/property' + translation_context = 'BBP/UTIL_ioport_shared.VirtoolsParams/property' ) # type: ignore def draw_virtools_params(self, context: bpy.types.Context, layout: bpy.types.UILayout, is_importer: bool) -> None: header: bpy.types.UILayout body: bpy.types.UILayout header, body = layout.panel("BBP_PT_ioport_shared_virtools_params", default_closed=False) - header.label(text = 'Virtools Parameters') + header.label(text='Virtools Parameters', text_ctxt='BBP/UTIL_ioport_shared.VirtoolsParams/draw') if body is None: return # draw encodings - body.label(text = 'Encodings') + body.label(text='Encodings', text_ctxt='BBP/UTIL_ioport_shared.VirtoolsParams/draw') ptrprops = PROP_ptrprop_resolver.PropsVisitor(context.scene) ptrprops.draw_ioport_encodings(body) # following field are only valid in exporter if not is_importer: body.separator() - body.label(text = 'Global Texture Save Options') - body.prop(self, 'texture_save_opt', text = '') + body.label(text='Global Texture Save Options', text_ctxt='BBP/UTIL_ioport_shared.VirtoolsParams/draw') + body.prop(self, 'texture_save_opt', text='') body.separator() - body.label(text = 'Compression') + body.label(text='Compression', text_ctxt='BBP/UTIL_ioport_shared.VirtoolsParams/draw') body.prop(self, 'use_compress') if self.use_compress: body.prop(self, 'compress_level') @@ -353,7 +354,7 @@ class BallanceParams(): name="Successive Sector", description = "Whether order exporter to use document specified sector count to make sure sector is successive.", default = True, - translation_context = 'BME/UTIL_ioport_shared.BallanceParams/property' + translation_context = 'BBP/UTIL_ioport_shared.BallanceParams/property' ) # type: ignore def draw_ballance_params(self, layout: bpy.types.UILayout, is_importer: bool) -> None: @@ -365,12 +366,14 @@ class BallanceParams(): header: bpy.types.UILayout body: bpy.types.UILayout header, body = layout.panel("BBP_PT_ioport_shared_ballance_params", default_closed=False) - header.label(text = 'Ballance Parameters') + header.label(text='Ballance Parameters', text_ctxt='BBP/UTIL_ioport_shared.BallanceParams/draw') if body is None: return map_info: PROP_ballance_map_info.RawBallanceMapInfo = PROP_ballance_map_info.get_raw_ballance_map_info(bpy.context.scene) body.prop(self, 'successive_sector') - body.label(text = f'Map Sectors: {map_info.mSectorCount}') + tr_text: str = bpy.app.translations.pgettext_iface( + 'Map Sectors: {0}', 'BBP/UTIL_ioport_shared.BallanceParams/draw') + body.label(text=tr_text.format(map_info.mSectorCount), translate=False) def general_get_successive_sector(self) -> bool: return self.successive_sector diff --git a/bbp_ng/UTIL_naming_convension.py b/bbp_ng/UTIL_naming_convension.py index ed7e674..f0f7325 100644 --- a/bbp_ng/UTIL_naming_convension.py +++ b/bbp_ng/UTIL_naming_convension.py @@ -70,7 +70,10 @@ class RenameErrorReporter(): def __enter__(self): # print console report header print('============') - print('Rename Report') + print(bpy.app.translations.pgettext_rpt( + 'Rename Report', + 'BBP/UTIL_naming_convension.RenameErrorReporter' + )) print('------------') # return self as context return self @@ -78,7 +81,9 @@ class RenameErrorReporter(): def __exit__(self, exc_type, exc_value, traceback): # print console report tail print('------------') - print(f'All / Failed - {self.mAllObjCounter} / {self.mFailedObjCounter}') + tr_text: str = bpy.app.translations.pgettext_rpt( + 'All / Failed - {0} / {1}', 'BBP/UTIL_naming_convension.RenameErrorReporter') + print(tr_text.format(self.mAllObjCounter, self.mFailedObjCounter)) print('============') # reset variables self.mAllObjCounter = 0 @@ -99,11 +104,14 @@ class RenameErrorReporter(): # output header # if new name is different with old name, output both of them + tr_text: str new_name: str = obj.name if self.mOldName == new_name: - print(f'For object "{new_name}"') + tr_text = bpy.app.translations.pgettext_rpt('For object "{0}"', 'BBP/UTIL_naming_convension.RenameErrorReporter') + print(tr_text.format(new_name)) else: - print(f'For object "{new_name}" (Old name: "{self.mOldName}")') + tr_text = bpy.app.translations.pgettext_rpt('For object "{0}" (Old name: "{1}")', 'BBP/UTIL_naming_convension.RenameErrorReporter') + print(tr_text.format(new_name, self.mOldName)) # output error list with indent for item in self.mErrList: @@ -116,9 +124,12 @@ class RenameErrorReporter(): @staticmethod def __errtype_to_string(err_v: _RenameErrorType) -> str: match(err_v): - case _RenameErrorType.ERROR: return 'ERROR' - case _RenameErrorType.WARNING: return 'WARN' - case _RenameErrorType.INFO: return 'INFO' + case _RenameErrorType.ERROR: + return bpy.app.translations.pgettext_rpt('ERROR', 'BBP/UTIL_naming_convension.RenameErrorReporter') + case _RenameErrorType.WARNING: + return bpy.app.translations.pgettext_rpt('WARN', 'BBP/UTIL_naming_convension.RenameErrorReporter') + case _RenameErrorType.INFO: + return bpy.app.translations.pgettext_rpt('INFO', 'BBP/UTIL_naming_convension.RenameErrorReporter') case _: raise UTIL_functions.BBPException("Unknown error type.") @staticmethod def __erritem_to_string(item: _RenameErrorItem) -> str: diff --git a/bbp_ng/UTIL_translation.py b/bbp_ng/UTIL_translation.py index f1af622..930d899 100644 --- a/bbp_ng/UTIL_translation.py +++ b/bbp_ng/UTIL_translation.py @@ -9,18 +9,21 @@ import bpy # BME module has its own context naming convention which make sure all configuration fields of prototypes are properly translated. # This module also provide a corresponding function to compute these context string from given BME prototype name and the index of configuration fields. # -# For BBP plugin self, there is a priniciple list which you should follow when providing translation context. -# - For operator, menu, panel and etc, set their `bl_translation_context` to their names, such as `BBP_OT_some_operator` -# - For property located in operator, menu, panel and etc, set their `translation_context` to corresponding class name, -# plus `/property` suffix, such as `BBP_OT_some_operator/property`. -# - For draw function located in operator, menu, panel and etc, set their `translation_context` to corresponding class name, -# plus `/draw` suffix, such as `BBP_OT_some_operator/draw`. -# - For property loacted in shared class (usually shared by multiple operators), set their `translation_context` to `BME/./property`. -# `` is the module name (file name) where this class located. `` is the name of this class. -# For example, `BBP/some_module.some_class/property` -# -# Due to the shitty design, I can't find a way to add translation context for descrption field. -# So these description may collide with Blender official translation and thus not put in result file. +# For BBP plugin self, there is a list containing multiple priniciples which you should follow when providing translation context. +# - For operator, menu, panel and etc. +# * For themselves, fill `bl_translation_context` to their name, such as `BBP_OT_some_operator`. +# * For properties located inside, add `/property` suffix, such as `BBP_OT_some_operator/property`. +# * For draw function (any function callings requiring translation context inside it), add `/draw` suffix, such as `BBP_OT_some_operator/draw`. +# * For execute function, or any functions mainly called by this execution function, add `/execute` suffix, such as `BBP_OT_some_operator/execute`. +# - For shared class (usually shared by multiple operators). +# * For themselves (usually not used because they don't have `bl_translation_context`), the default context is `BME/.`, such as `BBP/some_module.some_class`. +# * For properties located inside, add `/property` suffix, such as `BBP/some_module.some_class/property`. +# * For draw function (any function callings requiring translation context inside it), add `/draw` suffix, such as `BBP/some_module.some_class/draw`. +# - For menu draw function (usually defined in __init__ module). +# * For themselves (any calling inside them), the context is `BME/.()`, such as `BBP/some_module.some_method()`. +# +# Due to the shitty design, I can't find a way to add translation context for descrption field and report function used string. +# So these description may collide with Blender official translation, thus they may not be put in result translation file. # I have no idea about this. # # Due to the shitty static analyse ability of Blender I18N plugin, all context should be written in literal, @@ -32,9 +35,18 @@ import bpy # please use `bpy.app.translations.pgettext_rpt()` to get translation message because they are report. # For the string given to `UTIL_functions.message_box()`, please use `bpy.app.translations.pgettext_iface` because they are UI elements. # -# It seema that `bpy.app.translations.pgettext` function family has fatal error when extracting message with context +# `bpy.app.translations.pgettext` function family has fatal error when extracting message with context # (it will produce a correct one and a wrong one which just simply concat the message and its context. I don't know why). -# +# This will happen if you put `bpy.app.translations.pgettext` calling inside `UILayout.label` or any UILayout functions like it. +# `bpy.app.translations.pgettext` will produce the correct entry but Blender used "magic of `UILayout.label` will produce the wrong one. +# It seems that Blender's magic just join the string provided in `text` argument as much as possible. +# So the solution is simple: +# - If we use `bpy.app.translations.pgettext` and `UILayout.label` together +# * Create a variable holding the result of `bpy.app.translations.pgettext`. +# * Format this gotten string if necessary. +# * Call `UILayout.label` and use this variable as its `text` argument. Then set `translated` to False. +# - If we use `bpy.app.translations.pgettext` with other non-Blender functions, such as `print`. +# * Use it as a normal function. # # All translation annotation are started with `TR:` # diff --git a/bbp_ng/UTIL_virtools_types.py b/bbp_ng/UTIL_virtools_types.py index 3c810dd..f7a017d 100644 --- a/bbp_ng/UTIL_virtools_types.py +++ b/bbp_ng/UTIL_virtools_types.py @@ -1,4 +1,4 @@ -import mathutils +import bpy, mathutils import typing, math from . import UTIL_functions @@ -263,7 +263,7 @@ class EnumPropHelper(UTIL_functions.EnumPropHelper): def virtools_name_regulator(name: str | None) -> str: if name: return name - else: return 'annoymous' + else: return bpy.app.translations.pgettext_data('annoymous', 'BME/UTIL_virtools_types.virtools_name_regulator()') ## Default Encoding for PyBMap # Use semicolon split each encodings. Support Western European and Simplified Chinese in default. diff --git a/bbp_ng/__init__.py b/bbp_ng/__init__.py index 1d93c9d..336f0c9 100644 --- a/bbp_ng/__init__.py +++ b/bbp_ng/__init__.py @@ -39,17 +39,17 @@ class BBP_MT_View3DMenu(bpy.types.Menu): def draw(self, context): layout = self.layout - layout.label(text='UV', icon='UV') + layout.label(text='UV', icon='UV', text_ctxt='BBP_MT_View3DMenu/draw') layout.operator(OP_UV_flatten_uv.BBP_OT_flatten_uv.bl_idname) layout.operator(OP_UV_rail_uv.BBP_OT_rail_uv.bl_idname) layout.separator() - layout.label(text='Align', icon='SNAP_ON') + layout.label(text='Align', icon='SNAP_ON', text_ctxt='BBP_MT_View3DMenu/draw') layout.operator(OP_OBJECT_legacy_align.BBP_OT_legacy_align.bl_idname) layout.separator() - layout.label(text='Select', icon='SELECT_SET') + layout.label(text='Select', icon='SELECT_SET', text_ctxt='BBP_MT_View3DMenu/draw') layout.operator(OP_OBJECT_virtools_group.BBP_OT_select_object_by_virtools_group.bl_idname) layout.separator() - layout.label(text='Material', icon='MATERIAL') + layout.label(text='Material', icon='MATERIAL', text_ctxt='BBP_MT_View3DMenu/draw') layout.operator(OP_MTL_fix_material.BBP_OT_fix_all_material.bl_idname) class BBP_MT_AddBmeMenu(bpy.types.Menu): @@ -71,18 +71,18 @@ class BBP_MT_AddRailMenu(bpy.types.Menu): def draw(self, context): layout = self.layout - layout.label(text="Sections", icon='MESH_CIRCLE') + layout.label(text="Sections", icon='MESH_CIRCLE', text_ctxt='BBP_MT_AddRailMenu/draw') layout.operator(OP_ADDS_rail.BBP_OT_add_rail_section.bl_idname) layout.operator(OP_ADDS_rail.BBP_OT_add_transition_section.bl_idname) layout.separator() - layout.label(text="Straight Rails", icon='IPO_CONSTANT') + layout.label(text="Straight Rails", icon='IPO_CONSTANT', text_ctxt='BBP_MT_AddRailMenu/draw') layout.operator(OP_ADDS_rail.BBP_OT_add_straight_rail.bl_idname) layout.operator(OP_ADDS_rail.BBP_OT_add_transition_rail.bl_idname) layout.operator(OP_ADDS_rail.BBP_OT_add_side_rail.bl_idname) layout.separator() - layout.label(text="Curve Rails", icon='MOD_SCREW') + layout.label(text="Curve Rails", icon='MOD_SCREW', text_ctxt='BBP_MT_AddRailMenu/draw') layout.operator(OP_ADDS_rail.BBP_OT_add_arc_rail.bl_idname) layout.operator(OP_ADDS_rail.BBP_OT_add_spiral_rail.bl_idname) layout.operator(OP_ADDS_rail.BBP_OT_add_side_spiral_rail.bl_idname) @@ -96,22 +96,22 @@ class BBP_MT_AddComponentsMenu(bpy.types.Menu): def draw(self, context): layout = self.layout - layout.label(text="Basic Components") + layout.label(text="Basic Components", text_ctxt='BBP_MT_AddComponentsMenu/draw') OP_ADDS_component.BBP_OT_add_component.draw_blc_menu(layout) layout.separator() - layout.label(text="Nong Components") + layout.label(text="Nong Components", text_ctxt='BBP_MT_AddComponentsMenu/draw') OP_ADDS_component.BBP_OT_add_nong_extra_point.draw_blc_menu(layout) OP_ADDS_component.BBP_OT_add_nong_ventilator.draw_blc_menu(layout) layout.separator() - layout.label(text="Series Components") + layout.label(text="Series Components", text_ctxt='BBP_MT_AddComponentsMenu/draw') OP_ADDS_component.BBP_OT_add_tilting_block_series.draw_blc_menu(layout) OP_ADDS_component.BBP_OT_add_swing_series.draw_blc_menu(layout) OP_ADDS_component.BBP_OT_add_ventilator_series.draw_blc_menu(layout) layout.separator() - layout.label(text="Components Pair") + layout.label(text="Components Pair", text_ctxt='BBP_MT_AddComponentsMenu/draw') OP_ADDS_component.BBP_OT_add_sector_component_pair.draw_blc_menu(layout) # ===== Menu Drawer ===== @@ -120,13 +120,29 @@ MenuDrawer_t = typing.Callable[[typing.Any, typing.Any], None] def menu_drawer_import(self, context) -> None: layout: bpy.types.UILayout = self.layout - #layout.operator(OP_IMPORT_bmfile.BBP_OT_import_bmfile.bl_idname, text="Ballance Map (.bmx)") - layout.operator(OP_IMPORT_virtools.BBP_OT_import_virtools.bl_idname, text="Virtools File (.nmo/.cmo/.vmo) (experimental)") + # layout.operator( + # OP_IMPORT_bmfile.BBP_OT_import_bmfile.bl_idname, + # text="Ballance Map (.bmx)", + # text_ctxt='BBP/__init__.menu_drawer_import()' + # ) + layout.operator( + OP_IMPORT_virtools.BBP_OT_import_virtools.bl_idname, + text="Virtools File (.nmo/.cmo/.vmo) (experimental)", + text_ctxt='BBP/__init__.menu_drawer_import()' + ) def menu_drawer_export(self, context) -> None: layout: bpy.types.UILayout = self.layout - #layout.operator(OP_EXPORT_bmfile.BBP_OT_export_bmfile.bl_idname, text="Ballance Map (.bmx)") - layout.operator(OP_EXPORT_virtools.BBP_OT_export_virtools.bl_idname, text="Virtools File (.nmo/.cmo/.vmo) (experimental)") + # layout.operator( + # OP_EXPORT_bmfile.BBP_OT_export_bmfile.bl_idname, + # text="Ballance Map (.bmx)", + # text_ctxt='BBP/__init__.menu_drawer_export()' + # ) + layout.operator( + OP_EXPORT_virtools.BBP_OT_export_virtools.bl_idname, + text="Virtools File (.nmo/.cmo/.vmo) (experimental)", + text_ctxt='BBP/__init__.menu_drawer_export()' + ) def menu_drawer_view3d(self, context) -> None: layout: bpy.types.UILayout = self.layout @@ -135,7 +151,7 @@ def menu_drawer_view3d(self, context) -> None: def menu_drawer_add(self, context) -> None: layout: bpy.types.UILayout = self.layout layout.separator() - layout.label(text="Ballance") + layout.label(text="Ballance", text_ctxt='BBP/__init__.menu_drawer_add()') layout.menu(BBP_MT_AddBmeMenu.bl_idname, icon='MESH_CUBE') layout.menu(BBP_MT_AddRailMenu.bl_idname, icon='MESH_CIRCLE') layout.menu(BBP_MT_AddComponentsMenu.bl_idname, icon='MESH_ICOSPHERE') @@ -151,15 +167,21 @@ def menu_drawer_grouping(self, context) -> None: col = layout.column() col.operator_context = 'INVOKE_DEFAULT' - col.label(text="Virtools Group") - col.operator(OP_OBJECT_virtools_group.BBP_OT_add_objects_virtools_group.bl_idname, icon='ADD', text="Group into...") - col.operator(OP_OBJECT_virtools_group.BBP_OT_rm_objects_virtools_group.bl_idname, icon='REMOVE', text="Ungroup from...") - col.operator(OP_OBJECT_virtools_group.BBP_OT_clear_objects_virtools_group.bl_idname, icon='TRASH', text="Clear All Groups") + col.label(text="Virtools Group", text_ctxt='BBP/__init__.menu_drawer_grouping()') + col.operator( + OP_OBJECT_virtools_group.BBP_OT_add_objects_virtools_group.bl_idname, icon='ADD', text="Group into...", + text_ctxt='BBP/__init__.menu_drawer_grouping()') + col.operator( + OP_OBJECT_virtools_group.BBP_OT_rm_objects_virtools_group.bl_idname, icon='REMOVE', text="Ungroup from...", + text_ctxt='BBP/__init__.menu_drawer_grouping()') + col.operator( + OP_OBJECT_virtools_group.BBP_OT_clear_objects_virtools_group.bl_idname, icon='TRASH', text="Clear All Groups", + text_ctxt='BBP/__init__.menu_drawer_grouping()') def menu_drawer_snoop_then_conv(self, context) -> None: layout: bpy.types.UILayout = self.layout layout.separator() - layout.label(text="Ballance") + layout.label(text="Ballance", text_ctxt='BBP/__init__.menu_drawer_snoop_then_conv()') layout.operator(OP_OBJECT_snoop_group_then_to_mesh.BBP_OT_snoop_group_then_to_mesh.bl_idname, icon='OUTLINER_OB_MESH') def menu_drawer_naming_convention(self, context) -> None: @@ -170,7 +192,7 @@ def menu_drawer_naming_convention(self, context) -> None: col = layout.column() col.operator_context = 'INVOKE_DEFAULT' - col.label(text="Ballance") + col.label(text="Ballance", text_ctxt='BBP/__init__.menu_drawer_naming_convention()') col.operator(OP_OBJECT_naming_convention.BBP_OT_regulate_objects_name.bl_idname, icon='GREASEPENCIL') col.operator(OP_OBJECT_naming_convention.BBP_OT_auto_grouping.bl_idname, icon='GROUP') col.operator(OP_OBJECT_naming_convention.BBP_OT_convert_to_imengyu.bl_idname, icon='ARROW_LEFTRIGHT')