2.5: Screen/Scene New/Delete operators.
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 15 Aug 2009 16:43:03 +0000 (16:43 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 15 Aug 2009 16:43:03 +0000 (16:43 +0000)
Implementation Note:
* Moved the scene copy/unlink code back into blenkernel, with
  the exception of the copy single user stuff which is still in
  object_edit.c.
* Uses SCREENDELETE notifier like SCREENBROWSE, seems only clean
  way to do this now.

19 files changed:
release/ui/space_info.py
source/blender/blenkernel/BKE_animsys.h
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/BKE_scene.h
source/blender/blenkernel/BKE_sequence.h
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/scene.c
source/blender/blenlib/intern/listbase.c
source/blender/editors/include/ED_screen.h
source/blender/editors/interface/interface_templates.c
source/blender/editors/object/object_edit.c
source/blender/editors/screen/screen_edit.c
source/blender/editors/screen/screen_ops.c
source/blender/editors/space_node/node_edit.c
source/blender/makesdna/DNA_scene_types.h
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_window.c

index f07234a4b0038a0014c03b1efd73d77ad10db8a9..af2dac02ccb773bf49a9e9a68fa618fa01c7c5d2 100644 (file)
@@ -22,8 +22,8 @@ class INFO_HT_header(bpy.types.Header):
                                row.itemM("INFO_MT_render")
                        row.itemM("INFO_MT_help")
 
-               layout.template_ID(context.window, "screen") #, new="screen.new", open="scene.unlink")
-               layout.template_ID(context.screen, "scene") #, new="screen.new", unlink="scene.unlink")
+               layout.template_ID(context.window, "screen", new="screen.new", unlink="screen.delete")
+               layout.template_ID(context.screen, "scene", new="scene.new", unlink="scene.delete")
 
                if rd.multiple_engines:
                        layout.itemR(rd, "engine", text="")
index 2447d1823af265e96744b26e06fe95d1b41c3957..cabbaa7aa0f5684cbdbb9e102400fca32a115fec 100644 (file)
@@ -66,6 +66,9 @@ void BKE_keyingset_add_destination(struct KeyingSet *ks, struct ID *id, const ch
 
 struct KS_Path *BKE_keyingset_find_destination(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, int group_mode);
 
+/* Copy all KeyingSets in the given list */
+void BKE_keyingsets_copy(struct ListBase *newlist, struct ListBase *list);
+
 /* Free data for KeyingSet but not set itself */
 void BKE_keyingset_free(struct KeyingSet *ks);
 
index 87ee8f9cab32d4a280ad92bf3cf8fbc4831fee34..183cdaff0e674d65bf8595c18e2bac18f4dbd4e7 100644 (file)
@@ -47,6 +47,7 @@ struct rctf;
 struct ListBase;
 struct RenderData;
 struct Scene;
+struct Main;
 struct Tex;
 struct GPUMaterial;
 struct GPUNode;
@@ -432,4 +433,8 @@ char* ntreeTexOutputMenu(struct bNodeTree *ntree);
 void init_nodesystem(void);
 void free_nodesystem(void);
 
+/**/
+
+void clear_scene_in_nodes(struct Main *bmain, struct Scene *sce);
+
 #endif
index 9bb246f88cc649825ecbb7784267473d45de3f59..12a13a2b50c0ff9d6f1746ea2d627a375089b53d 100644 (file)
@@ -40,6 +40,12 @@ struct AviCodecData;
 struct QuicktimeCodecData;
 struct RenderData;
 struct Text;
+struct Main;
+
+#define SCE_COPY_EMPTY         0
+#define SCE_COPY_LINK_OB       1
+#define SCE_COPY_LINK_DATA     2
+#define SCE_COPY_FULL          3
 
 /* note; doesn't work when scene is empty */
 #define SETLOOPER(s, b) sce= s, b= (Base*)sce->base.first; b; b= (Base*)(b->next?b->next:sce->set?(sce=sce->set)->base.first:NULL)
@@ -48,13 +54,16 @@ struct Text;
 void free_avicodecdata(struct AviCodecData *acd);
 void free_qtcodecdata(struct QuicktimeCodecData *acd);
 
-void free_scene(struct Scene *me);
+void free_scene(struct Scene *sce);
 struct Scene *add_scene(char *name);
 struct Base *object_in_scene(struct Object *ob, struct Scene *sce);
 
 void set_scene_bg(struct Scene *sce);
 void set_scene_name(char *name);
 
+struct Scene *copy_scene(struct Main *bmain, struct Scene *sce, int type);
+void unlink_scene(struct Main *bmain, struct Scene *sce, struct Scene *newsce);
+
 int next_object(struct Scene *scene, int val, struct Base **base, struct Object **ob);
 struct Object *scene_find_camera(struct Scene *sc);
 
index 35cff5c94221b5c8632e2e3f76be3b06811c7e74..f72617c83128da36e1d9c56989f629357167d4b6 100644 (file)
@@ -184,3 +184,7 @@ int shuffle_seq(struct ListBase * seqbasep, struct Sequence *test);
 void free_imbuf_seq(struct ListBase * seqbasep, int check_mem_usage);
 
 void seq_update_sound(struct Sequence *seq);
+
+void clear_scene_in_allseqs(struct Scene *sce);
+
+
index 983f1ecc31c7a1d6840c3da8645e6470b6161768..204935cc38d3dc007d13a415351d0c6b45609d74 100644 (file)
@@ -342,6 +342,21 @@ void BKE_keyingset_add_destination (KeyingSet *ks, ID *id, const char group_name
        BLI_addtail(&ks->paths, ksp);
 }      
 
+/* Copy all KeyingSets in the given list */
+void BKE_keyingsets_copy(ListBase *newlist, ListBase *list)
+{
+       KeyingSet *ksn;
+       KS_Path *kspn;
+
+       BLI_duplicatelist(newlist, list);
+
+       for(ksn=newlist->first; ksn; ksn=ksn->next) {
+               BLI_duplicatelist(&ksn->paths, &ksn->paths);
+
+               for(kspn=ksn->paths.first; kspn; kspn=kspn->next)
+                       kspn->rna_path= MEM_dupallocN(kspn->rna_path);
+       }
+}
 
 /* Freeing Tools --------------------------- */
 
index 0f42ba0d2e281ccfc3ce1f2cf801740e52c05b46..836f4281eb9822e4932f5c9cd026489921fcebe8 100644 (file)
@@ -3112,3 +3112,29 @@ void free_nodesystem(void)
        BLI_freelistN(&node_all_shaders);
        BLI_freelistN(&node_all_textures);
 }
+
+/* called from unlink_scene, when deleting a scene goes over all scenes
+ * other than the input, checks if they have render layer nodes referencing
+ * the to-be-deleted scene, and resets them to NULL. */
+
+/* XXX needs to get current scene then! */
+void clear_scene_in_nodes(Main *bmain, Scene *sce)
+{
+       Scene *sce1;
+       bNode *node;
+
+       for(sce1= bmain->scene.first; sce1; sce1=sce1->id.next) {
+               if(sce1!=sce) {
+                       if(sce1->nodetree) {
+                               for(node= sce1->nodetree->nodes.first; node; node= node->next) {
+                                       if(node->type==CMP_NODE_R_LAYERS) {
+                                               Scene *nodesce= (Scene *)node->id;
+                                               
+                                               if (nodesce==sce) node->id = NULL;
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
index 0e987850acda3e23fe902a9c20e0096750874b74..83b1976aabe78fa821d76016b8a41d58e33b2afe 100644 (file)
@@ -54,6 +54,7 @@
 #include "DNA_meta_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
 #include "DNA_texture_types.h"
 #include "DNA_userdef_types.h"
 
@@ -125,7 +126,113 @@ void free_qtcodecdata(QuicktimeCodecData *qcd)
        }
 }
 
-/* copy_scene moved to src/header_info.c... should be back */
+Scene *copy_scene(Main *bmain, Scene *sce, int type)
+{
+       Scene *scen;
+       ToolSettings *ts;
+       Base *base, *obase;
+       
+       if(type == SCE_COPY_EMPTY) {
+               ListBase lb;
+               scen= add_scene(sce->id.name+2);
+               
+               lb= scen->r.layers;
+               scen->r= sce->r;
+               scen->r.layers= lb;
+       }
+       else {
+               scen= copy_libblock(sce);
+               BLI_duplicatelist(&(scen->base), &(sce->base));
+               
+               clear_id_newpoins();
+               
+               id_us_plus((ID *)scen->world);
+               id_us_plus((ID *)scen->set);
+               id_us_plus((ID *)scen->ima);
+               id_us_plus((ID *)scen->gm.dome.warptext);
+
+               scen->ed= NULL;
+               scen->theDag= NULL;
+               scen->obedit= NULL;
+               scen->toolsettings= MEM_dupallocN(sce->toolsettings);
+
+               ts= scen->toolsettings;
+               if(ts) {
+                       if(ts->vpaint) {
+                               ts->vpaint= MEM_dupallocN(ts->vpaint);
+                               ts->vpaint->paintcursor= NULL;
+                               ts->vpaint->vpaint_prev= NULL;
+                               ts->vpaint->wpaint_prev= NULL;
+                               id_us_plus((ID *)ts->vpaint->brush);
+                       }
+                       if(ts->wpaint) {
+                               ts->wpaint= MEM_dupallocN(ts->wpaint);
+                               ts->wpaint->paintcursor= NULL;
+                               ts->wpaint->vpaint_prev= NULL;
+                               ts->wpaint->wpaint_prev= NULL;
+                               id_us_plus((ID *)ts->wpaint->brush);
+                       }
+                       if(ts->sculpt) {
+                               ts->sculpt= MEM_dupallocN(ts->sculpt);
+                               ts->sculpt->session= NULL;
+                               id_us_plus((ID *)ts->sculpt->brush);
+                       }
+
+                       id_us_plus((ID *)ts->imapaint.brush);
+                       ts->imapaint.paintcursor= NULL;
+
+                       ts->particle.paintcursor= NULL;
+               }
+               
+               BLI_duplicatelist(&(scen->markers), &(sce->markers));
+               BLI_duplicatelist(&(scen->transform_spaces), &(sce->transform_spaces));
+               BLI_duplicatelist(&(scen->r.layers), &(sce->r.layers));
+               BKE_keyingsets_copy(&(scen->keyingsets), &(sce->keyingsets));
+               
+               scen->nodetree= ntreeCopyTree(sce->nodetree, 0);
+               
+               obase= sce->base.first;
+               base= scen->base.first;
+               while(base) {
+                       id_us_plus(&base->object->id);
+                       if(obase==sce->basact) scen->basact= base;
+       
+                       obase= obase->next;
+                       base= base->next;
+               }
+       }
+       
+       /* make a private copy of the avicodecdata */
+       if(sce->r.avicodecdata) {
+               scen->r.avicodecdata = MEM_dupallocN(sce->r.avicodecdata);
+               scen->r.avicodecdata->lpFormat = MEM_dupallocN(scen->r.avicodecdata->lpFormat);
+               scen->r.avicodecdata->lpParms = MEM_dupallocN(scen->r.avicodecdata->lpParms);
+       }
+       
+       /* make a private copy of the qtcodecdata */
+       if(sce->r.qtcodecdata) {
+               scen->r.qtcodecdata = MEM_dupallocN(sce->r.qtcodecdata);
+               scen->r.qtcodecdata->cdParms = MEM_dupallocN(scen->r.qtcodecdata->cdParms);
+       }
+       
+       /* NOTE: part of SCE_COPY_LINK_DATA and SCE_COPY_FULL operations
+        * are done outside of blenkernel with ED_objects_single_users! */
+
+    /*  camera */
+       if(type == SCE_COPY_LINK_DATA || type == SCE_COPY_FULL) {
+           ID_NEW(scen->camera);
+       }
+
+       /* world */
+       if(type == SCE_COPY_FULL) {
+        if(scen->world) {
+            id_us_plus((ID *)scen->world);
+            scen->world= copy_world(scen->world);
+        }
+       }
+
+       return scen;
+}
 
 /* do not free scene itself */
 void free_scene(Scene *sce)
@@ -413,6 +520,30 @@ void set_scene_name(char *name)
        //XXX error("Can't find scene: %s", name);
 }
 
+void unlink_scene(Main *bmain, Scene *sce, Scene *newsce)
+{
+       Scene *sce1;
+       bScreen *sc;
+
+       /* check all sets */
+       for(sce1= bmain->scene.first; sce1; sce1= sce1->id.next)
+               if(sce1->set == sce)
+                       sce1->set= NULL;
+       
+       /* check all sequences */
+       clear_scene_in_allseqs(sce);
+
+       /* check render layer nodes in other scenes */
+       clear_scene_in_nodes(bmain, sce);
+       
+       /* al screens */
+       for(sc= bmain->screen.first; sc; sc= sc->id.next)
+               if(sc->scene == sce)
+                       sc->scene= newsce;
+
+       free_libblock(&bmain->scene, sce);
+}
+
 /* used by metaballs
  * doesnt return the original duplicated object, only dupli's
  */
index 1064c8ac1bf324105e3682008eb8424289d4c9ce..3194593374f2461014ac2ed1ddf6a2ac9ee6e35b 100644 (file)
@@ -347,11 +347,11 @@ void BLI_duplicatelist(ListBase *list1, ListBase *list2)  /* copy from 2 to 1 */
 {
        struct Link *link1, *link2;
        
+       /* in this order, to ensure it works if list1 == list2 */
+       link2= list2->first;
        list1->first= list1->last= 0;
        
-       link2= list2->first;
        while(link2) {
-               
                link1= MEM_dupallocN(link2);
                BLI_addtail(list1, link1);
                
index fc29d64eb37354667a9815110e68e33396014acf..1c504f84eae31e5bc49be6f5bfdfede1fd02c611 100644 (file)
@@ -89,7 +89,9 @@ void  ED_screen_do_listen(struct wmWindow *win, struct wmNotifier *note);
 bScreen *ED_screen_duplicate(struct wmWindow *win, struct bScreen *sc);
 bScreen *ED_screen_add(struct wmWindow *win, struct Scene *scene, 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_delete_scene(struct bContext *C, struct Scene *scene);
 void   ED_screen_set_subwinactive(struct wmWindow *win, struct wmEvent *event);
 void   ED_screen_exit(struct bContext *C, struct wmWindow *window, struct bScreen *screen);
 void   ED_screen_animation_timer(struct bContext *C, int redraws, int enable);
index 0217e9646faab58bc74aef553913397e4438fb7d..cdd6e3eaa1a33e35b2658be6e96baa3dd88f4247 100644 (file)
@@ -236,7 +236,7 @@ static void template_ID(bContext *C, uiBlock *block, TemplateID *template, Struc
                int w= idptr.data?UI_UNIT_X:UI_UNIT_X*6;
                
                if(newop) {
-                       but= uiDefIconTextButO(block, BUT, newop, WM_OP_EXEC_REGION_WIN, ICON_ZOOMIN, "Add New", 0, 0, w, UI_UNIT_Y, NULL);
+                       but= uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_REGION_WIN, ICON_ZOOMIN, "Add New", 0, 0, w, UI_UNIT_Y, NULL);
                        uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
                }
                else {
@@ -248,7 +248,7 @@ static void template_ID(bContext *C, uiBlock *block, TemplateID *template, Struc
        /* delete button */
        if(idptr.data && (flag & UI_ID_DELETE)) {
                if(unlinkop) {
-                       but= uiDefIconButO(block, BUT, unlinkop, WM_OP_EXEC_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
+                       but= uiDefIconButO(block, BUT, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
                }
                else {
                        but= uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
index 4cc3f22d5f8bd8b3ea29330887105fc556695eee..7d00884760233900f497680075329301891344d9 100644 (file)
@@ -5727,7 +5727,7 @@ void new_id_matar(Material **matar, int totcol)
        }
 }
 
-void single_obdata_users(Scene *scene, View3D *v3d, int flag)
+void single_obdata_users(Scene *scene, int flag)
 {
        Object *ob;
        Lamp *la;
@@ -5850,7 +5850,7 @@ void single_obdata_users(Scene *scene, View3D *v3d, int flag)
        }
 }
 
-void single_ipo_users(Scene *scene, View3D *v3d, int flag)
+void single_ipo_users(Scene *scene, int flag)
 {
 #if 0 // XXX old animation system
        Object *ob;
@@ -5873,7 +5873,7 @@ void single_ipo_users(Scene *scene, View3D *v3d, int flag)
 #endif // XXX old animation system
 }
 
-void single_mat_users(Scene *scene, View3D *v3d, int flag)
+void single_mat_users(Scene *scene, int flag)
 {
        Object *ob;
        Base *base;
@@ -6059,19 +6059,19 @@ void single_user(Scene *scene, View3D *v3d)
        
                else if(nr==2) {
                        single_object_users(scene, v3d, 1);
-                       single_obdata_users(scene, v3d, 1);
+                       single_obdata_users(scene, 1);
                }
                else if(nr==3) {
                        single_object_users(scene, v3d, 1);
-                       single_obdata_users(scene, v3d, 1);
-                       single_mat_users(scene, v3d, 1); /* also tex */
+                       single_obdata_users(scene, 1);
+                       single_mat_users(scene, 1); /* also tex */
                        
                }
                else if(nr==4) {
-                       single_mat_users(scene, v3d, 1);
+                       single_mat_users(scene, 1);
                }
                else if(nr==5) {
-                       single_ipo_users(scene, v3d, 1);
+                       single_ipo_users(scene, 1);
                }
                
                
@@ -6080,6 +6080,20 @@ void single_user(Scene *scene, View3D *v3d)
        }
 }
 
+/* used for copying scenes */
+void ED_object_single_users(Scene *scene, int full)
+{
+    single_object_users(scene, NULL, 0);
+
+    if(full) {
+        single_obdata_users(scene, 0);
+        single_mat_users_expand();
+        single_tex_users_expand();
+    }
+
+       clear_id_newpoins();
+}
+
 /* ************************************************************* */
 
 /* helper for below, ma was checked to be not NULL */
index 5519b2609a1494dda08edc354fee7278d5fcafa9..b6c2ece1a024cee0b739f0e630ffac39064dff4a 100644 (file)
@@ -923,12 +923,6 @@ bScreen *ED_screen_duplicate(wmWindow *win, bScreen *sc)
        newsc= ED_screen_add(win, sc->scene, sc->id.name+2);
        /* copy all data */
        screen_copy(newsc, sc);
-       /* set in window */
-       win->screen= newsc;
-       
-       /* store identifier */
-       win->screen->winid= win->winid;
-       BLI_strncpy(win->screenname, win->screen->id.name+2, 21);
 
        return newsc;
 }
@@ -1289,6 +1283,49 @@ void ED_screen_set(bContext *C, bScreen *sc)
        }
 }
 
+static int ed_screen_used(wmWindowManager *wm, bScreen *sc)
+{
+       wmWindow *win;
+
+       for(win=wm->windows.first; win; win=win->next)
+               if(win->screen == sc)
+                       return 1;
+       
+       return 0;
+}
+
+/* only call outside of area/region loops */
+void ED_screen_delete(bContext *C, bScreen *sc)
+{
+       Main *bmain= CTX_data_main(C);
+       wmWindowManager *wm= CTX_wm_manager(C);
+       wmWindow *win= CTX_wm_window(C);
+       bScreen *newsc;
+       int delete= 1;
+
+       /* screen can only be in use by one window at a time, so as
+          long as we are able to find a screen that is unused, we
+          can safely assume ours is not in use anywhere an delete it */
+
+       for(newsc= sc->id.prev; newsc; newsc=newsc->id.prev)
+               if(!ed_screen_used(wm, newsc))
+                       break;
+       
+       if(!newsc) {
+               for(newsc= sc->id.next; newsc; newsc=newsc->id.next)
+                       if(!ed_screen_used(wm, newsc))
+                               break;
+       }
+
+       if(!newsc)
+               return;
+
+       ED_screen_set(C, newsc);
+
+       if(delete && win->screen != sc)
+               free_libblock(&bmain->screen, sc);
+}
+
 /* only call outside of area/region loops */
 void ED_screen_set_scene(bContext *C, Scene *scene)
 {
@@ -1346,6 +1383,24 @@ void ED_screen_set_scene(bContext *C, Scene *scene)
        
 }
 
+/* only call outside of area/region loops */
+void ED_screen_delete_scene(bContext *C, Scene *scene)
+{
+       Main *bmain= CTX_data_main(C);
+       Scene *newscene;
+
+       if(scene->id.prev)
+               newscene= scene->id.prev;
+       else if(scene->id.next)
+               newscene= scene->id.next;
+       else
+               return;
+
+       ED_screen_set_scene(C, newscene);
+
+       unlink_scene(bmain, scene, newscene);
+}
+
 /* this function toggles: if area is full then the parent will be restored */
 void ed_screen_fullarea(bContext *C, ScrArea *sa)
 {
index f882a25c36360e96a195052b8489196b324dabf4..b8980d86fdcba60e0831a81ddcf658402867c9e7 100644 (file)
@@ -54,6 +54,7 @@
 #include "BKE_mesh.h"
 #include "BKE_multires.h"
 #include "BKE_report.h"
+#include "BKE_scene.h"
 #include "BKE_screen.h"
 #include "BKE_utildefines.h"
 #include "BKE_sound.h"
@@ -3087,7 +3088,124 @@ static void SCREEN_OT_userpref_show(struct wmOperatorType *ot)
        ot->poll= ED_operator_screenactive;
 }
 
+/********************* new screen operator *********************/
 
+static int screen_new_exec(bContext *C, wmOperator *op)
+{
+       wmWindow *win= CTX_wm_window(C);
+       bScreen *sc= CTX_wm_screen(C);
+
+       sc= ED_screen_duplicate(win, sc);
+       WM_event_add_notifier(C, NC_SCREEN|ND_SCREENBROWSE, sc);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCREEN_OT_new(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "New Screen";
+       ot->idname= "SCREEN_OT_new";
+       
+       /* api callbacks */
+       ot->exec= screen_new_exec;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************* delete screen operator *********************/
+
+static int screen_delete_exec(bContext *C, wmOperator *op)
+{
+       bScreen *sc= CTX_wm_screen(C);
+
+       WM_event_add_notifier(C, NC_SCREEN|ND_SCREENDELETE, sc);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCREEN_OT_delete(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Delete Scene";
+       ot->idname= "SCREEN_OT_delete";
+       
+       /* api callbacks */
+       ot->exec= screen_delete_exec;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************* new scene operator *********************/
+
+static int scene_new_exec(bContext *C, wmOperator *op)
+{
+       Scene *newscene, *scene= CTX_data_scene(C);
+       Main *bmain= CTX_data_main(C);
+       int type= RNA_enum_get(op->ptr, "type");
+
+       newscene= copy_scene(bmain, scene, type);
+
+       /* these can't be handled in blenkernel curently, so do them here */
+       if(type == SCE_COPY_LINK_DATA)
+               ED_object_single_users(newscene, 0);
+       else if(type == SCE_COPY_FULL)
+               ED_object_single_users(newscene, 1);
+
+       WM_event_add_notifier(C, NC_SCENE|ND_SCENEBROWSE, newscene);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_new(wmOperatorType *ot)
+{
+       static EnumPropertyItem type_items[]= {
+               {SCE_COPY_EMPTY, "EMPTY", 0, "Empty", "Add empty scene."},
+               {SCE_COPY_LINK_OB, "LINK_OBJECTS", 0, "Link Objects", "Link to the objects from the current scene."},
+               {SCE_COPY_LINK_DATA, "LINK_OBJECT_DATA", 0, "Link Object Data", "Copy objects linked to data from the current scene."},
+               {SCE_COPY_FULL, "FULL_COPY", 0, "Full Copy", "Make a full copy of the current scene."},
+               {0, NULL, 0, NULL, NULL}};
+
+       /* identifiers */
+       ot->name= "New Scene";
+       ot->idname= "SCENE_OT_new";
+       
+       /* api callbacks */
+       ot->exec= scene_new_exec;
+       ot->invoke= WM_menu_invoke;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       /* properties */
+       RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "");
+}
+
+/********************* delete scene operator *********************/
+
+static int scene_delete_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+
+       WM_event_add_notifier(C, NC_SCENE|ND_SCENEDELETE, scene);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_delete(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Delete Scene";
+       ot->idname= "SCENE_OT_delete";
+       
+       /* api callbacks */
+       ot->exec= scene_delete_exec;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
 
 /* ****************  Assigning operatortypes to global list, adding handlers **************** */
 
@@ -3129,6 +3247,12 @@ void ED_operatortypes_screen(void)
        WM_operatortype_append(SCREEN_OT_render_view_cancel);
        WM_operatortype_append(SCREEN_OT_render_view_show);
 
+       /* new/delete */
+       WM_operatortype_append(SCREEN_OT_new);
+       WM_operatortype_append(SCREEN_OT_delete);
+       WM_operatortype_append(SCENE_OT_new);
+       WM_operatortype_append(SCENE_OT_delete);
+
        /* tools shared by more space types */
        WM_operatortype_append(ED_OT_undo);
        WM_operatortype_append(ED_OT_redo);     
index fe68a56dea5d37afcaef67d0ca8bee10ec480caf..467637d3f60d7d63dc081daf9cc9ba2b83677f1e 100644 (file)
@@ -2270,34 +2270,6 @@ void node_read_fullsamplelayers(SpaceNode *snode)
        WM_cursor_wait(0);
 }
 
-/* called from header_info, when deleting a scene
- * goes over all scenes other than the input, checks if they have
- * render layer nodes referencing the to-be-deleted scene, and
- * resets them to NULL. */
-
-/* XXX needs to get current scene then! */
-void clear_scene_in_nodes(Scene *sce)
-{
-       Scene *sce1;
-       bNode *node;
-
-       sce1= G.main->scene.first;
-       while(sce1) {
-               if(sce1!=sce) {
-                       if (sce1->nodetree) {
-                               for(node= sce1->nodetree->nodes.first; node; node= node->next) {
-                                       if(node->type==CMP_NODE_R_LAYERS) {
-                                               Scene *nodesce= (Scene *)node->id;
-                                               
-                                               if (nodesce==sce) node->id = NULL;
-                                       }
-                               }
-                       }
-               }
-               sce1= sce1->id.next;
-       }
-}
-
 void imagepaint_composite_tags(bNodeTree *ntree, Image *image, ImageUser *iuser)
 {
        bNode *node;
index 7404072db47658a3118729e1693606668ca41abe..e256b12ca46b968a8a79929807eb2093442b694f 100644 (file)
@@ -468,7 +468,7 @@ typedef struct TransformOrientation {
 struct SculptSession;
 typedef struct Sculpt
 {
-       /* Note! a deep copy of this struct must be done header_info.c's copy_scene function */ 
+       /* Note! a deep copy of this struct must be done scene.c's copy_scene function */       
        /* Data stored only from entering sculptmode until exiting sculptmode */
        struct SculptSession *session;
        struct Brush *brush;
index a083d589d31a230ab5ac9edded490368f4cdb74a..899270032209267a697bf2fcc02653d59a9a07dc 100644 (file)
@@ -144,8 +144,9 @@ typedef struct wmNotifier {
 
        /* NC_SCREEN screen */
 #define ND_SCREENBROWSE                (1<<16)
-#define ND_SCREENCAST          (2<<16)
-#define ND_ANIMPLAY                    (3<<16)
+#define ND_SCREENDELETE                (2<<16)
+#define ND_SCREENCAST          (3<<16)
+#define ND_ANIMPLAY                    (4<<16)
 
        /* NC_SCENE Scene */
 #define ND_SCENEBROWSE         (1<<16)
@@ -160,6 +161,7 @@ typedef struct wmNotifier {
 #define ND_RENDER_RESULT       (10<<16)
 #define ND_COMPO_RESULT                (11<<16)
 #define ND_KEYINGSET           (12<<16)
+#define ND_SCENEDELETE         (13<<16)
 
        /* NC_OBJECT Object */
 #define        ND_TRANSFORM            (16<<16)
index d40e6c60bfddb51f0d2e224b844bde0eeb3edf1b..dbb4086c541deafa2018a200b5e6606540da9421 100644 (file)
@@ -156,12 +156,20 @@ void wm_event_do_notifiers(bContext *C)
                                                ED_screen_set(C, note->reference);      // XXX hrms, think this over!
                                                printf("screen set %p\n", note->reference);
                                        }
+                                       else if(note->data==ND_SCREENDELETE) {
+                                               ED_screen_delete(C, note->reference);   // XXX hrms, think this over!
+                                               printf("screen delete %p\n", note->reference);
+                                       }
                                }
                                else if(note->category==NC_SCENE) {
                                        if(note->data==ND_SCENEBROWSE) {
                                                ED_screen_set_scene(C, note->reference);        // XXX hrms, think this over!
                                                printf("scene set %p\n", note->reference);
                                        }
+                                       if(note->data==ND_SCENEDELETE) {
+                                               ED_screen_delete_scene(C, note->reference);     // XXX hrms, think this over!
+                                               printf("scene delete %p\n", note->reference);
+                                       }
                                        else if(note->data==ND_FRAME)
                                                do_anim= 1;
                                }
index 4d80836dd05a6ae710346057ba8074d23e83719b..3006944533aef4bffff2f54a2c226728708ff3c3 100644 (file)
@@ -207,7 +207,10 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig)
        win->sizey= winorig->sizey;
        
        /* duplicate assigns to window */
-       ED_screen_duplicate(win, winorig->screen);
+       win->screen= ED_screen_duplicate(win, winorig->screen);
+       BLI_strncpy(win->screenname, win->screen->id.name+2, 21);
+       win->screen->winid= win->winid;
+
        win->screen->do_refresh= 1;
        win->screen->do_draw= 1;