Fix #19311: adding/opening datablocks did not always make the right
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 1 Oct 2009 23:32:57 +0000 (23:32 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 1 Oct 2009 23:32:57 +0000 (23:32 +0000)
one active. Now there's a function to get the pointer + property from
the UI, just like for the animation operators.

Also two fixes for fileselect events, regions are now preserved so that
context is restored to the old region, and the cancel callback is called
when the operator is cancelled.

source/blender/blenkernel/intern/world.c
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface_templates.c
source/blender/editors/physics/particle_boids.c
source/blender/editors/render/render_shading.c
source/blender/editors/screen/area.c
source/blender/editors/space_action/action_edit.c
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_text/text_ops.c
source/blender/makesrna/RNA_types.h
source/blender/windowmanager/intern/wm_event_system.c

index f795c147f54f1ff2fb59cb373e5094ba076317e5..c75c9272e5cf16ef7fe3109a9d1d0a9b4d94bf74 100644 (file)
@@ -86,15 +86,20 @@ World *add_world(char *name)
 
        wrld= alloc_libblock(&G.main->world, ID_WO, name);
        
-       wrld->horb= 0.6f;
-       wrld->skytype= WO_SKYBLEND;
+       wrld->horr= 0.25f;
+       wrld->horg= 0.25f;
+       wrld->horb= 0.25f;
+       wrld->zenr= 0.1f;
+       wrld->zeng= 0.1f;
+       wrld->zenb= 0.1f;
+       wrld->skytype= 0;
        wrld->stardist= 15.0f;
        wrld->starsize= 2.0f;
        
        wrld->exp= 0.0f;
        wrld->exposure=wrld->range= 1.0f;
 
-       wrld->aodist= 5.0f;
+       wrld->aodist= 10.0f;
        wrld->aosamp= 5;
        wrld->aoenergy= 1.0f;
        wrld->aobias= 0.05f;
index e17629916763cb721014f842c3805cf99727126d..7fea4b10ed911f91074c5776e30bdb2dc05021d7 100644 (file)
@@ -670,6 +670,7 @@ void uiItemMenuEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *
 /* Helpers for Operators */
 void uiAnimContextProperty(const struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop, int *index);
 void uiFileBrowseContextProperty(const struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop);
+void uiIDContextProperty(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop);
 
 /* Styled text draw */
 void uiStyleFontSet(struct uiFontStyle *fs);
index 57dc484f975a542198206a1a4a2adf4d260c0d49..5b93f9ee06dbd9331171f396499055d962c2d44b 100644 (file)
@@ -153,6 +153,36 @@ static uiBlock *search_menu(bContext *C, ARegion *ar, void *arg_litem)
 
 /************************ ID Template ***************************/
 
+/* for new/open operators */
+void uiIDContextProperty(bContext *C, PointerRNA *ptr, PropertyRNA **prop)
+{
+       TemplateID *template;
+       ARegion *ar= CTX_wm_region(C);
+       uiBlock *block;
+       uiBut *but;
+
+       memset(ptr, 0, sizeof(*ptr));
+       *prop= NULL;
+
+       if(!ar)
+               return;
+
+       for(block=ar->uiblocks.first; block; block=block->next) {
+               for(but=block->buttons.first; but; but= but->next) {
+                       /* find the button before the active one */
+                       if((but->flag & (UI_BUT_LAST_ACTIVE|UI_ACTIVE))) {
+                               if(but->func_argN) {
+                                       template= but->func_argN;
+                                       *ptr= template->ptr;
+                                       *prop= template->prop;
+                                       return;
+                               }
+                       }
+               }
+       }
+}
+
+
 static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
 {
        TemplateID *template= (TemplateID*)arg_litem;
@@ -167,11 +197,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
                        break;
                case UI_ID_OPEN:
                case UI_ID_ADD_NEW:
-                       if(template->idlb->last) {
-                               RNA_id_pointer_create(template->idlb->last, &idptr);
-                               RNA_property_pointer_set(&template->ptr, template->prop, idptr);
-                               RNA_property_update(C, &template->ptr, template->prop);
-                       }
+                       /* these call uiIDContextPropertySet */
                        break;
                case UI_ID_DELETE:
                        memset(&idptr, 0, sizeof(idptr));
@@ -291,7 +317,7 @@ static void template_ID(bContext *C, uiBlock *block, TemplateID *template, Struc
                int w= id?UI_UNIT_X: (flag & UI_ID_OPEN)? UI_UNIT_X*3: UI_UNIT_X*6;
                
                if(newop) {
-                       but= uiDefIconTextButO(block, BUT, newop, WM_OP_EXEC_REGION_WIN, ICON_ZOOMIN, (id)? "": "New", 0, 0, w, UI_UNIT_Y, NULL);
+                       but= uiDefIconTextButO(block, BUT, newop, WM_OP_EXEC_DEFAULT, ICON_ZOOMIN, (id)? "": "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 {
@@ -307,7 +333,7 @@ static void template_ID(bContext *C, uiBlock *block, TemplateID *template, Struc
                int w= id?UI_UNIT_X: (flag & UI_ID_ADD_NEW)? UI_UNIT_X*3: UI_UNIT_X*6;
                
                if(openop) {
-                       but= uiDefIconTextButO(block, BUT, openop, WM_OP_INVOKE_REGION_WIN, ICON_FILESEL, (id)? "": "Open", 0, 0, w, UI_UNIT_Y, NULL);
+                       but= uiDefIconTextButO(block, BUT, openop, WM_OP_INVOKE_DEFAULT, ICON_FILESEL, (id)? "": "Open", 0, 0, w, UI_UNIT_Y, NULL);
                        uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN));
                }
                else {
index 0b63f1a98ff158182113283716deef38bc4eb482..b7a97d1131aea967ef1f20fe915d8ea475fb627b 100644 (file)
@@ -52,7 +52,6 @@
 /************************ add/del boid rule operators *********************/
 static int rule_add_exec(bContext *C, wmOperator *op)
 {
-       Scene *scene = CTX_data_scene(C);
        PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
        ParticleSystem *psys= ptr.data;
        Object *ob= ptr.id.data;
@@ -152,7 +151,6 @@ void BOID_OT_rule_del(wmOperatorType *ot)
 /************************ move up/down boid rule operators *********************/
 static int rule_move_up_exec(bContext *C, wmOperator *op)
 {
-       Scene *scene= CTX_data_scene(C);
        PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
        ParticleSystem *psys= ptr.data;
        Object *ob = ptr.id.data;
@@ -191,7 +189,6 @@ void BOID_OT_rule_move_up(wmOperatorType *ot)
 
 static int rule_move_down_exec(bContext *C, wmOperator *op)
 {
-       Scene *scene= CTX_data_scene(C);
        PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
        ParticleSystem *psys= ptr.data;
        Object *ob = ptr.id.data;
@@ -363,7 +360,6 @@ void BOID_OT_state_move_up(wmOperatorType *ot)
 
 static int state_move_down_exec(bContext *C, wmOperator *op)
 {
-       Scene *scene= CTX_data_scene(C);
        PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
        ParticleSystem *psys= ptr.data;
        BoidSettings *boids;
index a31a60ecbd6bf6000eac3a0622e2a7a0f1ee2d68..56605ad097040acac6213516bcc527eaa062ff6d 100644 (file)
@@ -436,9 +436,8 @@ void OBJECT_OT_material_slot_deselect(wmOperatorType *ot)
 static int new_material_exec(bContext *C, wmOperator *op)
 {
        Material *ma= CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
-       Object *ob;
-       PointerRNA ptr;
-       int index;
+       PointerRNA ptr, idptr;
+       PropertyRNA *prop;
 
        /* add or copy material */
        if(ma)
@@ -446,18 +445,17 @@ static int new_material_exec(bContext *C, wmOperator *op)
        else
                ma= add_material("Material");
 
-       ma->id.us--; /* compensating for us++ in assign_material */
-
-       /* attempt to assign to material slot */
-       ptr= CTX_data_pointer_get_type(C, "material_slot", &RNA_MaterialSlot);
-
-       if(ptr.data) {
-               ob= ptr.id.data;
-               index= (Material**)ptr.data - ob->mat;
+       /* hook into UI */
+       uiIDContextProperty(C, &ptr, &prop);
 
-               assign_material(ob, ma, index+1);
+       if(prop) {
+               /* when creating new ID blocks, use is already 1, but RNA
+                * pointer se also increases user, so this compensates it */
+               ma->id.us--;
 
-               WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+               RNA_id_pointer_create(&ma->id, &idptr);
+               RNA_property_pointer_set(&ptr, prop, idptr);
+               RNA_property_update(C, &ptr, prop);
        }
 
        WM_event_add_notifier(C, NC_MATERIAL|NA_ADDED, ma);
@@ -484,9 +482,8 @@ void MATERIAL_OT_new(wmOperatorType *ot)
 static int new_texture_exec(bContext *C, wmOperator *op)
 {
        Tex *tex= CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
-       ID *id;
-       MTex *mtex;
-       PointerRNA ptr;
+       PointerRNA ptr, idptr;
+       PropertyRNA *prop;
 
        /* add or copy texture */
        if(tex)
@@ -494,23 +491,17 @@ static int new_texture_exec(bContext *C, wmOperator *op)
        else
                tex= add_texture("Texture");
 
-       id_us_min(&tex->id);
-
-       /* attempt to assign to texture slot */
-       ptr= CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot);
-
-       if(ptr.data) {
-               id= ptr.id.data;
-               mtex= ptr.data;
+       /* hook into UI */
+       uiIDContextProperty(C, &ptr, &prop);
 
-               if(mtex) {
-                       if(mtex->tex)
-                               id_us_min(&mtex->tex->id);
-                       mtex->tex= tex;
-                       id_us_plus(&tex->id);
-               }
+       if(prop) {
+               /* when creating new ID blocks, use is already 1, but RNA
+                * pointer se also increases user, so this compensates it */
+               tex->id.us--;
 
-               /* XXX nodes, notifier .. */
+               RNA_id_pointer_create(&tex->id, &idptr);
+               RNA_property_pointer_set(&ptr, prop, idptr);
+               RNA_property_update(C, &ptr, prop);
        }
 
        WM_event_add_notifier(C, NC_TEXTURE|NA_ADDED, tex);
@@ -536,8 +527,9 @@ void TEXTURE_OT_new(wmOperatorType *ot)
 
 static int new_world_exec(bContext *C, wmOperator *op)
 {
-       Scene *scene= CTX_data_scene(C);
        World *wo= CTX_data_pointer_get_type(C, "world", &RNA_World).data;
+       PointerRNA ptr, idptr;
+       PropertyRNA *prop;
 
        /* add or copy world */
        if(wo)
@@ -545,10 +537,18 @@ static int new_world_exec(bContext *C, wmOperator *op)
        else
                wo= add_world("World");
 
-       /* assign to scene */
-       if(scene->world)
-               id_us_min(&scene->world->id);
-       scene->world= wo;
+       /* hook into UI */
+       uiIDContextProperty(C, &ptr, &prop);
+
+       if(prop) {
+               /* when creating new ID blocks, use is already 1, but RNA
+                * pointer se also increases user, so this compensates it */
+               wo->id.us--;
+
+               RNA_id_pointer_create(&wo->id, &idptr);
+               RNA_property_pointer_set(&ptr, prop, idptr);
+               RNA_property_update(C, &ptr, prop);
+       }
 
        WM_event_add_notifier(C, NC_WORLD|NA_ADDED, wo);
        
index 87901d754949e1bcb64023dc2a276f70c00fc7a5..fb782837d5e14df77bc1ed303624e65cdee80b45 100644 (file)
@@ -958,17 +958,22 @@ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space)
        /* Note; SPACE_EMPTY is possible on new screens */
        
        /* regions */
-       if(swap_space<2) {
-               st= BKE_spacetype_from_id(sa1->spacetype);
-               for(ar= sa1->regionbase.first; ar; ar= ar->next)
-                       BKE_area_region_free(st, ar);
-               BLI_freelistN(&sa1->regionbase);
+       if(swap_space == 1) {
+               SWAP(ListBase, sa1->regionbase, sa2->regionbase);
        }
-       
-       st= BKE_spacetype_from_id(sa2->spacetype);
-       for(ar= sa2->regionbase.first; ar; ar= ar->next) {
-               ARegion *newar= BKE_area_region_copy(st, ar);
-               BLI_addtail(&sa1->regionbase, newar);
+       else {
+               if(swap_space<2) {
+                       st= BKE_spacetype_from_id(sa1->spacetype);
+                       for(ar= sa1->regionbase.first; ar; ar= ar->next)
+                               BKE_area_region_free(st, ar);
+                       BLI_freelistN(&sa1->regionbase);
+               }
+               
+               st= BKE_spacetype_from_id(sa2->spacetype);
+               for(ar= sa2->regionbase.first; ar; ar= ar->next) {
+                       ARegion *newar= BKE_area_region_copy(st, ar);
+                       BLI_addtail(&sa1->regionbase, newar);
+               }
        }
 }
 
index 865d072d9385af578ddc10d4493e8fffe87ff056..0bcf4b037cb73cec0f17fb8eccb18f3236fd3bd2 100644 (file)
@@ -86,6 +86,8 @@
 #include "WM_api.h"
 #include "WM_types.h"
 
+#include "UI_interface.h"
+
 #include "action_intern.h"
 
 /* ************************************************************************** */
 static int act_new_exec(bContext *C, wmOperator *op)
 {
        bAction *action;
+       PointerRNA ptr, idptr;
+       PropertyRNA *prop;
 
        // XXX need to restore behaviour to copy old actions...
        action= add_empty_action("Action");
 
-       /* combined with RNA property, this will assign & increase user,
-          so decrease here to compensate for that */
-       action->id.us--;
-       
+       /* hook into UI */
+       uiIDContextProperty(C, &ptr, &prop);
+
+       if(prop) {
+               /* when creating new ID blocks, use is already 1, but RNA
+                * pointer se also increases user, so this compensates it */
+               action->id.us--;
+
+               RNA_id_pointer_create(&action->id, &idptr);
+               RNA_property_pointer_set(&ptr, prop, idptr);
+               RNA_property_update(C, &ptr, prop);
+       }
+
        /* set notifier that keyframes have changed */
        WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
        
index 89427ba8535d6878d9c111480e6c685a9b9d1b64..91316fba4d02a00af52cb0c2e9708c55ec06b9fe 100644 (file)
@@ -616,27 +616,61 @@ static void image_filesel(bContext *C, wmOperator *op, const char *path)
 
 /******************** open image operator ********************/
 
+static void open_init(bContext *C, wmOperator *op)
+{
+       PropertyPointerRNA *pprop;
+
+       op->customdata= pprop= MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
+       uiIDContextProperty(C, &pprop->ptr, &pprop->prop);
+}
+
+static int open_cancel(bContext *C, wmOperator *op)
+{
+       MEM_freeN(op->customdata);
+       op->customdata= NULL;
+       return OPERATOR_CANCELLED;
+}
+
 static int open_exec(bContext *C, wmOperator *op)
 {
        SpaceImage *sima= CTX_wm_space_image(C);
        Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
+       PropertyPointerRNA *pprop;
+       PointerRNA idptr;
        Image *ima= NULL;
        char str[FILE_MAX];
 
        RNA_string_get(op->ptr, "path", str);
        ima= BKE_add_image_file(str, scene->r.cfra);
 
-       if(!ima)
+       if(!ima) {
+               if(op->customdata) MEM_freeN(op->customdata);
                return OPERATOR_CANCELLED;
+       }
        
-       /* already set later */
-       ima->id.us--;
+       if(!op->customdata)
+               open_init(C, op);
+
+       /* hook into UI */
+       pprop= op->customdata;
+
+       if(pprop->prop) {
+               /* when creating new ID blocks, use is already 1, but RNA
+                * pointer se also increases user, so this compensates it */
+               ima->id.us--;
+
+               RNA_id_pointer_create(&ima->id, &idptr);
+               RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr);
+               RNA_property_update(C, &pprop->ptr, pprop->prop);
+       }
+       else if(sima)
+               ED_space_image_set(C, sima, scene, obedit, ima);
 
        // XXX other users?
        BKE_image_signal(ima, (sima)? &sima->iuser: NULL, IMA_SIGNAL_RELOAD);
-       if(sima)
-               ED_space_image_set(C, sima, scene, obedit, ima);
+
+       MEM_freeN(op->customdata);
 
        return OPERATOR_FINISHED;
 }
@@ -649,6 +683,8 @@ static int open_invoke(bContext *C, wmOperator *op, wmEvent *event)
        if(RNA_property_is_set(op->ptr, "path"))
                return open_exec(C, op);
        
+       open_init(C, op);
+
        image_filesel(C, op, path);
 
        return OPERATOR_RUNNING_MODAL;
@@ -663,6 +699,7 @@ void IMAGE_OT_open(wmOperatorType *ot)
        /* api callbacks */
        ot->exec= open_exec;
        ot->invoke= open_invoke;
+       ot->cancel= open_cancel;
 
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -1060,6 +1097,8 @@ static int new_exec(bContext *C, wmOperator *op)
        Scene *scene;
        Object *obedit;
        Image *ima;
+       PointerRNA ptr, idptr;
+       PropertyRNA *prop;
        char name[22];
        float color[4];
        int width, height, floatbuf, uvtestgrid;
@@ -1078,12 +1117,27 @@ static int new_exec(bContext *C, wmOperator *op)
        color[3]= RNA_float_get(op->ptr, "alpha");
 
        ima = BKE_add_image_size(width, height, name, floatbuf, uvtestgrid, color);
-       ima->id.us--; /* already set later */
 
-       if(sima) { // XXX other users?
-               BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE);
-               ED_space_image_set(C, sima, scene, obedit, ima);
+       if(!ima)
+               return OPERATOR_CANCELLED;
+
+       /* hook into UI */
+       uiIDContextProperty(C, &ptr, &prop);
+
+       if(prop) {
+               /* when creating new ID blocks, use is already 1, but RNA
+                * pointer se also increases user, so this compensates it */
+               ima->id.us--;
+
+               RNA_id_pointer_create(&ima->id, &idptr);
+               RNA_property_pointer_set(&ptr, prop, idptr);
+               RNA_property_update(C, &ptr, prop);
        }
+       else if(sima)
+               ED_space_image_set(C, sima, scene, obedit, ima);
+
+       // XXX other users?
+       BKE_image_signal(ima, (sima)? &sima->iuser: NULL, IMA_SIGNAL_USER_NEW_IMAGE);
        
        return OPERATOR_FINISHED;
 }
index 8e81336912be375a706eeed7760e3c978c4f3984..44f7a097a183966505c8e9ff976b6ba64be47c5d 100644 (file)
@@ -159,10 +159,24 @@ static int new_exec(bContext *C, wmOperator *op)
 {
        SpaceText *st= CTX_wm_space_text(C);
        Text *text;
+       PointerRNA ptr, idptr;
+       PropertyRNA *prop;
 
        text= add_empty_text("Text");
 
-       if(st) {
+       /* hook into UI */
+       uiIDContextProperty(C, &ptr, &prop);
+
+       if(prop) {
+               /* when creating new ID blocks, use is already 1, but RNA
+                * pointer se also increases user, so this compensates it */
+               text->id.us--;
+
+               RNA_id_pointer_create(&text->id, &idptr);
+               RNA_property_pointer_set(&ptr, prop, idptr);
+               RNA_property_update(C, &ptr, prop);
+       }
+       else if(st) {
                st->text= text;
                st->top= 0;
        }
@@ -186,23 +200,61 @@ void TEXT_OT_new(wmOperatorType *ot)
 
 /******************* open operator *********************/
 
+static void open_init(bContext *C, wmOperator *op)
+{
+       PropertyPointerRNA *pprop;
+
+       op->customdata= pprop= MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
+       uiIDContextProperty(C, &pprop->ptr, &pprop->prop);
+}
+
+static int open_cancel(bContext *C, wmOperator *op)
+{
+       MEM_freeN(op->customdata);
+       return OPERATOR_CANCELLED;
+}
+
 static int open_exec(bContext *C, wmOperator *op)
 {
        SpaceText *st= CTX_wm_space_text(C);
        Text *text;
+       PropertyPointerRNA *pprop;
+       PointerRNA idptr;
        char str[FILE_MAX];
 
        RNA_string_get(op->ptr, "path", str);
 
        text= add_text(str, G.sce);
 
-       if(st) {
+       if(!text) {
+               if(op->customdata) MEM_freeN(op->customdata);
+               return OPERATOR_CANCELLED;
+       }
+
+       if(!op->customdata)
+               open_init(C, op);
+
+       /* hook into UI */
+       pprop= op->customdata;
+
+       if(pprop->prop) {
+               /* when creating new ID blocks, use is already 1, but RNA
+                * pointer se also increases user, so this compensates it */
+               text->id.us--;
+
+               RNA_id_pointer_create(&text->id, &idptr);
+               RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr);
+               RNA_property_update(C, &pprop->ptr, pprop->prop);
+       }
+       else if(st) {
                st->text= text;
                st->top= 0;
        }
 
        WM_event_add_notifier(C, NC_TEXT|NA_ADDED, text);
 
+       MEM_freeN(op->customdata);
+
        return OPERATOR_FINISHED;
 }
 
@@ -214,6 +266,7 @@ static int open_invoke(bContext *C, wmOperator *op, wmEvent *event)
        if(RNA_property_is_set(op->ptr, "path"))
                return open_exec(C, op);
        
+       open_init(C, op);
        RNA_string_set(op->ptr, "path", path);
        WM_event_add_fileselect(C, op); 
 
@@ -230,6 +283,7 @@ void TEXT_OT_open(wmOperatorType *ot)
        /* api callbacks */
        ot->exec= open_exec;
        ot->invoke= open_invoke;
+       ot->cancel= open_cancel;
        ot->poll= text_new_poll;
 
        /* properties */
index 98df8c34d58775b3fc03a0f44fb07b6439acb64c..df44789483027d583eb932c865d21505803010e2 100644 (file)
@@ -54,6 +54,11 @@ typedef struct PointerRNA {
        void *data;
 } PointerRNA;
 
+typedef struct PropertyPointerRNA {
+       PointerRNA ptr;
+       struct PropertyRNA *prop;
+} PropertyPointerRNA;
+
 /* Property */
 
 typedef enum PropertyType {
index b7156a17383f51bde2eb84b69fafaf016245409a..80878cf6884aa3245676085d17a41548c553989b 100644 (file)
@@ -298,6 +298,8 @@ static int wm_operator_exec(bContext *C, wmOperator *op, int repeat)
                        uiPupMenuReports(C, op->reports);
        
        if(retval & OPERATOR_FINISHED) {
+               op->customdata= NULL;
+
                if(op->type->flag & OPTYPE_UNDO)
                        ED_undo_push_op(C, op);
                
@@ -427,6 +429,8 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P
                }
 
                if(retval & OPERATOR_FINISHED) {
+                       op->customdata= NULL;
+
                        if(ot->flag & OPTYPE_UNDO)
                                ED_undo_push_op(C, op);
                        
@@ -813,6 +817,8 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
                        }                       
 
                        if(retval & OPERATOR_FINISHED) {
+                               op->customdata= NULL;
+
                                if(ot->flag & OPTYPE_UNDO)
                                        ED_undo_push_op(C, op);
                                
@@ -936,9 +942,9 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
                                /* remlink now, for load file case */
                                BLI_remlink(handlers, handler);
                                
+                               wm_handler_op_context(C, handler);
+
                                if(event->val==EVT_FILESELECT_EXEC) {
-                                       wm_handler_op_context(C, handler);
-                               
                                        /* a bit weak, might become arg for WM_event_fileselect? */
                                        /* XXX also extension code in image-save doesnt work for this yet */
                                        if(strncmp(handler->op->type->name, "Save", 4)==0) {
@@ -954,11 +960,15 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
                                                
                                                WM_operator_free(handler->op);
                                        }
-                                       
-                                       CTX_wm_area_set(C, NULL);
                                }
-                               else 
+                               else {
+                                       if(handler->op->type->cancel)
+                                               handler->op->type->cancel(C, handler->op);
+
                                        WM_operator_free(handler->op);
+                               }
+
+                               CTX_wm_area_set(C, NULL);
                                
                                wm_event_free_handler(handler);
                                if(path)