patch [#30481] rna_Screen_scene_set does the wrong thing [patch]
authorCampbell Barton <ideasman42@gmail.com>
Wed, 7 Mar 2012 16:43:42 +0000 (16:43 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 7 Mar 2012 16:43:42 +0000 (16:43 +0000)
from Dan Eicher (dna)

--- from the tracker
Setting Screen.scene only uses the active screen through a call to CTX_wm_screen(C) instead of the actual referenced scene.

The attached py-op demonstrates this behavior, assuming at least two separate scenes in the VSE.

source/blender/editors/include/ED_screen.h
source/blender/editors/screen/screen_edit.c
source/blender/editors/screen/screen_ops.c
source/blender/editors/space_outliner/outliner_select.c
source/blender/editors/space_outliner/outliner_tools.c
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_screen.c

index fa13cbf73b78bb768a660cfddc801ef2372fa369..f0fffb34b73760804c26cc9b9d65a62b652e5b6a 100644 (file)
@@ -100,7 +100,7 @@ bScreen *ED_screen_duplicate(struct wmWindow *win, struct bScreen *sc);
 bScreen *ED_screen_add(struct wmWindow *win, struct Scene *scene, const char *name);
 void   ED_screen_set(struct bContext *C, struct bScreen *sc);
 void   ED_screen_delete(struct bContext *C, struct bScreen *sc);
-void   ED_screen_set_scene(struct bContext *C, struct Scene *scene);
+void   ED_screen_set_scene(struct bContext *C, struct bScreen *screen, struct Scene *scene);
 void   ED_screen_delete_scene(struct bContext *C, struct Scene *scene);
 void   ED_screen_set_subwinactive(struct bContext *C, struct wmEvent *event);
 void   ED_screen_exit(struct bContext *C, struct wmWindow *window, struct bScreen *screen);
index 7ab73c6b9764919c2ccd81fcb404f35ce24a7f39..24a8de6688ee1b27a4a2fe2b76dd749d15f14580 100644 (file)
@@ -1424,16 +1424,19 @@ void ED_screen_delete(bContext *C, bScreen *sc)
 }
 
 /* only call outside of area/region loops */
-void ED_screen_set_scene(bContext *C, Scene *scene)
+void ED_screen_set_scene(bContext *C, bScreen *screen, Scene *scene)
 {
        Main *bmain= CTX_data_main(C);
        bScreen *sc;
-       bScreen *curscreen= CTX_wm_screen(C);
+
+       if(screen == NULL)
+               return;
        
-       ED_object_exit_editmode(C, EM_FREEDATA|EM_DO_UNDO);
+       if(ed_screen_used(CTX_wm_manager(C), screen))
+               ED_object_exit_editmode(C, EM_FREEDATA|EM_DO_UNDO);
 
        for(sc= CTX_data_main(C)->screen.first; sc; sc= sc->id.next) {
-               if((U.flag & USER_SCENEGLOBAL) || sc==curscreen) {
+               if((U.flag & USER_SCENEGLOBAL) || sc==screen) {
                        
                        if(scene != sc->scene) {
                                /* all areas endlocalview */
@@ -1452,7 +1455,7 @@ void ED_screen_set_scene(bContext *C, Scene *scene)
        
        /* are there cameras in the views that are not in the scene? */
        for(sc= CTX_data_main(C)->screen.first; sc; sc= sc->id.next) {
-               if( (U.flag & USER_SCENEGLOBAL) || sc==curscreen) {
+               if( (U.flag & USER_SCENEGLOBAL) || sc==screen) {
                        ScrArea *sa= sc->areabase.first;
                        while(sa) {
                                SpaceLink *sl= sa->spacedata.first;
@@ -1489,7 +1492,7 @@ void ED_screen_set_scene(bContext *C, Scene *scene)
        set_scene_bg(bmain, scene);
        
        ED_render_engine_changed(bmain);
-       ED_update_for_newframe(bmain, scene, curscreen, 1);
+       ED_update_for_newframe(bmain, scene, screen, 1);
        
        /* complete redraw */
        WM_event_add_notifier(C, NC_WINDOW, NULL);
@@ -1509,7 +1512,7 @@ void ED_screen_delete_scene(bContext *C, Scene *scene)
        else
                return;
 
-       ED_screen_set_scene(C, newscene);
+       ED_screen_set_scene(C, CTX_wm_screen(C), newscene);
 
        unlink_scene(bmain, scene, newscene);
 }
index a8ad50b2f53e47aa0328215d32bba6de91a4c3d3..b1d718f08b5778e026a6f6dc11061a9b97c367dc 100644 (file)
@@ -3326,7 +3326,7 @@ static int scene_new_exec(bContext *C, wmOperator *op)
                }
        }
        
-       ED_screen_set_scene(C, newscene);
+       ED_screen_set_scene(C, CTX_wm_screen(C), newscene);
        
        WM_event_add_notifier(C, NC_SCENE|ND_SCENEBROWSE, newscene);
        
index a71ea9a6d4ab0aa5e8ab48ec2b67eeaaa15f5354..4814edf585ecd4d3bf11708a30ecc94b17fd6379 100644 (file)
@@ -190,7 +190,7 @@ static int  tree_element_set_active_object(bContext *C, Scene *scene, SpaceOops
        
        sce= (Scene *)outliner_search_back(soops, te, ID_SCE);
        if(sce && scene != sce) {
-               ED_screen_set_scene(C, sce);
+               ED_screen_set_scene(C, CTX_wm_screen(C), sce);
        }
        
        /* find associated base in current scene */
@@ -374,7 +374,7 @@ static int tree_element_active_world(bContext *C, Scene *scene, SpaceOops *soops
        
        if(set) {       // make new scene active
                if(sce && scene != sce) {
-                       ED_screen_set_scene(C, sce);
+                       ED_screen_set_scene(C, CTX_wm_screen(C), sce);
                }
        }
        
@@ -761,7 +761,7 @@ static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, Spa
                                /* editmode? */
                                if(te->idcode==ID_SCE) {
                                        if(scene!=(Scene *)tselem->id) {
-                                               ED_screen_set_scene(C, (Scene *)tselem->id);
+                                               ED_screen_set_scene(C, CTX_wm_screen(C), (Scene *)tselem->id);
                                        }
                                }
                                else if(te->idcode==ID_GR) {
index c8da45270b7c6e36905be19f1eb7a90dbf31ef06..7fdd2e73181970444ed2c03ffbcf9013015d1c02 100644 (file)
@@ -409,7 +409,7 @@ void outliner_do_object_operation(bContext *C, Scene *scene_act, SpaceOops *soop
                                // when objects selected in other scenes... dunno if that should be allowed
                                Scene *scene_owner= (Scene *)outliner_search_back(soops, te, ID_SCE);
                                if(scene_owner && scene_act != scene_owner) {
-                                       ED_screen_set_scene(C, scene_owner);
+                                       ED_screen_set_scene(C, CTX_wm_screen(C), scene_owner);
                                }
                                /* important to use 'scene_owner' not scene_act else deleting objects can crash.
                                 * only use 'scene_act' when 'scene_owner' is NULL, which can happen when the
@@ -561,7 +561,7 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
                Scene *sce= scene;      // to be able to delete, scenes are set...
                outliner_do_object_operation(C, scene, soops, &soops->tree, object_select_cb);
                if(scene != sce) {
-                       ED_screen_set_scene(C, sce);
+                       ED_screen_set_scene(C, CTX_wm_screen(C), sce);
                }
                
                str= "Select Objects";
index 073624965ea7420e4d625302e20ba0df584c4468..1afd5d816d125cd052e84f7e123142a51a6d1ff4 100644 (file)
@@ -131,7 +131,7 @@ void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports, struc
        }
 
        if (CTX_wm_screen(C)->scene == scene)
-               ED_screen_set_scene(C, newscene);
+               ED_screen_set_scene(C, CTX_wm_screen(C), newscene);
 
        unlink_scene(bmain, scene, newscene);
 }
index d72b8c8f73b4630e62f9b762794969df11a2dcd6..88c982609ea240d7f8e299ae10284b47d015305f 100644 (file)
@@ -72,7 +72,7 @@ static void rna_Screen_scene_update(bContext *C, PointerRNA *ptr)
 
        /* exception: must use context so notifier gets to the right window  */
        if (sc->newscene) {
-               ED_screen_set_scene(C, sc->newscene);
+               ED_screen_set_scene(C, sc, sc->newscene);
                WM_event_add_notifier(C, NC_SCENE|ND_SCENEBROWSE, sc->newscene);
 
                if (G.f & G_DEBUG)