UI: initialize Overridable Static checkbox for custom properties.
[blender.git] / release / scripts / startup / bl_operators / wm.py
index f082fd308c6a1907e52bcc3998bbfd76fa997810..e26e2ddf214a82f1eb25f98edea11a19dbf5f7eb 100644 (file)
@@ -162,42 +162,6 @@ def module_filesystem_remove(path_base, module_name):
                 os.remove(f_full)
 
 
                 os.remove(f_full)
 
 
-class BRUSH_OT_active_index_set(Operator):
-    """Set active sculpt/paint brush from it's number"""
-    bl_idname = "brush.active_index_set"
-    bl_label = "Set Brush Number"
-
-    mode: StringProperty(
-        name="Mode",
-        description="Paint mode to set brush for",
-        maxlen=1024,
-    )
-    index: IntProperty(
-        name="Number",
-        description="Brush number",
-    )
-
-    _attr_dict = {
-        "sculpt": "use_paint_sculpt",
-        "vertex_paint": "use_paint_vertex",
-        "weight_paint": "use_paint_weight",
-        "image_paint": "use_paint_image",
-    }
-
-    def execute(self, context):
-        attr = self._attr_dict.get(self.mode)
-        if attr is None:
-            return {'CANCELLED'}
-
-        toolsettings = context.tool_settings
-        for i, brush in enumerate((cur for cur in bpy.data.brushes if getattr(cur, attr))):
-            if i == self.index:
-                getattr(toolsettings, self.mode).brush = brush
-                return {'FINISHED'}
-
-        return {'CANCELLED'}
-
-
 class WM_OT_context_set_boolean(Operator):
     """Set a context value"""
     bl_idname = "wm.context_set_boolean"
 class WM_OT_context_set_boolean(Operator):
     """Set a context value"""
     bl_idname = "wm.context_set_boolean"
@@ -1060,9 +1024,9 @@ class WM_OT_doc_view(Operator):
 
     doc_id: doc_id
     if bpy.app.version_cycle == "release":
 
     doc_id: doc_id
     if bpy.app.version_cycle == "release":
-        _prefix = ("https://docs.blender.org/api/blender_python_api_current")
+        _prefix = ("https://docs.blender.org/api/current")
     else:
     else:
-        _prefix = ("https://docs.blender.org/api/blender_python_api_master")
+        _prefix = ("https://docs.blender.org/api/blender2.8")
 
     def execute(self, context):
         url = _wm_doc_get_id(self.doc_id, do_url=True, url_prefix=self._prefix)
 
     def execute(self, context):
         url = _wm_doc_get_id(self.doc_id, do_url=True, url_prefix=self._prefix)
@@ -1255,6 +1219,10 @@ class WM_OT_properties_edit(Operator):
 
         item = eval("context.%s" % data_path)
 
 
         item = eval("context.%s" % data_path)
 
+        # retrieve overridable static
+        exec_str = "item.is_property_overridable_static('[\"%s\"]')" % (self.property)
+        self.is_overridable_static = bool(eval(exec_str))
+
         # setup defaults
         prop_ui = rna_idprop_ui_prop_get(item, self.property, False)  # don't create
         if prop_ui:
         # setup defaults
         prop_ui = rna_idprop_ui_prop_get(item, self.property, False)  # don't create
         if prop_ui:
@@ -1419,49 +1387,6 @@ class WM_OT_keyconfig_activate(Operator):
             return {'CANCELLED'}
 
 
             return {'CANCELLED'}
 
 
-class WM_OT_appconfig_default(Operator):
-    bl_idname = "wm.appconfig_default"
-    bl_label = "Default Application Configuration"
-
-    def execute(self, context):
-        import os
-
-        context.window_manager.keyconfigs.active = context.window_manager.keyconfigs.default
-
-        filepath = os.path.join(bpy.utils.preset_paths("interaction")[0], "blender.py")
-
-        if os.path.exists(filepath):
-            bpy.ops.script.execute_preset(
-                filepath=filepath,
-                menu_idname="USERPREF_MT_interaction_presets",
-            )
-
-        return {'FINISHED'}
-
-
-class WM_OT_appconfig_activate(Operator):
-    bl_idname = "wm.appconfig_activate"
-    bl_label = "Activate Application Configuration"
-
-    filepath: StringProperty(
-        subtype='FILE_PATH',
-    )
-
-    def execute(self, context):
-        import os
-        filepath = self.filepath
-        bpy.utils.keyconfig_set(filepath)
-        dirname, filename = os.path.split(filepath)
-        filepath = os.path.normpath(os.path.join(dirname, os.pardir, "interaction", filename))
-        if os.path.exists(filepath):
-            bpy.ops.script.execute_preset(
-                filepath=filepath,
-                menu_idname="USERPREF_MT_interaction_presets",
-            )
-
-        return {'FINISHED'}
-
-
 class WM_OT_sysinfo(Operator):
     """Generate system information, saved into a text file"""
 
 class WM_OT_sysinfo(Operator):
     """Generate system information, saved into a text file"""
 
@@ -1656,7 +1581,7 @@ class WM_OT_keyconfig_export(Operator):
     )
 
     def execute(self, context):
     )
 
     def execute(self, context):
-        from bpy_extras import keyconfig_utils
+        from bl_keymap_utils.io import keyconfig_export_as_data
 
         if not self.filepath:
             raise Exception("Filepath not set")
 
         if not self.filepath:
             raise Exception("Filepath not set")
@@ -1666,7 +1591,7 @@ class WM_OT_keyconfig_export(Operator):
 
         wm = context.window_manager
 
 
         wm = context.window_manager
 
-        keyconfig_utils.keyconfig_export_as_data(
+        keyconfig_export_as_data(
             wm,
             wm.keyconfigs.active,
             self.filepath,
             wm,
             wm.keyconfigs.active,
             self.filepath,
@@ -2255,7 +2180,7 @@ class WM_OT_addon_userpref_show(Operator):
 
         module_name = self.module
 
 
         module_name = self.module
 
-        modules = addon_utils.modules(refresh=False)
+        _modules = addon_utils.modules(refresh=False)
         mod = addon_utils.addons_fake_modules.get(module_name)
         if mod is not None:
             info = addon_utils.module_bl_info(mod)
         mod = addon_utils.addons_fake_modules.get(module_name)
         if mod is not None:
             info = addon_utils.module_bl_info(mod)
@@ -2393,9 +2318,9 @@ class WM_OT_tool_set_by_name(Operator):
             if not self.properties.is_property_set("name"):
                 WM_OT_toolbar._key_held = False
                 return {'PASS_THROUGH'}
             if not self.properties.is_property_set("name"):
                 WM_OT_toolbar._key_held = False
                 return {'PASS_THROUGH'}
-            elif WM_OT_toolbar._key_held and event.value != 'RELEASE':
+            elif (WM_OT_toolbar._key_held == event.type) and (event.value != 'RELEASE'):
                 return {'PASS_THROUGH'}
                 return {'PASS_THROUGH'}
-            WM_OT_toolbar._key_held = False
+            WM_OT_toolbar._key_held = None
 
             return self.execute(context)
 
 
             return self.execute(context)
 
@@ -2422,32 +2347,29 @@ class WM_OT_toolbar(Operator):
     bl_idname = "wm.toolbar"
     bl_label = "Toolbar"
 
     bl_idname = "wm.toolbar"
     bl_label = "Toolbar"
 
-    if use_toolbar_release_hack:
-        _key_held = False
-
     @classmethod
     def poll(cls, context):
         return context.space_data is not None
 
     @classmethod
     def poll(cls, context):
         return context.space_data is not None
 
+    if use_toolbar_release_hack:
+        _key_held = None
+        def invoke(self, context, event):
+            WM_OT_toolbar._key_held = event.type
+            return self.execute(context)
+
     def execute(self, context):
     def execute(self, context):
-        from bl_ui.space_toolsystem_common import (
-            ToolSelectPanelHelper,
-            keymap_from_context,
-        )
-        space_type = context.space_data.type
+        from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
+        from bl_keymap_utils import keymap_from_toolbar
 
 
+        space_type = context.space_data.type
         cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type)
         if cls is None:
             return {'CANCELLED'}
 
         wm = context.window_manager
         cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type)
         if cls is None:
             return {'CANCELLED'}
 
         wm = context.window_manager
-        keymap = keymap_from_context(context, space_type)
+        keymap = keymap_from_toolbar.generate(context, space_type)
 
         def draw_menu(popover, context):
 
         def draw_menu(popover, context):
-            if use_toolbar_release_hack:
-                # Release event sets false.
-                WM_OT_toolbar._key_held = True
-
             layout = popover.layout
             layout.operator_context = 'INVOKE_REGION_WIN'
             cls.draw_cls(layout, context, detect_layout=False, scale_y=1.0)
             layout = popover.layout
             layout.operator_context = 'INVOKE_REGION_WIN'
             cls.draw_cls(layout, context, detect_layout=False, scale_y=1.0)
@@ -2478,11 +2400,11 @@ class WM_OT_studiolight_install(Operator):
         default="*.png;*.jpg;*.hdr;*.exr",
         options={'HIDDEN'},
     )
         default="*.png;*.jpg;*.hdr;*.exr",
         options={'HIDDEN'},
     )
-    orientation: EnumProperty(
+    type: EnumProperty(
         items=(
             ('MATCAP', "MatCap", ""),
             ('WORLD', "World", ""),
         items=(
             ('MATCAP', "MatCap", ""),
             ('WORLD', "World", ""),
-            ('CAMERA', "Camera", ""),
+            ('STUDIO', "Studio", ""),
         )
     )
 
         )
     )
 
@@ -2499,7 +2421,7 @@ class WM_OT_studiolight_install(Operator):
             self.report({'ERROR'}, "Failed to get Studio Light path")
             return {'CANCELLED'}
 
             self.report({'ERROR'}, "Failed to get Studio Light path")
             return {'CANCELLED'}
 
-        path_studiolights = pathlib.Path(path_studiolights, "studiolights", self.orientation.lower())
+        path_studiolights = pathlib.Path(path_studiolights, "studiolights", self.type.lower())
         if not path_studiolights.exists():
             try:
                 path_studiolights.mkdir(parents=True, exist_ok=True)
         if not path_studiolights.exists():
             try:
                 path_studiolights.mkdir(parents=True, exist_ok=True)
@@ -2508,7 +2430,7 @@ class WM_OT_studiolight_install(Operator):
 
         for filepath in filepaths:
             shutil.copy(str(filepath), str(path_studiolights))
 
         for filepath in filepaths:
             shutil.copy(str(filepath), str(path_studiolights))
-            userpref.studio_lights.new(str(path_studiolights.joinpath(filepath.name)), self.orientation)
+            userpref.studio_lights.load(str(path_studiolights.joinpath(filepath.name)), self.type)
 
         # print message
         msg = (
 
         # print message
         msg = (
@@ -2525,7 +2447,71 @@ class WM_OT_studiolight_install(Operator):
         return {'RUNNING_MODAL'}
 
 
         return {'RUNNING_MODAL'}
 
 
+class WM_OT_studiolight_new(Operator):
+    """Save custom studio light from the studio light editor settings"""
+    bl_idname = 'wm.studiolight_new'
+    bl_label = "Save custom Studio light"
+
+    filename: StringProperty(
+        name="Name",
+        default="StudioLight",
+    )
+
+    ask_overide = False
+
+    def execute(self, context):
+        import pathlib
+        userpref = context.user_preferences
+        wm = context.window_manager
+
+        path_studiolights = bpy.utils.user_resource('DATAFILES')
+
+        if not path_studiolights:
+            self.report({'ERROR'}, "Failed to get Studio Light path")
+            return {'CANCELLED'}
+
+        path_studiolights = pathlib.Path(path_studiolights, "studiolights", "studio")
+        if not path_studiolights.exists():
+            try:
+                path_studiolights.mkdir(parents=True, exist_ok=True)
+            except:
+                traceback.print_exc()
+
+        finalpath = str(path_studiolights.joinpath(self.filename));
+        if pathlib.Path(finalpath + ".sl").is_file():
+            if not self.ask_overide:
+                self.ask_overide = True
+                return wm.invoke_props_dialog(self, width=600)
+            else:
+                for studio_light in userpref.studio_lights:
+                    if studio_light.name == self.filename + ".sl":
+                        bpy.ops.wm.studiolight_uninstall(index=studio_light.index)
+
+        userpref.studio_lights.new(path=finalpath)
+
+        # print message
+        msg = (
+            tip_("StudioLight Installed %r into %r") %
+            (self.filename, str(path_studiolights))
+        )
+        print(msg)
+        self.report({'INFO'}, msg)
+        return {'FINISHED'}
+
+    def draw(self, context):
+        layout = self.layout
+        if self.ask_overide:
+            layout.label(text="Warning, file already exists. Overwrite existing file?")
+        else:
+            layout.prop(self, "filename")
+
+    def invoke(self, context, event):
+        wm = context.window_manager
+        return wm.invoke_props_dialog(self, width=600)
+
+
 class WM_OT_studiolight_uninstall(Operator):
 class WM_OT_studiolight_uninstall(Operator):
+    """Delete Studio Light"""
     bl_idname = 'wm.studiolight_uninstall'
     bl_label = "Uninstall Studio Light"
     index: bpy.props.IntProperty()
     bl_idname = 'wm.studiolight_uninstall'
     bl_label = "Uninstall Studio Light"
     index: bpy.props.IntProperty()
@@ -2550,6 +2536,28 @@ class WM_OT_studiolight_uninstall(Operator):
         return {'CANCELLED'}
 
 
         return {'CANCELLED'}
 
 
+class WM_OT_studiolight_copy_settings(Operator):
+    """Copy Studio Light settings to the Studio light editor"""
+    bl_idname = 'wm.studiolight_copy_settings'
+    bl_label = "Copy Studio Light settings"
+    index: bpy.props.IntProperty()
+
+    def execute(self, context):
+        userpref = context.user_preferences
+        system = userpref.system
+        for studio_light in userpref.studio_lights:
+            if studio_light.index == self.index:
+                system.light_ambient = studio_light.light_ambient
+                for sys_light, light in zip(system.solid_lights, studio_light.solid_lights):
+                    sys_light.use = light.use
+                    sys_light.diffuse_color = light.diffuse_color
+                    sys_light.specular_color = light.specular_color
+                    sys_light.smooth = light.smooth
+                    sys_light.direction = light.direction
+                return {'FINISHED'}
+        return {'CANCELLED'}
+
+
 class WM_OT_studiolight_userpref_show(Operator):
     """Show light user preferences"""
     bl_idname = "wm.studiolight_userpref_show"
 class WM_OT_studiolight_userpref_show(Operator):
     """Show light user preferences"""
     bl_idname = "wm.studiolight_userpref_show"
@@ -2567,7 +2575,7 @@ class WM_MT_splash(Menu):
 
     def draw_setup(self, context):
         wm = context.window_manager
 
     def draw_setup(self, context):
         wm = context.window_manager
-        userpref = context.user_preferences
+        userpref = context.user_preferences
 
         layout = self.layout
 
 
         layout = self.layout
 
@@ -2592,11 +2600,25 @@ class WM_MT_splash(Menu):
             text = "Blender"
         sub.menu("USERPREF_MT_keyconfigs", text=text)
 
             text = "Blender"
         sub.menu("USERPREF_MT_keyconfigs", text=text)
 
-        sub = col.split(factor=0.35)
-        row = sub.row()
-        row.alignment = 'RIGHT'
-        row.label(text="Select With")
-        sub.row().prop(userpref.inputs, 'select_mouse', expand=True)
+        kc = wm.keyconfigs.active
+        kc_prefs = kc.preferences
+        has_select_mouse = hasattr(kc_prefs, "select_mouse")
+        if has_select_mouse:
+            sub = col.split(factor=0.35)
+            row = sub.row()
+            row.alignment = 'RIGHT'
+            row.label(text="Select With")
+            sub.row().prop(kc_prefs, "select_mouse", expand=True)
+            has_select_mouse = True
+
+        has_spacebar_action = hasattr(kc_prefs, "spacebar_action")
+        if has_spacebar_action:
+            sub = col.split(factor=0.35)
+            row = sub.row()
+            row.alignment = 'RIGHT'
+            row.label(text="Spacebar")
+            sub.row().prop(kc_prefs, "spacebar_action", expand=True)
+            has_select_mouse = True
 
         col.separator()
 
 
         col.separator()
 
@@ -2617,7 +2639,11 @@ class WM_MT_splash(Menu):
         #userpref = context.user_preferences
         #sub.prop(userpref.system, "language", text="")
 
         #userpref = context.user_preferences
         #sub.prop(userpref.system, "language", text="")
 
-        col.label()
+        # Keep height constant
+        if not has_select_mouse:
+            col.label()
+        if not has_spacebar_action:
+            col.label()
 
         layout.label()
 
 
         layout.label()
 
@@ -2634,6 +2660,7 @@ class WM_MT_splash(Menu):
             sub.operator("wm.save_userpref", text="Next")
 
         layout.separator()
             sub.operator("wm.save_userpref", text="Next")
 
         layout.separator()
+        layout.separator()
 
     def draw(self, context):
         # Draw setup screen if no user preferences have been saved yet.
 
     def draw(self, context):
         # Draw setup screen if no user preferences have been saved yet.
@@ -2711,6 +2738,7 @@ class WM_MT_splash(Menu):
             ).url = "https://www.blender.org/foundation/donation-payment/"
 
         layout.separator()
             ).url = "https://www.blender.org/foundation/donation-payment/"
 
         layout.separator()
+        layout.separator()
 
 
 class WM_OT_drop_blend_file(Operator):
 
 
 class WM_OT_drop_blend_file(Operator):
@@ -2738,7 +2766,6 @@ class WM_OT_drop_blend_file(Operator):
         col.operator("wm.append", text="Append...", icon='APPEND_BLEND').filepath = self.filepath
 
 classes = (
         col.operator("wm.append", text="Append...", icon='APPEND_BLEND').filepath = self.filepath
 
 classes = (
-    BRUSH_OT_active_index_set,
     WM_OT_addon_disable,
     WM_OT_addon_enable,
     WM_OT_addon_expand,
     WM_OT_addon_disable,
     WM_OT_addon_enable,
     WM_OT_addon_expand,
@@ -2747,8 +2774,6 @@ classes = (
     WM_OT_addon_remove,
     WM_OT_addon_userpref_show,
     WM_OT_app_template_install,
     WM_OT_addon_remove,
     WM_OT_addon_userpref_show,
     WM_OT_app_template_install,
-    WM_OT_appconfig_activate,
-    WM_OT_appconfig_default,
     WM_OT_context_collection_boolean_set,
     WM_OT_context_cycle_array,
     WM_OT_context_cycle_enum,
     WM_OT_context_collection_boolean_set,
     WM_OT_context_cycle_array,
     WM_OT_context_cycle_enum,
@@ -2793,7 +2818,9 @@ classes = (
     WM_OT_owner_enable,
     WM_OT_url_open,
     WM_OT_studiolight_install,
     WM_OT_owner_enable,
     WM_OT_url_open,
     WM_OT_studiolight_install,
+    WM_OT_studiolight_new,
     WM_OT_studiolight_uninstall,
     WM_OT_studiolight_uninstall,
+    WM_OT_studiolight_copy_settings,
     WM_OT_studiolight_userpref_show,
     WM_OT_tool_set_by_name,
     WM_OT_toolbar,
     WM_OT_studiolight_userpref_show,
     WM_OT_tool_set_by_name,
     WM_OT_toolbar,