Another step in the undo evolution.
authorTon Roosendaal <ton@blender.org>
Sat, 18 Sep 2004 12:12:45 +0000 (12:12 +0000)
committerTon Roosendaal <ton@blender.org>
Sat, 18 Sep 2004 12:12:45 +0000 (12:12 +0000)
- Made unified API for undo calls, to be found in space.c
  BIF_undo_push(char *str)
  BIF_undo(void)
  BIF_redo(void)
  These calls will do all undo levels, including editmode and vpaint.

  The transition is work in progress, because mesh undo needs recode.

- New global hotkey CTR+Z for undo
  Note: 'shaded draw mode' still is SHIFT+Z, the old CTRL+Z was to recalc
  the lighting in shaded mode, which already became much more interactive,
  like during/after any transform().
  Recalc hotkey now is SHIFT+ALT+Z

  CTRL+<any modifier>+Z is redo.

- For OSX users; the Apple-key ("Command") now maps to CTRL as well. This
  disables the one-mouse-button hack for rightmouse btw, will be fixed in
  next commit. At least we can use Apple-Z :)

- Old Ukey for undo is still there, as a training period... my preference is
  to restore Ukey to "reload original data" as in past, and only use new
  CTRL+Z for undo.

- Added undo_push() for all of editobject.c and editview.c. Meaning we can
  start using/testing global undo in the 3d window. Please dont comment on
  missing parts for now, first I want someone to volunteer to tackle all of
  that.

- Since the global undo has a full 'file' in memory, it can save extremely
  fast on exit to <temp dir>/quit.blend. That's default now when global undo
  is enabled. It prints "Saved session recovery to ..." in console then.

- In file menu, a new option is added "Recover Last Session". Note that this
  reads the undo-save, which is without UI.

- With such nice new features we then can also kill the disputed
  Cancel/Confirm menu on Q-KEY.

- Added fix which initializes seam/normal theme color on saved themes.
  They showed black now.... (Note: that's in usiblender.c!)

20 files changed:
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/intern/blender.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/undofile.c
source/blender/include/BDR_editobject.h
source/blender/include/BIF_editmesh.h
source/blender/include/BIF_space.h
source/blender/src/buttons_editing.c
source/blender/src/edit.c
source/blender/src/editmesh.c
source/blender/src/editobject.c
source/blender/src/editscreen.c
source/blender/src/editview.c
source/blender/src/header_info.c
source/blender/src/header_view3d.c
source/blender/src/interface.c
source/blender/src/resources.c
source/blender/src/space.c
source/blender/src/toets.c
source/blender/src/usiblender.c

index 81805a63f73129b33fdd29a231fc14e8dd5055b2..51c8e9fd855154dcb5407f8473788030301027e1 100644 (file)
@@ -59,6 +59,13 @@ void poplast(void *data);
 void free_pushpop(void);
 void pushpop_test(void);
 
+/* global undo */
+void BKE_write_undo(char *name);
+void BKE_undo_step(int step);
+void BKE_reset_undo(void);
+void BKE_undo_menu(void);
+void BKE_undo_save_quit(void);
+
 #ifdef __cplusplus
 }
 #endif
index 793a8f30c608829bf6fa883cdcb9cda795d82567..00cd8771ff091e9e00a5ad833f84c65e835a225f 100644 (file)
@@ -82,7 +82,8 @@
 #include "BLI_editVert.h"
 
 #include "BLO_undofile.h"
-#include "BLO_readfile.h" /* for BLO_read_file */
+#include "BLO_readfile.h" 
+#include "BLO_writefile.h" 
 
 #include "BKE_bad_level_calls.h" // for freeAllRad editNurb free_editMesh free_editText free_editArmature
 #include "BKE_utildefines.h" // O_BINARY FALSE
@@ -436,3 +437,195 @@ int BKE_read_file_from_memfile(MemFile *memfile)
        return (bfd?1:0);
 }
 
+
+/* ***************** GLOBAL UNDO *************** */
+
+#define UNDO_DISK      0
+
+#define MAXUNDONAME    64
+typedef struct UndoElem {
+       struct UndoElem *next, *prev;
+       char str[FILE_MAXDIR+FILE_MAXFILE];
+       char name[MAXUNDONAME];
+       MemFile memfile;
+} UndoElem;
+
+#define MAXUNDO         32
+static ListBase undobase={NULL, NULL};
+static UndoElem *curundo= NULL;
+
+
+static int read_undosave(UndoElem *uel)
+{
+       char scestr[FILE_MAXDIR+FILE_MAXFILE];
+       int success=0, fileflags;
+       
+       strcpy(scestr, G.sce);  /* temporal store */
+       fileflags= G.fileflags;
+       G.fileflags |= G_FILE_NO_UI;
+
+       if(UNDO_DISK) 
+               success= BKE_read_file(uel->str, NULL);
+       else
+               success= BKE_read_file_from_memfile(&uel->memfile);
+       
+       /* restore */
+       strcpy(G.sce, scestr);
+       G.fileflags= fileflags;
+
+       return success;
+}
+
+/* name can be a dynamic string */
+void BKE_write_undo(char *name)
+{
+       int nr, success;
+       UndoElem *uel;
+       
+       if( (U.uiflag & USER_GLOBALUNDO)==0) return;
+
+       /* remove all undos after (also when curundo==NULL) */
+       while(undobase.last != curundo) {
+               uel= undobase.last;
+               BLI_remlink(&undobase, uel);
+               BLO_free_memfile(&uel->memfile);
+               MEM_freeN(uel);
+       }
+       
+       /* make new */
+       curundo= uel= MEM_callocN(sizeof(UndoElem), "undo file");
+       strncpy(uel->name, name, MAXUNDONAME-1);
+       BLI_addtail(&undobase, uel);
+       
+       /* and limit amount to the maximum */
+       nr= 0;
+       uel= undobase.last;
+       while(uel) {
+               nr++;
+               if(nr==MAXUNDO) break;
+               uel= uel->prev;
+       }
+       if(uel) {
+               while(undobase.first!=uel) {
+                       UndoElem *first= undobase.first;
+                       BLI_remlink(&undobase, first);
+                       /* the merge is because of compression */
+                       BLO_merge_memfile(&first->memfile, &first->next->memfile);
+                       MEM_freeN(first);
+               }
+       }
+
+
+       /* disk save version */
+       if(UNDO_DISK) {
+               static int counter= 0;
+               char *err, tstr[FILE_MAXDIR+FILE_MAXFILE];
+               char numstr[32];
+               
+               /* calculate current filename */
+               counter++;
+               counter= counter % MAXUNDO;     
+       
+               sprintf(numstr, "%d.blend", counter);
+               BLI_make_file_string("/", tstr, U.tempdir, numstr);
+       
+               success= BLO_write_file(tstr, G.fileflags, &err);
+               
+               strcpy(curundo->str, tstr);
+       }
+       else {
+               MemFile *prevfile=NULL;
+               char *err;
+               
+               if(curundo->prev) prevfile= &(curundo->prev->memfile);
+               
+               success= BLO_write_file_mem(prevfile, &curundo->memfile, G.fileflags, &err);
+               
+       }
+}
+
+/* 1= an undo, -1 is a redo. we have to make sure 'curundo' remains at current situation */
+void BKE_undo_step(int step)
+{
+       
+       if(step==1) {
+               /* curundo should never be NULL, after restart or load file it should call undo_save */
+               if(curundo==NULL || curundo->prev==NULL) error("No undo available");
+               else {
+                       printf("undo %s\n", curundo->name);
+                       curundo= curundo->prev;
+                       read_undosave(curundo);
+               }
+       }
+       else {
+               
+               /* curundo has to remain current situation! */
+               
+               if(curundo==NULL || curundo->next==NULL) error("No redo available");
+               else {
+                       read_undosave(curundo->next);
+                       curundo= curundo->next;
+                       printf("redo %s\n", curundo->name);
+               }
+       }
+}
+
+void BKE_reset_undo(void)
+{
+       UndoElem *uel;
+       
+       uel= undobase.first;
+       while(uel) {
+               BLO_free_memfile(&uel->memfile);
+               uel= uel->next;
+       }
+       
+       BLI_freelistN(&undobase);
+       curundo= NULL;
+}
+
+
+void BKE_undo_menu(void)
+{
+       
+}
+
+       /* saves quit.blend */
+void BKE_undo_save_quit(void)
+{
+       UndoElem *uel;
+       MemFileChunk *chunk;
+       int file;
+       char str[FILE_MAXDIR+FILE_MAXFILE];
+       
+       if( (U.uiflag & USER_GLOBALUNDO)==0) return;
+       
+       uel= curundo;
+       if(uel==NULL) {
+               printf("No undo buffer to save recovery file\n");
+               return;
+       }
+       
+       /* no undo state to save */
+       if(undobase.first==undobase.last) return;
+               
+       BLI_make_file_string("/", str, U.tempdir, "quit.blend");
+
+       file = open(str,O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666);
+       if(file == -1) {
+               printf("Unable to save %s\n", str);
+               return;
+       }
+
+       chunk= uel->memfile.chunks.first;
+       while(chunk) {
+               if( write(file, chunk->buf, chunk->size) != chunk->size) break;
+               chunk= chunk->next;
+       }
+       
+       close(file);
+       
+       if(chunk) printf("Unable to save %s\n", str);
+       else printf("Saved session recovery to %s\n", str);
+}
+
index a9a5b16b46237f464ea56d13a6fa6b874e88ee9e..f75af94ea4f7bc433b9d9670cee6beb5030662e6 100644 (file)
@@ -2720,7 +2720,7 @@ void lib_link_screen_restore(Main *newmain, char mode, Scene *curscene)
 
                                }
                                else if(sl->spacetype==SPACE_IMASEL) {
-                                       check_imasel_copy((SpaceImaSel *)sl);
+                                       ;
                                }
                                else if(sl->spacetype==SPACE_ACTION) {
                                        SpaceAction *saction= (SpaceAction *)sl;
index 25ed891f0a4cdd02c0b9963b6b4100c6e76f33c2..af278c89133015d823e315690be0c5871241043f 100644 (file)
@@ -148,151 +148,3 @@ void add_memfilechunk(MemFile *compare, MemFile *current, char *buf, unsigned in
        }
 }
 
-/* ***************** GLOBAL UNDO *************** */
-
-#define UNDO_DISK      0
-
-#define MAXUNDONAME    64
-typedef struct UndoElem {
-       struct UndoElem *next, *prev;
-       char str[FILE_MAXDIR+FILE_MAXFILE];
-       char name[MAXUNDONAME];
-       MemFile memfile;
-} UndoElem;
-
-#define MAXUNDO         32
-static ListBase undobase={NULL, NULL};
-static UndoElem *curundo= NULL;
-
-
-static int read_undosave(UndoElem *uel)
-{
-       char scestr[FILE_MAXDIR+FILE_MAXFILE];
-       int success=0, fileflags;
-       
-       strcpy(scestr, G.sce);  /* temporal store */
-       fileflags= G.fileflags;
-       G.fileflags |= G_FILE_NO_UI;
-
-       if(UNDO_DISK) 
-               success= BKE_read_file(uel->str, NULL);
-       else
-               success= BKE_read_file_from_memfile(&uel->memfile);
-       
-       /* restore */
-       strcpy(G.sce, scestr);
-       G.fileflags= fileflags;
-
-       return success;
-}
-
-/* name can be a dynamic string */
-void BIF_write_undo(char *name)
-{
-       int nr, success;
-       UndoElem *uel;
-       
-       if( (U.uiflag & USER_GLOBALUNDO)==0) return;
-
-       /* remove all undos after (also when curundo==NULL) */
-       while(undobase.last != curundo) {
-               uel= undobase.last;
-               BLI_remlink(&undobase, uel);
-               BLO_free_memfile(&uel->memfile);
-               MEM_freeN(uel);
-       }
-       
-       /* make new */
-       curundo= uel= MEM_callocN(sizeof(UndoElem), "undo file");
-       strncpy(uel->name, name, MAXUNDONAME-1);
-       BLI_addtail(&undobase, uel);
-       
-       /* and limit amount to the maximum */
-       nr= 0;
-       uel= undobase.last;
-       while(uel) {
-               nr++;
-               if(nr==MAXUNDO) break;
-               uel= uel->prev;
-       }
-       if(uel) {
-               while(undobase.first!=uel) {
-                       UndoElem *first= undobase.first;
-                       BLI_remlink(&undobase, first);
-                       /* the merge is because of compression */
-                       BLO_merge_memfile(&first->memfile, &first->next->memfile);
-                       MEM_freeN(first);
-               }
-       }
-
-
-       /* disk save version */
-       if(UNDO_DISK) {
-               static int counter= 0;
-               char *err, tstr[FILE_MAXDIR+FILE_MAXFILE];
-               char numstr[32];
-               
-               /* calculate current filename */
-               counter++;
-               counter= counter % MAXUNDO;     
-       
-               sprintf(numstr, "%d.blend", counter);
-               BLI_make_file_string("/", tstr, U.tempdir, numstr);
-       
-               success= BLO_write_file(tstr, G.fileflags, &err);
-               
-               strcpy(curundo->str, tstr);
-       }
-       else {
-               MemFile *prevfile=NULL;
-               char *err;
-               
-               if(curundo->prev) prevfile= &(curundo->prev->memfile);
-               
-               success= BLO_write_file_mem(prevfile, &curundo->memfile, G.fileflags, &err);
-               
-       }
-}
-
-/* 1= an undo, -1 is a redo. we have to make sure 'curundo' remains at current situation */
-void BIF_undo_step(int step)
-{
-       
-       if(step==1) {
-               /* curundo should never be NULL, after restart or load file it should call undo_save */
-               if(curundo==NULL || curundo->prev==NULL) error("No undo available");
-               else {
-                       printf("undo %s\n", curundo->name);
-                       curundo= curundo->prev;
-                       read_undosave(curundo);
-               }
-       }
-       else {
-               
-               /* curundo has to remain current situation! */
-               
-               if(curundo==NULL || curundo->next==NULL) error("No redo available");
-               else {
-                       read_undosave(curundo->next);
-                       curundo= curundo->next;
-                       printf("redo %s\n", curundo->name);
-               }
-       }
-}
-
-void BIF_reset_undo(void)
-{
-       UndoElem *uel;
-       
-       uel= undobase.first;
-       while(uel) {
-               BLO_free_memfile(&uel->memfile);
-               uel= uel->next;
-       }
-       
-       BLI_freelistN(&undobase);
-       curundo= NULL;
-}
-
-
-
index a00878448fa869742de2a7695a852615ab34e82d..6feee2d8a88dea5979a7ec7ccf038be7cd671d1b 100644 (file)
@@ -57,7 +57,7 @@ void make_parent(void);
 void make_displists_by_parent(struct Object *ob);
 void exit_editmode(int freedata);
 void check_editmode(int type);
-void docentre(void);
+void docentre(int centremode);
 void docentre_new(void);
 void docentre_cursor(void);
 void movetolayer(void);
index 7b71111faac6b7d544282eb0fcce8d2733b38bff..bb4d22a66575d61a6e6a7ae814559229d729238c 100644 (file)
@@ -144,7 +144,6 @@ void beauty_fill(void);
 void join_triangles(void);
 void edge_flip(void);
 void join_mesh(void);
-void clever_numbuts_mesh(void);
 void sort_faces(void);
 void vertices_to_sphere(void);
 void fill_mesh(void);
index 14f83531ae608c3db6f7e0ac939ad062be589ad0..83a0c4a898db302edc81329dd6558a60b3004f57 100644 (file)
@@ -120,6 +120,10 @@ extern       void start_game(void);
 extern          void select_group_menu(void);
 extern          void select_group(short nr);
 
+extern                 void BIF_undo_push(char *str);
+extern                 void BIF_undo(void);
+extern                 void BIF_redo(void);
+extern                 void BIF_undo_menu(void);
 
 #ifdef _WIN32  // FULLSCREEN
 extern          void mainwindow_toggle_fullscreen(int fullscreen);
index 8d40bb2307f2ee2ea4e2b44f61cb1e9b9ec57c68..de3920b2b6349060f4b140409d0716dff6a6be0b 100644 (file)
@@ -549,7 +549,7 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
                }
                break;
        case B_DOCENTRE:
-               docentre();
+               docentre(0);
                break;
        case B_DOCENTRENEW:
                docentre_new();
index 0f29ee8bc182c0bce4555eb4cdbf73f9e4539b33..c7ab61fb5aba41c6854fa8e4c36d057f4a2206b6 100644 (file)
@@ -1233,14 +1233,17 @@ void duplicate_context_selected(void) {
        }
 }
 
-void toggle_shading(void) {
-       if(G.qual & LR_CTRLKEY) {
-               reshadeall_displist();
-               G.vd->drawtype= OB_SHADED;
-       }
-       else if(G.qual & LR_SHIFTKEY) {
-               if(G.vd->drawtype== OB_SHADED) G.vd->drawtype= OB_WIRE;
-               else G.vd->drawtype= OB_SHADED;
+void toggle_shading(void) 
+{
+       if(G.qual & LR_SHIFTKEY) {
+               if(G.qual & LR_ALTKEY) {
+                       reshadeall_displist();
+                       G.vd->drawtype= OB_SHADED;
+               }
+               else {
+                       if(G.vd->drawtype== OB_SHADED) G.vd->drawtype= OB_WIRE;
+                       else G.vd->drawtype= OB_SHADED;
+               }
        }
        else if(G.qual & LR_ALTKEY) {
                if(G.vd->drawtype== OB_TEXTURE) G.vd->drawtype= OB_SOLID;
index cafa89532185e34394ede999826a747bbd5dd81c..7e92fa24439ff8d46b05dcc458b0388c98b3eebb 100644 (file)
@@ -7748,34 +7748,15 @@ void join_mesh(void)
        test_object_materials((ID *)me);
        
        enter_editmode();
-       exit_editmode(1);
+       exit_editmode(1);       // freedata, but no undo
        
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWBUTSSHADING, 0);
-       makeDispList(G.obedit);
-
-}
-
-void clever_numbuts_mesh(void)
-{
-       EditMesh *em = G.editMesh;
-       EditVert *eve;
-       
-       eve= em->verts.first;
-       while(eve) {
-               if(eve->f & 1) break;
-               eve= eve->next;
-       }
-       if(eve==0) return;
+       makeDispList(ob);
 
-       add_numbut(0, NUM|FLO, "LocX:", -G.vd->far, G.vd->far, eve->co, 0);
-       add_numbut(1, NUM|FLO, "LocY:", -G.vd->far, G.vd->far, eve->co+1, 0);
-       add_numbut(2, NUM|FLO, "LocZ:", -G.vd->far, G.vd->far, eve->co+2, 0);
-       
-       do_clever_numbuts("Active Vertex", 3, REDRAW);
+       BIF_undo_push("Join Mesh");
 }
 
-
 static void permutate(void *list, int num, int size, int *index)
 {
        void *buf;
index a8399aa0bc73a689f1c81b5c2d3df6ca641b505c..b12dfc90e82ba569b9dd3e4973b759b51999d090 100644 (file)
@@ -85,7 +85,6 @@
 #include "BLI_editVert.h"
 #include "BLI_ghash.h"
 
-#include "BKE_utildefines.h"
 #include "BKE_anim.h"
 #include "BKE_blender.h"
 #include "BKE_booleanops.h"
 #include "BKE_scene.h"
 #include "BKE_subsurf.h"
 #include "BKE_texture.h"
+#include "BKE_utildefines.h"
 
 #include "BIF_gl.h"
 #include "BIF_graphics.h"
@@ -194,7 +194,7 @@ void add_object_draw(int type)      /* for toolbox */
        setcursor_space(SPACE_VIEW3D, CURSOR_STD);
 
        if ELEM3(curarea->spacetype, SPACE_VIEW3D, SPACE_BUTS, SPACE_INFO) {
-               if (G.obedit) exit_editmode(1);
+               if (G.obedit) exit_editmode(2); // freedata, and undo
                ob= add_object(type);
                base_init_from_view3d(BASACT, G.vd);
 
@@ -255,6 +255,8 @@ void delete_obj(int ok)
        allqueue(REDRAWOOPS, 0);
        allqueue(REDRAWACTION, 0);
        allqueue(REDRAWNLA, 0);
+       
+       BIF_undo_push("Delete object(s)");
 }
 
 int return_editmesh_indexar(int **indexar, float *cent)
@@ -631,6 +633,7 @@ void add_hook(void)
 
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWBUTSOBJECT, 0);
+       BIF_undo_push("Add hook");
 }
 
 void make_track(void)
@@ -725,6 +728,7 @@ void make_track(void)
                allqueue(REDRAWOOPS, 0);
                sort_baselist(G.scene);
        }
+       BIF_undo_push("make Track");
 }
 
 void apply_obmat(Object *ob)
@@ -802,6 +806,8 @@ void clear_parent(void)
        test_scene_constraints();
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWOOPS, 0);
+       
+       BIF_undo_push("Clear Parent");  
 }
 
 void clear_track(void)
@@ -830,6 +836,8 @@ void clear_track(void)
        test_scene_constraints();
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWOOPS, 0);
+       
+       BIF_undo_push("Clear Track");   
 }
 
 void clear_object(char mode)
@@ -837,14 +845,18 @@ void clear_object(char mode)
        Base *base;
        Object *ob;
        float *v1, *v3, mat[3][3];
+       char *str=NULL;
        
        if(G.obedit) return;
        if(G.scene->id.lib) return;
        
-       if(mode=='r' && okee("Clear rotation")==0) return;
-       else if(mode=='g' && okee("Clear location")==0) return;
-       else if(mode=='s' && okee("Clear size")==0) return;
-       else if(mode=='o' && okee("Clear origin")==0) return;
+       if(mode=='r') str= "Clear rotation";
+       else if(mode=='g') str= "Clear location";
+       else if(mode=='s') str= "Clear size";
+       else if(mode=='o') str= "Clear origin";
+       else return;
+       
+       if(okee(str)==0) return;
        
        if (G.obpose){
 
@@ -859,6 +871,7 @@ void clear_object(char mode)
                }
 
                allqueue(REDRAWVIEW3D, 0);
+               BIF_undo_push(str);
                return;
        }
 
@@ -906,6 +919,7 @@ void clear_object(char mode)
        }
        
        allqueue(REDRAWVIEW3D, 0);
+       BIF_undo_push(str);
 }
 
 void reset_slowparents(void)
@@ -939,7 +953,7 @@ void set_slowparent(void)
                }
                base= base->next;
        }
-       
+       BIF_undo_push("Slow parent");
 }
 
 void make_vertex_parent(void)
@@ -953,7 +967,7 @@ void make_vertex_parent(void)
        Object *par, *ob;
        int a, v1=0, v2=0, v3=0, nr=1;
        
-       /* we need 1 ot 3 selected vertices */
+       /* we need 1 to 3 selected vertices */
        
        if(G.obedit->type==OB_MESH) {
                eve= em->verts.first;
@@ -1054,6 +1068,7 @@ void make_vertex_parent(void)
        }
        allqueue(REDRAWVIEW3D, 0);
        
+       // BIF_undo_push(str); not, conflicts with editmode undo...
 }
 
 int test_parent_loop(Object *par, Object *ob)
@@ -1078,8 +1093,7 @@ void make_parent(void)
 {
        Base *base;
        Object *par;
-       Ika *ika;
-       short qual, ok, mode=0, limbnr=0, effchild=0;
+       short qual, mode=0, limbnr=0, effchild=0;
        char *bonestr=NULL;
        Bone    *bone=NULL;
        int     bonenr;
@@ -1095,56 +1109,7 @@ void make_parent(void)
        qual= G.qual;
        par= BASACT->object;
 
-       if(par->type==OB_IKA) {
-               
-               if(qual & LR_SHIFTKEY)
-                       mode= pupmenu("Make Parent Without Inverse%t|Use Vertex %x1|Use Limb %x2|Use Skeleton %x3");
-               else 
-                       mode= pupmenu("Make Parent %t|Use Vertex %x1|Use Limb %x2|Use Skeleton %x3");
-               
-               if(mode==1) {
-                       draw_ika_nrs(par, 0);
-                       if(button(&limbnr, 0, 99, "Vertex: ")==0) {
-                               allqueue(REDRAWVIEW3D, 0);
-                               return;
-                       }
-               }
-               else if(mode==2) {
-                       draw_ika_nrs(par, 1);
-                       if(button(&limbnr, 0, 99, "Limb: ")==0) {
-                               allqueue(REDRAWVIEW3D, 0);
-                               return;
-                       }
-               }
-               else if(mode==3) {
-                       ika= par->data;
-                       if(ika->def==0) {
-                               error("No skeleton available: use CTRL K");
-                               return;
-                       }
-               }
-               else return;
-
-               if(mode==1) mode= PARVERT1;
-               else if(mode==2) mode= PARLIMB;
-               else if(mode==3) mode= PARSKEL;
-
-               /* test effchild */
-               base= FIRSTBASE;
-               while(base) {
-                       if TESTBASELIB(base) {
-                               if(base->object->type==OB_IKA && base->object!=par && mode==PARVERT1 ) {
-                                       if(effchild==0) {
-                                               if(okee("Effector as child")) effchild= 1;
-                                               else effchild= 2;
-                                       }
-                               }
-                       }
-                       if(effchild) break;
-                       base= base->next;
-               }
-       }
-       else if(par->type == OB_CURVE){
+       if(par->type == OB_CURVE){
                bConstraint *con;
                bFollowPathConstraint *data;
 
@@ -1188,6 +1153,7 @@ void make_parent(void)
                        test_scene_constraints();
                        allqueue(REDRAWVIEW3D, 0);
                        sort_baselist(G.scene);
+                       BIF_undo_push("make Parent");
                        return;
                }
        }
@@ -1294,91 +1260,67 @@ void make_parent(void)
                if TESTBASELIB(base) {
                        if(base!=BASACT) {
                                
-                               ok= 1;
-                               if(base->object->type==OB_IKA) {
-                               
-                                       if(effchild==1) {
-                                       
-                                               if( test_parent_loop(par, base->object)==0 ) {
-                                               
-                                                       Ika *ika= base->object->data;
-                                                       
-                                                       ika->parent= par;
-                                                       ika->par1= limbnr;
-                                                       ika->partype= mode;
-                                                       itterate_ika(base->object);
-                                                       ok= 0;
-                                               }
-                                               else {
-                                                       ok= 0;
-                                                       error("Loop in parents");
-                                               }
-                                       }
+                               if( test_parent_loop(par, base->object) ) {
+                                       error("Loop in parents");
                                }
-                               
-                               if(ok) {
-                                       if( test_parent_loop(par, base->object) ) {
-                                               error("Loop in parents");
+                               else {
+                                       
+                                       /* the ifs below are horrible code (ton) */
+                                       
+                                       if(par->type==OB_IKA){
+                                               base->object->partype= mode;
+                                               base->object->par1= limbnr;
+                                       }
+                                       else if (par->type==OB_ARMATURE){
+                                               base->object->partype= mode;
+                                               if (bone)
+                                                       strcpy (base->object->parsubstr, bone->name);
+                                               else
+                                                       base->object->parsubstr[0]=0;
                                        }
                                        else {
-                                               
-                                               /* the ifs below are horrible code (ton) */
-                                               
-                                               if(par->type==OB_IKA){
-                                                       base->object->partype= mode;
-                                                       base->object->par1= limbnr;
+                                               if(qual & LR_ALTKEY) {
+                                                       base->object->partype= PARVERT1;
                                                }
-                                               else if (par->type==OB_ARMATURE){
+                                               else if(par->type==OB_CURVE) {
                                                        base->object->partype= mode;
-                                                       if (bone)
-                                                               strcpy (base->object->parsubstr, bone->name);
-                                                       else
-                                                               base->object->parsubstr[0]=0;
                                                }
                                                else {
-                                                       if(qual & LR_ALTKEY) {
-                                                               base->object->partype= PARVERT1;
-                                                       }
-                                                       else if(par->type==OB_CURVE) {
-                                                               base->object->partype= mode;
-                                                       }
-                                                       else {
-                                                               base->object->partype= PAROBJECT;
-                                                       }
-                                               }
-                                               base->object->parent= par;
-                                               
-                                               /* calculate inverse parent matrix? */
-                                               if( (qual & LR_SHIFTKEY) ) {
-                                                       /* not... */
-                                                       Mat4One(base->object->parentinv);
-                                                       memset(base->object->loc, 0, 3*sizeof(float));
+                                                       base->object->partype= PAROBJECT;
                                                }
-                                               else {
-                                                       if(mode==PARSKEL && par->type == OB_ARMATURE) {
-                                                               /* Prompt the user as to whether he wants to
-                                                                * add some vertex groups based on the bones
-                                                                * in the parent armature.
-                                                                */
-                                                               create_vgroups_from_armature(base->object, 
-                                                                                                                        par);
-
-                                                               base->object->partype= PAROBJECT;
-                                                               what_does_parent(base->object);
-                                                               Mat4One (base->object->parentinv);
-                                                               base->object->partype= mode;
-                                                       }
-                                                       else
-                                                               what_does_parent(base->object);
-                                                       Mat4Invert(base->object->parentinv, workob.obmat);
-                                               }
-                                               
-                                               if(par->type==OB_LATTICE) makeDispList(base->object);
-                                               if(par->type==OB_CURVE && mode==PARSKEL) makeDispList(base->object);
-                                               if(par->type==OB_ARMATURE && mode == PARSKEL){
-                                                       verify_defgroups(base->object);
-                                                       makeDispList(base->object);
+                                       }
+                                       base->object->parent= par;
+                                       
+                                       /* calculate inverse parent matrix? */
+                                       if( (qual & LR_SHIFTKEY) ) {
+                                               /* not... */
+                                               Mat4One(base->object->parentinv);
+                                               memset(base->object->loc, 0, 3*sizeof(float));
+                                       }
+                                       else {
+                                               if(mode==PARSKEL && par->type == OB_ARMATURE) {
+                                                       /* Prompt the user as to whether he wants to
+                                                               * add some vertex groups based on the bones
+                                                               * in the parent armature.
+                                                               */
+                                                       create_vgroups_from_armature(base->object, 
+                                                                                                                       par);
+
+                                                       base->object->partype= PAROBJECT;
+                                                       what_does_parent(base->object);
+                                                       Mat4One (base->object->parentinv);
+                                                       base->object->partype= mode;
                                                }
+                                               else
+                                                       what_does_parent(base->object);
+                                               Mat4Invert(base->object->parentinv, workob.obmat);
+                                       }
+                                       
+                                       if(par->type==OB_LATTICE) makeDispList(base->object);
+                                       if(par->type==OB_CURVE && mode==PARSKEL) makeDispList(base->object);
+                                       if(par->type==OB_ARMATURE && mode == PARSKEL){
+                                               verify_defgroups(base->object);
+                                               makeDispList(base->object);
                                        }
                                }
                        }
@@ -1390,6 +1332,8 @@ void make_parent(void)
        
        test_scene_constraints();
        sort_baselist(G.scene);
+
+       BIF_undo_push("make Parent");
 }
 
 
@@ -1499,13 +1443,13 @@ void make_displists_by_parent(Object *ob) {
                        makeDispList(base->object);
 }
 
-void exit_editmode(int freedata)       /* freedata==0 at render */
+void exit_editmode(int freedata)       /* freedata==0 at render, 1= freedata, 2= do undo buffer too */
 {
        Base *base;
        Object *ob;
        Curve *cu;
 
-       if(G.obedit==0) return;
+       if(G.obedit==NULL) return;
 
        if(G.obedit->type==OB_MESH) {
 
@@ -1588,6 +1532,8 @@ void exit_editmode(int freedata)  /* freedata==0 at render */
        }
        scrarea_queue_headredraw(curarea);
 
+       if(G.obedit==NULL && freedata==2) 
+               BIF_undo_push("Editmode");
 }
 
 void check_editmode(int type)
@@ -1595,12 +1541,12 @@ void check_editmode(int type)
        
        if (G.obedit==0 || G.obedit->type==type) return;
 
-       exit_editmode(1);
+       exit_editmode(2); // freedata, and undo
 }
 
-static int centremode= 0; /* 0 == do centre, 1 == centre new, 2 == centre cursor */
+/* 0 == do centre, 1 == centre new, 2 == centre cursor */
 
-void docentre(void)
+void docentre(int centremode)
 {
        EditMesh *em = G.editMesh;
        Base *base;
@@ -1830,6 +1776,7 @@ void docentre(void)
        }
 
        allqueue(REDRAWVIEW3D, 0);
+       BIF_undo_push("Do Centre");     
 }
 
 void docentre_new(void)
@@ -1840,9 +1787,7 @@ void docentre_new(void)
                error("Unable to center new in Edit Mode");
        }
        else {
-               centremode= 1;
-               docentre();
-               centremode= 0;
+               docentre(1);
        }
 }
 
@@ -1854,9 +1799,7 @@ void docentre_cursor(void)
                error("Unable to center cursor in Edit Mode");
        }
        else {
-               centremode= 2;
-               docentre();
-               centremode= 0;
+               docentre(2);
        }
 }
 
@@ -1893,6 +1836,8 @@ void movetolayer(void)
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWOOPS, 0);
        allqueue(REDRAWINFO, 0);
+       
+       BIF_undo_push("Move to layer");
 }
 
 
@@ -1943,7 +1888,8 @@ void special_editmenu(void)
                                }
                        }
                        allqueue(REDRAWVIEW3D, 0);
-                       allqueue(REDRAWBUTSLOGIC, 0);
+                       allqueue(REDRAWBUTSEDIT, 0);
+                       BIF_undo_push("Change texture face");
                }
                else if(G.f & G_VERTEXPAINT) {
                        Mesh *me= get_mesh(OBACT);
@@ -1959,6 +1905,7 @@ void special_editmenu(void)
                                do_shared_vertexcol(me);
                                
                                if(me->tface) mcol_to_tface(me, 1);
+                               BIF_undo_push("Shared VertexCol");
                        }
                }
                else {
@@ -1996,6 +1943,7 @@ void special_editmenu(void)
                                                        } else if(ret==-1) {
                                                                error("Selected meshes must have faces to perform boolean operations");
                                                        }
+                                                       else BIF_undo_push("Boolean");
 
                                                        waitcursor(0);
                                                } else {
@@ -2215,7 +2163,7 @@ void convertmenu(void)
                                        /* texspace and normals */
                                        BASACT= base;
                                        enter_editmode();
-                                       exit_editmode(1);
+                                       exit_editmode(1); // freedata, but no undo
                                        BASACT= basact;
                                }
                        }
@@ -2262,6 +2210,7 @@ void convertmenu(void)
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWOOPS, 0);
        allqueue(REDRAWBUTSEDIT, 0);
+       BIF_undo_push("Convert Object");
 }
 
        /* Change subdivision properties of mesh object ob, if
@@ -2281,6 +2230,8 @@ void flip_subdivison(Object *ob, int level)
        allqueue(REDRAWOOPS, 0);
        allqueue(REDRAWBUTSEDIT, 0);
        makeDispList(ob);
+       
+       BIF_undo_push("Switch subsurf on/off");
 }
  
 void copymenu_properties(Object *ob)
@@ -2345,6 +2296,8 @@ void copymenu_properties(Object *ob)
        }
        MEM_freeN(str);
        allqueue(REDRAWVIEW3D, 0);
+       
+       BIF_undo_push("Copy properties");
 }
 
 void copymenu_logicbricks(Object *ob)
@@ -2378,6 +2331,7 @@ void copymenu_logicbricks(Object *ob)
                }
                base= base->next;
        }
+       BIF_undo_push("Copy logic");
 }
 
 void copy_attr_menu()
@@ -2604,6 +2558,7 @@ void copy_attr(short event)
                allqueue(REDRAWBUTSOBJECT, 0);
        }
        
+       BIF_undo_push("Copy attributes");
 }
 
 void link_to_scene(unsigned short nr)
@@ -2818,6 +2773,8 @@ void make_links(short event)
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWOOPS, 0);
        allqueue(REDRAWBUTSHEAD, 0);
+       
+       BIF_undo_push("Create links");
 }
 
 void make_duplilist_real()
@@ -2866,6 +2823,8 @@ void make_duplilist_real()
        
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWOOPS, 0);
+       
+       BIF_undo_push("Make duplicates real");
 }
 
 void apply_object()
@@ -2928,7 +2887,7 @@ void apply_object()
                                /* texspace and normals */
                                BASACT= base;
                                enter_editmode();
-                               exit_editmode(1);
+                               exit_editmode(1); // freedata, but no undo
                                BASACT= basact;                         
                                
                        }
@@ -2995,7 +2954,7 @@ void apply_object()
                                /* texspace and normals */
                                BASACT= base;
                                enter_editmode();
-                               exit_editmode(1);
+                               exit_editmode(1); // freedata, but no undo
                                BASACT= basact;
                        }
                }
@@ -3003,6 +2962,7 @@ void apply_object()
        }
        
        allqueue(REDRAWVIEW3D, 0);
+       BIF_undo_push("Apply object");
 }
 
 
@@ -6579,7 +6539,7 @@ void transform(int mode)
 
        /* undo after transform, since it's storing current situations */
        if(canceled==0 && G.obedit==NULL) 
-               BIF_write_undo(transform_mode_to_string(mode));
+               BIF_undo_push(transform_mode_to_string(mode));
 }
 
 void std_rmouse_transform(void (*xf_func)(int))
@@ -6612,7 +6572,9 @@ void std_rmouse_transform(void (*xf_func)(int))
                                return;
                        }
                }
-       }       
+       }
+       /* if gets here it's a select, later on remove obedit check */
+       if(G.obedit==NULL) BIF_undo_push("Select");
 }
 
 void rightmouse_transform(void)
@@ -7027,6 +6989,7 @@ void single_user(void)
 
                countall();
                allqueue(REDRAWALL, 0);
+               BIF_undo_push("Single user");
        }
 }
 
@@ -7190,7 +7153,7 @@ void make_local(void)
 
 
        allqueue(REDRAWALL, 0);
-
+       BIF_undo_push("Make local");
 }
 
 
@@ -7552,6 +7515,7 @@ void selectlinks(int nr)
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWDATASELECT, 0);
        allqueue(REDRAWOOPS, 0);
+       BIF_undo_push("Select links");
 }
 
 void image_aspect(void)
@@ -7612,6 +7576,7 @@ void image_aspect(void)
        }
        
        allqueue(REDRAWVIEW3D, 0);
+       BIF_undo_push("Image aspect");
 }
 
 void set_ob_ipoflags(void)
@@ -7693,6 +7658,8 @@ void select_select_keys(void)
        allspace(REMAKEIPO, 0);
        allqueue(REDRAWIPO, 0);
 
+       BIF_undo_push("Selet keys");
+
 }
 
 
@@ -7836,7 +7803,8 @@ void make_displists_by_obdata(void *obdata) {
 /* ******************************************************************** */
 /* Mirror function in Edit Mode */
 
-void mirror_edit(short mode) {
+void mirror_edit(short mode) 
+{
        short axis, a;
        float mat[3][3], imat[3][3], min[3], max[3];
        TransVert *tv;
@@ -8043,6 +8011,9 @@ void mirrormenu(void){
 
                if (mode==-1) return; /* return */
                mirror_edit(mode); /* separating functionality from interface | call*/
+
+               BIF_undo_push("Mirror");
+
        }
 }
 
index 89709be2ff415999ad0e404a26cbaf292e447f7d..a71a20f68f01ca6887fac683d2927bb84e1bcd80 100644 (file)
@@ -1076,9 +1076,7 @@ void screenmain(void)
                        if((G.obedit && G.obedit->type==OB_FONT && g_activearea->spacetype==SPACE_VIEW3D)||g_activearea->spacetype==SPACE_TEXT||g_activearea->spacetype==SPACE_SCRIPT);
                        else {
                                if(val) {
-                                       int mode = 0;
-                                       mode= pupmenu("Quit Blender?%t|Cancel%x1|Confirm%x2");
-                                       if (mode == 2)
+                                       if(okee("Quit Blender?"))
                                                exit_usiblender();
                                }
                                towin= 0;
index cf4399a29d8159087472b627bec2f1e193a6a99a..747aa18c67190c0d9d14b03f1d47c4e6fd49a483 100644 (file)
@@ -392,7 +392,7 @@ void deselectall(void)      /* is toggle */
        allqueue(REDRAWNLA, 0);
        
        countall();
-
+       BIF_undo_push("(De)select all");
 }
 
 /* selects all objects of a particular type, on currently visible layers */
@@ -414,7 +414,7 @@ void selectall_type(short obtype)
        allqueue(REDRAWNLA, 0);
        
        countall();
-
+       BIF_undo_push("Select all per type");
 }
 /* selects all objects on a particular layer */
 void selectall_layer(int layernum) 
@@ -435,8 +435,9 @@ void selectall_layer(int layernum)
        allqueue(REDRAWNLA, 0);
        
        countall();
-
+       BIF_undo_push("Select all per layer");
 }
+
 static void deselectall_except(Base *b)   /* deselect all except b */
 {
        Base *base;
@@ -658,13 +659,14 @@ void mouse_select(void)
                        allqueue(REDRAWACTION, 0);
                        allqueue(REDRAWNLA, 0);
                        allqueue(REDRAWHEADERS, 0);     /* To force display update for the posebutton */
+                       
                }
                
        }
 
        countall();
 
-       rightmouse_transform();
+       rightmouse_transform(); // does undo push!
 }
 
 /* ------------------------------------------------------------------------- */
@@ -915,6 +917,9 @@ void borderselect(void)
                
                allqueue(REDRAWINFO, 0);
        }
+       /* remove obedit check later */
+       if(G.obedit==NULL) BIF_undo_push("Border select");
+       
 } /* end of borderselect() */
 
 /* ------------------------------------------------------------------------- */
@@ -1322,6 +1327,7 @@ void fly(void)
                                }
                                else if(toets==SPACEKEY) {
                                        loop= 0;
+                                       BIF_undo_push("Fly camera");
                                        break;
                                }
                                else if(toets==LEFTMOUSE) {
index 6d22e5a0dae8b1ec7f21d5a8b64cbc324ca6cbc2..b337882d354507696adea810ef3dd97cd0bc7958 100644 (file)
@@ -886,6 +886,26 @@ static void do_info_filemenu(void *arg, int event)
        case 14:
                G.fileflags ^= G_FILE_NO_UI;
                break;
+       case 15:        /* recover previous session */
+               {
+                       extern short winqueue_break; /* editscreen.c */
+                       int save_over;
+                       char str[FILE_MAXDIR+FILE_MAXFILE];
+                       char scestr[FILE_MAXDIR+FILE_MAXFILE];
+                       
+                       strcpy(scestr, G.sce);  /* temporal store */
+                       save_over = G.save_over;
+                       BLI_make_file_string("/", str, U.tempdir, "quit.blend");
+                       BKE_read_file(str, NULL);
+                       G.save_over = save_over;
+                       strcpy(G.sce, scestr);
+
+                       winqueue_break= 1;      /* leave queues everywhere */
+               
+                       BKE_reset_undo();
+                       BKE_write_undo("original");     /* save current state */
+               }
+               break;
        case 31: /* save default settings */
                BIF_write_homefile();
                break;
@@ -905,6 +925,7 @@ static uiBlock *info_filemenu(void *arg_unused)
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "New|Ctrl X",                             0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Open...|F1",                             0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reopen Last|Ctrl O",                             0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Recover Last Session",                           0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
 
        uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
 
index afb60b19a4f7c4d31a47ea0a4485a1bb4ee12ae4..ade66e5a8c96f7564877163caf568a5526defc1f 100644 (file)
@@ -3436,7 +3436,7 @@ void do_view3d_buttons(short event)
                }
 #endif /* NAN_VPT */
                if(G.obedit==0) enter_editmode();
-               else exit_editmode(1);
+               else exit_editmode(2); // freedata, and undo
                scrarea_queue_headredraw(curarea);
                break;
        case B_POSEMODE:
@@ -3590,7 +3590,7 @@ void do_view3d_buttons(short event)
                        G.f &= ~G_WEIGHTPAINT;          /* Switch off weight paint */
                        G.f &= ~G_FACESELECT;           /* Switch off face select */
                        if (G.obpose) exit_posemode(1); /* exit posemode */
-                       if(G.obedit) exit_editmode(1);  /* exit editmode */
+                       if(G.obedit) exit_editmode(2);  /* exit editmode and undo */
                } else if (G.vd->modeselect == V3D_EDITMODE_SEL) {
                        if(!G.obedit) {
                                G.vd->flag &= ~V3D_MODE;
@@ -3603,7 +3603,7 @@ void do_view3d_buttons(short event)
                        }
                } else if (G.vd->modeselect == V3D_FACESELECTMODE_SEL) {
                        if ((G.obedit) && (G.f & G_FACESELECT)) {
-                               exit_editmode(1); /* exit editmode */
+                               exit_editmode(2); /* exit editmode and undo */
                        } else if ((G.f & G_FACESELECT) && (G.f & G_VERTEXPAINT)) {
                                G.f &= ~G_VERTEXPAINT;  
                        } else if ((G.f & G_FACESELECT) && (G.f & G_TEXTUREPAINT)) {
@@ -3614,7 +3614,7 @@ void do_view3d_buttons(short event)
                                G.f &= ~G_TEXTUREPAINT;         /* Switch off texture paint */
                                G.f &= ~G_WEIGHTPAINT;          /* Switch off weight paint */
                                if (G.obpose) exit_posemode(1); /* exit posemode */
-                               if (G.obedit) exit_editmode(1); /* exit editmode */
+                               if (G.obedit) exit_editmode(2); /* exit editmode and undo */
                                
                                set_faceselect();
                        }
@@ -3624,7 +3624,7 @@ void do_view3d_buttons(short event)
                                G.f &= ~G_TEXTUREPAINT;         /* Switch off texture paint */
                                G.f &= ~G_WEIGHTPAINT;          /* Switch off weight paint */
                                if (G.obpose) exit_posemode(1); /* exit posemode */
-                               if(G.obedit) exit_editmode(1);  /* exit editmode */
+                               if(G.obedit) exit_editmode(2);  /* exit editmode and undo */
                                        
                                set_vpaint();
                        }
@@ -3634,7 +3634,7 @@ void do_view3d_buttons(short event)
                                G.f &= ~G_VERTEXPAINT;          /* Switch off vertex paint */
                                G.f &= ~G_WEIGHTPAINT;          /* Switch off weight paint */
                                if (G.obpose) exit_posemode(1); /* exit posemode */
-                               if(G.obedit) exit_editmode(1);  /* exit editmode */
+                               if(G.obedit) exit_editmode(2);  /* exit editmode and undo */
                                        
                                G.f |= G_TEXTUREPAINT;          /* Switch on texture paint flag */
                        }
@@ -3644,14 +3644,14 @@ void do_view3d_buttons(short event)
                                G.f &= ~G_VERTEXPAINT;          /* Switch off vertex paint */
                                G.f &= ~G_TEXTUREPAINT;         /* Switch off texture paint */
                                if (G.obpose) exit_posemode(1); /* exit posemode */
-                               if(G.obedit) exit_editmode(1);  /* exit editmode */
+                               if(G.obedit) exit_editmode(2);  /* exit editmode and undo */
                                
                                set_wpaint();
                        }
                } else if (G.vd->modeselect == V3D_POSEMODE_SEL) {
                        if (!G.obpose) {
                                G.vd->flag &= ~V3D_MODE;
-                               if(G.obedit) exit_editmode(1);  /* exit editmode */
+                               if(G.obedit) exit_editmode(2);  /* exit editmode and undo */
                                        
                                enter_posemode();
                        }
index f7fa04982ccfd4ad74faf2445ed414be99819525..7cae99a428f30b91823405ccedd5440582fbf78b 100644 (file)
@@ -3091,8 +3091,9 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
                                        if(inside || uevent->event!=LEFTMOUSE) {
                                                butevent= ui_do_button(block, but, uevent);
                                                
-                                               if(but->type!=BLOCK && but->type!=MENU) BIF_write_undo(but->str);
-
+                                               if( !(block->flag & UI_BLOCK_LOOP))
+                                                       if(but->type!=BLOCK && but->type!=MENU) BIF_undo_push(but->str);
+                               
                                                if(butevent) addqueue(block->winq, UI_BUT_EVENT, (short)butevent);
 
                                                /* i doubt about the next line! */
index 15fea1251dfeaf27d56c9a85b8b5bf2f1c1f6c9f..a5bb1aaa8119fd3e3da292dfff3040ae15f78552 100644 (file)
@@ -474,7 +474,10 @@ char *BIF_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
 
 #define SETCOL(col, r, g, b, a)  col[0]=r; col[1]=g; col[2]= b; col[3]= a;
 
-// initialize
+/* initialize
+   Note: when you add new colors, created & saved themes need initialized
+   in usiblender.c, search for "versionfile"
+*/
 void BIF_InitTheme(void)
 {
        bTheme *btheme= U.themes.first;
index 3b65338d646b6cc50d4e43d2e48531286151b5eb..2ade584c712588b5cd1351349a99368e3d4416c9 100644 (file)
@@ -620,18 +620,87 @@ static unsigned short convert_for_nonumpad(unsigned short event)
 
 /* *************** */
 
-void BIF_undo()
+void BIF_undo_push(char *str)
 {
+       if(G.obedit) {
+               if(G.obedit->type==OB_MESH)
+                       undo_push_mesh(str);
+               else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
+                       undo_push_curve(str);
+       }
+       else {
+               if(U.uiflag & USER_GLOBALUNDO) 
+                       BKE_write_undo(str);
+       }
+}
 
+void BIF_undo(void)
+{
+       extern void undo_curve_step(int step);  // editcurve.c
+       
+       if(G.obedit) {
+               if(G.obedit->type==OB_MESH)
+                       undo_pop_mesh(1);
+               else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
+                       undo_curve_step(1);
+                       
+       }
+       else {
+               if (G.f & G_FACESELECT)
+                       ;
+               else if(G.f & G_WEIGHTPAINT)
+                       wpaint_undo();
+               else if(G.f & G_VERTEXPAINT)
+                       vpaint_undo();
+               else {
+                       if(U.uiflag & USER_GLOBALUNDO) BKE_undo_step(1);
+               }
+       }
 }
 
-void BIF_redo()
+void BIF_redo(void)
 {
+       extern void undo_curve_step(int step);  // editcurve.c
 
+       if(G.obedit) {
+               if(G.obedit->type==OB_MESH)
+                       undo_redo_mesh();
+               else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
+                       undo_curve_step(-1);
+       
+       }
+       else {
+               if (G.f & G_FACESELECT)
+                       ;
+               else if(G.f & G_WEIGHTPAINT)
+                       wpaint_undo();
+               else if(G.f & G_VERTEXPAINT)
+                       vpaint_undo();
+               else {
+                       if(U.uiflag & USER_GLOBALUNDO) BKE_undo_step(-1);
+               }
+       }
 }
 
-void BIF_undo_menu()
+void BIF_undo_menu(void)
 {
+       if(G.obedit) {
+               if(G.obedit->type==OB_MESH)
+                       undo_menu_mesh();
+               else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
+                       ;//undo_menu_curve();
+       }
+       else {
+               if (G.f & G_FACESELECT)
+                       ;
+               else if(G.f & G_WEIGHTPAINT)
+                       ;
+               else if(G.f & G_VERTEXPAINT)
+                       ;
+               else {
+                       if(U.uiflag & USER_GLOBALUNDO) BKE_undo_menu();
+               }
+       }
 
 }
 
@@ -1469,12 +1538,12 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                        else if(G.f & G_VERTEXPAINT)
                                                vpaint_undo();
                                        else {
-                                               if(U.uiflag & USER_GLOBALUNDO) BIF_undo_step(1);
+                                               if(U.uiflag & USER_GLOBALUNDO) BIF_undo();
                                                else single_user();
                                        }
                                }
                                else if(G.qual==LR_SHIFTKEY)
-                                       if(U.uiflag & USER_GLOBALUNDO) BIF_undo_step(-1);
+                                       if(U.uiflag & USER_GLOBALUNDO) BIF_redo();
                                        
                                break;
                        case VKEY:
@@ -1536,7 +1605,6 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                scrarea_queue_headredraw(curarea);
                                scrarea_queue_winredraw(curarea);
                                break;
-                               
                        
                        case HOMEKEY:
                                if(G.qual==0)
index 81270c9f846eb346dd19b74ded04ec526c964f30..14273892946bcf6f0ce3e7586466c817bb821d29 100644 (file)
 #include "DNA_view3d_types.h"
 #include "DNA_userdef_types.h"
 
-#include "BKE_utildefines.h"
-#include "BKE_global.h"
+#include "BKE_action.h"
 #include "BKE_anim.h"
-#include "BKE_scene.h"
+#include "BKE_blender.h"
+#include "BKE_displist.h"
+#include "BKE_global.h"
 #include "BKE_ipo.h"
-#include "BKE_action.h"
 #include "BKE_ika.h"
 #include "BKE_key.h"
-#include "BKE_displist.h"
+#include "BKE_scene.h"
+#include "BKE_utildefines.h"
 
 #include "BIF_interface.h"
 #include "BIF_screen.h"
@@ -742,7 +743,7 @@ int blenderqread(unsigned short event, short val)
                                        if(G.obedit==0)
                                                enter_editmode();
                                        else
-                                               exit_editmode(1);
+                                               exit_editmode(2); // freedata, and undo
                                }
                                return 0;
                        }
@@ -757,7 +758,7 @@ int blenderqread(unsigned short event, short val)
                }
                else if(G.qual==LR_SHIFTKEY) {
                        if(G.obedit)
-                               exit_editmode(1);
+                               exit_editmode(2); // freedata, and undo
                        if(G.f & G_FACESELECT)
                                set_faceselect();
                        if(G.f & G_VERTEXPAINT)
@@ -795,7 +796,7 @@ int blenderqread(unsigned short event, short val)
                                if(G.obedit==0)
                                        enter_editmode();
                                else
-                                       exit_editmode(1);
+                                       exit_editmode(2); // freedata, and undo
                                return 0;
                        }                       
                }
@@ -908,8 +909,7 @@ int blenderqread(unsigned short event, short val)
                                                }
                                        }
                                        else if(event==4) {
-                                               extern void BIF_write_undo(char *name);
-                                               BIF_write_undo("10 timer");
+                                               BKE_write_undo("10 timer");
                                        }
                                }
                        
@@ -967,6 +967,13 @@ int blenderqread(unsigned short event, short val)
                        }
                }
                break;
+       case ZKEY:      // undo
+               if(G.qual & LR_CTRLKEY) { // all combos with ctrl/cammandkey are accepted
+                       if(G.qual==LR_CTRLKEY) BIF_undo();
+                       else BIF_redo(); // all combos with ctrl is redo
+                       return 0;
+               }
+               break; 
        }
        
        return 1;
index 50e599b1427aa7d77999690653a8bdb0a29bb0c2..8b006ba2e385eda3df2415a39f7f6a0a5b074849 100644 (file)
 
 #include "PIL_time.h"
 
-// temporal, will go to include file
-void BIF_reset_undo(void);
-void BIF_write_undo(char *);   
-
-
 /***/
 
 void BIF_read_file(char *name)
@@ -150,8 +145,8 @@ void BIF_read_file(char *name)
 
        winqueue_break= 1;      /* leave queues everywhere */
 
-       BIF_reset_undo();
-       BIF_write_undo("original");     /* save current state */
+       BKE_reset_undo();
+       BKE_write_undo("original");     /* save current state */
 }
 
 int BIF_read_homefile(void)
@@ -213,7 +208,7 @@ int BIF_read_homefile(void)
                }
                if (U.savetime <= 0) {
                        U.savetime = 1;
-                       error("%s is buggy, please cosider removing it.\n",
+                       error("%s is buggy, please consider removing it.\n",
                                tstr);
                }
                if (G.main->versionfile <= 191) {
@@ -231,11 +226,32 @@ int BIF_read_homefile(void)
                        U.vrmlflag= USER_VRML_LAYERS;
                }
 
+                       /* added seam, normal color */
+               if (G.main->versionfile <= 234) {
+                       bTheme *btheme;
+                       
+                       for(btheme= U.themes.first; btheme; btheme= btheme->next) {
+                               /* check for alpha==0 is safe, then color was never set */
+                               if(btheme->tv3d.edge_seam[3]==0) {
+                                       btheme->tv3d.edge_seam[0]= 230;
+                                       btheme->tv3d.edge_seam[1]= 150;
+                                       btheme->tv3d.edge_seam[2]= 50;
+                                       btheme->tv3d.edge_seam[3]= 255;
+                               }
+                               if(btheme->tv3d.normal[3]==0) {
+                                       btheme->tv3d.normal[0]= 0x22;
+                                       btheme->tv3d.normal[1]= 0xDD;
+                                       btheme->tv3d.normal[2]= 0xDD;
+                                       btheme->tv3d.normal[3]= 255;
+                               }
+                       }
+               }
+               
                space_set_commmandline_options();
 
                if (U.undosteps==0) U.undosteps=32;
-               BIF_reset_undo();
-               BIF_write_undo("original");     /* save current state */
+               BKE_reset_undo();
+               BKE_write_undo("original");     /* save current state */
 
                reset_autosave();
 
@@ -455,6 +471,7 @@ void BIF_write_autosave(void)
        BLO_write_file(tstr, write_flags, &err);
 }
 
+/* if global undo; remove tempsave, otherwise rename */
 static void delete_autosave(void)
 {
        char tstr[FILE_MAXDIR+FILE_MAXFILE];
@@ -464,7 +481,9 @@ static void delete_autosave(void)
        if (BLI_exists(tstr)) {
                char str[FILE_MAXDIR+FILE_MAXFILE];
                BLI_make_file_string("/", str, U.tempdir, "quit.blend");
-               BLI_rename(tstr, str);
+
+               if(U.uiflag & USER_GLOBALUNDO) BLI_delete(tstr, 0, 0);
+               else BLI_rename(tstr, str);
        }
 }
 
@@ -586,7 +605,9 @@ void exit_usiblender(void)
 
        if (G.undo_clear) G.undo_clear();
        undo_clear_curve();
-       BIF_reset_undo();
+       
+       BKE_undo_save_quit();   // saves quit.blend if global undo is on
+       BKE_reset_undo(); 
        
        BLI_freelistN(&U.themes);