diff options
Diffstat (limited to 'release/scripts/startup/bl_operators')
25 files changed, 513 insertions, 121 deletions
diff --git a/release/scripts/startup/bl_operators/__init__.py b/release/scripts/startup/bl_operators/__init__.py index a696410ca1c..1e0dbe6925e 100644 --- a/release/scripts/startup/bl_operators/__init__.py +++ b/release/scripts/startup/bl_operators/__init__.py @@ -21,8 +21,7 @@ # support reloading sub-modules if "bpy" in locals(): from importlib import reload - for val in _modules_loaded: - reload(val) + _modules_loaded[:] = [reload(val) for val in _modules_loaded] del reload _modules = [ @@ -63,8 +62,15 @@ del _namespace def register(): - bpy.utils.register_module(__name__) + from bpy.utils import register_class + for mod in _modules_loaded: + for cls in mod.classes: + register_class(cls) def unregister(): - bpy.utils.unregister_module(__name__) + from bpy.utils import unregister_class + for mod in reversed(_modules_loaded): + for cls in reversed(mod.classes): + if cls.is_registered: + unregister_class(cls) diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py index 247b91e147f..0e5acea94f9 100644 --- a/release/scripts/startup/bl_operators/add_mesh_torus.py +++ b/release/scripts/startup/bl_operators/add_mesh_torus.py @@ -282,3 +282,8 @@ class AddTorus(Operator, object_utils.AddObjectHelper): object_utils.object_data_add(context, mesh, operator=self) return {'FINISHED'} + + +classes = ( + AddTorus, +)
\ No newline at end of file diff --git a/release/scripts/startup/bl_operators/anim.py b/release/scripts/startup/bl_operators/anim.py index c20d591241c..78fcf0dd124 100644 --- a/release/scripts/startup/bl_operators/anim.py +++ b/release/scripts/startup/bl_operators/anim.py @@ -28,11 +28,11 @@ if "bpy" in locals(): import bpy from bpy.types import Operator from bpy.props import ( - IntProperty, - BoolProperty, - EnumProperty, - StringProperty, - ) + IntProperty, + BoolProperty, + EnumProperty, + StringProperty, +) class ANIM_OT_keying_set_export(Operator): @@ -115,30 +115,30 @@ class ANIM_OT_keying_set_export(Operator): # Find material or lamp using this node tree... id_bpy_path = "bpy.data.nodes[\"%s\"]" found = False - + for mat in bpy.data.materials: if mat.node_tree == ksp.id: id_bpy_path = "bpy.data.materials[\"%s\"].node_tree" % (mat.name) found = True - break; - + break + if not found: for lamp in bpy.data.lamps: if lamp.node_tree == ksp.id: id_bpy_path = "bpy.data.lamps[\"%s\"].node_tree" % (lamp.name) found = True - break; - + break + if not found: - self.report({'WARN'}, "Could not find material or lamp using Shader Node Tree - %s" % (ksp.id)) + self.report({'WARN'}, "Could not find material or lamp using Shader Node Tree - %s" % (ksp.id)) elif ksp.id.bl_rna.identifier.startswith("CompositorNodeTree"): # Find compositor nodetree using this node tree... for scene in bpy.data.scenes: if scene.node_tree == ksp.id: id_bpy_path = "bpy.data.scenes[\"%s\"].node_tree" % (scene.name) - break; + break else: - self.report({'WARN'}, "Could not find scene using Compositor Node Tree - %s" % (ksp.id)) + self.report({'WARN'}, "Could not find scene using Compositor Node Tree - %s" % (ksp.id)) else: idtype_list = ksp.id.bl_rna.name.lower() + "s" id_bpy_path = "bpy.data.%s[\"%s\"]" % (idtype_list, ksp.id.name) @@ -302,9 +302,11 @@ class ClearUselessActions(Operator): bl_label = "Clear Useless Actions" bl_options = {'REGISTER', 'UNDO'} - only_unused = BoolProperty(name="Only Unused", + only_unused = BoolProperty( + name="Only Unused", description="Only unused (Fake User only) actions get considered", - default=True) + default=True, + ) @classmethod def poll(cls, context): @@ -393,7 +395,7 @@ class UpdateAnimatedTransformConstraint(Operator): except: pass ret = (data, new_path) - #print(ret) + # print(ret) return ret @@ -412,3 +414,11 @@ class UpdateAnimatedTransformConstraint(Operator): text.from_string(log) self.report({'INFO'}, "Complete report available on '%s' text datablock" % text.name) return {'FINISHED'} + + +classes = ( + ANIM_OT_keying_set_export, + BakeAction, + ClearUselessActions, + UpdateAnimatedTransformConstraint, +) diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py index d60703236d6..6747bfec1fb 100644 --- a/release/scripts/startup/bl_operators/clip.py +++ b/release/scripts/startup/bl_operators/clip.py @@ -21,7 +21,10 @@ import bpy import os from bpy.types import Operator from bpy.props import FloatProperty -from mathutils import Vector, Matrix +from mathutils import ( + Vector, + Matrix, +) def CLIP_spaces_walk(context, all_screens, tarea, tspace, callback, *args): @@ -1071,3 +1074,17 @@ class CLIP_OT_track_settings_to_track(bpy.types.Operator): setattr(marker_selected, attr, getattr(marker, attr)) return {'FINISHED'} + + +classes = ( + CLIP_OT_bundles_to_mesh, + CLIP_OT_constraint_to_fcurve, + CLIP_OT_delete_proxy, + CLIP_OT_filter_tracks, + CLIP_OT_set_active_clip, + CLIP_OT_set_viewport_background, + CLIP_OT_setup_tracking_scene, + CLIP_OT_track_settings_as_default, + CLIP_OT_track_settings_to_track, + CLIP_OT_track_to_empty, +) diff --git a/release/scripts/startup/bl_operators/console.py b/release/scripts/startup/bl_operators/console.py index 8cfc977294a..fb36f80239e 100644 --- a/release/scripts/startup/bl_operators/console.py +++ b/release/scripts/startup/bl_operators/console.py @@ -159,3 +159,12 @@ class ConsoleLanguage(Operator): remove_duplicates=True) return {'FINISHED'} + + +classes = ( + ConsoleAutocomplete, + ConsoleBanner, + ConsoleCopyAsScript, + ConsoleExec, + ConsoleLanguage, +)
\ No newline at end of file diff --git a/release/scripts/startup/bl_operators/file.py b/release/scripts/startup/bl_operators/file.py index 51e079164b6..d710b9af715 100644 --- a/release/scripts/startup/bl_operators/file.py +++ b/release/scripts/startup/bl_operators/file.py @@ -248,3 +248,8 @@ class WM_OT_previews_batch_clear(Operator): return {'FINISHED'} + +classes = ( + WM_OT_previews_batch_clear, + WM_OT_previews_batch_generate, +)
\ No newline at end of file diff --git a/release/scripts/startup/bl_operators/freestyle.py b/release/scripts/startup/bl_operators/freestyle.py index 43cd3110beb..4cee1abf15f 100644 --- a/release/scripts/startup/bl_operators/freestyle.py +++ b/release/scripts/startup/bl_operators/freestyle.py @@ -16,13 +16,15 @@ # # ##### END GPL LICENSE BLOCK ##### +# <pep8 compliant> + import bpy from bpy.props import ( - BoolProperty, - EnumProperty, - StringProperty, - ) + BoolProperty, + EnumProperty, + StringProperty, +) class SCENE_OT_freestyle_fill_range_by_selection(bpy.types.Operator): @@ -218,3 +220,11 @@ class SCENE_OT_freestyle_module_open(bpy.types.Operator): text = bpy.data.texts.load(self.filepath, self.make_internal) self.freestyle_module.script = text return {'FINISHED'} + + +classes = ( + SCENE_OT_freestyle_add_edge_marks_to_keying_set, + SCENE_OT_freestyle_add_face_marks_to_keying_set, + SCENE_OT_freestyle_fill_range_by_selection, + SCENE_OT_freestyle_module_open, +) diff --git a/release/scripts/startup/bl_operators/image.py b/release/scripts/startup/bl_operators/image.py index d3460383fe7..6a538f0ae33 100644 --- a/release/scripts/startup/bl_operators/image.py +++ b/release/scripts/startup/bl_operators/image.py @@ -242,3 +242,11 @@ class ProjectApply(Operator): bpy.ops.paint.project_image(image=image_name) return {'FINISHED'} + + +classes = ( + EditExternally, + ProjectApply, + ProjectEdit, + SaveDirty, +)
\ No newline at end of file diff --git a/release/scripts/startup/bl_operators/mask.py b/release/scripts/startup/bl_operators/mask.py index aa984659430..78a4bd9af27 100644 --- a/release/scripts/startup/bl_operators/mask.py +++ b/release/scripts/startup/bl_operators/mask.py @@ -31,3 +31,8 @@ class MASK_MT_add(Menu): layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("mask.primitive_circle_add", text="Circle", icon='MESH_CIRCLE') layout.operator("mask.primitive_square_add", text="Square", icon='MESH_PLANE') + + +classes = ( + MASK_MT_add, +)
\ No newline at end of file diff --git a/release/scripts/startup/bl_operators/mesh.py b/release/scripts/startup/bl_operators/mesh.py index 58eab5436e6..4edefd7bf9b 100644 --- a/release/scripts/startup/bl_operators/mesh.py +++ b/release/scripts/startup/bl_operators/mesh.py @@ -21,7 +21,10 @@ import bpy from bpy.types import Operator -from bpy.props import EnumProperty, IntProperty +from bpy.props import ( + EnumProperty, + IntProperty, +) class MeshMirrorUV(Operator): @@ -248,3 +251,10 @@ class MehsSetNormalsFromFaces(Operator): return {'FINISHED'} + +classes = ( + MehsSetNormalsFromFaces, + MeshMirrorUV, + MeshSelectNext, + MeshSelectPrev, +) diff --git a/release/scripts/startup/bl_operators/node.py b/release/scripts/startup/bl_operators/node.py index acff259e503..40876e2b069 100644 --- a/release/scripts/startup/bl_operators/node.py +++ b/release/scripts/startup/bl_operators/node.py @@ -21,16 +21,16 @@ import bpy import nodeitems_utils from bpy.types import ( - Operator, - PropertyGroup, - ) + Operator, + PropertyGroup, +) from bpy.props import ( - BoolProperty, - CollectionProperty, - EnumProperty, - IntProperty, - StringProperty, - ) + BoolProperty, + CollectionProperty, + EnumProperty, + IntProperty, + StringProperty, +) class NodeSetting(PropertyGroup): @@ -295,3 +295,14 @@ class NODE_OT_tree_path_parent(Operator): space.path.pop() return {'FINISHED'} + + +classes = ( + NodeSetting, + + NODE_OT_add_and_link_node, + NODE_OT_add_node, + NODE_OT_add_search, + NODE_OT_collapse_hide_unused_toggle, + NODE_OT_tree_path_parent, +) diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py index be680a6df0c..b730e866323 100644 --- a/release/scripts/startup/bl_operators/object.py +++ b/release/scripts/startup/bl_operators/object.py @@ -21,12 +21,12 @@ import bpy from bpy.types import Operator from bpy.props import ( - StringProperty, - BoolProperty, - EnumProperty, - IntProperty, - FloatProperty, - ) + BoolProperty, + EnumProperty, + FloatProperty, + IntProperty, + StringProperty, +) class SelectPattern(Operator): @@ -1036,3 +1036,22 @@ class LodGenerate(Operator): scene.objects.active = ob return {'FINISHED'} + + +classes = ( + ClearAllRestrictRender, + DupliOffsetFromCursor, + IsolateTypeRender, + JoinUVs, + LodByName, + LodClearAll, + LodGenerate, + MakeDupliFace, + SelectCamera, + SelectHierarchy, + SelectPattern, + ShapeTransfer, + SubdivisionSet, + TransformsToDeltas, + TransformsToDeltasAnim, +) diff --git a/release/scripts/startup/bl_operators/object_align.py b/release/scripts/startup/bl_operators/object_align.py index a6ee16e6b71..1539ffb3545 100644 --- a/release/scripts/startup/bl_operators/object_align.py +++ b/release/scripts/startup/bl_operators/object_align.py @@ -26,13 +26,14 @@ from mathutils import Vector def GlobalBB_LQ(bb_world): # Initialize the variables with the 8th vertex - left, right, front, back, down, up = (bb_world[7][0], - bb_world[7][0], - bb_world[7][1], - bb_world[7][1], - bb_world[7][2], - bb_world[7][2], - ) + left, right, front, back, down, up = ( + bb_world[7][0], + bb_world[7][0], + bb_world[7][1], + bb_world[7][1], + bb_world[7][2], + bb_world[7][2], + ) # Test against the other 7 verts for i in range(7): @@ -398,16 +399,23 @@ class AlignObjects(Operator): def execute(self, context): align_axis = self.align_axis - ret = align_objects(context, - 'X' in align_axis, - 'Y' in align_axis, - 'Z' in align_axis, - self.align_mode, - self.relative_to, - self.bb_quality) + ret = align_objects( + context, + 'X' in align_axis, + 'Y' in align_axis, + 'Z' in align_axis, + self.align_mode, + self.relative_to, + self.bb_quality, + ) if not ret: self.report({'WARNING'}, "No objects with bound-box selected") return {'CANCELLED'} else: return {'FINISHED'} + + +classes = ( + AlignObjects, +) diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py index ef10e279bb4..16f29c77bb9 100644 --- a/release/scripts/startup/bl_operators/object_quick_effects.py +++ b/release/scripts/startup/bl_operators/object_quick_effects.py @@ -22,12 +22,12 @@ from mathutils import Vector import bpy from bpy.types import Operator from bpy.props import ( - BoolProperty, - EnumProperty, - IntProperty, - FloatProperty, - FloatVectorProperty, - ) + BoolProperty, + EnumProperty, + IntProperty, + FloatProperty, + FloatVectorProperty, +) def object_ensure_material(obj, mat_name): @@ -319,7 +319,7 @@ class QuickSmoke(Operator): def execute(self, context): if not bpy.app.build_options.mod_smoke: - self.report({'ERROR'}, "Build without Smoke modifier support") + self.report({'ERROR'}, "Built without Smoke modifier support") return {'CANCELLED'} fake_context = context.copy() @@ -568,7 +568,7 @@ class QuickFluid(Operator): def execute(self, context): if not bpy.app.build_options.mod_fluid: - self.report({'ERROR'}, "Build without Fluid modifier support") + self.report({'ERROR'}, "Built without Fluid modifier support") return {'CANCELLED'} fake_context = context.copy() @@ -645,3 +645,11 @@ class QuickFluid(Operator): bpy.ops.fluid.bake('INVOKE_DEFAULT') return {'FINISHED'} + + +classes = ( + QuickExplode, + QuickFluid, + QuickFur, + QuickSmoke, +) diff --git a/release/scripts/startup/bl_operators/object_randomize_transform.py b/release/scripts/startup/bl_operators/object_randomize_transform.py index 38110328603..f856b85844e 100644 --- a/release/scripts/startup/bl_operators/object_randomize_transform.py +++ b/release/scripts/startup/bl_operators/object_randomize_transform.py @@ -185,3 +185,8 @@ class RandomizeLocRotSize(Operator): loc, rot, scale, scale_even, scale_min) return {'FINISHED'} + + +classes = ( + RandomizeLocRotSize, +)
\ No newline at end of file diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index e01e509b292..fdacf24f6e0 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -135,7 +135,7 @@ class AddPresetBase: file_preset.write("%s = %r\n" % (rna_path_step, value)) - file_preset = open(filepath, 'w') + file_preset = open(filepath, 'w', encoding="utf-8") file_preset.write("import bpy\n") if hasattr(self, "preset_defines"): @@ -680,3 +680,26 @@ class AddPresetUnitsLength(AddPresetBase, Operator): ] preset_subdir = "units_length" + + +classes = ( + AddPresetCamera, + AddPresetCloth, + AddPresetFluid, + AddPresetHairDynamics, + AddPresetInteraction, + AddPresetInterfaceTheme, + AddPresetKeyconfig, + AddPresetNodeColor, + AddPresetOperator, + AddPresetRender, + AddPresetSSS, + AddPresetSafeAreas, + AddPresetSunSky, + AddPresetTrackingCamera, + AddPresetTrackingSettings, + AddPresetTrackingTrackColor, + AddPresetUnitsLength, + ExecutePreset, + WM_MT_operator_presets, +)
\ No newline at end of file diff --git a/release/scripts/startup/bl_operators/rigidbody.py b/release/scripts/startup/bl_operators/rigidbody.py index cba49c629be..e10a2a2915e 100644 --- a/release/scripts/startup/bl_operators/rigidbody.py +++ b/release/scripts/startup/bl_operators/rigidbody.py @@ -20,8 +20,10 @@ import bpy from bpy.types import Operator -from bpy.props import IntProperty -from bpy.props import EnumProperty +from bpy.props import ( + EnumProperty, + IntProperty, +) class CopyRigidbodySettings(Operator): @@ -309,3 +311,10 @@ class ConnectRigidBodies(Operator): else: self.report({'WARNING'}, "No other objects selected") return {'CANCELLED'} + + +classes = ( + BakeToKeyframes, + ConnectRigidBodies, + CopyRigidbodySettings, +) diff --git a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py index a5565699364..f4d6c7065a9 100644 --- a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py +++ b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py @@ -180,3 +180,8 @@ class PlayRenderedAnim(Operator): return {'CANCELLED'} return {'FINISHED'} + + +classes = ( + PlayRenderedAnim, +)
\ No newline at end of file diff --git a/release/scripts/startup/bl_operators/sequencer.py b/release/scripts/startup/bl_operators/sequencer.py index 31ca4249a9d..7209b6b478f 100644 --- a/release/scripts/startup/bl_operators/sequencer.py +++ b/release/scripts/startup/bl_operators/sequencer.py @@ -134,3 +134,10 @@ class SequencerDeinterlaceSelectedMovies(Operator): s.use_deinterlace = True return {'FINISHED'} + + +classes = ( + SequencerCrossfadeSounds, + SequencerCutMulticam, + SequencerDeinterlaceSelectedMovies, +)
\ No newline at end of file diff --git a/release/scripts/startup/bl_operators/uvcalc_follow_active.py b/release/scripts/startup/bl_operators/uvcalc_follow_active.py index d1ac9e0b586..25ee5cafe81 100644 --- a/release/scripts/startup/bl_operators/uvcalc_follow_active.py +++ b/release/scripts/startup/bl_operators/uvcalc_follow_active.py @@ -248,3 +248,8 @@ class FollowActiveQuads(Operator): def invoke(self, context, event): wm = context.window_manager return wm.invoke_props_dialog(self) + + +classes = ( + FollowActiveQuads, +)
\ No newline at end of file diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py index 3b095c883a3..8ee29d15d1b 100644 --- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py +++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py @@ -668,3 +668,8 @@ class LightMapPack(Operator): def invoke(self, context, event): wm = context.window_manager return wm.invoke_props_dialog(self) + + +classes = ( + LightMapPack, +)
\ No newline at end of file diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py index 52e7b0e0ae4..5581415c083 100644 --- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py +++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py @@ -18,7 +18,11 @@ # TODO <pep8 compliant> -from mathutils import Matrix, Vector, geometry +from mathutils import ( + Matrix, + Vector, + geometry, +) import bpy from bpy.types import Operator @@ -1100,3 +1104,8 @@ class SmartProject(Operator): def invoke(self, context, event): wm = context.window_manager return wm.invoke_props_dialog(self) + + +classes = ( + SmartProject, +) diff --git a/release/scripts/startup/bl_operators/vertexpaint_dirt.py b/release/scripts/startup/bl_operators/vertexpaint_dirt.py index 892e1822d68..c006e8e6e92 100644 --- a/release/scripts/startup/bl_operators/vertexpaint_dirt.py +++ b/release/scripts/startup/bl_operators/vertexpaint_dirt.py @@ -182,3 +182,8 @@ class VertexPaintDirt(Operator): ret = applyVertexDirt(mesh, self.blur_iterations, self.blur_strength, self.dirt_angle, self.clean_angle, self.dirt_only) return ret + + +classes = ( + VertexPaintDirt, +)
\ No newline at end of file diff --git a/release/scripts/startup/bl_operators/view3d.py b/release/scripts/startup/bl_operators/view3d.py index df4a93bb87f..acec2d8fe91 100644 --- a/release/scripts/startup/bl_operators/view3d.py +++ b/release/scripts/startup/bl_operators/view3d.py @@ -213,3 +213,11 @@ class VIEW3D_OT_select_or_deselect_all(Operator): enumerate=self.enumerate, object=self.object, location=(x, y)) + + +classes = ( + VIEW3D_OT_edit_mesh_extrude_individual_move, + VIEW3D_OT_edit_mesh_extrude_move, + VIEW3D_OT_edit_mesh_extrude_shrink_fatten, + VIEW3D_OT_select_or_deselect_all, +)
\ No newline at end of file diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index f5460d58d44..d94951341c1 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -21,12 +21,12 @@ import bpy from bpy.types import Operator from bpy.props import ( - StringProperty, - BoolProperty, - IntProperty, - FloatProperty, - EnumProperty, - ) + StringProperty, + BoolProperty, + IntProperty, + FloatProperty, + EnumProperty, +) from bpy.app.translations import pgettext_tip as tip_ @@ -130,6 +130,20 @@ def execute_context_assign(self, context): return operator_path_undo_return(context, data_path) +def module_filesystem_remove(path_base, module_name): + import os + module_name = os.path.splitext(module_name)[0] + for f in os.listdir(path_base): + f_base = os.path.splitext(f)[0] + if f_base == module_name: + f_full = os.path.join(path_base, f) + + if os.path.isdir(f_full): + os.rmdir(f_full) + else: + os.remove(f_full) + + class BRUSH_OT_active_index_set(Operator): """Set active sculpt/paint brush from it's number""" bl_idname = "brush.active_index_set" @@ -907,7 +921,10 @@ def _wm_doc_get_id(doc_id, do_url=True, url_prefix=""): # an operator (common case - just button referencing an op) if hasattr(bpy.types, class_name.upper() + "_OT_" + class_prop): if do_url: - url = ("%s/bpy.ops.%s.html#bpy.ops.%s.%s" % (url_prefix, class_name, class_name, class_prop)) + url = ( + "%s/bpy.ops.%s.html#bpy.ops.%s.%s" % + (url_prefix, class_name, class_name, class_prop) + ) else: rna = "bpy.ops.%s.%s" % (class_name, class_prop) else: @@ -922,7 +939,10 @@ def _wm_doc_get_id(doc_id, do_url=True, url_prefix=""): class_name, class_prop = class_name.split("_OT_", 1) class_name = class_name.lower() if do_url: - url = ("%s/bpy.ops.%s.html#bpy.ops.%s.%s" % (url_prefix, class_name, class_name, class_prop)) + url = ( + "%s/bpy.ops.%s.html#bpy.ops.%s.%s" % + (url_prefix, class_name, class_name, class_prop) + ) else: rna = "bpy.ops.%s.%s" % (class_name, class_prop) else: @@ -938,9 +958,12 @@ def _wm_doc_get_id(doc_id, do_url=True, url_prefix=""): rna_parent = rna_parent.base if do_url: - url = ("%s/bpy.types.%s.html#bpy.types.%s.%s" % (url_prefix, class_name, class_name, class_prop)) + url = ( + "%s/bpy.types.%s.html#bpy.types.%s.%s" % + (url_prefix, class_name, class_name, class_prop) + ) else: - rna = ("bpy.types.%s.%s" % (class_name, class_prop)) + rna = "bpy.types.%s.%s" % (class_name, class_prop) else: # We assume this is custom property, only try to generate generic url/rna_id... if do_url: @@ -1008,11 +1031,9 @@ class WM_OT_doc_view(Operator): doc_id = doc_id if bpy.app.version_cycle == "release": - _prefix = ("https://www.blender.org/api/blender_python_api_%s%s_release" % - ("_".join(str(v) for v in bpy.app.version[:2]), bpy.app.version_char)) + _prefix = ("https://docs.blender.org/api/blender_python_api_current") else: - _prefix = ("https://www.blender.org/api/blender_python_api_%s" % - "_".join(str(v) for v in bpy.app.version)) + _prefix = ("https://docs.blender.org/api/blender_python_api_master") def execute(self, context): url = _wm_doc_get_id(self.doc_id, do_url=True, url_prefix=self._prefix) @@ -1089,10 +1110,10 @@ class WM_OT_properties_edit(Operator): def execute(self, context): from rna_prop_ui import ( - rna_idprop_ui_prop_get, - rna_idprop_ui_prop_clear, - rna_idprop_ui_prop_update, - ) + rna_idprop_ui_prop_get, + rna_idprop_ui_prop_clear, + rna_idprop_ui_prop_update, + ) data_path = self.data_path value = self.value @@ -1269,9 +1290,9 @@ class WM_OT_properties_add(Operator): def execute(self, context): from rna_prop_ui import ( - rna_idprop_ui_prop_get, - rna_idprop_ui_prop_update, - ) + rna_idprop_ui_prop_get, + rna_idprop_ui_prop_update, + ) data_path = self.data_path item = eval("context.%s" % data_path) @@ -1286,10 +1307,10 @@ class WM_OT_properties_add(Operator): return prop_new - prop = unique_name( - {*item.keys(), - *type(item).bl_rna.properties.keys(), - }) + prop = unique_name({ + *item.keys(), + *type(item).bl_rna.properties.keys(), + }) item[prop] = 1.0 rna_idprop_ui_prop_update(item, prop) @@ -1329,9 +1350,9 @@ class WM_OT_properties_remove(Operator): def execute(self, context): from rna_prop_ui import ( - rna_idprop_ui_prop_clear, - rna_idprop_ui_prop_update, - ) + rna_idprop_ui_prop_clear, + rna_idprop_ui_prop_update, + ) data_path = self.data_path item = eval("context.%s" % data_path) prop = self.property @@ -1369,7 +1390,10 @@ class WM_OT_appconfig_default(Operator): filepath = os.path.join(bpy.utils.preset_paths("interaction")[0], "blender.py") if os.path.exists(filepath): - bpy.ops.script.execute_preset(filepath=filepath, menu_idname="USERPREF_MT_interaction_presets") + bpy.ops.script.execute_preset( + filepath=filepath, + menu_idname="USERPREF_MT_interaction_presets", + ) return {'FINISHED'} @@ -1389,7 +1413,10 @@ class WM_OT_appconfig_activate(Operator): filepath = self.filepath.replace("keyconfig", "interaction") if os.path.exists(filepath): - bpy.ops.script.execute_preset(filepath=filepath, menu_idname="USERPREF_MT_interaction_presets") + bpy.ops.script.execute_preset( + filepath=filepath, + menu_idname="USERPREF_MT_interaction_presets", + ) return {'FINISHED'} @@ -1494,7 +1521,7 @@ class WM_OT_blenderplayer_start(Operator): "-g", "show_profile", "=", "%d" % gs.show_framerate_profile, "-g", "show_properties", "=", "%d" % gs.show_debug_properties, "-g", "ignore_deprecation_warnings", "=", "%d" % (not gs.use_deprecation_warnings), - ]) + ]) # finish the call with the path to the blend file args.append(filepath) @@ -1624,10 +1651,11 @@ class WM_OT_keyconfig_export(Operator): wm = context.window_manager - keyconfig_utils.keyconfig_export(wm, - wm.keyconfigs.active, - self.filepath, - ) + keyconfig_utils.keyconfig_export( + wm, + wm.keyconfigs.active, + self.filepath, + ) return {'FINISHED'} @@ -1892,7 +1920,10 @@ class WM_OT_theme_install(Operator): try: shutil.copyfile(xmlfile, path_dest) - bpy.ops.script.execute_preset(filepath=path_dest, menu_idname="USERPREF_MT_interface_theme_presets") + bpy.ops.script.execute_preset( + filepath=path_dest, + menu_idname="USERPREF_MT_interface_theme_presets", + ) except: traceback.print_exc() @@ -1919,10 +1950,12 @@ class WM_OT_addon_refresh(Operator): return {'FINISHED'} +# Note: shares some logic with WM_OT_app_template_install +# but not enough to de-duplicate. Fixed here may apply to both. class WM_OT_addon_install(Operator): "Install an add-on" bl_idname = "wm.addon_install" - bl_label = "Install from File..." + bl_label = "Install Add-on from File..." overwrite = BoolProperty( name="Overwrite", @@ -1953,20 +1986,6 @@ class WM_OT_addon_install(Operator): options={'HIDDEN'}, ) - @staticmethod - def _module_remove(path_addons, module): - import os - module = os.path.splitext(module)[0] - for f in os.listdir(path_addons): - f_base = os.path.splitext(f)[0] - if f_base == module: - f_full = os.path.join(path_addons, f) - - if os.path.isdir(f_full): - os.rmdir(f_full) - else: - os.remove(f_full) - def execute(self, context): import addon_utils import traceback @@ -2019,7 +2038,7 @@ class WM_OT_addon_install(Operator): if self.overwrite: for f in file_to_extract.namelist(): - WM_OT_addon_install._module_remove(path_addons, f) + module_filesystem_remove(path_addons, f) else: for f in file_to_extract.namelist(): path_dest = os.path.join(path_addons, os.path.basename(f)) @@ -2037,7 +2056,7 @@ class WM_OT_addon_install(Operator): path_dest = os.path.join(path_addons, os.path.basename(pyfile)) if self.overwrite: - WM_OT_addon_install._module_remove(path_addons, os.path.basename(pyfile)) + module_filesystem_remove(path_addons, os.path.basename(pyfile)) elif os.path.exists(path_dest): self.report({'WARNING'}, "File already installed to %r\n" % path_dest) return {'CANCELLED'} @@ -2072,7 +2091,10 @@ class WM_OT_addon_install(Operator): bpy.utils.refresh_script_paths() # print message - msg = tip_("Modules Installed from %r into %r (%s)") % (pyfile, path_addons, ", ".join(sorted(addons_new))) + msg = ( + tip_("Modules Installed (%s) from %r into %r") % + (", ".join(sorted(addons_new)), pyfile, path_addons) + ) print(msg) self.report({'INFO'}, msg) @@ -2166,6 +2188,7 @@ class WM_OT_addon_expand(Operator): return {'FINISHED'} + class WM_OT_addon_userpref_show(Operator): "Show add-on user preferences" bl_idname = "wm.addon_userpref_show" @@ -2194,3 +2217,160 @@ class WM_OT_addon_userpref_show(Operator): bpy.ops.screen.userpref_show('INVOKE_DEFAULT') return {'FINISHED'} + + +# Note: shares some logic with WM_OT_addon_install +# but not enough to de-duplicate. Fixes here may apply to both. +class WM_OT_app_template_install(Operator): + "Install an application-template" + bl_idname = "wm.app_template_install" + bl_label = "Install Template from File..." + + overwrite = BoolProperty( + name="Overwrite", + description="Remove existing template with the same ID", + default=True, + ) + + filepath = StringProperty( + subtype='FILE_PATH', + ) + filter_folder = BoolProperty( + name="Filter folders", + default=True, + options={'HIDDEN'}, + ) + filter_glob = StringProperty( + default="*.zip", + options={'HIDDEN'}, + ) + + def execute(self, context): + import traceback + import zipfile + import shutil + import os + + filepath = self.filepath + + path_app_templates = bpy.utils.user_resource( + 'SCRIPTS', os.path.join("startup", "bl_app_templates_user"), + create=True, + ) + + if not path_app_templates: + self.report({'ERROR'}, "Failed to get add-ons path") + return {'CANCELLED'} + + if not os.path.isdir(path_app_templates): + try: + os.makedirs(path_app_templates, exist_ok=True) + except: + traceback.print_exc() + + app_templates_old = set(os.listdir(path_app_templates)) + + # check to see if the file is in compressed format (.zip) + if zipfile.is_zipfile(filepath): + try: + file_to_extract = zipfile.ZipFile(filepath, 'r') + except: + traceback.print_exc() + return {'CANCELLED'} + + if self.overwrite: + for f in file_to_extract.namelist(): + module_filesystem_remove(path_app_templates, f) + else: + for f in file_to_extract.namelist(): + path_dest = os.path.join(path_app_templates, os.path.basename(f)) + if os.path.exists(path_dest): + self.report({'WARNING'}, "File already installed to %r\n" % path_dest) + return {'CANCELLED'} + + try: # extract the file to "bl_app_templates_user" + file_to_extract.extractall(path_app_templates) + except: + traceback.print_exc() + return {'CANCELLED'} + + else: + # Only support installing zipfiles + self.report({'WARNING'}, "Expected a zip-file %r\n" % filepath) + return {'CANCELLED'} + + app_templates_new = set(os.listdir(path_app_templates)) - app_templates_old + + # in case a new module path was created to install this addon. + bpy.utils.refresh_script_paths() + + # print message + msg = ( + tip_("Template Installed (%s) from %r into %r") % + (", ".join(sorted(app_templates_new)), filepath, path_app_templates) + ) + print(msg) + self.report({'INFO'}, msg) + + return {'FINISHED'} + + def invoke(self, context, event): + wm = context.window_manager + wm.fileselect_add(self) + return {'RUNNING_MODAL'} + + +classes = ( + BRUSH_OT_active_index_set, + WM_OT_addon_disable, + WM_OT_addon_enable, + WM_OT_addon_expand, + WM_OT_addon_install, + WM_OT_addon_refresh, + WM_OT_addon_remove, + WM_OT_addon_userpref_show, + WM_OT_app_template_install, + WM_OT_appconfig_activate, + WM_OT_appconfig_default, + WM_OT_blenderplayer_start, + WM_OT_context_collection_boolean_set, + WM_OT_context_cycle_array, + WM_OT_context_cycle_enum, + WM_OT_context_cycle_int, + WM_OT_context_menu_enum, + WM_OT_context_modal_mouse, + WM_OT_context_pie_enum, + WM_OT_context_scale_float, + WM_OT_context_scale_int, + WM_OT_context_set_boolean, + WM_OT_context_set_enum, + WM_OT_context_set_float, + WM_OT_context_set_id, + WM_OT_context_set_int, + WM_OT_context_set_string, + WM_OT_context_set_value, + WM_OT_context_toggle, + WM_OT_context_toggle_enum, + WM_OT_copy_prev_settings, + WM_OT_doc_view, + WM_OT_doc_view_manual, + WM_OT_keyconfig_activate, + WM_OT_keyconfig_export, + WM_OT_keyconfig_import, + WM_OT_keyconfig_remove, + WM_OT_keyconfig_test, + WM_OT_keyitem_add, + WM_OT_keyitem_remove, + WM_OT_keyitem_restore, + WM_OT_keymap_restore, + WM_OT_operator_cheat_sheet, + WM_OT_operator_pie_enum, + WM_OT_path_open, + WM_OT_properties_add, + WM_OT_properties_context_change, + WM_OT_properties_edit, + WM_OT_properties_remove, + WM_OT_sysinfo, + WM_OT_theme_install, + WM_OT_url_open, +) |