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 #####
21 "name": "Edit Operator Source",
22 "author": "scorpion81",
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",
28 "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/"
29 "Py/Scripts/Development/Edit_Operator_Source",
30 "category": "Development"}
35 from bpy
.types
import (
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
)
59 mod_name
= cls
.__module
__
61 line
= inspect
.getsourcelines(cls
)[1]
67 if mod_name
== 'bpy.types':
69 elif mod_name
!= '__main__':
70 mod
= sys
.modules
[mod_name
].__file
__
75 return mod
, line
, addon
81 for opmodname
in opsdir
:
82 opmod
= getattr(bpy
.ops
, opmodname
)
85 name
= opmodname
+ "." + o
86 cls
= get_py_class_from_op(name
)
91 # add own operator name too, since its not loaded yet when this is called
92 allops
.append("text.edit_operator")
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"
114 def invoke(self
, context
, event
):
115 context
.window_manager
.invoke_search_popup(self
)
116 return {'PASS_THROUGH'}
118 def execute(self
, context
):
120 path
, line
, addon
= getmodule(self
.op
)
122 for t
in bpy
.data
.texts
:
123 if t
.filepath
== path
:
126 bpy
.ops
.text
.jump(ctx
, line
=line
)
131 self
.report({'INFO'},
132 "Opened file: " + path
)
133 bpy
.ops
.text
.open(filepath
=path
)
134 bpy
.ops
.text
.jump(line
=line
)
138 self
.report({'WARNING'},
139 "Found no source file for " + self
.op
)
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
):
152 layout
.operator("text.edit_operator")
156 bpy
.utils
.register_class(EditOperator
)
157 bpy
.utils
.register_class(EditOperatorPanel
)
161 bpy
.utils
.unregister_class(EditOperatorPanel
)
162 bpy
.utils
.unregister_class(EditOperator
)
165 if __name__
== "__main__":