The tool-redo depends on a working undo system, so it can rewind
a step and then redo operator with new settings. When a user
disables undo, this won't work.

Now the properties for redo operator (toolbar, F6) will grey out
when a redo isn't possible.
This commit is contained in:
2011-01-12 18:00:23 +00:00
parent 505e2d882a
commit 604d029ddf
12 changed files with 119 additions and 0 deletions

View File

@@ -73,6 +73,7 @@ int blender_test_break(void);
extern void BKE_write_undo(struct bContext *C, const char *name);
extern void BKE_undo_step(struct bContext *C, int step);
extern void BKE_undo_name(struct bContext *C, const char *name);
extern int BKE_undo_valid(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);

View File

@@ -638,6 +638,22 @@ void BKE_undo_name(bContext *C, const char *name)
}
}
/* name optional */
int BKE_undo_valid(const char *name)
{
if(name) {
UndoElem *uel;
for(uel= undobase.last; uel; uel= uel->prev)
if(strcmp(name, uel->name)==0)
break;
return uel && uel->prev;
}
return undobase.last != undobase.first;
}
char *BKE_undo_menu_string(void)
{

View File

@@ -68,6 +68,7 @@ void PE_undo_step(struct Scene *scene, int step);
void PE_undo(struct Scene *scene);
void PE_redo(struct Scene *scene);
void PE_undo_menu(struct Scene *scene, struct Object *ob);
int PE_undo_valid(struct Scene *scene);
#endif /* ED_PARTICLE_H */

View File

@@ -51,5 +51,6 @@ void ED_keymap_paint(struct wmKeyConfig *keyconf);
int ED_undo_paint_step(struct bContext *C, int type, int step, const char *name);
void ED_undo_paint_free(void);
int ED_undo_paint_valid(int type, const char *name);
#endif

View File

@@ -56,6 +56,8 @@ int ED_undo_operator_repeat(struct bContext *C, struct wmOperator *op);
void ED_undo_operator_repeat_cb(struct bContext *C, void *arg_op, void *arg_unused);
void ED_undo_operator_repeat_cb_evt(struct bContext *C, void *arg_op, int arg_unused);
int ED_undo_valid (const struct bContext *C, const char *undoname);
/* undo_editmode.c */
void undo_editmode_push(struct bContext *C, const char *name,
void * (*getdata)(struct bContext *C),

View File

@@ -3884,6 +3884,16 @@ void PE_undo_step(Scene *scene, int step)
DAG_id_tag_update(&OBACT->id, OB_RECALC_DATA);
}
int PE_undo_valid(Scene *scene)
{
PTCacheEdit *edit= PE_get_current(scene, OBACT);
if(edit) {
return (edit->undo.last != edit->undo.first);
}
return 0;
}
static void PTCacheUndo_number(Scene *scene, PTCacheEdit *edit, int nr)
{
PTCacheUndo *undo;

View File

@@ -239,6 +239,27 @@ int ED_undo_paint_step(bContext *C, int type, int step, const char *name)
return 0;
}
int ED_undo_paint_valid(int type, const char *name)
{
UndoStack *stack;
if(type == UNDO_PAINT_IMAGE)
stack= &ImageUndoStack;
else if(type == UNDO_PAINT_MESH)
stack= &MeshUndoStack;
else
return 0;
if(stack->current==NULL);
else {
if(name && strcmp(stack->current->name, name) == 0)
return 1;
else
return stack->elems.first != stack->elems.last;
}
return 0;
}
void ED_undo_paint_free(void)
{
undo_stack_free(&ImageUndoStack);

View File

@@ -114,6 +114,9 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
return;
block= uiLayoutGetBlock(pa->layout);
if(ED_undo_valid(C, op->type->name)==0)
uiLayoutSetEnabled(pa->layout, 0);
uiBlockSetFunc(block, ED_undo_operator_repeat_cb, op, NULL);

View File

@@ -314,6 +314,20 @@ void undo_editmode_name(bContext *C, const char *undoname)
}
}
/* undoname optionally, if NULL it just checks for existing undo steps */
int undo_editmode_valid(const char *undoname)
{
if(undoname) {
UndoElem *uel;
for(uel= undobase.last; uel; uel= uel->prev) {
if(strcmp(undoname, uel->name)==0)
break;
}
return uel != NULL;
}
return undobase.last != undobase.first;
}
/* ************** for interaction with menu/pullown */

View File

@@ -199,6 +199,52 @@ void ED_undo_pop_op(bContext *C, wmOperator *op)
ed_undo_step(C, 0, op->type->name);
}
/* name optionally, function used to check for operator redo panel */
int ED_undo_valid(const bContext *C, const char *undoname)
{
Object *obedit= CTX_data_edit_object(C);
Object *obact= CTX_data_active_object(C);
ScrArea *sa= CTX_wm_area(C);
if(sa && sa->spacetype==SPACE_IMAGE) {
SpaceImage *sima= (SpaceImage *)sa->spacedata.first;
if((obact && obact->mode & OB_MODE_TEXTURE_PAINT) || sima->flag & SI_DRAWTOOL) {
return 1;
}
}
if(sa && sa->spacetype==SPACE_TEXT) {
return 1;
}
else if(obedit) {
if ELEM7(obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE) {
return undo_editmode_valid(undoname);
}
}
else {
/* if below tests fail, global undo gets executed */
if(obact && obact->mode & OB_MODE_TEXTURE_PAINT) {
if( ED_undo_paint_valid(UNDO_PAINT_IMAGE, undoname) )
return 1;
}
else if(obact && obact->mode & OB_MODE_SCULPT) {
if( ED_undo_paint_valid(UNDO_PAINT_MESH, undoname) )
return 1;
}
else if(obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
return PE_undo_valid(CTX_data_scene(C));
}
if(U.uiflag & USER_GLOBALUNDO) {
return BKE_undo_valid(undoname);
}
}
return 0;
}
static int ed_undo_exec(bContext *C, wmOperator *UNUSED(op))
{
/* "last operator" should disappear, later we can tie ths with undo stack nicer */

View File

@@ -34,6 +34,7 @@
/* editmode_undo.c */
void undo_editmode_clear(void);
void undo_editmode_name(bContext *C, const char *undoname);
int undo_editmode_valid(const char *undoname);
#endif /* ED_UTIL_INTERN_H */

View File

@@ -892,6 +892,9 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, arg_op);
layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, width, 20, style);
if(ED_undo_valid(C, op->type->name)==0)
uiLayoutSetEnabled(layout, 0);
uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
uiPopupBoundsBlock(block, 4.0f, 0, 0);