From bec263e2a3747d5e6f0ed4d29df0958b0e80b9f7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 21 Mar 2012 06:33:31 +0000 Subject: wm/operator code: Change operator previous settings initialization not to use the redo stack since this gets cleared and it means only redo operators can re-use last settings. now this works for import/export as well. --- source/blender/windowmanager/WM_api.h | 3 ++ source/blender/windowmanager/WM_types.h | 3 ++ .../blender/windowmanager/intern/wm_event_system.c | 53 ++++++++++++++++------ source/blender/windowmanager/intern/wm_operators.c | 12 ++++- 4 files changed, 55 insertions(+), 16 deletions(-) (limited to 'source/blender/windowmanager') diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 21ea1bf909f..a794cf10a86 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -214,6 +214,9 @@ void WM_operator_properties_select_all(struct wmOperatorType *ot); int WM_operator_check_ui_enabled(const struct bContext *C, const char *idname); wmOperator *WM_operator_last_redo(const struct bContext *C); +int WM_operator_last_properties_init(struct wmOperator *op); +int WM_operator_last_properties_store(struct wmOperator *op); + /* MOVE THIS SOMEWHERE ELSE */ #define SEL_TOGGLE 0 #define SEL_SELECT 1 diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 25915444657..4aa2c3f6405 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -466,6 +466,9 @@ typedef struct wmOperatorType { /* rna for properties */ struct StructRNA *srna; + /* previous settings - for initializing on re-use */ + struct IDProperty *last_properties; + /* rna property to use for generic invoke functions. * menus, enum search... etc */ PropertyRNA *prop; diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index e15ed7b8929..095a6bae966 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -585,10 +585,17 @@ static int wm_operator_exec(bContext *C, wmOperator *op, int repeat) if (retval & (OPERATOR_FINISHED|OPERATOR_CANCELLED) && repeat == 0) wm_operator_reports(C, op, retval, FALSE); - if(retval & OPERATOR_FINISHED) + if(retval & OPERATOR_FINISHED) { + if (repeat) { + if (wm->op_undo_depth == 0) { /* not called by py script */ + WM_operator_last_properties_store(op); + } + } wm_operator_finished(C, op, repeat); - else if(repeat==0) + } + else if(repeat==0) { WM_operator_free(op); + } return retval | OPERATOR_HANDLED; @@ -738,19 +745,11 @@ static void wm_region_mouse_co(bContext *C, wmEvent *event) } } -static int wm_operator_init_from_last(wmWindowManager *wm, wmOperator *op) +int WM_operator_last_properties_init(wmOperator *op) { int change= FALSE; - wmOperator *lastop; - for(lastop= wm->operators.last; lastop; lastop= lastop->prev) { - /* equality check is a bit paranoid but just in case */ - if((op != lastop) && (op->type == (lastop->type))) { - break; - } - } - - if (lastop && op != lastop) { + if (op->type->last_properties) { PropertyRNA *iterprop; iterprop= RNA_struct_iterator_property(op->type->srna); @@ -759,7 +758,7 @@ static int wm_operator_init_from_last(wmWindowManager *wm, wmOperator *op) if((RNA_property_flag(prop) & PROP_SKIP_SAVE) == 0) { if (!RNA_property_is_set(op->ptr, prop)) { /* don't override a setting already set */ const char *identifier= RNA_property_identifier(prop); - IDProperty *idp_src= IDP_GetPropertyFromGroup(lastop->properties, identifier); + IDProperty *idp_src= IDP_GetPropertyFromGroup(op->type->last_properties, identifier); if(idp_src) { IDProperty *idp_dst = IDP_CopyProperty(idp_src); @@ -779,6 +778,23 @@ static int wm_operator_init_from_last(wmWindowManager *wm, wmOperator *op) return change; } +int WM_operator_last_properties_store(wmOperator *op) +{ + if (op->type->last_properties) { + IDP_FreeProperty(op->type->last_properties); + MEM_freeN(op->type->last_properties); + op->type->last_properties = NULL; + } + + if (op->properties) { + op->type->last_properties = IDP_CopyProperty(op->properties); + return TRUE; + } + else { + return FALSE; + } +} + static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, PointerRNA *properties, ReportList *reports, short poll_only) { wmWindowManager *wm= CTX_wm_manager(C); @@ -792,8 +808,8 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P wmOperator *op= wm_operator_create(wm, ot, properties, reports); /* if reports==NULL, theyll be initialized */ /* initialize setting from previous run */ - if(wm->op_undo_depth == 0 && (ot->flag & OPTYPE_REGISTER)) { /* not called by py script */ - wm_operator_init_from_last(wm, op); + if(wm->op_undo_depth == 0) { /* not called by py script */ + WM_operator_last_properties_init(op); } if((G.f & G_DEBUG) && event && event->type!=MOUSEMOVE) @@ -836,6 +852,9 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P if(retval & OPERATOR_HANDLED) ; /* do nothing, wm_operator_exec() has been called somewhere */ else if(retval & OPERATOR_FINISHED) { + if (wm->op_undo_depth == 0) { /* not called by py script */ + WM_operator_last_properties_store(op); + } wm_operator_finished(C, op, 0); } else if(retval & OPERATOR_RUNNING_MODAL) { @@ -1535,6 +1554,10 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa CTX_wm_region_set(C, ar_prev); } + if (retval & OPERATOR_FINISHED) { + WM_operator_last_properties_store(handler->op); + } + WM_operator_free(handler->op); } } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 7ee29945f57..8fe5bba3cc4 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -449,7 +449,12 @@ int WM_operatortype_remove(const char *idname) return 0; RNA_struct_free(&BLENDER_RNA, ot->srna); - + + if (ot->last_properties) { + IDP_FreeProperty(ot->last_properties); + MEM_freeN(ot->last_properties); + } + if(ot->macro.first) wm_operatortype_free_macro(ot); @@ -3618,6 +3623,11 @@ static void WM_OT_ndof_sensitivity_change(wmOperatorType *ot) static void operatortype_ghash_free_cb(wmOperatorType *ot) { + if (ot->last_properties) { + IDP_FreeProperty(ot->last_properties); + MEM_freeN(ot->last_properties); + } + if(ot->macro.first) wm_operatortype_free_macro(ot); -- cgit v1.2.3