# SPDX-License-Identifier: GPL-2.0-or-later import os if "bpy" in locals(): import importlib importlib.reload(settings) importlib.reload(utils_i18n) else: import bpy from bpy.types import ( Operator, Panel, PropertyGroup, UIList, ) from bpy.props import ( BoolProperty, IntProperty, StringProperty, CollectionProperty, ) from . import settings from bl_i18n_utils import utils as utils_i18n from bpy.app.translations import pgettext_iface as iface_ # Data ######################################################################## class I18nUpdateTranslationLanguage(PropertyGroup): """Settings/info about a language""" uid: StringProperty( name="Language ID", description="ISO code (eg. \"fr_FR\")", default="", ) num_id: IntProperty( name="Numeric ID", description="Numeric ID (read only!)", default=0, min=0, ) name: StringProperty( name="Language Name", description="Language label (eg. \"French (Français)\")", default="", ) use: BoolProperty( name="Use", description="If this language should be used in the current operator", default=True, ) po_path: StringProperty( name="PO File Path", description="Path to the relevant po file in branches", subtype='FILE_PATH', default="", ) po_path_trunk: StringProperty( name="PO Trunk File Path", description="Path to the relevant po file in trunk", subtype='FILE_PATH', default="", ) mo_path_trunk: StringProperty( name="MO File Path", description="Path to the relevant mo file", subtype='FILE_PATH', default="", ) po_path_git: StringProperty( name="PO Git Master File Path", description="Path to the relevant po file in Blender's translations git repository", subtype='FILE_PATH', default="", ) class I18nUpdateTranslationSettings(PropertyGroup): """Settings/info about a language""" langs: CollectionProperty( name="Languages", type=I18nUpdateTranslationLanguage, description="Languages to update in branches", ) active_lang: IntProperty( name="Active Language", default=0, description="Index of active language in langs collection", ) pot_path: StringProperty( name="POT File Path", description="Path to the pot template file", subtype='FILE_PATH', default="", ) is_init: BoolProperty( description="Whether these settings have already been auto-set or not", default=False, options={'HIDDEN'}, ) # UI ########################################################################## class UI_UL_i18n_languages(UIList): """ """ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): if self.layout_type in {'DEFAULT', 'COMPACT'}: layout.label(text=item.name, icon_value=icon) layout.prop(item, "use", text="") elif self.layout_type in {'GRID'}: layout.alignment = 'CENTER' layout.label(text=item.uid) layout.prop(item, "use", text="") class UI_PT_i18n_update_translations_settings(Panel): """ """ bl_label = "I18n Update Translation" bl_space_type = "PROPERTIES" bl_region_type = "WINDOW" bl_context = "render" def draw(self, context): layout = self.layout i18n_sett = context.window_manager.i18n_update_svn_settings if not i18n_sett.is_init and bpy.ops.ui.i18n_updatetranslation_svn_init_settings.poll(): # Cannot call the operator from here, this code might run while `pyrna_write_check()` returns False # (which prevents any operator call from Python), during initialization of Blender. UI_OT_i18n_updatetranslation_svn_init_settings.execute_static(context, settings.settings) if not i18n_sett.is_init: layout.label(text="Could not init languages data!") layout.label(text="Please edit the preferences of the UI Translate add-on") layout.operator("ui.i18n_updatetranslation_svn_init_settings", text="Init Settings") else: split = layout.split(factor=0.75) split.template_list("UI_UL_i18n_languages", "", i18n_sett, "langs", i18n_sett, "active_lang", rows=8) col = split.column() col.operator("ui.i18n_updatetranslation_svn_init_settings", text="Reset Settings") deselect = any(l.use for l in i18n_sett.langs) op = col.operator("ui.i18n_updatetranslation_svn_settings_select", text="Deselect All" if deselect else "Select All") op.use_invert = False op.use_select = not deselect col.operator("ui.i18n_updatetranslation_svn_settings_select", text="Invert Selection").use_invert = True col.separator() col.operator("ui.i18n_updatetranslation_svn_branches", text="Update Branches") col.operator("ui.i18n_updatetranslation_svn_trunk", text="Update Trunk") col.separator() col.operator("ui.i18n_cleanuptranslation_svn_branches", text="Clean up Branches") col.operator("ui.i18n_updatetranslation_svn_statistics", text="Statistics") if i18n_sett.active_lang >= 0 and i18n_sett.active_lang < len(i18n_sett.langs): lng = i18n_sett.langs[i18n_sett.active_lang] col = layout.column() col.active = lng.use row = col.row() row.label(text="[{}]: \"{}\" ({})".format(lng.uid, iface_(lng.name), lng.num_id), translate=False) row.prop(lng, "use", text="") col.prop(lng, "po_path") col.prop(lng, "po_path_trunk") col.prop(lng, "mo_path_trunk") col.prop(lng, "po_path_git") layout.separator() layout.prop(i18n_sett, "pot_path") layout.separator() layout.label(text="Add-ons:") row = layout.row() op = row.operator("ui.i18n_addon_translation_invoke", text="Refresh I18n Data...") op.op_id = "ui.i18n_addon_translation_update" op = row.operator("ui.i18n_addon_translation_invoke", text="Export PO...") op.op_id = "ui.i18n_addon_translation_export" op = row.operator("ui.i18n_addon_translation_invoke", text="Import PO...") op.op_id = "ui.i18n_addon_translation_import" # Operators ################################################################### class UI_OT_i18n_updatetranslation_svn_init_settings(Operator): """Init settings for i18n svn's update operators""" bl_idname = "ui.i18n_updatetranslation_svn_init_settings" bl_label = "Init I18n Update Settings" bl_option = {'REGISTER'} @classmethod def poll(cls, context): return context.window_manager is not None @staticmethod def execute_static(context, self_settings): i18n_sett = context.window_manager.i18n_update_svn_settings # First, create the list of languages from settings. i18n_sett.langs.clear() root_br = self_settings.BRANCHES_DIR root_tr_po = self_settings.TRUNK_PO_DIR root_git_po = self_settings.GIT_I18N_PO_DIR root_tr_mo = os.path.join(self_settings.TRUNK_DIR, self_settings.MO_PATH_TEMPLATE, self_settings.MO_FILE_NAME) if not (os.path.isdir(root_br) and os.path.isdir(root_tr_po)): i18n_sett.is_init = False return; for can_use, uid, num_id, name, isocode, po_path_branch in utils_i18n.list_po_dir(root_br, self_settings): lng = i18n_sett.langs.add() lng.use = can_use lng.uid = uid lng.num_id = num_id lng.name = name if can_use: lng.po_path = po_path_branch lng.po_path_trunk = os.path.join(root_tr_po, isocode + ".po") lng.mo_path_trunk = root_tr_mo.format(isocode) lng.po_path_git = os.path.join(root_git_po, isocode + ".po") i18n_sett.pot_path = self_settings.FILE_NAME_POT i18n_sett.is_init = True def execute(self, context): if not hasattr(self, "settings"): self.settings = settings.settings self.execute_static(context, self.settings) if context.window_manager.i18n_update_svn_settings.is_init is False: return {'CANCELLED'} return {'FINISHED'} class UI_OT_i18n_updatetranslation_svn_settings_select(Operator): """(De)select (or invert selection of) all languages for i18n svn's update operators""" bl_idname = "ui.i18n_updatetranslation_svn_settings_select" bl_label = "Init I18n Update Select Languages" # Operator Arguments use_select: BoolProperty( name="Select All", description="Select all if True, else deselect all", default=True, ) use_invert: BoolProperty( name="Invert Selection", description="Inverse selection (overrides 'Select All' when True)", default=False, ) # /End Operator Arguments @classmethod def poll(cls, context): return context.window_manager is not None def execute(self, context): if self.use_invert: for lng in context.window_manager.i18n_update_svn_settings.langs: lng.use = not lng.use else: for lng in context.window_manager.i18n_update_svn_settings.langs: lng.use = self.use_select return {'FINISHED'} classes = ( I18nUpdateTranslationLanguage, I18nUpdateTranslationSettings, UI_UL_i18n_languages, UI_PT_i18n_update_translations_settings, UI_OT_i18n_updatetranslation_svn_init_settings, UI_OT_i18n_updatetranslation_svn_settings_select, )