| 
									
										
										
										
											2009-11-04 20:50:09 +00:00
										 |  |  | # ##### BEGIN GPL LICENSE BLOCK ##### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #  This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  | #  modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  | #  as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  | #  of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2009-11-21 23:55:14 +00:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2009-11-04 20:50:09 +00:00
										 |  |  | #  This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | #  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | #  GNU General Public License for more details. | 
					
						
							| 
									
										
										
										
											2009-11-21 23:55:14 +00:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2009-11-04 20:50:09 +00:00
										 |  |  | #  You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | #  along with this program; if not, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2010-02-12 13:34:04 +00:00
										 |  |  | #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2009-11-04 20:50:09 +00:00
										 |  |  | # | 
					
						
							|  |  |  | # ##### END GPL LICENSE BLOCK ##### | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-09 19:12:03 +00:00
										 |  |  | # <pep8 compliant> | 
					
						
							| 
									
										
										
										
											2009-11-04 20:50:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | import bpy | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | from bpy.types import Menu, Operator | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  | from bpy.props import (StringProperty, | 
					
						
							|  |  |  |                        BoolProperty, | 
					
						
							|  |  |  |                        IntProperty, | 
					
						
							|  |  |  |                        FloatProperty, | 
					
						
							|  |  |  |                        EnumProperty, | 
					
						
							|  |  |  |                        ) | 
					
						
							| 
									
										
										
										
											2011-06-27 07:51:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-02 22:52:55 +00:00
										 |  |  | from rna_prop_ui import rna_idprop_ui_prop_get, rna_idprop_ui_prop_clear | 
					
						
							| 
									
										
										
										
											2009-12-13 13:59:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-08 01:03:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class MESH_OT_delete_edgeloop(Operator): | 
					
						
							| 
									
										
										
										
											2010-05-14 07:20:16 +00:00
										 |  |  |     '''Delete an edge loop by merging the faces on each side to a single face loop''' | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |     bl_idname = "mesh.delete_edgeloop" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Delete Edge Loop" | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2010-12-05 00:08:25 +00:00
										 |  |  |         if 'FINISHED' in bpy.ops.transform.edge_slide(value=1.0): | 
					
						
							| 
									
										
										
										
											2010-12-04 13:46:25 +00:00
										 |  |  |             bpy.ops.mesh.select_more() | 
					
						
							|  |  |  |             bpy.ops.mesh.remove_doubles() | 
					
						
							|  |  |  |             return {'FINISHED'} | 
					
						
							| 
									
										
										
										
											2010-12-05 00:08:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-04 13:46:25 +00:00
										 |  |  |         return {'CANCELLED'} | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  | rna_path_prop = StringProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |         name="Context Attributes", | 
					
						
							|  |  |  |         description="rna context string", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |         maxlen=1024, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  | rna_reverse_prop = BoolProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |         name="Reverse", | 
					
						
							|  |  |  |         description="Cycle backwards", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |         default=False, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  | rna_relative_prop = BoolProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |         name="Relative", | 
					
						
							|  |  |  |         description="Apply relative to the current value (delta)", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |         default=False, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2010-01-31 14:46:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-13 13:59:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  | def context_path_validate(context, data_path): | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2011-02-19 04:28:07 +00:00
										 |  |  |         value = eval("context.%s" % data_path) if data_path else Ellipsis | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |     except AttributeError as e: | 
					
						
							|  |  |  |         if str(e).startswith("'NoneType'"): | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |             # One of the items in the rna path is None, just ignore this | 
					
						
							| 
									
										
										
										
											2009-12-14 01:58:08 +00:00
										 |  |  |             value = Ellipsis | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             # We have a real error in the rna path, dont ignore that | 
					
						
							|  |  |  |             raise | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 16:01:11 +00:00
										 |  |  | def operator_value_is_undo(value): | 
					
						
							|  |  |  |     if value in {None, Ellipsis}: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # typical properties or objects | 
					
						
							|  |  |  |     id_data = getattr(value, "id_data", Ellipsis) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if id_data is None: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     elif id_data is Ellipsis: | 
					
						
							|  |  |  |         # handle mathutils types | 
					
						
							|  |  |  |         id_data = getattr(getattr(value, "owner", None), "id_data", None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if id_data is None: | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # return True if its a non window ID type | 
					
						
							|  |  |  |     return (isinstance(id_data, bpy.types.ID) and | 
					
						
							|  |  |  |             (not isinstance(id_data, (bpy.types.WindowManager, | 
					
						
							|  |  |  |                                       bpy.types.Screen, | 
					
						
							|  |  |  |                                       bpy.types.Scene, | 
					
						
							|  |  |  |                                       bpy.types.Brush, | 
					
						
							|  |  |  |                                       )))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def operator_path_is_undo(context, data_path): | 
					
						
							|  |  |  |     # note that if we have data paths that use strings this could fail | 
					
						
							|  |  |  |     # luckily we dont do this! | 
					
						
							|  |  |  |     # | 
					
						
							|  |  |  |     # When we cant find the data owner assume no undo is needed. | 
					
						
							|  |  |  |     data_path_head, data_path_sep, data_path_tail = data_path.rpartition(".") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not data_path_head: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     value = context_path_validate(context, data_path_head) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return operator_value_is_undo(value) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def operator_path_undo_return(context, data_path): | 
					
						
							|  |  |  |     return {'FINISHED'} if operator_path_is_undo(context, data_path) else {'CANCELLED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def operator_value_undo_return(value): | 
					
						
							|  |  |  |     return {'FINISHED'} if operator_value_is_undo(value) else {'CANCELLED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | def execute_context_assign(self, context): | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |     data_path = self.data_path | 
					
						
							|  |  |  |     if context_path_validate(context, data_path) is Ellipsis: | 
					
						
							| 
									
										
										
										
											2009-12-24 19:50:43 +00:00
										 |  |  |         return {'PASS_THROUGH'} | 
					
						
							| 
									
										
										
										
											2010-01-04 08:24:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |     if getattr(self, "relative", False): | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         exec("context.%s += self.value" % data_path) | 
					
						
							| 
									
										
										
										
											2010-01-04 08:24:24 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         exec("context.%s = self.value" % data_path) | 
					
						
							| 
									
										
										
										
											2010-01-04 08:24:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 16:01:11 +00:00
										 |  |  |     return operator_path_undo_return(context, data_path) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class BRUSH_OT_active_index_set(Operator): | 
					
						
							| 
									
										
										
										
											2010-11-10 08:11:58 +00:00
										 |  |  |     '''Set active sculpt/paint brush from it's number''' | 
					
						
							| 
									
										
										
										
											2011-04-01 04:22:30 +00:00
										 |  |  |     bl_idname = "brush.active_index_set" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Set Brush Number" | 
					
						
							| 
									
										
										
										
											2010-11-10 08:11:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |     mode = StringProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |             name="mode", | 
					
						
							|  |  |  |             description="Paint mode to set brush for", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             maxlen=1024, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |     index = IntProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |             name="number", | 
					
						
							|  |  |  |             description="Brush number", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2010-11-10 08:11:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-01 07:20:34 +00:00
										 |  |  |     _attr_dict = {"sculpt": "use_paint_sculpt", | 
					
						
							| 
									
										
										
										
											2010-11-10 08:11:58 +00:00
										 |  |  |                   "vertex_paint": "use_paint_vertex", | 
					
						
							|  |  |  |                   "weight_paint": "use_paint_weight", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |                   "image_paint": "use_paint_image", | 
					
						
							|  |  |  |                   } | 
					
						
							| 
									
										
										
										
											2010-11-10 08:11:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         attr = self._attr_dict.get(self.mode) | 
					
						
							|  |  |  |         if attr is None: | 
					
						
							|  |  |  |             return {'CANCELLED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for i, brush in enumerate((cur for cur in bpy.data.brushes if getattr(cur, attr))): | 
					
						
							| 
									
										
										
										
											2011-04-01 06:14:39 +00:00
										 |  |  |             if i == self.index: | 
					
						
							| 
									
										
										
										
											2010-11-10 08:11:58 +00:00
										 |  |  |                 getattr(context.tool_settings, self.mode).brush = brush | 
					
						
							|  |  |  |                 return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return {'CANCELLED'} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-01 07:20:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_context_set_boolean(Operator): | 
					
						
							| 
									
										
										
										
											2011-09-21 17:52:51 +00:00
										 |  |  |     '''Set a context value''' | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |     bl_idname = "wm.context_set_boolean" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Context Set Boolean" | 
					
						
							| 
									
										
										
										
											2011-06-06 11:56:54 +00:00
										 |  |  |     bl_options = {'UNDO', 'INTERNAL'} | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  |     data_path = rna_path_prop | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |     value = BoolProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |             name="Value", | 
					
						
							|  |  |  |             description="Assignment value", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             default=True, | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     execute = execute_context_assign | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_context_set_int(Operator):  # same as enum | 
					
						
							| 
									
										
										
										
											2011-09-21 17:52:51 +00:00
										 |  |  |     '''Set a context value''' | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |     bl_idname = "wm.context_set_int" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Context Set" | 
					
						
							| 
									
										
										
										
											2011-06-06 11:56:54 +00:00
										 |  |  |     bl_options = {'UNDO', 'INTERNAL'} | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  |     data_path = rna_path_prop | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |     value = IntProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |             name="Value", | 
					
						
							|  |  |  |             description="Assign value", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             default=0, | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2010-01-04 08:24:24 +00:00
										 |  |  |     relative = rna_relative_prop | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     execute = execute_context_assign | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_context_scale_int(Operator): | 
					
						
							| 
									
										
										
										
											2011-09-21 17:52:51 +00:00
										 |  |  |     '''Scale an int context value''' | 
					
						
							| 
									
										
										
										
											2010-03-08 23:34:38 +00:00
										 |  |  |     bl_idname = "wm.context_scale_int" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Context Set" | 
					
						
							| 
									
										
										
										
											2011-06-06 11:56:54 +00:00
										 |  |  |     bl_options = {'UNDO', 'INTERNAL'} | 
					
						
							| 
									
										
										
										
											2010-03-08 23:34:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  |     data_path = rna_path_prop | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |     value = FloatProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |             name="Value", | 
					
						
							|  |  |  |             description="Assign value", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             default=1.0, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |     always_step = BoolProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |             name="Always Step", | 
					
						
							| 
									
										
										
										
											2011-09-19 14:00:42 +00:00
										 |  |  |             description="Always adjust the value by a minimum of 1 when 'value' is not 1.0", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             default=True, | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2010-03-08 23:34:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         data_path = self.data_path | 
					
						
							|  |  |  |         if context_path_validate(context, data_path) is Ellipsis: | 
					
						
							| 
									
										
										
										
											2010-03-08 23:34:38 +00:00
										 |  |  |             return {'PASS_THROUGH'} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         value = self.value | 
					
						
							| 
									
										
										
										
											2010-03-08 23:34:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  |         if value == 1.0:  # nothing to do | 
					
						
							| 
									
										
										
										
											2010-03-08 23:34:38 +00:00
										 |  |  |             return {'CANCELLED'} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         if getattr(self, "always_step", False): | 
					
						
							| 
									
										
										
										
											2010-03-08 23:34:38 +00:00
										 |  |  |             if value > 1.0: | 
					
						
							|  |  |  |                 add = "1" | 
					
						
							|  |  |  |                 func = "max" | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 add = "-1" | 
					
						
							|  |  |  |                 func = "min" | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             exec("context.%s = %s(round(context.%s * value), context.%s + %s)" % | 
					
						
							|  |  |  |                  (data_path, func, data_path, data_path, add)) | 
					
						
							| 
									
										
										
										
											2010-03-08 23:34:38 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |             exec("context.%s *= value" % data_path) | 
					
						
							| 
									
										
										
										
											2010-03-08 23:34:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 16:01:11 +00:00
										 |  |  |         return operator_path_undo_return(context, data_path) | 
					
						
							| 
									
										
										
										
											2010-03-08 23:34:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_context_set_float(Operator):  # same as enum | 
					
						
							| 
									
										
										
										
											2011-09-21 17:52:51 +00:00
										 |  |  |     '''Set a context value''' | 
					
						
							| 
									
										
										
										
											2009-11-17 16:04:17 +00:00
										 |  |  |     bl_idname = "wm.context_set_float" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Context Set Float" | 
					
						
							| 
									
										
										
										
											2011-06-06 11:56:54 +00:00
										 |  |  |     bl_options = {'UNDO', 'INTERNAL'} | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  |     data_path = rna_path_prop | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |     value = FloatProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |             name="Value", | 
					
						
							|  |  |  |             description="Assignment value", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             default=0.0, | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2010-01-04 08:24:24 +00:00
										 |  |  |     relative = rna_relative_prop | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     execute = execute_context_assign | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_context_set_string(Operator):  # same as enum | 
					
						
							| 
									
										
										
										
											2011-09-21 17:52:51 +00:00
										 |  |  |     '''Set a context value''' | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |     bl_idname = "wm.context_set_string" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Context Set String" | 
					
						
							| 
									
										
										
										
											2011-06-06 11:56:54 +00:00
										 |  |  |     bl_options = {'UNDO', 'INTERNAL'} | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  |     data_path = rna_path_prop | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |     value = StringProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |             name="Value", | 
					
						
							|  |  |  |             description="Assign value", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             maxlen=1024, | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     execute = execute_context_assign | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_context_set_enum(Operator): | 
					
						
							| 
									
										
										
										
											2011-09-21 17:52:51 +00:00
										 |  |  |     '''Set a context value''' | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |     bl_idname = "wm.context_set_enum" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Context Set Enum" | 
					
						
							| 
									
										
										
										
											2011-06-06 11:56:54 +00:00
										 |  |  |     bl_options = {'UNDO', 'INTERNAL'} | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  |     data_path = rna_path_prop | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |     value = StringProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |             name="Value", | 
					
						
							|  |  |  |             description="Assignment value (as a string)", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             maxlen=1024, | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     execute = execute_context_assign | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_context_set_value(Operator): | 
					
						
							| 
									
										
										
										
											2011-09-21 17:52:51 +00:00
										 |  |  |     '''Set a context value''' | 
					
						
							| 
									
										
										
										
											2009-12-22 16:11:11 +00:00
										 |  |  |     bl_idname = "wm.context_set_value" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Context Set Value" | 
					
						
							| 
									
										
										
										
											2011-06-06 11:56:54 +00:00
										 |  |  |     bl_options = {'UNDO', 'INTERNAL'} | 
					
						
							| 
									
										
										
										
											2009-12-22 16:11:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  |     data_path = rna_path_prop | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |     value = StringProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |             name="Value", | 
					
						
							|  |  |  |             description="Assignment value (as a string)", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             maxlen=1024, | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2009-12-22 16:11:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         data_path = self.data_path | 
					
						
							|  |  |  |         if context_path_validate(context, data_path) is Ellipsis: | 
					
						
							| 
									
										
										
										
											2009-12-24 19:50:43 +00:00
										 |  |  |             return {'PASS_THROUGH'} | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         exec("context.%s = %s" % (data_path, self.value)) | 
					
						
							| 
									
										
										
										
											2011-08-18 16:01:11 +00:00
										 |  |  |         return operator_path_undo_return(context, data_path) | 
					
						
							| 
									
										
										
										
											2009-12-22 16:11:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_context_toggle(Operator): | 
					
						
							| 
									
										
										
										
											2011-09-21 17:52:51 +00:00
										 |  |  |     '''Toggle a context value''' | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |     bl_idname = "wm.context_toggle" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Context Toggle" | 
					
						
							| 
									
										
										
										
											2011-06-06 11:56:54 +00:00
										 |  |  |     bl_options = {'UNDO', 'INTERNAL'} | 
					
						
							| 
									
										
										
										
											2009-12-22 16:11:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  |     data_path = rna_path_prop | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         data_path = self.data_path | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         if context_path_validate(context, data_path) is Ellipsis: | 
					
						
							| 
									
										
										
										
											2009-12-24 19:50:43 +00:00
										 |  |  |             return {'PASS_THROUGH'} | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         exec("context.%s = not (context.%s)" % (data_path, data_path)) | 
					
						
							| 
									
										
										
										
											2009-12-13 13:59:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 16:01:11 +00:00
										 |  |  |         return operator_path_undo_return(context, data_path) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_context_toggle_enum(Operator): | 
					
						
							| 
									
										
										
										
											2011-09-21 17:52:51 +00:00
										 |  |  |     '''Toggle a context value''' | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |     bl_idname = "wm.context_toggle_enum" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Context Toggle Values" | 
					
						
							| 
									
										
										
										
											2011-06-06 11:56:54 +00:00
										 |  |  |     bl_options = {'UNDO', 'INTERNAL'} | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  |     data_path = rna_path_prop | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |     value_1 = StringProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |             name="Value", | 
					
						
							|  |  |  |             description="Toggle enum", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             maxlen=1024, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |     value_2 = StringProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |             name="Value", | 
					
						
							|  |  |  |             description="Toggle enum", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             maxlen=1024, | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         data_path = self.data_path | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         if context_path_validate(context, data_path) is Ellipsis: | 
					
						
							| 
									
										
										
										
											2009-12-24 19:50:43 +00:00
										 |  |  |             return {'PASS_THROUGH'} | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         exec("context.%s = ('%s', '%s')[context.%s != '%s']" % | 
					
						
							|  |  |  |              (data_path, self.value_1, | 
					
						
							|  |  |  |               self.value_2, data_path, | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |               self.value_2, | 
					
						
							|  |  |  |               )) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 16:01:11 +00:00
										 |  |  |         return operator_path_undo_return(context, data_path) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_context_cycle_int(Operator): | 
					
						
							| 
									
										
										
										
											2010-11-17 07:22:20 +00:00
										 |  |  |     '''Set a context value. Useful for cycling active material, ''' | 
					
						
							| 
									
										
										
										
											2011-09-21 17:52:51 +00:00
										 |  |  |     '''vertex keys, groups' etc''' | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |     bl_idname = "wm.context_cycle_int" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Context Int Cycle" | 
					
						
							| 
									
										
										
										
											2011-06-06 11:56:54 +00:00
										 |  |  |     bl_options = {'UNDO', 'INTERNAL'} | 
					
						
							| 
									
										
										
										
											2009-12-22 16:11:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  |     data_path = rna_path_prop | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |     reverse = rna_reverse_prop | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         data_path = self.data_path | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  |         value = context_path_validate(context, data_path) | 
					
						
							| 
									
										
										
										
											2009-12-14 01:58:08 +00:00
										 |  |  |         if value is Ellipsis: | 
					
						
							| 
									
										
										
										
											2009-12-24 19:50:43 +00:00
										 |  |  |             return {'PASS_THROUGH'} | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         if self.reverse: | 
					
						
							| 
									
										
										
										
											2010-01-03 02:24:53 +00:00
										 |  |  |             value -= 1 | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2010-01-03 02:24:53 +00:00
										 |  |  |             value += 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         exec("context.%s = value" % data_path) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  |         if value != eval("context.%s" % data_path): | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |             # relies on rna clamping int's out of the range | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |             if self.reverse: | 
					
						
							| 
									
										
										
										
											2010-10-03 01:44:00 +00:00
										 |  |  |                 value = (1 << 31) - 1 | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2010-10-03 01:44:00 +00:00
										 |  |  |                 value = -1 << 31 | 
					
						
							| 
									
										
										
										
											2010-01-03 02:24:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |             exec("context.%s = value" % data_path) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 16:01:11 +00:00
										 |  |  |         return operator_path_undo_return(context, data_path) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_context_cycle_enum(Operator): | 
					
						
							| 
									
										
										
										
											2011-09-21 17:52:51 +00:00
										 |  |  |     '''Toggle a context value''' | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |     bl_idname = "wm.context_cycle_enum" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Context Enum Cycle" | 
					
						
							| 
									
										
										
										
											2011-06-06 11:56:54 +00:00
										 |  |  |     bl_options = {'UNDO', 'INTERNAL'} | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  |     data_path = rna_path_prop | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |     reverse = rna_reverse_prop | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         data_path = self.data_path | 
					
						
							|  |  |  |         value = context_path_validate(context, data_path) | 
					
						
							| 
									
										
										
										
											2009-12-14 01:58:08 +00:00
										 |  |  |         if value is Ellipsis: | 
					
						
							| 
									
										
										
										
											2009-12-24 19:50:43 +00:00
										 |  |  |             return {'PASS_THROUGH'} | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         orig_value = value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Have to get rna enum values | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         rna_struct_str, rna_prop_str = data_path.rsplit('.', 1) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |         i = rna_prop_str.find('[') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # just incse we get "context.foo.bar[0]" | 
					
						
							|  |  |  |         if i != -1: | 
					
						
							|  |  |  |             rna_prop_str = rna_prop_str[0:i] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         rna_struct = eval("context.%s.rna_type" % rna_struct_str) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         rna_prop = rna_struct.properties[rna_prop_str] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if type(rna_prop) != bpy.types.EnumProperty: | 
					
						
							|  |  |  |             raise Exception("expected an enum property") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-03 22:28:33 +00:00
										 |  |  |         enums = rna_struct.properties[rna_prop_str].enum_items.keys() | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |         orig_index = enums.index(orig_value) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Have the info we need, advance to the next item | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         if self.reverse: | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |             if orig_index == 0: | 
					
						
							|  |  |  |                 advance_enum = enums[-1] | 
					
						
							|  |  |  |             else: | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  |                 advance_enum = enums[orig_index - 1] | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             if orig_index == len(enums) - 1: | 
					
						
							|  |  |  |                 advance_enum = enums[0] | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 advance_enum = enums[orig_index + 1] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # set the new value | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         exec("context.%s = advance_enum" % data_path) | 
					
						
							| 
									
										
										
										
											2011-08-18 16:01:11 +00:00
										 |  |  |         return operator_path_undo_return(context, data_path) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-04 12:18:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_context_cycle_array(Operator): | 
					
						
							| 
									
										
										
										
											2010-09-06 22:43:09 +00:00
										 |  |  |     '''Set a context array value.
 | 
					
						
							| 
									
										
										
										
											2011-09-21 17:52:51 +00:00
										 |  |  |     Useful for cycling the active mesh edit mode'''
 | 
					
						
							| 
									
										
										
										
											2010-09-06 22:43:09 +00:00
										 |  |  |     bl_idname = "wm.context_cycle_array" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Context Array Cycle" | 
					
						
							| 
									
										
										
										
											2011-06-06 11:56:54 +00:00
										 |  |  |     bl_options = {'UNDO', 'INTERNAL'} | 
					
						
							| 
									
										
										
										
											2010-09-06 22:43:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     data_path = rna_path_prop | 
					
						
							|  |  |  |     reverse = rna_reverse_prop | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         data_path = self.data_path | 
					
						
							| 
									
										
										
										
											2010-09-06 22:43:09 +00:00
										 |  |  |         value = context_path_validate(context, data_path) | 
					
						
							|  |  |  |         if value is Ellipsis: | 
					
						
							|  |  |  |             return {'PASS_THROUGH'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def cycle(array): | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |             if self.reverse: | 
					
						
							| 
									
										
										
										
											2010-09-06 22:43:09 +00:00
										 |  |  |                 array.insert(0, array.pop()) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 array.append(array.pop(0)) | 
					
						
							|  |  |  |             return array | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         exec("context.%s = cycle(context.%s[:])" % (data_path, data_path)) | 
					
						
							| 
									
										
										
										
											2010-09-06 22:43:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 16:01:11 +00:00
										 |  |  |         return operator_path_undo_return(context, data_path) | 
					
						
							| 
									
										
										
										
											2010-09-06 22:43:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_MT_context_menu_enum(Menu): | 
					
						
							| 
									
										
										
										
											2011-02-15 18:12:41 +00:00
										 |  |  |     bl_label = "" | 
					
						
							|  |  |  |     data_path = ""  # BAD DESIGN, set from operator below. | 
					
						
							| 
									
										
										
										
											2011-02-16 02:25:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-15 18:12:41 +00:00
										 |  |  |     def draw(self, context): | 
					
						
							|  |  |  |         data_path = self.data_path | 
					
						
							|  |  |  |         value = context_path_validate(bpy.context, data_path) | 
					
						
							|  |  |  |         if value is Ellipsis: | 
					
						
							|  |  |  |             return {'PASS_THROUGH'} | 
					
						
							|  |  |  |         base_path, prop_string = data_path.rsplit(".", 1) | 
					
						
							|  |  |  |         value_base = context_path_validate(context, base_path) | 
					
						
							| 
									
										
										
										
											2011-02-16 02:25:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-01 07:39:21 +00:00
										 |  |  |         values = [(i.name, i.identifier) for i in value_base.bl_rna.properties[prop_string].enum_items] | 
					
						
							| 
									
										
										
										
											2011-02-15 18:12:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for name, identifier in values: | 
					
						
							|  |  |  |             prop = self.layout.operator("wm.context_set_enum", text=name) | 
					
						
							|  |  |  |             prop.data_path = data_path | 
					
						
							|  |  |  |             prop.value = identifier | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_context_menu_enum(Operator): | 
					
						
							| 
									
										
										
										
											2011-02-15 18:12:41 +00:00
										 |  |  |     bl_idname = "wm.context_menu_enum" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Context Enum Menu" | 
					
						
							| 
									
										
										
										
											2011-06-06 11:56:54 +00:00
										 |  |  |     bl_options = {'UNDO', 'INTERNAL'} | 
					
						
							| 
									
										
										
										
											2011-02-15 18:12:41 +00:00
										 |  |  |     data_path = rna_path_prop | 
					
						
							| 
									
										
										
										
											2011-02-16 02:25:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-15 18:12:41 +00:00
										 |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         data_path = self.data_path | 
					
						
							|  |  |  |         WM_MT_context_menu_enum.data_path = data_path | 
					
						
							|  |  |  |         bpy.ops.wm.call_menu(name="WM_MT_context_menu_enum") | 
					
						
							|  |  |  |         return {'PASS_THROUGH'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_context_set_id(Operator): | 
					
						
							| 
									
										
										
										
											2011-09-21 17:52:51 +00:00
										 |  |  |     '''Toggle a context value''' | 
					
						
							| 
									
										
										
										
											2010-08-04 12:18:07 +00:00
										 |  |  |     bl_idname = "wm.context_set_id" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Set Library ID" | 
					
						
							| 
									
										
										
										
											2011-06-06 11:56:54 +00:00
										 |  |  |     bl_options = {'UNDO', 'INTERNAL'} | 
					
						
							| 
									
										
										
										
											2010-08-04 12:18:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     data_path = rna_path_prop | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |     value = StringProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |             name="Value", | 
					
						
							|  |  |  |             description="Assign value", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             maxlen=1024, | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2010-08-04 12:18:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         value = self.value | 
					
						
							|  |  |  |         data_path = self.data_path | 
					
						
							| 
									
										
										
										
											2010-08-04 13:59:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # match the pointer type from the target property to bpy.data.* | 
					
						
							|  |  |  |         # so we lookup the correct list. | 
					
						
							|  |  |  |         data_path_base, data_path_prop = data_path.rsplit(".", 1) | 
					
						
							|  |  |  |         data_prop_rna = eval("context.%s" % data_path_base).rna_type.properties[data_path_prop] | 
					
						
							|  |  |  |         data_prop_rna_type = data_prop_rna.fixed_type | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         id_iter = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for prop in bpy.data.rna_type.properties: | 
					
						
							|  |  |  |             if prop.rna_type.identifier == "CollectionProperty": | 
					
						
							|  |  |  |                 if prop.fixed_type == data_prop_rna_type: | 
					
						
							|  |  |  |                     id_iter = prop.identifier | 
					
						
							|  |  |  |                     break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if id_iter: | 
					
						
							|  |  |  |             value_id = getattr(bpy.data, id_iter).get(value) | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |             exec("context.%s = value_id" % data_path) | 
					
						
							| 
									
										
										
										
											2010-08-04 12:18:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 16:01:11 +00:00
										 |  |  |         return operator_path_undo_return(context, data_path) | 
					
						
							| 
									
										
										
										
											2010-08-04 12:18:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  | doc_id = StringProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |         name="Doc ID", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |         maxlen=1024, | 
					
						
							|  |  |  |         options={'HIDDEN'}, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  | doc_new = StringProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |         name="Edit Description", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |         maxlen=1024, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-27 07:51:52 +00:00
										 |  |  | data_path_iter = StringProperty( | 
					
						
							| 
									
										
										
										
											2011-09-19 14:00:42 +00:00
										 |  |  |         description="The data path relative to the context, must point to an iterable") | 
					
						
							| 
									
										
										
										
											2011-06-27 07:51:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | data_path_item = StringProperty( | 
					
						
							|  |  |  |         description="The data path from each iterable to the value (int or float)") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_context_collection_boolean_set(Operator): | 
					
						
							| 
									
										
										
										
											2011-06-27 07:51:52 +00:00
										 |  |  |     '''Set boolean values for a collection of items''' | 
					
						
							|  |  |  |     bl_idname = "wm.context_collection_boolean_set" | 
					
						
							|  |  |  |     bl_label = "Context Collection Boolean Set" | 
					
						
							|  |  |  |     bl_options = {'UNDO', 'REGISTER', 'INTERNAL'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     data_path_iter = data_path_iter | 
					
						
							|  |  |  |     data_path_item = data_path_item | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |     type = EnumProperty( | 
					
						
							|  |  |  |             name="Type", | 
					
						
							|  |  |  |             items=(('TOGGLE', "Toggle", ""), | 
					
						
							|  |  |  |                    ('ENABLE', "Enable", ""), | 
					
						
							|  |  |  |                    ('DISABLE', "Disable", ""), | 
					
						
							|  |  |  |                    ), | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2011-06-27 07:51:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         data_path_iter = self.data_path_iter | 
					
						
							|  |  |  |         data_path_item = self.data_path_item | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         items = list(getattr(context, data_path_iter)) | 
					
						
							|  |  |  |         items_ok = [] | 
					
						
							|  |  |  |         is_set = False | 
					
						
							|  |  |  |         for item in items: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 value_orig = eval("item." + data_path_item) | 
					
						
							|  |  |  |             except: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if value_orig == True: | 
					
						
							|  |  |  |                 is_set = True | 
					
						
							|  |  |  |             elif value_orig == False: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 self.report({'WARNING'}, "Non boolean value found: %s[ ].%s" % | 
					
						
							|  |  |  |                             (data_path_iter, data_path_item)) | 
					
						
							|  |  |  |                 return {'CANCELLED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             items_ok.append(item) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 16:01:11 +00:00
										 |  |  |         # avoid undo push when nothing to do | 
					
						
							|  |  |  |         if not items_ok: | 
					
						
							|  |  |  |             return {'CANCELLED'} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-27 07:51:52 +00:00
										 |  |  |         if self.type == 'ENABLE': | 
					
						
							|  |  |  |             is_set = True | 
					
						
							|  |  |  |         elif self.type == 'DISABLE': | 
					
						
							|  |  |  |             is_set = False | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             is_set = not is_set | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         exec_str = "item.%s = %s" % (data_path_item, is_set) | 
					
						
							|  |  |  |         for item in items_ok: | 
					
						
							|  |  |  |             exec(exec_str) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 16:01:11 +00:00
										 |  |  |         return operator_value_undo_return(item) | 
					
						
							| 
									
										
										
										
											2011-06-27 07:51:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_context_modal_mouse(Operator): | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  |     '''Adjust arbitrary values with mouse input''' | 
					
						
							|  |  |  |     bl_idname = "wm.context_modal_mouse" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Context Modal Mouse" | 
					
						
							| 
									
										
										
										
											2011-08-18 16:01:11 +00:00
										 |  |  |     bl_options = {'GRAB_POINTER', 'BLOCKING', 'UNDO', 'INTERNAL'} | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-27 07:51:52 +00:00
										 |  |  |     data_path_iter = data_path_iter | 
					
						
							|  |  |  |     data_path_item = data_path_item | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |     input_scale = FloatProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |             description="Scale the mouse movement by this value before applying the delta", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             default=0.01, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |     invert = BoolProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |             description="Invert the mouse input", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             default=False, | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  |     initial_x = IntProperty(options={'HIDDEN'}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _values_store(self, context): | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         data_path_iter = self.data_path_iter | 
					
						
							|  |  |  |         data_path_item = self.data_path_item | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-27 14:54:45 +00:00
										 |  |  |         self._values = values = {} | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  |         for item in getattr(context, data_path_iter): | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  |                 value_orig = eval("item." + data_path_item) | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  |             except: | 
					
						
							|  |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  |             # check this can be set, maybe this is library data. | 
					
						
							|  |  |  |             try: | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  |                 exec("item.%s = %s" % (data_path_item, value_orig)) | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  |             except: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             values[item] = value_orig | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _values_delta(self, delta): | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         delta *= self.input_scale | 
					
						
							|  |  |  |         if self.invert: | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  |             delta = - delta | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         data_path_item = self.data_path_item | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  |         for item, value_orig in self._values.items(): | 
					
						
							| 
									
										
										
										
											2010-02-23 15:34:02 +00:00
										 |  |  |             if type(value_orig) == int: | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  |                 exec("item.%s = int(%d)" % (data_path_item, round(value_orig + delta))) | 
					
						
							| 
									
										
										
										
											2010-02-23 15:34:02 +00:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  |                 exec("item.%s = %f" % (data_path_item, value_orig + delta)) | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def _values_restore(self): | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         data_path_item = self.data_path_item | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  |         for item, value_orig in self._values.items(): | 
					
						
							| 
									
										
										
										
											2010-06-14 03:52:10 +00:00
										 |  |  |             exec("item.%s = %s" % (data_path_item, value_orig)) | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self._values.clear() | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  |     def _values_clear(self): | 
					
						
							|  |  |  |         self._values.clear() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def modal(self, context, event): | 
					
						
							|  |  |  |         event_type = event.type | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if event_type == 'MOUSEMOVE': | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |             delta = event.mouse_x - self.initial_x | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  |             self._values_delta(delta) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         elif 'LEFTMOUSE' == event_type: | 
					
						
							| 
									
										
										
										
											2011-08-18 16:01:11 +00:00
										 |  |  |             item = next(iter(self._values.keys())) | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  |             self._values_clear() | 
					
						
							| 
									
										
										
										
											2011-08-18 16:01:11 +00:00
										 |  |  |             return operator_value_undo_return(item) | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-08 05:21:37 +00:00
										 |  |  |         elif event_type in {'RIGHTMOUSE', 'ESC'}: | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  |             self._values_restore() | 
					
						
							| 
									
										
										
										
											2011-08-18 16:01:11 +00:00
										 |  |  |             return {'CANCELLED'} | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  |         return {'RUNNING_MODAL'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def invoke(self, context, event): | 
					
						
							|  |  |  |         self._values_store(context) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if not self._values: | 
					
						
							| 
									
										
										
										
											2010-03-06 01:40:29 +00:00
										 |  |  |             self.report({'WARNING'}, "Nothing to operate on: %s[ ].%s" % | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |                     (self.data_path_iter, self.data_path_item)) | 
					
						
							| 
									
										
										
										
											2010-03-06 01:40:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  |             return {'CANCELLED'} | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |             self.initial_x = event.mouse_x | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-08 11:42:11 +00:00
										 |  |  |             context.window_manager.modal_handler_add(self) | 
					
						
							| 
									
										
										
										
											2010-02-21 14:05:02 +00:00
										 |  |  |             return {'RUNNING_MODAL'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_url_open(Operator): | 
					
						
							| 
									
										
										
										
											2010-05-31 11:38:13 +00:00
										 |  |  |     "Open a website in the Webbrowser" | 
					
						
							| 
									
										
										
										
											2010-03-14 20:07:15 +00:00
										 |  |  |     bl_idname = "wm.url_open" | 
					
						
							|  |  |  |     bl_label = "" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |     url = StringProperty( | 
					
						
							|  |  |  |             name="URL", | 
					
						
							|  |  |  |             description="URL to open", | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2010-03-14 20:07:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         import webbrowser | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         webbrowser.open(self.url) | 
					
						
							| 
									
										
										
										
											2010-03-14 20:07:15 +00:00
										 |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_path_open(Operator): | 
					
						
							| 
									
										
										
										
											2010-07-04 10:02:30 +00:00
										 |  |  |     "Open a path in a file browser" | 
					
						
							|  |  |  |     bl_idname = "wm.path_open" | 
					
						
							|  |  |  |     bl_label = "" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |     filepath = StringProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |             name="File Path", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             maxlen=1024, | 
					
						
							|  |  |  |             subtype='FILE_PATH', | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2010-07-04 10:02:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         import sys | 
					
						
							| 
									
										
										
										
											2011-09-23 13:47:29 +00:00
										 |  |  |         import os | 
					
						
							| 
									
										
										
										
											2010-07-04 10:02:30 +00:00
										 |  |  |         import subprocess | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         filepath = bpy.path.abspath(self.filepath) | 
					
						
							| 
									
										
										
										
											2010-07-04 10:02:30 +00:00
										 |  |  |         filepath = os.path.normpath(filepath) | 
					
						
							| 
									
										
										
										
											2010-07-05 22:22:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-04 10:02:30 +00:00
										 |  |  |         if not os.path.exists(filepath): | 
					
						
							|  |  |  |             self.report({'ERROR'}, "File '%s' not found" % filepath) | 
					
						
							|  |  |  |             return {'CANCELLED'} | 
					
						
							| 
									
										
										
										
											2010-07-05 22:22:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-11 01:24:16 +00:00
										 |  |  |         if sys.platform[:3] == "win": | 
					
						
							| 
									
										
										
										
											2010-07-05 22:22:22 +00:00
										 |  |  |             subprocess.Popen(['start', filepath], shell=True) | 
					
						
							| 
									
										
										
										
											2010-07-04 10:02:30 +00:00
										 |  |  |         elif sys.platform == 'darwin': | 
					
						
							|  |  |  |             subprocess.Popen(['open', filepath]) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 subprocess.Popen(['xdg-open', filepath]) | 
					
						
							|  |  |  |             except OSError: | 
					
						
							|  |  |  |                 # xdg-open *should* be supported by recent Gnome, KDE, Xfce | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_doc_view(Operator): | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |     '''Load online reference docs''' | 
					
						
							|  |  |  |     bl_idname = "wm.doc_view" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "View Documentation" | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     doc_id = doc_id | 
					
						
							| 
									
										
										
										
											2011-04-01 15:13:58 +00:00
										 |  |  |     if bpy.app.version_cycle == "release": | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |         _prefix = ("http://www.blender.org/documentation/blender_python_api_%s%s_release" % | 
					
						
							|  |  |  |                    ("_".join(str(v) for v in bpy.app.version[:2]), bpy.app.version_char)) | 
					
						
							| 
									
										
										
										
											2011-04-01 15:13:58 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |         _prefix = ("http://www.blender.org/documentation/blender_python_api_%s" % | 
					
						
							|  |  |  |                    "_".join(str(v) for v in bpy.app.version)) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def _nested_class_string(self, class_string): | 
					
						
							|  |  |  |         ls = [] | 
					
						
							|  |  |  |         class_obj = getattr(bpy.types, class_string, None).bl_rna | 
					
						
							|  |  |  |         while class_obj: | 
					
						
							|  |  |  |             ls.insert(0, class_obj) | 
					
						
							|  |  |  |             class_obj = class_obj.nested | 
					
						
							| 
									
										
										
										
											2010-09-19 07:07:14 +00:00
										 |  |  |         return '.'.join(class_obj.identifier for class_obj in ls) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         id_split = self.doc_id.split('.') | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  |         if len(id_split) == 1:  # rna, class | 
					
						
							| 
									
										
										
										
											2009-12-25 15:50:53 +00:00
										 |  |  |             url = '%s/bpy.types.%s.html' % (self._prefix, id_split[0]) | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  |         elif len(id_split) == 2:  # rna, class.prop | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |             class_name, class_prop = id_split | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if hasattr(bpy.types, class_name.upper() + '_OT_' + class_prop): | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |                 url = ("%s/bpy.ops.%s.html#bpy.ops.%s.%s" % | 
					
						
							|  |  |  |                        (self._prefix, class_name, class_name, class_prop)) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2011-03-27 06:15:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 # detect if this is a inherited member and use that name instead | 
					
						
							|  |  |  |                 rna_parent = getattr(bpy.types, class_name).bl_rna | 
					
						
							|  |  |  |                 rna_prop = rna_parent.properties[class_prop] | 
					
						
							|  |  |  |                 rna_parent = rna_parent.base | 
					
						
							|  |  |  |                 while rna_parent and rna_prop == rna_parent.properties.get(class_prop): | 
					
						
							|  |  |  |                     class_name = rna_parent.identifier | 
					
						
							|  |  |  |                     rna_parent = rna_parent.base | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-25 15:50:53 +00:00
										 |  |  |                 # It so happens that epydoc nests these, not sphinx | 
					
						
							|  |  |  |                 # class_name_full = self._nested_class_string(class_name) | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |                 url = ("%s/bpy.types.%s.html#bpy.types.%s.%s" % | 
					
						
							|  |  |  |                        (self._prefix, class_name, class_name, class_prop)) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2009-12-24 19:50:43 +00:00
										 |  |  |             return {'PASS_THROUGH'} | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         import webbrowser | 
					
						
							|  |  |  |         webbrowser.open(url) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-24 19:50:43 +00:00
										 |  |  |         return {'FINISHED'} | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_doc_edit(Operator): | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |     '''Load online reference docs''' | 
					
						
							|  |  |  |     bl_idname = "wm.doc_edit" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Edit Documentation" | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     doc_id = doc_id | 
					
						
							|  |  |  |     doc_new = doc_new | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _url = "http://www.mindrones.com/blender/svn/xmlrpc.php" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _send_xmlrpc(self, data_dict): | 
					
						
							|  |  |  |         print("sending data:", data_dict) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         import xmlrpc.client | 
					
						
							|  |  |  |         user = 'blenderuser' | 
					
						
							|  |  |  |         pwd = 'blender>user' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         docblog = xmlrpc.client.ServerProxy(self._url) | 
					
						
							|  |  |  |         docblog.metaWeblog.newPost(1, user, pwd, data_dict, 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         doc_id = self.doc_id | 
					
						
							|  |  |  |         doc_new = self.doc_new | 
					
						
							| 
									
										
										
										
											2009-12-13 13:59:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         class_name, class_prop = doc_id.split('.') | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-13 13:59:16 +00:00
										 |  |  |         if not doc_new: | 
					
						
							| 
									
										
										
										
											2010-03-20 19:22:34 +00:00
										 |  |  |             self.report({'ERROR'}, "No input given for '%s'" % doc_id) | 
					
						
							|  |  |  |             return {'CANCELLED'} | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # check if this is an operator | 
					
						
							|  |  |  |         op_name = class_name.upper() + '_OT_' + class_prop | 
					
						
							|  |  |  |         op_class = getattr(bpy.types, op_name, None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Upload this to the web server | 
					
						
							|  |  |  |         upload = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if op_class: | 
					
						
							|  |  |  |             rna = op_class.bl_rna | 
					
						
							|  |  |  |             doc_orig = rna.description | 
					
						
							| 
									
										
										
										
											2009-12-13 13:59:16 +00:00
										 |  |  |             if doc_orig == doc_new: | 
					
						
							| 
									
										
										
										
											2009-12-24 21:17:14 +00:00
										 |  |  |                 return {'RUNNING_MODAL'} | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-13 13:59:16 +00:00
										 |  |  |             print("op - old:'%s' -> new:'%s'" % (doc_orig, doc_new)) | 
					
						
							|  |  |  |             upload["title"] = 'OPERATOR %s:%s' % (doc_id, doc_orig) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             rna = getattr(bpy.types, class_name).bl_rna | 
					
						
							|  |  |  |             doc_orig = rna.properties[class_prop].description | 
					
						
							| 
									
										
										
										
											2009-12-13 13:59:16 +00:00
										 |  |  |             if doc_orig == doc_new: | 
					
						
							| 
									
										
										
										
											2009-12-24 21:17:14 +00:00
										 |  |  |                 return {'RUNNING_MODAL'} | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-13 13:59:16 +00:00
										 |  |  |             print("rna - old:'%s' -> new:'%s'" % (doc_orig, doc_new)) | 
					
						
							|  |  |  |             upload["title"] = 'RNA %s:%s' % (doc_id, doc_orig) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-13 13:59:16 +00:00
										 |  |  |         upload["description"] = doc_new | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self._send_xmlrpc(upload) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-24 19:50:43 +00:00
										 |  |  |         return {'FINISHED'} | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-20 19:22:34 +00:00
										 |  |  |     def draw(self, context): | 
					
						
							|  |  |  |         layout = self.layout | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |         layout.label(text="Descriptor ID: '%s'" % self.doc_id) | 
					
						
							| 
									
										
										
										
											2010-10-27 22:15:55 +00:00
										 |  |  |         layout.prop(self, "doc_new", text="") | 
					
						
							| 
									
										
										
										
											2010-03-20 19:22:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  |     def invoke(self, context, event): | 
					
						
							| 
									
										
										
										
											2010-09-02 04:53:05 +00:00
										 |  |  |         wm = context.window_manager | 
					
						
							| 
									
										
										
										
											2010-03-28 10:52:24 +00:00
										 |  |  |         return wm.invoke_props_dialog(self, width=600) | 
					
						
							| 
									
										
										
										
											2009-11-04 20:21:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  | rna_path = StringProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |         name="Property Edit", | 
					
						
							|  |  |  |         description="Property data_path edit", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |         maxlen=1024, | 
					
						
							|  |  |  |         options={'HIDDEN'}, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | rna_value = StringProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |         name="Property Value", | 
					
						
							|  |  |  |         description="Property value edit", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |         maxlen=1024, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  | rna_property = StringProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |         name="Property Name", | 
					
						
							|  |  |  |         description="Property name edit", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |         maxlen=1024, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  | rna_min = FloatProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |         name="Min", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |         default=0.0, | 
					
						
							|  |  |  |         precision=3, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  | rna_max = FloatProperty( | 
					
						
							|  |  |  |         name="Max", | 
					
						
							|  |  |  |         default=1.0, | 
					
						
							|  |  |  |         precision=3, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_properties_edit(Operator): | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  |     '''Internal use (edit a property data_path)''' | 
					
						
							|  |  |  |     bl_idname = "wm.properties_edit" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Edit Property" | 
					
						
							| 
									
										
										
										
											2011-01-01 07:20:34 +00:00
										 |  |  |     bl_options = {'REGISTER'}  # only because invoke_props_popup requires. | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     data_path = rna_path | 
					
						
							|  |  |  |     property = rna_property | 
					
						
							|  |  |  |     value = rna_value | 
					
						
							|  |  |  |     min = rna_min | 
					
						
							|  |  |  |     max = rna_max | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |     description = StringProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |             name="Tip", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         data_path = self.data_path | 
					
						
							|  |  |  |         value = self.value | 
					
						
							|  |  |  |         prop = self.property | 
					
						
							| 
									
										
										
										
											2011-03-21 23:53:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         prop_old = getattr(self, "_last_prop", [None])[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if prop_old is None: | 
					
						
							|  |  |  |             self.report({'ERROR'}, "Direct execution not supported") | 
					
						
							|  |  |  |             return {'CANCELLED'} | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             value_eval = eval(value) | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             value_eval = value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # First remove | 
					
						
							|  |  |  |         item = eval("context.%s" % data_path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         rna_idprop_ui_prop_clear(item, prop_old) | 
					
						
							|  |  |  |         exec_str = "del item['%s']" % prop_old | 
					
						
							|  |  |  |         # print(exec_str) | 
					
						
							|  |  |  |         exec(exec_str) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Reassign | 
					
						
							|  |  |  |         exec_str = "item['%s'] = %s" % (prop, repr(value_eval)) | 
					
						
							|  |  |  |         # print(exec_str) | 
					
						
							|  |  |  |         exec(exec_str) | 
					
						
							|  |  |  |         self._last_prop[:] = [prop] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         prop_type = type(item[prop]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         prop_ui = rna_idprop_ui_prop_get(item, prop) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-08 05:21:37 +00:00
										 |  |  |         if prop_type in {float, int}: | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |             prop_ui['soft_min'] = prop_ui['min'] = prop_type(self.min) | 
					
						
							|  |  |  |             prop_ui['soft_max'] = prop_ui['max'] = prop_type(self.max) | 
					
						
							| 
									
										
										
										
											2010-02-14 11:21:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         prop_ui['description'] = self.description | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-18 06:36:57 +00:00
										 |  |  |         # otherwise existing buttons which reference freed | 
					
						
							|  |  |  |         # memory may crash blender [#26510] | 
					
						
							| 
									
										
										
										
											2011-03-24 11:38:20 +00:00
										 |  |  |         # context.area.tag_redraw() | 
					
						
							|  |  |  |         for win in context.window_manager.windows: | 
					
						
							|  |  |  |             for area in win.screen.areas: | 
					
						
							|  |  |  |                 area.tag_redraw() | 
					
						
							| 
									
										
										
										
											2011-03-18 06:36:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def invoke(self, context, event): | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         data_path = self.data_path | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         if not data_path: | 
					
						
							| 
									
										
										
										
											2011-03-21 23:53:19 +00:00
										 |  |  |             self.report({'ERROR'}, "Data path not set") | 
					
						
							|  |  |  |             return {'CANCELLED'} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         self._last_prop = [self.property] | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         item = eval("context.%s" % data_path) | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # setup defaults | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         prop_ui = rna_idprop_ui_prop_get(item, self.property, False)  # dont create | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  |         if prop_ui: | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |             self.min = prop_ui.get("min", -1000000000) | 
					
						
							|  |  |  |             self.max = prop_ui.get("max", 1000000000) | 
					
						
							|  |  |  |             self.description = prop_ui.get("description", "") | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-02 04:53:05 +00:00
										 |  |  |         wm = context.window_manager | 
					
						
							| 
									
										
										
										
											2011-01-15 19:15:35 +00:00
										 |  |  |         return wm.invoke_props_dialog(self) | 
					
						
							| 
									
										
										
										
											2010-02-14 11:21:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-14 23:26:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_properties_add(Operator): | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  |     '''Internal use (edit a property data_path)''' | 
					
						
							|  |  |  |     bl_idname = "wm.properties_add" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Add Property" | 
					
						
							| 
									
										
										
										
											2010-02-14 11:21:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  |     data_path = rna_path | 
					
						
							| 
									
										
										
										
											2010-02-14 11:21:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         data_path = self.data_path | 
					
						
							|  |  |  |         item = eval("context.%s" % data_path) | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def unique_name(names): | 
					
						
							|  |  |  |             prop = 'prop' | 
					
						
							|  |  |  |             prop_new = prop | 
					
						
							|  |  |  |             i = 1 | 
					
						
							|  |  |  |             while prop_new in names: | 
					
						
							|  |  |  |                 prop_new = prop + str(i) | 
					
						
							|  |  |  |                 i += 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return prop_new | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         property = unique_name(item.keys()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         item[property] = 1.0 | 
					
						
							|  |  |  |         return {'FINISHED'} | 
					
						
							| 
									
										
										
										
											2010-02-14 11:21:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-02 17:29:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_properties_context_change(Operator): | 
					
						
							| 
									
										
										
										
											2011-04-25 13:47:15 +00:00
										 |  |  |     "Change the context tab in a Properties Window" | 
					
						
							|  |  |  |     bl_idname = "wm.properties_context_change" | 
					
						
							|  |  |  |     bl_label = "" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |     context = StringProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |             name="Context", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             maxlen=32, | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2011-04-25 13:47:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         context.space_data.context = self.context | 
					
						
							| 
									
										
										
										
											2011-04-25 13:47:15 +00:00
										 |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-22 23:32:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_properties_remove(Operator): | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  |     '''Internal use (edit a property data_path)''' | 
					
						
							|  |  |  |     bl_idname = "wm.properties_remove" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Remove Property" | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     data_path = rna_path | 
					
						
							|  |  |  |     property = rna_property | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2011-08-18 15:25:18 +00:00
										 |  |  |         data_path = self.data_path | 
					
						
							|  |  |  |         item = eval("context.%s" % data_path) | 
					
						
							| 
									
										
										
										
											2010-09-09 18:03:57 +00:00
										 |  |  |         del item[self.property] | 
					
						
							| 
									
										
										
										
											2010-08-02 02:55:12 +00:00
										 |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-07 15:17:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_keyconfig_activate(Operator): | 
					
						
							| 
									
										
										
										
											2010-09-14 16:45:24 +00:00
										 |  |  |     bl_idname = "wm.keyconfig_activate" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Activate Keyconfig" | 
					
						
							| 
									
										
										
										
											2010-09-14 16:45:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |     filepath = StringProperty( | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |             name="File Path", | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |             maxlen=1024, | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2010-09-14 16:45:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         bpy.utils.keyconfig_set(self.filepath) | 
					
						
							|  |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 02:41:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_appconfig_default(Operator): | 
					
						
							| 
									
										
										
										
											2011-03-27 21:45:37 +00:00
										 |  |  |     bl_idname = "wm.appconfig_default" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Default Application Configuration" | 
					
						
							| 
									
										
										
										
											2011-03-27 21:45:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2011-09-23 13:47:29 +00:00
										 |  |  |         import os | 
					
						
							| 
									
										
										
										
											2011-03-27 21:45:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         context.window_manager.keyconfigs.active = context.window_manager.keyconfigs.default | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 02:41:15 +00:00
										 |  |  |         filepath = os.path.join(bpy.utils.preset_paths("interaction")[0], "blender.py") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-27 21:45:37 +00:00
										 |  |  |         if os.path.exists(filepath): | 
					
						
							| 
									
										
										
										
											2011-04-01 02:41:15 +00:00
										 |  |  |             bpy.ops.script.execute_preset(filepath=filepath, menu_idname="USERPREF_MT_interaction_presets") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-27 21:45:37 +00:00
										 |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 02:41:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_appconfig_activate(Operator): | 
					
						
							| 
									
										
										
										
											2011-03-27 21:45:37 +00:00
										 |  |  |     bl_idname = "wm.appconfig_activate" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Activate Application Configuration" | 
					
						
							| 
									
										
										
										
											2011-03-27 21:45:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-18 12:20:10 +00:00
										 |  |  |     filepath = StringProperty( | 
					
						
							|  |  |  |             name="File Path", | 
					
						
							|  |  |  |             maxlen=1024, | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2011-03-27 21:45:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2011-09-23 13:47:29 +00:00
										 |  |  |         import os | 
					
						
							| 
									
										
										
										
											2011-03-27 21:45:37 +00:00
										 |  |  |         bpy.utils.keyconfig_set(self.filepath) | 
					
						
							| 
									
										
										
										
											2011-04-01 02:41:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-27 21:45:37 +00:00
										 |  |  |         filepath = self.filepath.replace("keyconfig", "interaction") | 
					
						
							| 
									
										
										
										
											2011-04-01 02:41:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-27 21:45:37 +00:00
										 |  |  |         if os.path.exists(filepath): | 
					
						
							| 
									
										
										
										
											2011-04-01 02:41:15 +00:00
										 |  |  |             bpy.ops.script.execute_preset(filepath=filepath, menu_idname="USERPREF_MT_interaction_presets") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-27 21:45:37 +00:00
										 |  |  |         return {'FINISHED'} | 
					
						
							| 
									
										
										
										
											2011-01-01 07:20:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 02:41:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_sysinfo(Operator): | 
					
						
							| 
									
										
										
										
											2010-10-16 17:26:40 +00:00
										 |  |  |     '''Generate System Info''' | 
					
						
							|  |  |  |     bl_idname = "wm.sysinfo" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "System Info" | 
					
						
							| 
									
										
										
										
											2010-10-16 17:26:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         import sys_info | 
					
						
							|  |  |  |         sys_info.write_sysinfo(self) | 
					
						
							|  |  |  |         return {'FINISHED'} | 
					
						
							| 
									
										
										
										
											2011-03-23 13:04:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-12 06:57:00 +00:00
										 |  |  | class WM_OT_copy_prev_settings(Operator): | 
					
						
							| 
									
										
										
										
											2011-04-12 21:00:53 +00:00
										 |  |  |     '''Copy settings from previous version''' | 
					
						
							| 
									
										
										
										
											2011-04-11 15:13:06 +00:00
										 |  |  |     bl_idname = "wm.copy_prev_settings" | 
					
						
							| 
									
										
										
										
											2011-09-15 13:20:18 +00:00
										 |  |  |     bl_label = "Copy Previous Settings" | 
					
						
							| 
									
										
										
										
											2011-04-11 15:13:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2011-09-23 13:47:29 +00:00
										 |  |  |         import os | 
					
						
							| 
									
										
										
										
											2011-04-11 15:13:06 +00:00
										 |  |  |         import shutil | 
					
						
							|  |  |  |         ver = bpy.app.version | 
					
						
							| 
									
										
										
										
											2011-04-12 04:23:38 +00:00
										 |  |  |         ver_old = ((ver[0] * 100) + ver[1]) - 1 | 
					
						
							|  |  |  |         path_src = bpy.utils.resource_path('USER', ver_old // 100, ver_old % 100) | 
					
						
							|  |  |  |         path_dst = bpy.utils.resource_path('USER') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if os.path.isdir(path_dst): | 
					
						
							|  |  |  |             self.report({'ERROR'}, "Target path %r exists" % path_dst) | 
					
						
							|  |  |  |         elif not os.path.isdir(path_src): | 
					
						
							|  |  |  |             self.report({'ERROR'}, "Source path %r exists" % path_src) | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2011-04-11 15:13:06 +00:00
										 |  |  |             shutil.copytree(path_src, path_dst) | 
					
						
							| 
									
										
											  
											
												Windows installer and Path changes, fixing various issues:
* Windows installer not working for non-admin users and multiple users
* Addon scripts not installing next to user configuration
* Portable install not being taken into account in all places
The main problem was the windows installer was installing system scripts in
AppData next to the user configuration directory, which is not shared between
users. Now these are installed in ProgramFiles, and only addon scripts added
by the users go to AppData.
On all platforms, addon scripts were sometimes getting installed between
system scripts, because the scripts folder in the executable directory was
given precedence over the user configuration folder, that is no longer done
now. So addons now behave like user configuration, they are preserved even
if you download a newer build of the same blender version.
If you have an installation of 2.57 on windows, the addon install location
will not change until we do the version bump to 2.58, to avoid conflicts with
the existing the installed 2.57 version.
The old behavior of giving precedence to the local folder was done to support
portable install, where all configuration is written to the local folder. This
is now implemented differently: if and only if a "config" folder exists in the
local folder, portable install will be assumed, and files will only be written
to that local folder.
											
										 
											2011-05-27 09:57:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # in 2.57 and earlier windows installers, system scripts were copied | 
					
						
							|  |  |  |             # into the configuration directory, don't want to copy those | 
					
						
							|  |  |  |             system_script = os.path.join(path_dst, 'scripts/modules/bpy_types.py') | 
					
						
							|  |  |  |             if os.path.isfile(system_script): | 
					
						
							|  |  |  |                 shutil.rmtree(os.path.join(path_dst, 'scripts')) | 
					
						
							|  |  |  |                 shutil.rmtree(os.path.join(path_dst, 'plugins')) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-12 04:23:38 +00:00
										 |  |  |             # dont loose users work if they open the splash later. | 
					
						
							|  |  |  |             if bpy.data.is_saved is bpy.data.is_dirty is False: | 
					
						
							|  |  |  |                 bpy.ops.wm.read_homefile() | 
					
						
							|  |  |  |             else: | 
					
						
							| 
									
										
										
										
											2011-09-19 14:00:42 +00:00
										 |  |  |                 self.report({'INFO'}, "Reload Start-Up file to restore settings") | 
					
						
							| 
									
										
										
										
											2011-04-12 04:23:38 +00:00
										 |  |  |             return {'FINISHED'} | 
					
						
							| 
									
										
										
										
											2011-04-11 15:13:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-12 04:23:38 +00:00
										 |  |  |         return {'CANCELLED'} | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  | class WM_OT_keyconfig_test(Operator): | 
					
						
							|  |  |  |     "Test keyconfig for conflicts" | 
					
						
							|  |  |  |     bl_idname = "wm.keyconfig_test" | 
					
						
							|  |  |  |     bl_label = "Test Key Configuration for Conflicts" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def testEntry(self, kc, entry, src=None, parent=None): | 
					
						
							|  |  |  |         result = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def kmistr(kmi): | 
					
						
							|  |  |  |             if km.is_modal: | 
					
						
							|  |  |  |                 s = ["kmi = km.keymap_items.new_modal(\'%s\', \'%s\', \'%s\'" % (kmi.propvalue, kmi.type, kmi.value)] | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 s = ["kmi = km.keymap_items.new(\'%s\', \'%s\', \'%s\'" % (kmi.idname, kmi.type, kmi.value)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if kmi.any: | 
					
						
							|  |  |  |                 s.append(", any=True") | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 if kmi.shift: | 
					
						
							|  |  |  |                     s.append(", shift=True") | 
					
						
							|  |  |  |                 if kmi.ctrl: | 
					
						
							|  |  |  |                     s.append(", ctrl=True") | 
					
						
							|  |  |  |                 if kmi.alt: | 
					
						
							|  |  |  |                     s.append(", alt=True") | 
					
						
							|  |  |  |                 if kmi.oskey: | 
					
						
							|  |  |  |                     s.append(", oskey=True") | 
					
						
							|  |  |  |             if kmi.key_modifier and kmi.key_modifier != 'NONE': | 
					
						
							|  |  |  |                 s.append(", key_modifier=\'%s\'" % kmi.key_modifier) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             s.append(")\n") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             props = kmi.properties | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if props is not None: | 
					
						
							|  |  |  |                 export_properties("kmi.properties", props, s) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return "".join(s).strip() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         idname, spaceid, regionid, children = entry | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         km = kc.keymaps.find(idname, space_type=spaceid, region_type=regionid) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if km: | 
					
						
							|  |  |  |             km = km.active() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if src: | 
					
						
							|  |  |  |                 for item in km.keymap_items: | 
					
						
							|  |  |  |                     if src.compare(item): | 
					
						
							|  |  |  |                         print("===========") | 
					
						
							|  |  |  |                         print(parent.name) | 
					
						
							|  |  |  |                         print(kmistr(src)) | 
					
						
							|  |  |  |                         print(km.name) | 
					
						
							|  |  |  |                         print(kmistr(item)) | 
					
						
							|  |  |  |                         result = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 for child in children: | 
					
						
							|  |  |  |                     if self.testEntry(kc, child, src, parent): | 
					
						
							|  |  |  |                         result = True | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 for i in range(len(km.keymap_items)): | 
					
						
							|  |  |  |                     src = km.keymap_items[i] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     for child in children: | 
					
						
							|  |  |  |                         if self.testEntry(kc, child, src, km): | 
					
						
							|  |  |  |                             result = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     for j in range(len(km.keymap_items) - i - 1): | 
					
						
							|  |  |  |                         item = km.keymap_items[j + i + 1] | 
					
						
							|  |  |  |                         if src.compare(item): | 
					
						
							|  |  |  |                             print("===========") | 
					
						
							|  |  |  |                             print(km.name) | 
					
						
							|  |  |  |                             print(kmistr(src)) | 
					
						
							|  |  |  |                             print(kmistr(item)) | 
					
						
							|  |  |  |                             result = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 for child in children: | 
					
						
							|  |  |  |                     if self.testEntry(kc, child): | 
					
						
							|  |  |  |                         result = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return result | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def testConfig(self, kc): | 
					
						
							|  |  |  |         result = False | 
					
						
							|  |  |  |         for entry in KM_HIERARCHY: | 
					
						
							|  |  |  |             if self.testEntry(kc, entry): | 
					
						
							|  |  |  |                 result = True | 
					
						
							|  |  |  |         return result | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         wm = context.window_manager | 
					
						
							|  |  |  |         kc = wm.keyconfigs.default | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if self.testConfig(kc): | 
					
						
							|  |  |  |             print("CONFLICT") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _string_value(value): | 
					
						
							|  |  |  |     if isinstance(value, str) or isinstance(value, bool) or isinstance(value, float) or isinstance(value, int): | 
					
						
							|  |  |  |         result = repr(value) | 
					
						
							|  |  |  |     elif getattr(value, '__len__', False): | 
					
						
							|  |  |  |         return repr(list(value)) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         print("Export key configuration: can't write ", value) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return result | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class WM_OT_keyconfig_import(Operator): | 
					
						
							|  |  |  |     "Import key configuration from a python script" | 
					
						
							|  |  |  |     bl_idname = "wm.keyconfig_import" | 
					
						
							|  |  |  |     bl_label = "Import Key Configuration..." | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     filepath = StringProperty( | 
					
						
							|  |  |  |             name="File Path", | 
					
						
							|  |  |  |             description="Filepath to write file to", | 
					
						
							|  |  |  |             default="keymap.py", | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |     filter_folder = BoolProperty( | 
					
						
							|  |  |  |             name="Filter folders", | 
					
						
							|  |  |  |             default=True, | 
					
						
							|  |  |  |             options={'HIDDEN'}, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |     filter_text = BoolProperty( | 
					
						
							|  |  |  |             name="Filter text", | 
					
						
							|  |  |  |             default=True, | 
					
						
							|  |  |  |             options={'HIDDEN'}, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |     filter_python = BoolProperty( | 
					
						
							|  |  |  |             name="Filter python", | 
					
						
							|  |  |  |             default=True, | 
					
						
							|  |  |  |             options={'HIDDEN'}, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |     keep_original = BoolProperty( | 
					
						
							|  |  |  |             name="Keep original", | 
					
						
							|  |  |  |             description="Keep original file after copying to configuration folder", | 
					
						
							|  |  |  |             default=True, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         from os.path import basename | 
					
						
							|  |  |  |         import shutil | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if not self.filepath: | 
					
						
							|  |  |  |             self.report({'ERROR'}, "Filepath not set") | 
					
						
							|  |  |  |             return {'CANCELLED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         config_name = basename(self.filepath) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         path = bpy.utils.user_resource('SCRIPTS', os.path.join("presets", "keyconfig"), create=True) | 
					
						
							|  |  |  |         path = os.path.join(path, config_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             if self.keep_original: | 
					
						
							|  |  |  |                 shutil.copy(self.filepath, path) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 shutil.move(self.filepath, path) | 
					
						
							|  |  |  |         except Exception as e: | 
					
						
							|  |  |  |             self.report({'ERROR'}, "Installing keymap failed: %s" % e) | 
					
						
							|  |  |  |             return {'CANCELLED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # sneaky way to check we're actually running the code. | 
					
						
							|  |  |  |         bpy.utils.keyconfig_set(path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def invoke(self, context, event): | 
					
						
							|  |  |  |         wm = context.window_manager | 
					
						
							|  |  |  |         wm.fileselect_add(self) | 
					
						
							|  |  |  |         return {'RUNNING_MODAL'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # This operator is also used by interaction presets saving - AddPresetBase | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class WM_OT_keyconfig_export(Operator): | 
					
						
							|  |  |  |     "Export key configuration to a python script" | 
					
						
							|  |  |  |     bl_idname = "wm.keyconfig_export" | 
					
						
							|  |  |  |     bl_label = "Export Key Configuration..." | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     filepath = StringProperty( | 
					
						
							|  |  |  |             name="File Path", | 
					
						
							|  |  |  |             description="Filepath to write file to", | 
					
						
							|  |  |  |             default="keymap.py", | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |     filter_folder = BoolProperty( | 
					
						
							|  |  |  |             name="Filter folders", | 
					
						
							|  |  |  |             default=True, | 
					
						
							|  |  |  |             options={'HIDDEN'}, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |     filter_text = BoolProperty( | 
					
						
							|  |  |  |             name="Filter text", | 
					
						
							|  |  |  |             default=True, | 
					
						
							|  |  |  |             options={'HIDDEN'}, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |     filter_python = BoolProperty( | 
					
						
							|  |  |  |             name="Filter python", | 
					
						
							|  |  |  |             default=True, | 
					
						
							|  |  |  |             options={'HIDDEN'}, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         if not self.filepath: | 
					
						
							|  |  |  |             raise Exception("Filepath not set") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if not self.filepath.endswith('.py'): | 
					
						
							|  |  |  |             self.filepath += '.py' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         f = open(self.filepath, "w") | 
					
						
							|  |  |  |         if not f: | 
					
						
							|  |  |  |             raise Exception("Could not open file") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         wm = context.window_manager | 
					
						
							|  |  |  |         kc = wm.keyconfigs.active | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         f.write("import bpy\n") | 
					
						
							|  |  |  |         f.write("import os\n\n") | 
					
						
							|  |  |  |         f.write("wm = bpy.context.window_manager\n") | 
					
						
							|  |  |  |         f.write("kc = wm.keyconfigs.new(os.path.splitext(os.path.basename(__file__))[0])\n\n")  # keymap must be created by caller | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Generate a list of keymaps to export: | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         # First add all user_modified keymaps (found in keyconfigs.user.keymaps list), | 
					
						
							|  |  |  |         # then add all remaining keymaps from the currently active custom keyconfig. | 
					
						
							|  |  |  |         # | 
					
						
							|  |  |  |         # This will create a final list of keymaps that can be used as a 'diff' against | 
					
						
							|  |  |  |         # the default blender keyconfig, recreating the current setup from a fresh blender | 
					
						
							|  |  |  |         # without needing to export keymaps which haven't been edited. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class FakeKeyConfig(): | 
					
						
							|  |  |  |             keymaps = [] | 
					
						
							|  |  |  |         edited_kc = FakeKeyConfig() | 
					
						
							|  |  |  |         for km in wm.keyconfigs.user.keymaps: | 
					
						
							|  |  |  |             if km.is_user_modified: | 
					
						
							|  |  |  |                 edited_kc.keymaps.append(km) | 
					
						
							|  |  |  |         # merge edited keymaps with non-default keyconfig, if it exists | 
					
						
							|  |  |  |         if kc != wm.keyconfigs.default: | 
					
						
							|  |  |  |             export_keymaps = _merge_keymaps(edited_kc, kc) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             export_keymaps = _merge_keymaps(edited_kc, edited_kc) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for km, kc_x in export_keymaps: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             km = km.active() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             f.write("# Map %s\n" % km.name) | 
					
						
							|  |  |  |             f.write("km = kc.keymaps.new('%s', space_type='%s', region_type='%s', modal=%s)\n\n" % (km.name, km.space_type, km.region_type, km.is_modal)) | 
					
						
							|  |  |  |             for kmi in km.keymap_items: | 
					
						
							|  |  |  |                 if km.is_modal: | 
					
						
							|  |  |  |                     f.write("kmi = km.keymap_items.new_modal('%s', '%s', '%s'" % (kmi.propvalue, kmi.type, kmi.value)) | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     f.write("kmi = km.keymap_items.new('%s', '%s', '%s'" % (kmi.idname, kmi.type, kmi.value)) | 
					
						
							|  |  |  |                 if kmi.any: | 
					
						
							|  |  |  |                     f.write(", any=True") | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     if kmi.shift: | 
					
						
							|  |  |  |                         f.write(", shift=True") | 
					
						
							|  |  |  |                     if kmi.ctrl: | 
					
						
							|  |  |  |                         f.write(", ctrl=True") | 
					
						
							|  |  |  |                     if kmi.alt: | 
					
						
							|  |  |  |                         f.write(", alt=True") | 
					
						
							|  |  |  |                     if kmi.oskey: | 
					
						
							|  |  |  |                         f.write(", oskey=True") | 
					
						
							|  |  |  |                 if kmi.key_modifier and kmi.key_modifier != 'NONE': | 
					
						
							|  |  |  |                     f.write(", key_modifier='%s'" % kmi.key_modifier) | 
					
						
							|  |  |  |                 f.write(")\n") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 props = kmi.properties | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if props is not None: | 
					
						
							|  |  |  |                     f.write("".join(export_properties("kmi.properties", props))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             f.write("\n") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         f.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def invoke(self, context, event): | 
					
						
							|  |  |  |         wm = context.window_manager | 
					
						
							|  |  |  |         wm.fileselect_add(self) | 
					
						
							|  |  |  |         return {'RUNNING_MODAL'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class WM_OT_keymap_restore(Operator): | 
					
						
							|  |  |  |     "Restore key map(s)" | 
					
						
							|  |  |  |     bl_idname = "wm.keymap_restore" | 
					
						
							|  |  |  |     bl_label = "Restore Key Map(s)" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     all = BoolProperty( | 
					
						
							|  |  |  |             name="All Keymaps", | 
					
						
							|  |  |  |             description="Restore all keymaps to default", | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         wm = context.window_manager | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if self.all: | 
					
						
							|  |  |  |             for km in wm.keyconfigs.user.keymaps: | 
					
						
							|  |  |  |                 km.restore_to_default() | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             km = context.keymap | 
					
						
							|  |  |  |             km.restore_to_default() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class WM_OT_keyitem_restore(Operator): | 
					
						
							|  |  |  |     "Restore key map item" | 
					
						
							|  |  |  |     bl_idname = "wm.keyitem_restore" | 
					
						
							|  |  |  |     bl_label = "Restore Key Map Item" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     item_id = IntProperty( | 
					
						
							|  |  |  |             name="Item Identifier", | 
					
						
							|  |  |  |             description="Identifier of the item to remove", | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def poll(cls, context): | 
					
						
							|  |  |  |         keymap = getattr(context, "keymap", None) | 
					
						
							|  |  |  |         return keymap | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         km = context.keymap | 
					
						
							|  |  |  |         kmi = km.keymap_items.from_id(self.item_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (not kmi.is_user_defined) and kmi.is_user_modified: | 
					
						
							|  |  |  |             km.restore_item_to_default(kmi) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class WM_OT_keyitem_add(Operator): | 
					
						
							|  |  |  |     "Add key map item" | 
					
						
							|  |  |  |     bl_idname = "wm.keyitem_add" | 
					
						
							|  |  |  |     bl_label = "Add Key Map Item" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         km = context.keymap | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if km.is_modal: | 
					
						
							|  |  |  |             km.keymap_items.new_modal("", 'A', 'PRESS')  # kmi | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             km.keymap_items.new("none", 'A', 'PRESS')  # kmi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # clear filter and expand keymap so we can see the newly added item | 
					
						
							|  |  |  |         if context.space_data.filter_text != "": | 
					
						
							|  |  |  |             context.space_data.filter_text = "" | 
					
						
							|  |  |  |             km.show_expanded_items = True | 
					
						
							|  |  |  |             km.show_expanded_children = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class WM_OT_keyitem_remove(Operator): | 
					
						
							|  |  |  |     "Remove key map item" | 
					
						
							|  |  |  |     bl_idname = "wm.keyitem_remove" | 
					
						
							|  |  |  |     bl_label = "Remove Key Map Item" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     item_id = IntProperty( | 
					
						
							|  |  |  |             name="Item Identifier", | 
					
						
							|  |  |  |             description="Identifier of the item to remove", | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def poll(cls, context): | 
					
						
							|  |  |  |         return hasattr(context, "keymap") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         km = context.keymap | 
					
						
							|  |  |  |         kmi = km.keymap_items.from_id(self.item_id) | 
					
						
							|  |  |  |         km.keymap_items.remove(kmi) | 
					
						
							|  |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class WM_OT_keyconfig_remove(Operator): | 
					
						
							|  |  |  |     "Remove key config" | 
					
						
							|  |  |  |     bl_idname = "wm.keyconfig_remove" | 
					
						
							|  |  |  |     bl_label = "Remove Key Config" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def poll(cls, context): | 
					
						
							|  |  |  |         wm = context.window_manager | 
					
						
							|  |  |  |         keyconf = wm.keyconfigs.active | 
					
						
							|  |  |  |         return keyconf and keyconf.is_user_defined | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         wm = context.window_manager | 
					
						
							|  |  |  |         keyconfig = wm.keyconfigs.active | 
					
						
							|  |  |  |         wm.keyconfigs.remove(keyconfig) | 
					
						
							|  |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class WM_OT_operator_cheat_sheet(Operator): | 
					
						
							|  |  |  |     bl_idname = "wm.operator_cheat_sheet" | 
					
						
							|  |  |  |     bl_label = "Operator Cheat Sheet" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							|  |  |  |         op_strings = [] | 
					
						
							|  |  |  |         tot = 0 | 
					
						
							|  |  |  |         for op_module_name in dir(bpy.ops): | 
					
						
							|  |  |  |             op_module = getattr(bpy.ops, op_module_name) | 
					
						
							|  |  |  |             for op_submodule_name in dir(op_module): | 
					
						
							|  |  |  |                 op = getattr(op_module, op_submodule_name) | 
					
						
							|  |  |  |                 text = repr(op) | 
					
						
							|  |  |  |                 if text.split("\n")[-1].startswith('bpy.ops.'): | 
					
						
							|  |  |  |                     op_strings.append(text) | 
					
						
							|  |  |  |                     tot += 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             op_strings.append('') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         textblock = bpy.data.texts.new("OperatorList.txt") | 
					
						
							|  |  |  |         textblock.write('# %d Operators\n\n' % tot) | 
					
						
							|  |  |  |         textblock.write('\n'.join(op_strings)) | 
					
						
							|  |  |  |         self.report({'INFO'}, "See OperatorList.txt textblock") | 
					
						
							|  |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  | class WM_OT_addon_enable(Operator): | 
					
						
							|  |  |  |     "Enable an addon" | 
					
						
							|  |  |  |     bl_idname = "wm.addon_enable" | 
					
						
							|  |  |  |     bl_label = "Enable Add-On" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     module = StringProperty( | 
					
						
							|  |  |  |             name="Module", | 
					
						
							|  |  |  |             description="Module name of the addon to enable", | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2011-09-23 13:47:29 +00:00
										 |  |  |         import addon_utils | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  |         mod = addon_utils.enable(self.module) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if mod: | 
					
						
							|  |  |  |             info = addon_utils.module_bl_info(mod) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             info_ver = info.get("blender", (0, 0, 0)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if info_ver > bpy.app.version: | 
					
						
							|  |  |  |                 self.report({'WARNING'}, ("This script was written Blender " | 
					
						
							|  |  |  |                                           "version %d.%d.%d and might not " | 
					
						
							|  |  |  |                                           "function (correctly), " | 
					
						
							|  |  |  |                                           "though it is enabled") % | 
					
						
							|  |  |  |                                          info_ver) | 
					
						
							|  |  |  |             return {'FINISHED'} | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return {'CANCELLED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class WM_OT_addon_disable(Operator): | 
					
						
							|  |  |  |     "Disable an addon" | 
					
						
							|  |  |  |     bl_idname = "wm.addon_disable" | 
					
						
							|  |  |  |     bl_label = "Disable Add-On" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     module = StringProperty( | 
					
						
							|  |  |  |             name="Module", | 
					
						
							|  |  |  |             description="Module name of the addon to disable", | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2011-09-23 13:47:29 +00:00
										 |  |  |         import addon_utils | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  |         addon_utils.disable(self.module) | 
					
						
							|  |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class WM_OT_addon_install(Operator): | 
					
						
							|  |  |  |     "Install an addon" | 
					
						
							|  |  |  |     bl_idname = "wm.addon_install" | 
					
						
							|  |  |  |     bl_label = "Install Add-On..." | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     overwrite = BoolProperty( | 
					
						
							|  |  |  |             name="Overwrite", | 
					
						
							|  |  |  |             description="Remove existing addons with the same ID", | 
					
						
							|  |  |  |             default=True, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |     target = EnumProperty( | 
					
						
							|  |  |  |             name="Target Path", | 
					
						
							|  |  |  |             items=(('DEFAULT', "Default", ""), | 
					
						
							|  |  |  |                    ('PREFS', "User Prefs", "")), | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     filepath = StringProperty( | 
					
						
							|  |  |  |             name="File Path", | 
					
						
							|  |  |  |             description="File path to write file to", | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |     filter_folder = BoolProperty( | 
					
						
							|  |  |  |             name="Filter folders", | 
					
						
							|  |  |  |             default=True, | 
					
						
							|  |  |  |             options={'HIDDEN'}, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |     filter_python = BoolProperty( | 
					
						
							|  |  |  |             name="Filter python", | 
					
						
							|  |  |  |             default=True, | 
					
						
							|  |  |  |             options={'HIDDEN'}, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |     filter_glob = StringProperty( | 
					
						
							|  |  |  |             default="*.py;*.zip", | 
					
						
							|  |  |  |             options={'HIDDEN'}, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def _module_remove(path_addons, module): | 
					
						
							|  |  |  |         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): | 
					
						
							| 
									
										
										
										
											2011-09-23 13:47:29 +00:00
										 |  |  |         import addon_utils | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  |         import traceback | 
					
						
							|  |  |  |         import zipfile | 
					
						
							|  |  |  |         import shutil | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         pyfile = self.filepath | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if self.target == 'DEFAULT': | 
					
						
							|  |  |  |             # dont use bpy.utils.script_paths("addons") because we may not be able to write to it. | 
					
						
							|  |  |  |             path_addons = bpy.utils.user_resource('SCRIPTS', "addons", create=True) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             path_addons = bpy.context.user_preferences.filepaths.script_directory | 
					
						
							|  |  |  |             if path_addons: | 
					
						
							|  |  |  |                 path_addons = os.path.join(path_addons, "addons") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if not path_addons: | 
					
						
							|  |  |  |             self.report({'ERROR'}, "Failed to get addons path") | 
					
						
							|  |  |  |             return {'CANCELLED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # create dir is if missing. | 
					
						
							|  |  |  |         if not os.path.exists(path_addons): | 
					
						
							|  |  |  |             os.makedirs(path_addons) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Check if we are installing from a target path, | 
					
						
							|  |  |  |         # doing so causes 2+ addons of same name or when the same from/to | 
					
						
							|  |  |  |         # location is used, removal of the file! | 
					
						
							|  |  |  |         addon_path = "" | 
					
						
							|  |  |  |         pyfile_dir = os.path.dirname(pyfile) | 
					
						
							|  |  |  |         for addon_path in addon_utils.paths(): | 
					
						
							|  |  |  |             if os.path.samefile(pyfile_dir, addon_path): | 
					
						
							|  |  |  |                 self.report({'ERROR'}, "Source file is in the addon search path: %r" % addon_path) | 
					
						
							|  |  |  |                 return {'CANCELLED'} | 
					
						
							|  |  |  |         del addon_path | 
					
						
							|  |  |  |         del pyfile_dir | 
					
						
							|  |  |  |         # done checking for exceptional case | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-23 13:47:29 +00:00
										 |  |  |         addons_old = {mod.__name__ for mod in addon_utils.modules(addon_utils.addons_fake_modules)} | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         #check to see if the file is in compressed format (.zip) | 
					
						
							|  |  |  |         if zipfile.is_zipfile(pyfile): | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 file_to_extract = zipfile.ZipFile(pyfile, 'r') | 
					
						
							|  |  |  |             except: | 
					
						
							|  |  |  |                 traceback.print_exc() | 
					
						
							|  |  |  |                 return {'CANCELLED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if self.overwrite: | 
					
						
							|  |  |  |                 for f in file_to_extract.namelist(): | 
					
						
							|  |  |  |                     WM_OT_addon_install._module_remove(path_addons, f) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 for f in file_to_extract.namelist(): | 
					
						
							|  |  |  |                     path_dest = os.path.join(path_addons, 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 "addons" | 
					
						
							|  |  |  |                 file_to_extract.extractall(path_addons) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # zip files can create this dir with metadata, don't need it | 
					
						
							|  |  |  |                 macosx_dir = os.path.join(path_addons, '__MACOSX') | 
					
						
							|  |  |  |                 if os.path.isdir(macosx_dir): | 
					
						
							|  |  |  |                     shutil.rmtree(macosx_dir) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             except: | 
					
						
							|  |  |  |                 traceback.print_exc() | 
					
						
							|  |  |  |                 return {'CANCELLED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             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)) | 
					
						
							|  |  |  |             elif os.path.exists(path_dest): | 
					
						
							|  |  |  |                 self.report({'WARNING'}, "File already installed to %r\n" % path_dest) | 
					
						
							|  |  |  |                 return {'CANCELLED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             #if not compressed file just copy into the addon path | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 shutil.copyfile(pyfile, path_dest) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             except: | 
					
						
							|  |  |  |                 traceback.print_exc() | 
					
						
							|  |  |  |                 return {'CANCELLED'} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-23 13:47:29 +00:00
										 |  |  |         addons_new = {mod.__name__ for mod in addon_utils.modules(addon_utils.addons_fake_modules)} - addons_old | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  |         addons_new.discard("modules") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # disable any addons we may have enabled previously and removed. | 
					
						
							|  |  |  |         # this is unlikely but do just incase. bug [#23978] | 
					
						
							|  |  |  |         for new_addon in addons_new: | 
					
						
							|  |  |  |             addon_utils.disable(new_addon) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # possible the zip contains multiple addons, we could disallow this | 
					
						
							|  |  |  |         # but for now just use the first | 
					
						
							| 
									
										
										
										
											2011-09-23 13:47:29 +00:00
										 |  |  |         for mod in addon_utils.modules(addon_utils.addons_fake_modules): | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  |             if mod.__name__ in addons_new: | 
					
						
							|  |  |  |                 info = addon_utils.module_bl_info(mod) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # show the newly installed addon. | 
					
						
							|  |  |  |                 context.window_manager.addon_filter = 'All' | 
					
						
							|  |  |  |                 context.window_manager.addon_search = info["name"] | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # incase a new module path was created to install this addon. | 
					
						
							|  |  |  |         bpy.utils.refresh_script_paths() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # TODO, should not be a warning. | 
					
						
							|  |  |  |         # self.report({'WARNING'}, "File installed to '%s'\n" % path_dest) | 
					
						
							|  |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def invoke(self, context, event): | 
					
						
							|  |  |  |         wm = context.window_manager | 
					
						
							|  |  |  |         wm.fileselect_add(self) | 
					
						
							|  |  |  |         return {'RUNNING_MODAL'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class WM_OT_addon_remove(Operator): | 
					
						
							|  |  |  |     "Disable an addon" | 
					
						
							|  |  |  |     bl_idname = "wm.addon_remove" | 
					
						
							|  |  |  |     bl_label = "Remove Add-On" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     module = StringProperty( | 
					
						
							|  |  |  |             name="Module", | 
					
						
							|  |  |  |             description="Module name of the addon to remove", | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def path_from_addon(module): | 
					
						
							| 
									
										
										
										
											2011-09-23 13:47:29 +00:00
										 |  |  |         import addon_utils | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for mod in addon_utils.modules(addon_utils.addons_fake_modules): | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  |             if mod.__name__ == module: | 
					
						
							|  |  |  |                 filepath = mod.__file__ | 
					
						
							|  |  |  |                 if os.path.exists(filepath): | 
					
						
							|  |  |  |                     if os.path.splitext(os.path.basename(filepath))[0] == "__init__": | 
					
						
							|  |  |  |                         return os.path.dirname(filepath), True | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         return filepath, False | 
					
						
							|  |  |  |         return None, False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2011-09-23 13:47:29 +00:00
										 |  |  |         import addon_utils | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  |         path, isdir = WM_OT_addon_remove.path_from_addon(self.module) | 
					
						
							|  |  |  |         if path is None: | 
					
						
							|  |  |  |             self.report('WARNING', "Addon path %r could not be found" % path) | 
					
						
							|  |  |  |             return {'CANCELLED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # incase its enabled | 
					
						
							|  |  |  |         addon_utils.disable(self.module) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         import shutil | 
					
						
							|  |  |  |         if isdir: | 
					
						
							|  |  |  |             shutil.rmtree(path) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             os.remove(path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         context.area.tag_redraw() | 
					
						
							|  |  |  |         return {'FINISHED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # lame confirmation check | 
					
						
							|  |  |  |     def draw(self, context): | 
					
						
							|  |  |  |         self.layout.label(text="Remove Addon: %r?" % self.module) | 
					
						
							|  |  |  |         path, isdir = WM_OT_addon_remove.path_from_addon(self.module) | 
					
						
							|  |  |  |         self.layout.label(text="Path: %r" % path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def invoke(self, context, event): | 
					
						
							|  |  |  |         wm = context.window_manager | 
					
						
							|  |  |  |         return wm.invoke_props_dialog(self, width=600) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class WM_OT_addon_expand(Operator): | 
					
						
							|  |  |  |     "Display more information on this add-on" | 
					
						
							|  |  |  |     bl_idname = "wm.addon_expand" | 
					
						
							|  |  |  |     bl_label = "" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     module = StringProperty( | 
					
						
							|  |  |  |             name="Module", | 
					
						
							|  |  |  |             description="Module name of the addon to expand", | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def execute(self, context): | 
					
						
							| 
									
										
										
										
											2011-09-23 13:47:29 +00:00
										 |  |  |         import addon_utils | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  |         module_name = self.module | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # unlikely to fail, module should have already been imported | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             # mod = __import__(module_name) | 
					
						
							| 
									
										
										
										
											2011-09-23 13:47:29 +00:00
										 |  |  |             mod = addon_utils.addons_fake_modules.get(module_name) | 
					
						
							| 
									
										
										
										
											2011-09-22 19:50:41 +00:00
										 |  |  |         except: | 
					
						
							|  |  |  |             import traceback | 
					
						
							|  |  |  |             traceback.print_exc() | 
					
						
							|  |  |  |             return {'CANCELLED'} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         info = addon_utils.module_bl_info(mod) | 
					
						
							|  |  |  |         info["show_expanded"] = not info["show_expanded"] | 
					
						
							|  |  |  |         return {'FINISHED'} |