Bugfix #25570
authorTon Roosendaal <ton@blender.org>
Wed, 12 Jan 2011 18:00:23 +0000 (18:00 +0000)
committerTon Roosendaal <ton@blender.org>
Wed, 12 Jan 2011 18:00:23 +0000 (18:00 +0000)
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.

12 files changed:
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/intern/blender.c
source/blender/editors/include/ED_particle.h
source/blender/editors/include/ED_sculpt.h
source/blender/editors/include/ED_util.h
source/blender/editors/physics/particle_edit.c
source/blender/editors/sculpt_paint/paint_undo.c
source/blender/editors/space_view3d/view3d_toolbar.c
source/blender/editors/util/editmode_undo.c
source/blender/editors/util/undo.c
source/blender/editors/util/util_intern.h
source/blender/windowmanager/intern/wm_operators.c

index a5c5cadc4f62a2696eb4d02d88bfcfe744790cd7..a4b7d8469e0f687e9123c778927edad526e7bc28 100644 (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 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);
 extern void BKE_reset_undo(void);
 extern char *BKE_undo_menu_string(void);
 extern void BKE_undo_number(struct bContext *C, int nr);
index 1d616c77f04dd478e436b494b1de89b933ed1a92..56869e503dd3e79600c13176f8c7099a44929954 100644 (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)
 {
 
 char *BKE_undo_menu_string(void)
 {
index 32b2b8194d25491f669bbf7bd0dbab5cb9a09f0c..77c4b1bbed68e3983af725f75baf7b6338ab56dc 100644 (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);
 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 */
 
 
 #endif /* ED_PARTICLE_H */
 
index 506813ce626878c5f297d2e5de974865ae89b615..f46ab37823bb983d4fa05828ed4e22ead9e7b4da 100644 (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_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
 
 #endif
index 2936d63511c99322abf698ccaa49b331f33a959b..626ca4bd1e80e6ab5e63b1df68dcdd323c02ae8b 100644 (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);
 
 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),
 /* undo_editmode.c */
 void undo_editmode_push(struct bContext *C, const char *name, 
                                                void * (*getdata)(struct bContext *C),
index 4ac4bf9fa9b1f2d5e511393e9a1ce2c96e5cff36..9ce8488c4616b83ae0206a7923b2a6a46d0d03c0 100644 (file)
@@ -3884,6 +3884,16 @@ void PE_undo_step(Scene *scene, int step)
        DAG_id_tag_update(&OBACT->id, OB_RECALC_DATA);
 }
 
        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;
 static void PTCacheUndo_number(Scene *scene, PTCacheEdit *edit, int nr)
 {
        PTCacheUndo *undo;
index 758ef2a2fc10ca709f2d005266e33a32ab35614e..6425e2d04946aafed7e8d8849ff87dde77daa79d 100644 (file)
@@ -239,6 +239,27 @@ int ED_undo_paint_step(bContext *C, int type, int step, const char *name)
        return 0;
 }
 
        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);
 void ED_undo_paint_free(void)
 {
        undo_stack_free(&ImageUndoStack);
index 730cc553ff3c27cd837b862a33d795a80ccdbc2e..33ba1dbb7f90b18cd88b65a6f9115f87de94a242 100644 (file)
@@ -114,6 +114,9 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
                return;
        
        block= uiLayoutGetBlock(pa->layout);
                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);
        
 
        uiBlockSetFunc(block, ED_undo_operator_repeat_cb, op, NULL);
        
index cff30f12369eaacf84b9cc15796072c3a2f1fbbb..85f343e331183bb1c6e0ecd0cdeed95be045261e 100644 (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 */
 
 
 /* ************** for interaction with menu/pullown */
 
index 60f526b940ad296d1c08966986a9ea82b7093c40..0158719b2fba34a70ca546f3389aebb1e0132ddd 100644 (file)
@@ -199,6 +199,52 @@ void ED_undo_pop_op(bContext *C, wmOperator *op)
        ed_undo_step(C, 0, op->type->name);
 }
 
        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 */
 static int ed_undo_exec(bContext *C, wmOperator *UNUSED(op))
 {
        /* "last operator" should disappear, later we can tie ths with undo stack nicer */
index 73675ab4ef9aa23f3b8ea3c403db2f268889c786..b5750c55c8748eda11cea863e40adea322735e07 100644 (file)
@@ -34,6 +34,7 @@
 /* editmode_undo.c */
 void undo_editmode_clear(void);
 void undo_editmode_name(bContext *C, const char *undoname);
 /* 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 */
 
 
 #endif /* ED_UTIL_INTERN_H */
 
index 605da96acea700cd3ef694928b4e515c21eca7c1..f6b3cfed2eb541e389049f3bda9d6cb5909e6207 100644 (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);
 
        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);
        uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
 
        uiPopupBoundsBlock(block, 4.0f, 0, 0);