AnimAll: rename the "Animate" tab back to "Animation"
[blender-addons.git] / ui_translate / update_ui.py
blob322d536bc494d690e29236e60fbf0675e83b66e3
1 # SPDX-FileCopyrightText: 2013-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 import os
7 if "bpy" in locals():
8 import importlib
9 importlib.reload(settings)
10 importlib.reload(utils_i18n)
11 else:
12 import bpy
13 from bpy.types import (
14 Operator,
15 Panel,
16 PropertyGroup,
17 UIList,
19 from bpy.props import (
20 BoolProperty,
21 IntProperty,
22 StringProperty,
23 CollectionProperty,
25 from . import settings
26 from bl_i18n_utils import utils as utils_i18n
28 from bpy.app.translations import pgettext_iface as iface_
31 # Data ########################################################################
33 class I18nUpdateTranslationLanguage(PropertyGroup):
34 """Settings/info about a language"""
36 uid: StringProperty(
37 name="Language ID",
38 description="ISO code (eg. \"fr_FR\")",
39 default="",
42 num_id: IntProperty(
43 name="Numeric ID",
44 description="Numeric ID (read only!)",
45 default=0, min=0,
48 name: StringProperty(
49 name="Language Name",
50 description="Language label (eg. \"French (Français)\")",
51 default="",
54 use: BoolProperty(
55 name="Use",
56 description="If this language should be used in the current operator",
57 default=True,
60 po_path: StringProperty(
61 name="PO Work File Path",
62 description="Path to the relevant po file in the work repository",
63 subtype='FILE_PATH',
64 default="",
67 po_path_blender: StringProperty(
68 name="PO Blender File Path",
69 description="Path to the relevant po file in Blender's source repository",
70 subtype='FILE_PATH',
71 default="",
75 class I18nUpdateTranslationSettings(PropertyGroup):
76 """Settings/info about a language"""
78 langs: CollectionProperty(
79 name="Languages",
80 type=I18nUpdateTranslationLanguage,
81 description="Languages to update in work repository",
84 active_lang: IntProperty(
85 name="Active Language",
86 default=0,
87 description="Index of active language in langs collection",
90 pot_path: StringProperty(
91 name="POT File Path",
92 description="Path to the pot template file",
93 subtype='FILE_PATH',
94 default="",
97 is_init: BoolProperty(
98 description="Whether these settings have already been auto-set or not",
99 default=False,
100 options={'HIDDEN'},
104 # UI ##########################################################################
106 class UI_UL_i18n_languages(UIList):
107 """ """
109 def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
110 if self.layout_type in {'DEFAULT', 'COMPACT'}:
111 layout.label(text=item.name, icon_value=icon)
112 layout.prop(item, "use", text="")
113 elif self.layout_type in {'GRID'}:
114 layout.alignment = 'CENTER'
115 layout.label(text=item.uid)
116 layout.prop(item, "use", text="")
119 class UI_PT_i18n_update_translations_settings(Panel):
120 """ """
122 bl_label = "I18n Update Translation"
123 bl_space_type = "PROPERTIES"
124 bl_region_type = "WINDOW"
125 bl_context = "render"
127 def draw(self, context):
128 layout = self.layout
129 i18n_sett = context.window_manager.i18n_update_settings
131 if not i18n_sett.is_init and bpy.ops.ui.i18n_updatetranslation_init_settings.poll():
132 # Cannot call the operator from here, this code might run while `pyrna_write_check()` returns False
133 # (which prevents any operator call from Python), during initialization of Blender.
134 UI_OT_i18n_updatetranslation_init_settings.execute_static(context, settings.settings)
136 if not i18n_sett.is_init:
137 layout.label(text="Could not init languages data!")
138 layout.label(text="Please edit the preferences of the UI Translate add-on")
139 layout.operator("ui.i18n_updatetranslation_init_settings", text="Init Settings")
140 else:
141 split = layout.split(factor=0.75)
142 split.template_list("UI_UL_i18n_languages", "", i18n_sett, "langs", i18n_sett, "active_lang", rows=8)
143 col = split.column()
144 col.operator("ui.i18n_updatetranslation_init_settings", text="Reset Settings")
145 deselect = any(l.use for l in i18n_sett.langs)
146 op = col.operator("ui.i18n_updatetranslation_settings_select",
147 text="Deselect All" if deselect else "Select All")
148 op.use_invert = False
149 op.use_select = not deselect
150 col.operator("ui.i18n_updatetranslation_settings_select", text="Invert Selection").use_invert = True
151 col.separator()
152 col.operator("ui.i18n_updatetranslation_work_repo", text="Update Work Repo")
153 col.operator("ui.i18n_cleanuptranslation_work_repo", text="Clean up Work Repo")
154 col.separator()
155 col.operator("ui.i18n_updatetranslation_blender_repo", text="Update Blender Repo")
156 col.separator()
157 col.operator("ui.i18n_updatetranslation_statistics", text="Statistics")
159 if i18n_sett.active_lang >= 0 and i18n_sett.active_lang < len(i18n_sett.langs):
160 lng = i18n_sett.langs[i18n_sett.active_lang]
161 col = layout.column()
162 col.active = lng.use
163 row = col.row()
164 row.label(text="[{}]: \"{}\" ({})".format(lng.uid, iface_(lng.name), lng.num_id), translate=False)
165 row.prop(lng, "use", text="")
166 col.prop(lng, "po_path")
167 col.prop(lng, "po_path_blender")
168 layout.separator()
169 layout.prop(i18n_sett, "pot_path")
171 layout.separator()
172 layout.label(text="Add-ons:")
173 row = layout.row()
174 op = row.operator("ui.i18n_addon_translation_invoke", text="Refresh I18n Data...")
175 op.op_id = "ui.i18n_addon_translation_update"
176 op = row.operator("ui.i18n_addon_translation_invoke", text="Export PO...")
177 op.op_id = "ui.i18n_addon_translation_export"
178 op = row.operator("ui.i18n_addon_translation_invoke", text="Import PO...")
179 op.op_id = "ui.i18n_addon_translation_import"
182 # Operators ###################################################################
184 class UI_OT_i18n_updatetranslation_init_settings(Operator):
185 """Init settings for i18n files update operators"""
187 bl_idname = "ui.i18n_updatetranslation_init_settings"
188 bl_label = "Init I18n Update Settings"
189 bl_option = {'REGISTER'}
191 @classmethod
192 def poll(cls, context):
193 return context.window_manager is not None
195 @staticmethod
196 def execute_static(context, self_settings):
197 i18n_sett = context.window_manager.i18n_update_settings
199 # First, create the list of languages from settings.
200 i18n_sett.langs.clear()
201 root_work = self_settings.WORK_DIR
202 root_blender_po = self_settings.BLENDER_I18N_PO_DIR
203 print(root_work)
204 print(root_blender_po)
205 print(self_settings.FILE_NAME_POT)
206 if not (os.path.isdir(root_work) and os.path.isdir(root_blender_po)):
207 i18n_sett.is_init = False
208 return;
209 for can_use, uid, num_id, name, isocode, po_path_work in utils_i18n.list_po_dir(root_work, self_settings):
210 lng = i18n_sett.langs.add()
211 lng.use = can_use
212 lng.uid = uid
213 lng.num_id = num_id
214 lng.name = name
215 if can_use:
216 lng.po_path = po_path_work
217 lng.po_path_blender = os.path.join(root_blender_po, isocode + ".po")
219 i18n_sett.pot_path = self_settings.FILE_NAME_POT
220 i18n_sett.is_init = True
222 def execute(self, context):
223 if not hasattr(self, "settings"):
224 self.settings = settings.settings
226 self.execute_static(context, self.settings)
228 if context.window_manager.i18n_update_settings.is_init is False:
229 return {'CANCELLED'}
230 return {'FINISHED'}
233 class UI_OT_i18n_updatetranslation_settings_select(Operator):
234 """(De)select (or invert selection of) all languages for i18n files update operators"""
236 bl_idname = "ui.i18n_updatetranslation_settings_select"
237 bl_label = "Init I18n Update Select Languages"
239 use_select: BoolProperty(
240 name="Select All",
241 description="Select all if True, else deselect all",
242 default=True,
245 use_invert: BoolProperty(
246 name="Invert Selection",
247 description="Inverse selection (overrides 'Select All' when True)",
248 default=False,
251 @classmethod
252 def poll(cls, context):
253 return context.window_manager is not None
255 def execute(self, context):
256 if self.use_invert:
257 for lng in context.window_manager.i18n_update_settings.langs:
258 lng.use = not lng.use
259 else:
260 for lng in context.window_manager.i18n_update_settings.langs:
261 lng.use = self.use_select
262 return {'FINISHED'}
265 classes = (
266 I18nUpdateTranslationLanguage,
267 I18nUpdateTranslationSettings,
268 UI_UL_i18n_languages,
269 UI_PT_i18n_update_translations_settings,
270 UI_OT_i18n_updatetranslation_init_settings,
271 UI_OT_i18n_updatetranslation_settings_select,