Fix T52833: OBJ triangulate doesn't match viewport
[blender-addons.git] / development_edit_operator.py
blobb921051f318e3a2f6fec12603010259406800d87
1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
20 bl_info = {
21 "name": "Edit Operator Source",
22 "author": "scorpion81",
23 "version": (1, 2, 2),
24 "blender": (2, 78, 0),
25 "location": "Text Editor > Edit > Edit Operator",
26 "description": "Opens source file of chosen operator, if it is an add-on one",
27 "warning": "",
28 "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/"
29 "Py/Scripts/Development/Edit_Operator_Source",
30 "category": "Development"}
32 import bpy
33 import sys
34 import inspect
35 from bpy.types import (
36 Operator,
37 Panel,
39 from bpy.props import EnumProperty
42 def get_py_class_from_op(opname):
43 opid = opname.split(".")
44 opmod = getattr(bpy.ops, opid[0])
45 op = getattr(opmod, opid[1])
46 id = op.get_rna().bl_rna.identifier
47 # C operators won't be added
48 return getattr(bpy.types, id, None)
51 def getmodule(opname):
52 cls = get_py_class_from_op(opname)
53 if cls is None:
54 addon = False
55 line = -1
56 mod = 'C operator'
57 else:
58 addon = True
59 mod_name = cls.__module__
60 try:
61 line = inspect.getsourcelines(cls)[1]
62 except IOError:
63 line = -1
64 except TypeError:
65 line = -1
67 if mod_name == 'bpy.types':
68 addon = False
69 elif mod_name != '__main__':
70 mod = sys.modules[mod_name].__file__
71 else:
72 addon = False
73 mod = mod_name
75 return mod, line, addon
78 def get_ops():
79 allops = []
80 opsdir = dir(bpy.ops)
81 for opmodname in opsdir:
82 opmod = getattr(bpy.ops, opmodname)
83 opmoddir = dir(opmod)
84 for o in opmoddir:
85 name = opmodname + "." + o
86 cls = get_py_class_from_op(name)
87 if cls is not None:
88 allops.append(name)
89 del opmoddir
91 # add own operator name too, since its not loaded yet when this is called
92 allops.append("text.edit_operator")
93 l = sorted(allops)
94 del allops
95 del opsdir
97 return [(y, y, "", x) for x, y in enumerate(l)]
100 class EditOperator(Operator):
101 bl_idname = "text.edit_operator"
102 bl_label = "Edit Operator"
103 bl_description = "Opens the source file of operators chosen from Menu"
104 bl_property = "op"
106 items = get_ops()
108 op = EnumProperty(
109 name="Op",
110 description="",
111 items=items
114 def invoke(self, context, event):
115 context.window_manager.invoke_search_popup(self)
116 return {'PASS_THROUGH'}
118 def execute(self, context):
119 found = False
120 path, line, addon = getmodule(self.op)
121 if addon:
122 for t in bpy.data.texts:
123 if t.filepath == path:
124 ctx = context.copy()
125 ctx['edit_text'] = t
126 bpy.ops.text.jump(ctx, line=line)
127 found = True
128 break
130 if (found is False):
131 self.report({'INFO'},
132 "Opened file: " + path)
133 bpy.ops.text.open(filepath=path)
134 bpy.ops.text.jump(line=line)
136 return {'FINISHED'}
137 else:
138 self.report({'WARNING'},
139 "Found no source file for " + self.op)
141 return {'CANCELLED'}
144 class EditOperatorPanel(Panel):
145 bl_idname = "DEVEDIT_PT_operator"
146 bl_space_type = 'TEXT_EDITOR'
147 bl_region_type = 'UI'
148 bl_label = "Edit Operator"
150 def draw(self, context):
151 layout = self.layout
152 layout.operator("text.edit_operator")
155 def register():
156 bpy.utils.register_class(EditOperator)
157 bpy.utils.register_class(EditOperatorPanel)
160 def unregister():
161 bpy.utils.unregister_class(EditOperatorPanel)
162 bpy.utils.unregister_class(EditOperator)
165 if __name__ == "__main__":
166 register()