How to set correct context for bpy.ops.time.view_all ?

I want to call: bpy.ops.time.view_all() from an Operator, but I get this message:

RuntimeError: Operator bpy.ops.time.view_all.poll() failed, context is incorrect

Is there an easy way to do this?
If not … is there a hard way?

Here’s the Operator as I currently have it:

class CBM_OT_refresh_operator(bpy.types.Operator):
    bl_idname = "cbm.refresh_operator"
    bl_label = "Refresh"
    bl_description = ("Simulate Refresh")
    bl_options = {'REGISTER'}

    def execute(self, context):
        print ( "Refreshing/Reloading the Data" )
        bpy.ops.time.view_all()   # RuntimeError: Operator bpy.ops.time.view_all.poll() failed, context is incorrect
        return {'FINISHED'}

See:

You should call it with a custom context with the correct area and region.

Thanks for the link.

I’ve tried to over-ride the context as per your example. Here’s my closest effort so far:


bl_info = {
  "version": "0.1",
  "name": "View All Operator Example",
  'author': 'BlenderHawkBob',
  "location": "Properties > Scene",
  "category": "Blender Experiments"
  }


import bpy
 
class ViewAllPanel(bpy.types.Panel):
    """Creates a Panel in the scene properties window"""
    bl_label = "View All Panel"
    bl_idname = "OBJECT_PT_ViewAll"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "scene"
 
    def draw(self, context):
        layout = self.layout
        layout.operator(ViewAllOperator.bl_idname)
 
class ViewAllOperator(bpy.types.Operator):
    """Execute View All in the Timeline"""
    bl_idname = "scene.view_all_operator"
    bl_label = "View All in Timeline"
 
    @classmethod
    def poll(cls, context):
        for area in bpy.context.screen.areas:
            if area.type == 'TIMELINE':
                return True
        return False

    def execute(self, context):
        print("Setting frame_start = 0, frame_end = 123")
        bpy.context.scene.frame_start = 0
        bpy.context.scene.frame_end = 123

        for area in bpy.context.screen.areas:
            if area.type == 'TIMELINE':
                override = bpy.context.copy()
                override['area'] = area
                bpy.ops.time.view_all(override)
                break
        return {'FINISHED'}
 
def register():
    bpy.utils.register_module(__name__)
 
def unregister():
    bpy.utils.unregister_module(__name__)
 
if __name__ == "__main__":
    register()

The poll function appears to work by graying out the button if I remove the timeline (by changing it to “INFO” for example). The button similarly “ungrays” itself when I switch any area back to a timeline. So the polling and finding of the proper area containing a timeline seems to be working.

Also, the start and end frames are set properly (0 to 123) and the “view_all” function no longer generates a run time error. This indicates that the context is no longer a problem.

But the “view all” doesn’t happen. Additionally, executing the operator resizes the text in the Properties panel to a very large font - possibly a clue to what’s going wrong?

Does anyone see the problem(s)?

Aha … I found part of the problem:

I may have needed to go through the regions list in each area as per this example:

I also slimmed it down to run from the text editor:

import bpy

print ( " " )
for area in bpy.context.screen.areas:
    print ( "Another Area" )
    if area.type == 'TIMELINE':
        print ( "Found a Timeline" )
        for region in area.regions:
            print ( "Another Region" )
            if region.type == 'WINDOW':
                print ( "Found a Window" )
                override = { 'area': area, 'region': region }
                print ( "Before View All" )
                bpy.ops.time.view_all(override)
                print ( "Done with View All" )

This code does resize the timeline, but I get a bunch of PyContext messages during the “view_all” call that I don’t understand:

Another Area
Another Area
Another Area
Found a Timeline
Another Region
Another Region
Found a Window
Before View All
PyContext 'window' not found
PyContext 'window' not found
PyContext 'screen' not found
PyContext 'window' not found
PyContext 'window' not found
PyContext 'screen' not found
PyContext 'scene' not found
PyContext 'screen' not found
PyContext 'screen' not found
Done with View All
Another Area
Another Area
Another Area

Do I need to add more fields to the override dictionary, or do I need to start with a copy of the context?

1 Like

Try this:

import bpy
for area in bpy.context.screen.areas:
    if area.type == 'TIMELINE':
        for region in area.regions:
            if region.type == 'WINDOW':
                ctx = bpy.context.copy()
                ctx[ 'area'] = area
                ctx['region'] = region
                bpy.ops.time.view_all(ctx)
                break

That’s the winner!!!

Thanks again.

Your help is . . . . . . . . amazing!!!