Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_blender.h1
-rw-r--r--source/blender/blenkernel/intern/blender.c16
-rw-r--r--source/blender/editors/include/ED_util.h1
-rw-r--r--source/blender/editors/interface/interface_handlers.c4
-rw-r--r--source/blender/editors/mesh/editmesh_add.c3
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c14
-rw-r--r--source/blender/editors/mesh/mesh_ops.c22
-rw-r--r--source/blender/editors/object/object_edit.c4
-rw-r--r--source/blender/editors/object/object_ops.c11
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c24
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_toolbar.c30
-rw-r--r--source/blender/editors/util/editmode_undo.c15
-rw-r--r--source/blender/editors/util/undo.c46
-rw-r--r--source/blender/editors/util/util_intern.h1
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h19
-rw-r--r--source/blender/windowmanager/WM_api.h4
-rw-r--r--source/blender/windowmanager/WM_types.h1
-rw-r--r--source/blender/windowmanager/intern/wm.c6
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c54
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c140
21 files changed, 360 insertions, 60 deletions
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 795c7585b9c..19b9c315939 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -71,6 +71,7 @@ void pushpop_test(void);
/* global undo */
extern void BKE_write_undo(struct bContext *C, char *name);
extern void BKE_undo_step(struct bContext *C, int step);
+extern void BKE_undo_name(struct bContext *C, const char *name);
extern void BKE_reset_undo(void);
extern char *BKE_undo_menu_string(void);
extern void BKE_undo_number(struct bContext *C, int nr);
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 20505356d95..2728aa30e6e 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -688,6 +688,22 @@ void BKE_undo_number(bContext *C, int nr)
BKE_undo_step(C, 0);
}
+/* go back to the last occurance of name in stack */
+void BKE_undo_name(bContext *C, const char *name)
+{
+ UndoElem *uel;
+
+ for(uel= undobase.last; uel; uel= uel->prev) {
+ if(strcmp(name, uel->name)==0)
+ break;
+ }
+ if(uel && uel->prev) {
+ curundo= uel->prev;
+ BKE_undo_step(C, 0);
+ }
+}
+
+
char *BKE_undo_menu_string(void)
{
UndoElem *uel;
diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h
index 7ccbf1ff18d..7b1c87f9cb2 100644
--- a/source/blender/editors/include/ED_util.h
+++ b/source/blender/editors/include/ED_util.h
@@ -44,6 +44,7 @@ void ED_editors_exit (struct bContext *C);
/* undo.c */
void ED_undo_push (struct bContext *C, char *str);
void ED_undo_push_op (struct bContext *C, struct wmOperator *op);
+void ED_undo_pop_op (struct bContext *C, struct wmOperator *op);
void ED_undo_pop (struct bContext *C);
void ED_undo_redo (struct bContext *C);
void ED_OT_undo (struct wmOperatorType *ot);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index da2899dd3b2..6f2b49c0513 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -358,8 +358,8 @@ static void ui_apply_but_funcs_after(bContext *C)
if(after.rename_orig)
MEM_freeN(after.rename_orig);
- if(after.undostr[0])
- ED_undo_push(C, after.undostr);
+// if(after.undostr[0])
+// ED_undo_push(C, after.undostr);
}
}
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index 92aa46ea390..34eca8748bc 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -1683,9 +1683,6 @@ static int mesh_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *event)
mesh_duplicate_exec(C, op);
WM_cursor_wait(0);
- RNA_int_set(op->ptr, "mode", TFM_TRANSLATION);
- WM_operator_name_call(C, "TFM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr);
-
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 76f355ab7f9..93e91732b2b 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -704,7 +704,7 @@ static int mesh_extrude_invoke(bContext *C, wmOperator *op, wmEvent *event)
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
- int constraint_axis[3] = {0, 0, 1};
+// int constraint_axis[3] = {0, 0, 1};
extrude_mesh(scene, obedit, em, op);
@@ -717,11 +717,11 @@ static int mesh_extrude_invoke(bContext *C, wmOperator *op, wmEvent *event)
RNA_boolean_set(op->ptr, "mirror", 0);
/* the following two should only be set when extruding faces */
- RNA_enum_set(op->ptr, "constraint_orientation", V3D_MANIP_NORMAL);
- RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
+// RNA_enum_set(op->ptr, "constraint_orientation", V3D_MANIP_NORMAL);
+// RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
- WM_operator_name_call(C, "TFM_OT_translate", WM_OP_INVOKE_REGION_WIN, op->ptr);
+// WM_operator_name_call(C, "TFM_OT_translate", WM_OP_INVOKE_REGION_WIN, op->ptr);
return OPERATOR_FINISHED;
}
@@ -4991,9 +4991,9 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
BKE_mesh_end_editmesh(obedit->data, em);
- RNA_enum_set(op->ptr, "proportional", 0);
- RNA_boolean_set(op->ptr, "mirror", 0);
- WM_operator_name_call(C, "TFM_OT_translate", WM_OP_INVOKE_REGION_WIN, op->ptr);
+// RNA_enum_set(op->ptr, "proportional", 0);
+// RNA_boolean_set(op->ptr, "mirror", 0);
+// WM_operator_name_call(C, "TFM_OT_translate", WM_OP_INVOKE_REGION_WIN, op->ptr);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 8ed68d5cd20..edb131d7da2 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -230,6 +230,8 @@ static void MESH_OT_specials(wmOperatorType *ot)
void ED_operatortypes_mesh(void)
{
+ wmOperatorType *ot;
+
WM_operatortype_append(MESH_OT_select_all_toggle);
WM_operatortype_append(MESH_OT_select_more);
WM_operatortype_append(MESH_OT_select_less);
@@ -313,6 +315,20 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_edge_specials);
WM_operatortype_append(MESH_OT_face_specials);
WM_operatortype_append(MESH_OT_specials);
+
+ /* macros */
+ ot= WM_operatortype_append_macro("MESH_OT_duplicate_move", "Add Duplicate", OPTYPE_UNDO|OPTYPE_REGISTER);
+ WM_operatortype_macro_define(ot, "MESH_OT_duplicate");
+ WM_operatortype_macro_define(ot, "TFM_OT_translate");
+
+ ot= WM_operatortype_append_macro("MESH_OT_rip_move", "Rip", OPTYPE_UNDO|OPTYPE_REGISTER);
+ WM_operatortype_macro_define(ot, "MESH_OT_rip");
+ WM_operatortype_macro_define(ot, "TFM_OT_translate");
+
+ ot= WM_operatortype_append_macro("MESH_OT_extrude_move", "Extrude", OPTYPE_UNDO|OPTYPE_REGISTER);
+ WM_operatortype_macro_define(ot, "MESH_OT_extrude");
+ WM_operatortype_macro_define(ot, "TFM_OT_translate");
+
}
/* note mesh keymap also for other space? */
@@ -363,7 +379,7 @@ void ED_keymap_mesh(wmWindowManager *wm)
WM_keymap_add_item(keymap, "MESH_OT_normals_make_consistent", NKEY, KM_PRESS, KM_CTRL, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "MESH_OT_normals_make_consistent", NKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0)->ptr, "inside", 1);
- WM_keymap_add_item(keymap, "MESH_OT_extrude", EKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_extrude_move", EKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MESH_OT_spin", RKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "MESH_OT_screw", NINEKEY, KM_PRESS, KM_CTRL, 0);
@@ -386,12 +402,12 @@ void ED_keymap_mesh(wmWindowManager *wm)
WM_keymap_add_item(keymap, "MESH_OT_colors_rotate",EIGHTKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "MESH_OT_colors_mirror",EIGHTKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_add_item(keymap, "MESH_OT_rip",VKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_rip_move",VKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MESH_OT_merge", MKEY, KM_PRESS, KM_ALT, 0);
/* add/remove */
WM_keymap_add_item(keymap, "MESH_OT_edge_face_add", FKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "MESH_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_mesh_add", AKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "MESH_OT_separate", PKEY, KM_PRESS, KM_SHIFT, 0);
/* use KM_RELEASE because same key is used for tweaks */
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index f34dc2e7c23..5fd5f4ff0ad 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -6497,8 +6497,8 @@ static int duplicate_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
duplicate_exec(C, op);
- RNA_int_set(op->ptr, "mode", TFM_TRANSLATION);
- WM_operator_name_call(C, "TFM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr);
+// RNA_int_set(op->ptr, "mode", TFM_TRANSLATION);
+// WM_operator_name_call(C, "TFM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index fe092847183..c1509e78502 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -63,6 +63,8 @@
void ED_operatortypes_object(void)
{
+ wmOperatorType *ot;
+
WM_operatortype_append(OBJECT_OT_editmode_toggle);
WM_operatortype_append(OBJECT_OT_posemode_toggle);
WM_operatortype_append(OBJECT_OT_parent_set);
@@ -147,6 +149,13 @@ void ED_operatortypes_object(void)
WM_operatortype_append(LATTICE_OT_select_all_toggle);
WM_operatortype_append(LATTICE_OT_make_regular);
+
+ /* macros */
+ ot= WM_operatortype_append_macro("OBJECT_OT_duplicate_move", "Add Duplicate", OPTYPE_UNDO|OPTYPE_REGISTER);
+ if(ot) {
+ WM_operatortype_macro_define(ot, "OBJECT_OT_duplicate");
+ WM_operatortype_macro_define(ot, "TFM_OT_translate");
+ }
}
void ED_keymap_object(wmWindowManager *wm)
@@ -185,7 +194,7 @@ void ED_keymap_object(wmWindowManager *wm)
WM_keymap_verify_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "OBJECT_OT_primitive_add", AKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "OBJECT_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "OBJECT_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_duplicate", DKEY, KM_PRESS, KM_ALT, 0)->ptr, "linked", 1);
WM_keymap_add_item(keymap, "OBJECT_OT_join", JKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_proxy_make", PKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index f278b717f10..acb3a2257dc 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -560,7 +560,7 @@ void VIEW3D_OT_viewrotate(wmOperatorType *ot)
ot->poll= ED_operator_view3d_active;
/* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_BLOCKING;
+ ot->flag= OPTYPE_BLOCKING;
}
/* ************************ viewmove ******************************** */
@@ -644,7 +644,7 @@ void VIEW3D_OT_viewmove(wmOperatorType *ot)
ot->poll= ED_operator_view3d_active;
/* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_BLOCKING;
+ ot->flag= OPTYPE_BLOCKING;
}
/* ************************ viewzoom ******************************** */
@@ -844,7 +844,7 @@ void VIEW3D_OT_zoom(wmOperatorType *ot)
ot->poll= ED_operator_view3d_active;
/* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_BLOCKING;
+ ot->flag= OPTYPE_BLOCKING;
RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX);
}
@@ -925,7 +925,7 @@ void VIEW3D_OT_view_all(wmOperatorType *ot)
ot->poll= ED_operator_view3d_active;
/* flags */
- ot->flag= OPTYPE_REGISTER;
+ ot->flag= 0;
RNA_def_boolean(ot->srna, "center", 0, "Center", "");
}
@@ -1064,7 +1064,7 @@ void VIEW3D_OT_view_center(wmOperatorType *ot)
ot->poll= ED_operator_view3d_active;
/* flags */
- ot->flag= OPTYPE_REGISTER;
+ ot->flag= 0;
}
/* ********************* Set render border operator ****************** */
@@ -1312,7 +1312,7 @@ void VIEW3D_OT_zoom_border(wmOperatorType *ot)
ot->poll= ED_operator_view3d_active;
/* flags */
- ot->flag= OPTYPE_REGISTER;
+ ot->flag= 0;
/* rna */
RNA_def_int(ot->srna, "xmin", 0, INT_MIN, INT_MAX, "X Min", "", INT_MIN, INT_MAX);
@@ -1477,7 +1477,7 @@ void VIEW3D_OT_viewnumpad(wmOperatorType *ot)
ot->poll= ED_operator_view3d_active;
/* flags */
- ot->flag= OPTYPE_REGISTER;
+ ot->flag= 0;
RNA_def_enum(ot->srna, "type", prop_view_items, 0, "View", "The Type of view");
}
@@ -1546,7 +1546,7 @@ void VIEW3D_OT_view_orbit(wmOperatorType *ot)
ot->poll= ED_operator_view3d_active;
/* flags */
- ot->flag= OPTYPE_REGISTER;
+ ot->flag= 0;
RNA_def_enum(ot->srna, "type", prop_view_orbit_items, 0, "Orbit", "Direction of View Orbit");
}
@@ -1596,7 +1596,7 @@ void VIEW3D_OT_view_pan(wmOperatorType *ot)
ot->poll= ED_operator_view3d_active;
/* flags */
- ot->flag= OPTYPE_REGISTER;
+ ot->flag= 0;
RNA_def_enum(ot->srna, "type", prop_view_pan_items, 0, "Pan", "Direction of View Pan");
}
@@ -1628,7 +1628,7 @@ void VIEW3D_OT_view_persportho(wmOperatorType *ot)
ot->poll= ED_operator_view3d_active;
/* flags */
- ot->flag= OPTYPE_REGISTER;
+ ot->flag= 0;
}
@@ -1730,7 +1730,7 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot)
ot->poll= ED_operator_view3d_active;
/* flags */
- ot->flag= OPTYPE_REGISTER;
+ ot->flag= 0;
/* rna */
RNA_def_int(ot->srna, "xmin", 0, INT_MIN, INT_MAX, "X Min", "", INT_MIN, INT_MAX);
@@ -1783,7 +1783,7 @@ void VIEW3D_OT_drawtype(wmOperatorType *ot)
ot->poll= ED_operator_view3d_active;
/* flags */
- ot->flag= OPTYPE_REGISTER;
+ ot->flag= 0;
/* rna XXX should become enum */
RNA_def_int(ot->srna, "draw_type", 0, INT_MIN, INT_MAX, "Draw Type", "", INT_MIN, INT_MAX);
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index 69b297b2e03..c82db3bbe32 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -218,8 +218,8 @@ void view3d_keymap(wmWindowManager *wm)
WM_keymap_add_item(keymap, "VIEW3D_OT_snap_menu", SKEY, KM_PRESS, KM_SHIFT, 0);
- /* drag & drop */
- WM_keymap_add_item(keymap, "VIEW3D_OT_drag", MOUSEDRAG, KM_ANY, 0, 0);
+ /* drag & drop (disabled) */
+// WM_keymap_add_item(keymap, "VIEW3D_OT_drag", MOUSEDRAG, KM_ANY, 0, 0);
/* radial control */
RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c
index 1564fcb169b..67d8bc3e5ee 100644
--- a/source/blender/editors/space_view3d/view3d_toolbar.c
+++ b/source/blender/editors/space_view3d/view3d_toolbar.c
@@ -109,7 +109,7 @@ static void redo_cb(bContext *C, void *arg_op, void *arg2)
int retval;
printf("operator redo %s\n", lastop->type->name);
- ED_undo_pop(C);
+ ED_undo_pop_op(C, lastop);
retval= WM_operator_repeat(C, lastop);
if((retval & OPERATOR_FINISHED)==0) {
printf("operator redo failed %s\n", lastop->type->name);
@@ -118,11 +118,25 @@ static void redo_cb(bContext *C, void *arg_op, void *arg2)
}
}
+static void view3d_panel_operator_redo_buts(const bContext *C, Panel *pa, wmOperator *op)
+{
+ wmWindowManager *wm= CTX_wm_manager(C);
+ PointerRNA ptr;
+
+ if(!op->properties) {
+ IDPropertyTemplate val = {0};
+ op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties");
+ }
+
+ RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
+ uiDefAutoButsRNA(C, pa->layout, &ptr, 1);
+
+}
+
static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
{
wmWindowManager *wm= CTX_wm_manager(C);
wmOperator *op;
- PointerRNA ptr;
uiBlock *block;
block= uiLayoutGetBlock(pa->layout);
@@ -139,13 +153,13 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
uiBlockSetFunc(block, redo_cb, op, NULL);
- if(!op->properties) {
- IDPropertyTemplate val = {0};
- op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties");
+ if(op->macro.first) {
+ for(op= op->macro.first; op; op= op->next)
+ view3d_panel_operator_redo_buts(C, pa, op);
+ }
+ else {
+ view3d_panel_operator_redo_buts(C, pa, op);
}
-
- RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
- uiDefAutoButsRNA(C, pa->layout, &ptr, 1);
}
/* ******************* */
diff --git a/source/blender/editors/util/editmode_undo.c b/source/blender/editors/util/editmode_undo.c
index 8484ad78bc4..17a1e0b6cdb 100644
--- a/source/blender/editors/util/editmode_undo.c
+++ b/source/blender/editors/util/editmode_undo.c
@@ -297,6 +297,21 @@ static void undo_number(bContext *C, int nr)
undo_editmode_step(C, 0);
}
+void undo_editmode_name(bContext *C, const char *undoname)
+{
+ UndoElem *uel;
+
+ for(uel= undobase.last; uel; uel= uel->prev) {
+ if(strcmp(undoname, uel->name)==0)
+ break;
+ }
+ if(uel && uel->prev) {
+ curundo= uel->prev;
+ undo_editmode_step(C, 0);
+ }
+}
+
+
/* ************** for interaction with menu/pullown */
void undo_editmode_menu(bContext *C)
diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c
index be04cdecac6..435f2c7ecf4 100644
--- a/source/blender/editors/util/undo.c
+++ b/source/blender/editors/util/undo.c
@@ -71,6 +71,8 @@
#include "UI_interface.h"
#include "UI_resources.h"
+#include "util_intern.h"
+
/* ***************** generic undo system ********************* */
/* ********* XXX **************** */
@@ -81,7 +83,7 @@ void ED_undo_push(bContext *C, char *str)
{
wmWindowManager *wm= CTX_wm_manager(C);
Object *obedit= CTX_data_edit_object(C);
-
+
if(obedit) {
if (U.undosteps == 0) return;
@@ -114,13 +116,7 @@ void ED_undo_push(bContext *C, char *str)
}
}
-void ED_undo_push_op(bContext *C, wmOperator *op)
-{
- /* in future, get undo string info? */
- ED_undo_push(C, op->type->name);
-}
-
-static int ed_undo_step(bContext *C, int step)
+static int ed_undo_step(bContext *C, int step, const char *undoname)
{
Object *obedit= CTX_data_edit_object(C);
ScrArea *sa= CTX_wm_area(C);
@@ -140,8 +136,12 @@ static int ed_undo_step(bContext *C, int step)
ED_text_undo_step(C, step);
}
else if(obedit) {
- if ELEM7(obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
- undo_editmode_step(C, step);
+ if ELEM7(obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE) {
+ if(undoname)
+ undo_editmode_name(C, undoname);
+ else
+ undo_editmode_step(C, step);
+ }
}
else {
int do_glob_undo= 0;
@@ -163,7 +163,10 @@ static int ed_undo_step(bContext *C, int step)
#ifndef DISABLE_PYTHON
// XXX BPY_scripts_clear_pyobjects();
#endif
- BKE_undo_step(C, step);
+ if(undoname)
+ BKE_undo_name(C, undoname);
+ else
+ BKE_undo_step(C, step);
sound_initialize_sounds();
}
@@ -177,22 +180,35 @@ static int ed_undo_step(bContext *C, int step)
void ED_undo_pop(bContext *C)
{
- ed_undo_step(C, 1);
+ ed_undo_step(C, 1, NULL);
}
void ED_undo_redo(bContext *C)
{
- ed_undo_step(C, -1);
+ ed_undo_step(C, -1, NULL);
+}
+
+void ED_undo_push_op(bContext *C, wmOperator *op)
+{
+ /* in future, get undo string info? */
+ ED_undo_push(C, op->type->name);
+}
+
+void ED_undo_pop_op(bContext *C, wmOperator *op)
+{
+ /* search back a couple of undo's, in case something else added pushes */
+ ed_undo_step(C, 0, op->type->name);
}
static int ed_undo_exec(bContext *C, wmOperator *op)
{
/* "last operator" should disappear, later we can tie ths with undo stack nicer */
WM_operator_stack_clear(C);
- return ed_undo_step(C, 1);
+ return ed_undo_step(C, 1, NULL);
}
+
static int ed_redo_exec(bContext *C, wmOperator *op)
{
- return ed_undo_step(C, -1);
+ return ed_undo_step(C, -1, NULL);
}
void ED_undo_menu(bContext *C)
diff --git a/source/blender/editors/util/util_intern.h b/source/blender/editors/util/util_intern.h
index 37e6c5c25e1..8a0787dde3f 100644
--- a/source/blender/editors/util/util_intern.h
+++ b/source/blender/editors/util/util_intern.h
@@ -33,6 +33,7 @@
/* editmode_undo.c */
void undo_editmode_clear(void);
+void undo_editmode_name(bContext *C, const char *undoname);
#endif /* ED_UTIL_INTERN_H */
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index a7ad502d438..704acbfd52b 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -173,6 +173,18 @@ typedef struct wmWindow {
#
#
+typedef struct wmOperatorTypeMacro {
+ struct wmOperatorTypeMacro *next, *prev;
+
+ /* operator id */
+ char idname[MAX_ID_NAME];
+ /* rna pointer to access properties, like keymap */
+ struct PointerRNA *ptr;
+
+} wmOperatorTypeMacro;
+
+#
+#
typedef struct wmOperatorType {
struct wmOperatorType *next, *prev;
@@ -204,6 +216,9 @@ typedef struct wmOperatorType {
/* rna for properties */
struct StructRNA *srna;
+ /* struct wmOperatorTypeMacro */
+ ListBase macro;
+
short flag;
/* pointer to modal keymap, do not free! */
@@ -265,9 +280,13 @@ typedef struct wmOperator {
/* runtime */
wmOperatorType *type; /* operator type definition from idname */
void *customdata; /* custom storage, only while operator runs */
+
struct PointerRNA *ptr; /* rna pointer to access properties */
struct ReportList *reports; /* errors and warnings storage */
+ ListBase macro; /* list of operators, can be a tree */
+ struct wmOperator *opm; /* current running macro, not saved */
+
} wmOperator;
/* operator type exec(), invoke() modal(), return values */
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 0d3ad96d8c3..f65e5b1b077 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -158,6 +158,10 @@ void WM_operatortype_append (void (*opfunc)(wmOperatorType*));
void WM_operatortype_append_ptr (void (*opfunc)(wmOperatorType*, void *), void *userdata);
int WM_operatortype_remove(const char *idname);
+wmOperatorType *WM_operatortype_append_macro(char *idname, char *name, int flag);
+wmOperatorTypeMacro *WM_operatortype_macro_define(wmOperatorType *ot, const char *idname);
+
+
int WM_operator_call (struct bContext *C, struct wmOperator *op);
int WM_operator_repeat (struct bContext *C, struct wmOperator *op);
int WM_operator_name_call (struct bContext *C, const char *opstring, int context, struct PointerRNA *properties);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 3a646c5e799..a083d589d31 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -43,6 +43,7 @@ struct wmWindowManager;
#define OPTYPE_REGISTER 1 /* register operators in stack after finishing */
#define OPTYPE_UNDO 2 /* do undo push after after */
#define OPTYPE_BLOCKING 4 /* let blender grab all input from the WM (X11) */
+#define OPTYPE_MACRO 8
/* context to call operator in for WM_operator_name_call */
/* rna_ui.c contains EnumPropertyItem's of these, keep in sync */
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 863fb3ab4bd..c0ac7b06f5a 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -74,6 +74,12 @@ void WM_operator_free(wmOperator *op)
MEM_freeN(op->reports);
}
+ if(op->macro.first) {
+ wmOperator *opm;
+ for(opm= op->macro.first; opm; opm= opm->next)
+ WM_operator_free(opm);
+ }
+
MEM_freeN(op);
}
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index c75feafe623..33e8a392ba3 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -244,6 +244,23 @@ void wm_event_do_notifiers(bContext *C)
/* ********************* operators ******************* */
+static int wm_operator_poll(bContext *C, wmOperatorType *ot)
+{
+ wmOperatorTypeMacro *otmacro;
+
+ for(otmacro= ot->macro.first; otmacro; otmacro= otmacro->next) {
+ wmOperatorType *ot= WM_operatortype_find(otmacro->idname, 0);
+
+ if(0==wm_operator_poll(C, ot))
+ return 0;
+ }
+
+ if(ot->poll)
+ return ot->poll(C);
+
+ return 1;
+}
+
/* if repeat is true, it doesn't register again, nor does it free */
static int wm_operator_exec(bContext *C, wmOperator *op, int repeat)
{
@@ -252,7 +269,7 @@ static int wm_operator_exec(bContext *C, wmOperator *op, int repeat)
if(op==NULL || op->type==NULL)
return retval;
- if(op->type->poll && op->type->poll(C)==0)
+ if(0==wm_operator_poll(C, op->type))
return retval;
if(op->type->exec)
@@ -320,6 +337,26 @@ static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot, P
BKE_reports_init(op->reports, RPT_STORE);
}
+ /* recursive filling of operator macro list */
+ if(ot->macro.first) {
+ static wmOperator *motherop= NULL;
+ wmOperatorTypeMacro *otmacro;
+
+ /* ensure all ops are in execution order in 1 list */
+ if(motherop==NULL)
+ motherop= op;
+
+ for(otmacro= ot->macro.first; otmacro; otmacro= otmacro->next) {
+ wmOperatorType *otm= WM_operatortype_find(otmacro->idname, 0);
+ wmOperator *opm= wm_operator_create(wm, otm, otmacro->ptr, NULL);
+
+ BLI_addtail(&motherop->macro, opm);
+ opm->opm= motherop; /* pointer to mom, for modal() */
+ }
+
+ motherop= NULL;
+ }
+
return op;
}
@@ -345,7 +382,7 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P
wmWindowManager *wm= CTX_wm_manager(C);
int retval= OPERATOR_PASS_THROUGH;
- if(ot->poll==NULL || ot->poll(C)) {
+ if(wm_operator_poll(C, ot)) {
wmOperator *op= wm_operator_create(wm, ot, properties, NULL);
if((G.f & G_DEBUG) && event && event->type!=MOUSEMOVE)
@@ -809,7 +846,6 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
case EVT_FILESELECT_OPEN:
case EVT_FILESELECT_FULL_OPEN:
{
- short flag =0; short display =FILE_SHORTDISPLAY; short filter =0; short sort =FILE_SORT_ALPHA;
char *dir= NULL; char *path= RNA_string_get_alloc(handler->op->ptr, "filename", NULL, 0);
if(event->val==EVT_FILESELECT_OPEN)
@@ -1198,7 +1234,17 @@ void WM_event_set_handler_flag(wmEventHandler *handler, int flag)
wmEventHandler *WM_event_add_modal_handler(bContext *C, ListBase *handlers, wmOperator *op)
{
wmEventHandler *handler= MEM_callocN(sizeof(wmEventHandler), "event modal handler");
- handler->op= op;
+
+ /* operator was part of macro */
+ if(op->opm) {
+ /* give the mother macro to the handler */
+ handler->op= op->opm;
+ /* mother macro opm becomes the macro element */
+ handler->op->opm= op;
+ }
+ else
+ handler->op= op;
+
handler->op_area= CTX_wm_area(C); /* means frozen screen context for modal handlers! */
handler->op_region= CTX_wm_region(C);
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index e25c86ea2fd..2b7a18dc1cf 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -154,6 +154,134 @@ void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType*, void*), void *us
BLI_addtail(&global_ops, ot);
}
+/* ********************* macro operator ******************** */
+
+/* macro exec only runs exec calls */
+static int wm_macro_exec(bContext *C, wmOperator *op)
+{
+ wmOperator *opm;
+ int retval= OPERATOR_FINISHED;
+
+// printf("macro exec %s\n", op->type->idname);
+
+ for(opm= op->macro.first; opm; opm= opm->next) {
+
+ if(opm->type->exec) {
+// printf("macro exec %s\n", opm->type->idname);
+ retval= opm->type->exec(C, opm);
+
+ if(!(retval & OPERATOR_FINISHED))
+ break;
+ }
+ }
+// if(opm)
+// printf("macro ended not finished\n");
+// else
+// printf("macro end\n");
+
+ return retval;
+}
+
+static int wm_macro_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ wmOperator *opm;
+ int retval= OPERATOR_FINISHED;
+
+// printf("macro invoke %s\n", op->type->idname);
+
+ for(opm= op->macro.first; opm; opm= opm->next) {
+
+ if(opm->type->invoke)
+ retval= opm->type->invoke(C, opm, event);
+ else if(opm->type->exec)
+ retval= opm->type->exec(C, opm);
+
+ if(!(retval & OPERATOR_FINISHED))
+ break;
+ }
+
+// if(opm)
+// printf("macro ended not finished\n");
+// else
+// printf("macro end\n");
+
+
+ return retval;
+}
+
+static int wm_macro_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+// printf("macro modal %s\n", op->type->idname);
+
+ if(op->opm==NULL)
+ printf("macro error, calling NULL modal()\n");
+ else {
+// printf("macro modal %s\n", op->opm->type->idname);
+ return op->opm->type->modal(C, op->opm, event);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+/* Names have to be static for now */
+wmOperatorType *WM_operatortype_append_macro(char *idname, char *name, int flag)
+{
+ wmOperatorType *ot;
+
+ if(WM_operatortype_exists(idname)) {
+ printf("Macro error: operator %s exists\n", idname);
+ return NULL;
+ }
+
+ ot= MEM_callocN(sizeof(wmOperatorType), "operatortype");
+ ot->srna= RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties");
+
+ ot->idname= idname;
+ ot->name= name;
+ ot->flag= OPTYPE_MACRO | flag;
+
+ ot->exec= wm_macro_exec;
+ ot->invoke= wm_macro_invoke;
+ ot->modal= wm_macro_modal;
+ ot->poll= NULL;
+
+ RNA_def_struct_ui_text(ot->srna, ot->name, ot->description ? ot->description:"(undocumented operator)"); // XXX All ops should have a description but for now allow them not to.
+ RNA_def_struct_identifier(ot->srna, ot->idname);
+
+ BLI_addtail(&global_ops, ot);
+
+ return ot;
+}
+
+wmOperatorTypeMacro *WM_operatortype_macro_define(wmOperatorType *ot, const char *idname)
+{
+ wmOperatorTypeMacro *otmacro= MEM_callocN(sizeof(wmOperatorTypeMacro), "wmOperatorTypeMacro");
+
+ BLI_strncpy(otmacro->idname, idname, OP_MAX_TYPENAME);
+
+ /* do this on first use, since operatordefinitions might have been not done yet */
+// otmacro->ptr= MEM_callocN(sizeof(PointerRNA), "optype macro ItemPtr");
+// WM_operator_properties_create(otmacro->ptr, idname);
+
+ BLI_addtail(&ot->macro, otmacro);
+
+ return otmacro;
+}
+
+static void wm_operatortype_free_macro(wmOperatorType *ot)
+{
+ wmOperatorTypeMacro *otmacro;
+
+ for(otmacro= ot->macro.first; otmacro; otmacro= otmacro->next) {
+ if(otmacro->ptr) {
+ WM_operator_properties_free(otmacro->ptr);
+ MEM_freeN(otmacro->ptr);
+ }
+ }
+ BLI_freelistN(&ot->macro);
+}
+
+
int WM_operatortype_remove(const char *idname)
{
wmOperatorType *ot = WM_operatortype_find(idname, 0);
@@ -163,6 +291,10 @@ int WM_operatortype_remove(const char *idname)
BLI_remlink(&global_ops, ot);
RNA_struct_free(&BLENDER_RNA, ot->srna);
+
+ if(ot->macro.first)
+ wm_operatortype_free_macro(ot);
+
MEM_freeN(ot);
return 1;
@@ -348,7 +480,7 @@ static void redo_cb(bContext *C, void *arg_op, void *arg2)
wmOperator *lastop= arg_op;
if(lastop) {
- ED_undo_pop(C);
+ ED_undo_pop_op(C, lastop);
WM_operator_repeat(C, lastop);
}
}
@@ -1677,6 +1809,12 @@ static void WM_OT_ten_timer(wmOperatorType *ot)
/* called on initialize WM_exit() */
void wm_operatortype_free(void)
{
+ wmOperatorType *ot;
+
+ for(ot= global_ops.first; ot; ot= ot->next)
+ if(ot->macro.first)
+ wm_operatortype_free_macro(ot);
+
BLI_freelistN(&global_ops);
}