Commit 731fac3a authored by Ivica Bukvic's avatar Ivica Bukvic
Browse files

added more improvements to the infinite undo and reworked existing undo...

added more improvements to the infinite undo and reworked existing undo actions to conform to the infinite undo model. fixed per-window undo menu updating, finalized undo actions 1,2,3,4,5,9, and 10. Still need 6,7,8 and a new action 11 (namely apply, canvas apply, to front/back, and rename). Also improved paste behavior to make it more user friendly, particularly within the context of infinite undo.
parent fdf76f44
......@@ -247,7 +247,7 @@ int glist_isselected(t_glist *x, t_gobj *y)
/* call this for unselected objects only */
void glist_select(t_glist *x, t_gobj *y)
{
fprintf(stderr,"glist_select\n");
//fprintf(stderr,"glist_select\n");
if (x->gl_editor)
{
if (c_selection && c_selection != x)
......@@ -303,7 +303,7 @@ void glist_deselect(t_glist *x, t_gobj *y)
//fprintf(stderr, "e_textedfor == fuddy\n");
if (x->gl_editor->e_textdirty)
{
fprintf(stderr, "textdirty yes\n");
//fprintf(stderr, "textdirty yes\n");
z = fuddy;
canvas_stowconnections(glist_getcanvas(x));
glist_checkanddeselectall(x, y);
......@@ -354,7 +354,7 @@ void glist_deselect(t_glist *x, t_gobj *y)
void glist_noselect(t_glist *x)
{
fprintf(stderr,"glist_noselect\n");
//fprintf(stderr,"glist_noselect\n");
if (x->gl_editor)
{
if (x->gl_editor->e_selection) {
......@@ -614,7 +614,7 @@ typedef struct _undo_cut
/* at least one object is selected, we dynamically resize it later */
} t_undo_cut;
static void *canvas_undo_set_cut(t_canvas *x, int mode)
void *canvas_undo_set_cut(t_canvas *x, int mode)
{
t_undo_cut *buf;
t_gobj *y;
......@@ -682,7 +682,7 @@ static void *canvas_undo_set_cut(t_canvas *x, int mode)
return (buf);
}
static void canvas_undo_cut(t_canvas *x, void *z, int action)
void canvas_undo_cut(t_canvas *x, void *z, int action)
{
//fprintf(stderr, "canvas_undo_cut canvas=%d buf=%d action=%d\n", (int)x, (int)z, action);
t_undo_cut *buf = z;
......@@ -902,13 +902,23 @@ void canvas_undo_move(t_canvas *x, void *z, int action)
typedef struct _undo_paste
{
int u_index; /* index of first object pasted */
int u_index; /* index of first object pasted */
int u_sel_index; /* index of object selected at the time the other object was pasted (for autopatching) */
t_binbuf *u_objectbuf; /* here we store actual copied data */
} t_undo_paste;
void *canvas_undo_set_paste(t_canvas *x, int offset)
{
t_undo_paste *buf = (t_undo_paste *)getbytes(sizeof(*buf));
buf->u_index = glist_getindex(x, 0) - offset;
buf->u_index = glist_getindex(x, 0) - offset; //do we need offset at all?
if (x->gl_editor->e_selection && !x->gl_editor->e_selection->sel_next) {
//if only one object is selected which will warrant autopatching
buf->u_sel_index = glist_getindex(x, x->gl_editor->e_selection->sel_what);
fprintf(stderr,"canvas_undo_set_paste selected object index %d\n", buf->u_sel_index);
} else {
buf->u_sel_index = -1;
}
buf->u_objectbuf = binbuf_duplicate(copy_binbuf);
return (buf);
}
......@@ -926,15 +936,23 @@ void canvas_undo_paste(t_canvas *x, void *z, int action)
else if (action == UNDO_REDO)
{
t_selection *sel;
canvas_dopaste(x, copy_binbuf);
glist_noselect(x);
//if the pasted object is supposed to be autopatched
//then select the object it should be autopatched to
if (buf->u_sel_index > -1)
glist_select(x, glist_nth(x, buf->u_sel_index));
canvas_dopaste(x, buf->u_objectbuf);
/* if it was "duplicate" have to re-enact the displacement. */
if (canvas_undo_name && canvas_undo_name[0] == 'd')
//for (sel = x->gl_editor->e_selection; sel; sel = sel->sel_next)
// gobj_displace(sel->sel_what, x, 10, 10);
canvas_paste_xyoffset(x);
}
else if (action == UNDO_FREE)
else if (action == UNDO_FREE) {
if (buf->u_objectbuf)
binbuf_free(buf->u_objectbuf);
t_freebytes(buf, sizeof(*buf));
}
}
/* recursively check for abstractions to reload as result of a save.
......@@ -964,8 +982,9 @@ static void glist_doreload(t_glist *gl, t_symbol *name, t_symbol *dir,
canvas_vis(glist_getcanvas(gl), 1);
glist_noselect(gl);
glist_select(gl, g);
canvas_setundo(gl, canvas_undo_cut,
canvas_undo_set_cut(gl, UCUT_CLEAR), "clear");
//canvas_setundo(gl, canvas_undo_cut,
// canvas_undo_set_cut(gl, UCUT_CLEAR), "clear");
canvas_undo_add(gl, 3, "clear", canvas_undo_set_cut(gl, UCUT_CLEAR));
canvas_doclear(gl);
canvas_undo(gl);
glist_noselect(gl);
......@@ -1454,6 +1473,8 @@ void canvas_canvas_setundo(t_canvas *x)
/* --------- 9. create ----------- */
extern t_pd *newest;
typedef struct _undo_create
{
int u_index; /* index of the created object object */
......@@ -1471,7 +1492,7 @@ void *canvas_undo_set_create(t_canvas *x)
t_undo_create *buf = (t_undo_create *)getbytes(sizeof(*buf));
buf->u_index = glist_getindex(x, 0) - 1;
int nnotsel= glist_selectionindex(x, 0, 0);
fprintf(stderr,"buf->u_index=%d nnotsel=%d\n", buf->u_index, nnotsel);
//fprintf(stderr,"buf->u_index=%d nnotsel=%d\n", buf->u_index, nnotsel);
buf->u_objectbuf = binbuf_new();
if (x->gl_list) {
......@@ -1479,7 +1500,7 @@ void *canvas_undo_set_create(t_canvas *x)
{
//if (glist_isselected(x, y)) {
if (!y->g_next) {
fprintf(stderr,"undo_set_create: gobj_save\n");
//fprintf(stderr,"undo_set_create: gobj_save\n");
gobj_save(y, buf->u_objectbuf);
break;
}
......@@ -1492,10 +1513,10 @@ void *canvas_undo_set_create(t_canvas *x)
//int issel2 = glist_isselected(x, &t.tr_ob2->ob_g);
issel1 = ( &t.tr_ob->ob_g == y ? 1 : 0);
issel2 = ( &t.tr_ob2->ob_g == y ? 1 : 0);
fprintf(stderr,"undo_set_create linetraverser %d %d\n", issel1, issel2);
//fprintf(stderr,"undo_set_create linetraverser %d %d\n", issel1, issel2);
if (issel1 != issel2)
{
fprintf(stderr,"undo_set_create store connection\n");
//fprintf(stderr,"undo_set_create store connection\n");
binbuf_addv(buf->u_reconnectbuf, "ssiiii;",
gensym("#X"), gensym("connect"),
(issel1 ? nnotsel : 0)
......@@ -1536,6 +1557,8 @@ void canvas_undo_create(t_canvas *x, void *z, int action)
pd_bind(&x->gl_pd, gensym("#X"));
binbuf_eval(buf->u_reconnectbuf, 0, 0, 0);
pd_unbind(&x->gl_pd, gensym("#X"));
if (newest && pd_class(newest) == canvas_class)
canvas_loadbang((t_canvas *)newest);
y = glist_nth(x, buf->u_index);
glist_select(x, y);
}
......@@ -1557,11 +1580,12 @@ void *canvas_undo_set_recreate(t_canvas *x, t_gobj *y)
int issel1, issel2;
t_undo_create *buf = (t_undo_create *)getbytes(sizeof(*buf));
buf->u_index = glist_getindex(x, y); // - 1; TODO: do we still need a -1 here???
buf->u_index = glist_getindex(x, y);
int nnotsel= glist_selectionindex(x, 0, 0) - 1; // - 1 is a critical difference from the create
fprintf(stderr,"buf->u_index=%d nnotsel=%d\n", buf->u_index, nnotsel);
//fprintf(stderr,"buf->u_index=%d nnotsel=%d\n", buf->u_index, nnotsel);
buf->u_objectbuf = binbuf_new();
fprintf(stderr,"undo_set_create: gobj_save\n");
//y = glist_nth(x, buf->u_index);
//fprintf(stderr,"undo_set_create: gobj_save\n");
gobj_save(y, buf->u_objectbuf);
buf->u_reconnectbuf = binbuf_new();
......@@ -1572,10 +1596,10 @@ void *canvas_undo_set_recreate(t_canvas *x, t_gobj *y)
//int issel2 = glist_isselected(x, &t.tr_ob2->ob_g);
issel1 = ( &t.tr_ob->ob_g == y ? 1 : 0);
issel2 = ( &t.tr_ob2->ob_g == y ? 1 : 0);
fprintf(stderr,"undo_set_create linetraverser %d %d\n", issel1, issel2);
//fprintf(stderr,"undo_set_create linetraverser %d %d\n", issel1, issel2);
if (issel1 != issel2)
{
fprintf(stderr,"undo_set_create store connection\n");
//fprintf(stderr,"undo_set_create store connection\n");
binbuf_addv(buf->u_reconnectbuf, "ssiiii;",
gensym("#X"), gensym("connect"),
(issel1 ? nnotsel : 0)
......@@ -1591,33 +1615,122 @@ void *canvas_undo_set_recreate(t_canvas *x, t_gobj *y)
void canvas_undo_recreate(t_canvas *x, void *z, int action)
{
//fprintf(stderr,"canvas_undo_recreate\n");
t_undo_create *buf = z;
t_gobj *y;
t_gobj *y = glist_nth(x, buf->u_index);
//fprintf(stderr,"canvas = %lx buf->u_index = %d\n", (t_int)x, buf->u_index);
if (action == UNDO_UNDO || action == UNDO_REDO)
{
/*TODO: copy new state of the current object
then cut the existing object
then paste old object
then free old data buffer and make it point to the new buffer
then reorder the object so that it is placed in the same order as the old one
glist_noselect(x);
y = glist_nth(x, buf->u_index);
// first copy new state of the current object
t_linetraverser t;
t_outconnect *oc;
int issel1, issel2;
t_undo_create *buf2 = (t_undo_create *)getbytes(sizeof(*buf));
buf2->u_index = glist_getindex(x, y);
int nnotsel= glist_selectionindex(x, 0, 0) - 1; // - 1 is a critical difference from the create
//fprintf(stderr,"buf2->u_index=%d nnotsel=%d\n", buf2->u_index, nnotsel);
buf2->u_objectbuf = binbuf_new();
//fprintf(stderr,"undo_set_recreate: gobj_save\n");
gobj_save(y, buf2->u_objectbuf);
buf2->u_reconnectbuf = binbuf_new();
linetraverser_start(&t, x);
while (oc = linetraverser_next(&t))
{
issel1 = ( &t.tr_ob->ob_g == y ? 1 : 0);
issel2 = ( &t.tr_ob2->ob_g == y ? 1 : 0);
//fprintf(stderr,"undo_set_recreate linetraverser %d %d\n", issel1, issel2);
if (issel1 != issel2)
{
//fprintf(stderr,"undo_set_recreate store connection\n");
binbuf_addv(buf2->u_reconnectbuf, "ssiiii;",
gensym("#X"), gensym("connect"),
(issel1 ? nnotsel : 0)
+ glist_selectionindex(x, &t.tr_ob->ob_g, issel1),
t.tr_outno,
(issel2 ? nnotsel : 0) +
glist_selectionindex(x, &t.tr_ob2->ob_g, issel2),
t.tr_inno);
}
}
// now then cut the existing object
glist_noselect(x);
glist_select(x, y);
canvas_doclear(x);
// then paste the old object
pd_bind(&x->gl_pd, gensym("#X"));
binbuf_eval(buf->u_objectbuf, 0, 0, 0);
pd_unbind(&x->gl_pd, gensym("#X"));
pd_bind(&x->gl_pd, gensym("#X"));
binbuf_eval(buf->u_reconnectbuf, 0, 0, 0);
pd_unbind(&x->gl_pd, gensym("#X"));
// free the old data
binbuf_free(buf->u_objectbuf);
binbuf_free(buf->u_reconnectbuf);
t_freebytes(buf, sizeof(*buf));
// readjust pointer
// (this should probably belong into g_undo.c, but since it is a unique case, we'll let it be for the time being)
x->u_last->data = (void *)buf2;
buf = buf2;
// reposition object to its original place
t_gobj *y_prev, *y_next;
//get the last object
y = glist_nth(x, glist_getindex(x, 0) - 1);
/*for (y = x->gl_list; y; y = y->g_next)
if (!y->g_next)
break;*/
// first check if we are in the same position already
if (glist_getindex(x, y) != buf->u_index) {
//fprintf(stderr,"not in the right place\n");
y_prev = glist_nth(x, buf->u_index-1);
y_next = glist_nth(x, buf->u_index);
//if the object is supposed to be first in the gl_list
if (buf->u_index == 0) {
if (y_prev && y_next) {
y_prev->g_next = y_next;
}
else if (y_prev && !y_next)
y_prev->g_next = NULL;
//now put the moved object at the beginning of the cue
y->g_next = glist_nth(x, 0);
x->gl_list = y;
}
//if the object is supposed to be at the current end of gl_list
//can this ever happen???
/*else if (!glist_nth(x,buf->p_a[i])) {
}*/
//if the object is supposed to be in the middle of gl_list
else {
if (y_prev && y_next) {
y_prev->g_next = y_next;
}
else if (y_prev && !y_next) {
y_prev->g_next = NULL;
}
//now put the moved object in its right place
y_prev = glist_nth(x, buf->u_index-1);
y_next = glist_nth(x, buf->u_index);
y_prev->g_next = y;
y->g_next = y_next;
}
}
// send a loadbang
if (newest && pd_class(newest) == canvas_class)
canvas_loadbang((t_canvas *)newest);
// select
y = glist_nth(x, buf->u_index);
glist_select(x, y);
}
......@@ -1797,7 +1910,7 @@ void canvas_vis(t_canvas *x, t_floatarg f)
int flag = (f != 0);
if (x != glist_getcanvas(x) && glist_isvisible(glist_getcanvas(x))) {
bug("canvas_vis");
fprintf(stderr,"canvas_vis .x%lx .x%lx %f\n", (t_int)x, (t_int)glist_getcanvas(x), f);
//fprintf(stderr,"canvas_vis .x%lx .x%lx %f\n", (t_int)x, (t_int)glist_getcanvas(x), f);
}
if (flag)
{
......@@ -3135,8 +3248,9 @@ void canvas_key(t_canvas *x, t_symbol *s, int ac, t_atom *av)
/* send the key to the box's editor */
if (!x->gl_editor->e_textdirty)
{
canvas_setundo(x, canvas_undo_cut,
canvas_undo_set_cut(x, UCUT_TEXT), "typing");
//canvas_setundo(x, canvas_undo_cut,
// canvas_undo_set_cut(x, UCUT_TEXT), "typing");
canvas_undo_add(x, 3, "typing", canvas_undo_set_cut(x, UCUT_TEXT));
}
rtext_key(x->gl_editor->e_textedfor,
(int)keynum, gotkeysym);
......@@ -3151,8 +3265,9 @@ void canvas_key(t_canvas *x, t_symbol *s, int ac, t_atom *av)
canvas_clearline(x);
else if (x->gl_editor->e_selection)
{
canvas_setundo(x, canvas_undo_cut,
canvas_undo_set_cut(x, UCUT_CLEAR), "clear");
//canvas_setundo(x, canvas_undo_cut,
// canvas_undo_set_cut(x, UCUT_CLEAR), "clear");
canvas_undo_add(x, 3, "clear", canvas_undo_set_cut(x, UCUT_CLEAR));
canvas_doclear(x);
}
}
......@@ -3533,7 +3648,7 @@ void canvas_finderror(void *error_object)
void canvas_stowconnections(t_canvas *x)
{
fprintf(stderr,"canvas_stowconnections\n");
//fprintf(stderr,"canvas_stowconnections\n");
t_gobj *selhead = 0, *seltail = 0, *nonhead = 0, *nontail = 0, *y, *y2;
t_linetraverser t;
t_outconnect *oc;
......@@ -3592,7 +3707,7 @@ void canvas_stowconnections(t_canvas *x)
void canvas_restoreconnections(t_canvas *x)
{
fprintf(stderr,"canvas_restoreconnections\n");
//fprintf(stderr,"canvas_restoreconnections\n");
pd_bind(&x->gl_pd, gensym("#X"));
binbuf_eval(x->gl_editor->e_connectbuf, 0, 0, 0);
pd_unbind(&x->gl_pd, gensym("#X"));
......@@ -3838,8 +3953,9 @@ static void canvas_cut(t_canvas *x)
/* else we are cutting objects */
else if (x->gl_editor && x->gl_editor->e_selection)
{
canvas_setundo(x, canvas_undo_cut,
canvas_undo_set_cut(x, UCUT_CUT), "cut");
//canvas_setundo(x, canvas_undo_cut,
// canvas_undo_set_cut(x, UCUT_CUT), "cut");
canvas_undo_add(x, 3, "cut", canvas_undo_set_cut(x, UCUT_CUT));
canvas_copy(x);
canvas_doclear(x);
paste_xyoffset = 0;
......@@ -4002,7 +4118,6 @@ static void canvas_dopaste(t_canvas *x, t_binbuf *b)
canvas_displaceselection(x, delta_x, delta_y);
//reset canvas_undo_already_set_move
canvas_undo_already_set_move = 0;
//TODO: now we need to update the undo queue which does not reflect these autopatching changes
}
//if we are pasting into a new window and this is not copied from external buffer OR
//if we are copying from external buffer and the current canvas is not empty
......@@ -4011,6 +4126,10 @@ static void canvas_dopaste(t_canvas *x, t_binbuf *b)
canvas_paste_atmouse(x);
//fprintf(stderr,"doing a paste\n");
}
//else let's provide courtesy offset
else if (!copyfromexternalbuffer) {
canvas_paste_xyoffset(x);
}
canvas_dirty(x, 1);
/*if (!canvas_undo_name || canvas_undo_name[0] != 'd') {
......@@ -4044,7 +4163,7 @@ static void canvas_paste(t_canvas *x)
{
//canvas_setundo(x, canvas_undo_paste, canvas_undo_set_paste(x),
// "paste");
canvas_undo_add(x, 5, "paste", (void *)canvas_undo_set_paste(x, 1));
canvas_undo_add(x, 5, "paste", (void *)canvas_undo_set_paste(x, 0));
canvas_dopaste(x, copy_binbuf);
//canvas_paste_xyoffset(x);
}
......
......@@ -34,6 +34,7 @@ extern void canvas_apply_setundo(t_canvas *x, t_gobj *y);
extern void canvas_setundo(t_canvas *x, t_undofn undofn, void *buf, const char *name);
extern void *canvas_undo_set_create(t_canvas *x);
extern void canvas_undo_create(t_canvas *x, void *z, int action);
extern int we_are_undoing;
/* ----------------- the "text" object. ------------------ */
......@@ -80,6 +81,9 @@ void glist_text(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
and objects though since there's no text in them at menu
creation. */
/* gobj_activate(&x->te_g, gl, 1); */
if (!we_are_undoing)
canvas_undo_add(glist_getcanvas(gl), 9, "create",
(void *)canvas_undo_set_create(glist_getcanvas(gl)));
canvas_startmotion(glist_getcanvas(gl));
}
}
......@@ -88,7 +92,6 @@ void glist_text(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
extern t_pd *newest;
void canvas_getargs(int *argcp, t_atom **argvp);
extern int we_are_undoing;
static void canvas_objtext(t_glist *gl, int xpix, int ypix, int selected,
t_binbuf *b)
......@@ -216,7 +219,7 @@ void canvas_howputnew(t_canvas *x, int *connectp, int *xpixp, int *ypixp,
void canvas_obj(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
{
fprintf(stderr,"canvas_obj\n");
//fprintf(stderr,"canvas_obj\n");
t_text *x;
if (argc >= 2)
{
......@@ -236,22 +239,18 @@ void canvas_obj(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
canvas_howputnew(gl, &connectme, &xpix, &ypix, &indx, &nobj);
pd_vmess(&gl->gl_pd, gensym("editmode"), "i", 1);
canvas_objtext(gl, xpix, ypix, 1, b);
//t_undo_create *u_c = (t_undo_create *)glist_getcanvas(gl)->u_last->data;
if (connectme) {
fprintf(stderr,"canvas_obj calls canvas_connect\n");
//u_c->indx = indx;
//u_c->nobj = nobj;
//fprintf(stderr,"canvas_obj calls canvas_connect\n");
canvas_connect(gl, indx, 0, nobj, 0);
}
else {
fprintf(stderr,"canvas_obj calls canvas_startmotion\n");
//u_c->indx = -1;
//u_c->nobj = -1;
//fprintf(stderr,"canvas_obj calls canvas_startmotion\n");
canvas_startmotion(glist_getcanvas(gl));
}
//canvas_setundo(glist_getcanvas(gl), canvas_undo_create, canvas_undo_set_create(gl), "create");
canvas_undo_add(glist_getcanvas(gl), 9, "create",
(void *)canvas_undo_set_create(glist_getcanvas(gl)));
if (!we_are_undoing)
canvas_undo_add(glist_getcanvas(gl), 9, "create",
(void *)canvas_undo_set_create(glist_getcanvas(gl)));
}
}
......@@ -1801,12 +1800,16 @@ void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize)
vec2[0].a_type == A_SYMBOL
&& !strcmp(vec2[0].a_w.w_symbol->s_name, "pd"))
{
//TODO: add rename undo
typedmess(&x->te_pd, gensym("rename"), natom2-1, vec2+1);
binbuf_free(x->te_binbuf);
x->te_binbuf = b;
}
else /* normally, just destroy the old one and make a new one. */
{
//fprintf(stderr,"text_setto calls canvas_undo_add\n");
canvas_undo_add(glist_getcanvas(glist), 10, "recreate",
(void *)canvas_undo_set_recreate(glist_getcanvas(glist), &x->te_g));
int xwas = x->te_xpix, ywas = x->te_ypix;
canvas_eraselinesfor(glist, x);
glist_delete(glist, &x->te_g);
......@@ -1815,10 +1818,6 @@ void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize)
if (newest && pd_class(newest) == canvas_class)
canvas_loadbang((t_canvas *)newest);
canvas_restoreconnections(glist_getcanvas(glist));
glist_select(
fprintf(stderr,"text_setto calls canvas_undo_add\n");
canvas_undo_add(glist_getcanvas(glist), 10, "recreate",
(void *)canvas_undo_set_recreate(glist_getcanvas(glist), &x->te_g));
}
/* if we made a new "pd" or changed a window name,
update window list */
......
......@@ -22,7 +22,7 @@ t_undo_action *canvas_undo_init(t_canvas *x)
x->u_last = a;
a->prev = NULL;
a->name = "no";
//sys_vgui("pdtk_undomenu .x%lx no no\n", (t_int)a->x);
sys_vgui("pdtk_undomenu .x%lx no no\n", (t_int)a->x);
}
else {
if (x->u_last->next) {
......@@ -33,7 +33,7 @@ t_undo_action *canvas_undo_init(t_canvas *x)
a->prev = x->u_last;
x->u_last = a;
}
fprintf(stderr,"canvas_undo_init\n");
//fprintf(stderr,"canvas_undo_init\n");
return(a);
}
......@@ -51,15 +51,15 @@ t_undo_action *canvas_undo_add(t_canvas *x, int type, const char *name, void *da
void canvas_undo_undo(t_canvas *x)
{
fprintf(stderr,"canvas_undo_undo\n");
if (x->u_queue && x->u_last != x->u_queue) {
fprintf(stderr,"do it\n");
we_are_undoing = 1;
fprintf(stderr,"canvas_undo_undo %d\n", x->u_last->type);
glist_noselect(x);
switch(x->u_last->type)
{
case 1: canvas_undo_connect(x, x->u_last->data, UNDO_UNDO); break; //connect
case 2: canvas_undo_disconnect(x, x->u_last->data, UNDO_UNDO); break; //disconnect
case 3: canvas_undo_cut(x, x->u_last->data, UNDO_UNDO); break; //cut
case 4: canvas_undo_move(x, x->u_last->data, UNDO_UNDO); break; //move
case 5: canvas_undo_paste(x, x->u_last->data, UNDO_UNDO); break; //paste
case 9: canvas_undo_create(x, x->u_last->data, UNDO_UNDO); break; //create
......@@ -80,16 +80,16 @@ void canvas_undo_undo(t_canvas *x)
void canvas_undo_redo(t_canvas *x)
{
fprintf(stderr,"canvas_undo_redo\n");
if (x->u_queue && x->u_last->next) {
fprintf(stderr,"do it\n");
we_are_undoing = 1;
x->u_last = x->u_last->next;
fprintf(stderr,"canvas_undo_undo %d\n", x->u_last->type);
glist_noselect(x);
switch(x->u_last->type)
{
case 1: canvas_undo_connect(x, x->u_last->data, UNDO_REDO); break; //connect
case 2: canvas_undo_disconnect(x, x->u_last->data, UNDO_REDO); break; //disconnect
case 3: canvas_undo_cut(x, x->u_last->data, UNDO_REDO); break; //cut
case 4: canvas_undo_move(x, x->u_last->data, UNDO_REDO); break; //move
case 5: canvas_undo_paste(x, x->u_last->data, UNDO_REDO); break; //paste
case 9: canvas_undo_create(x, x->u_last->data, UNDO_REDO); break; //create
......@@ -118,6 +118,7 @@ void canvas_undo_rebranch(t_canvas *x)
{
case 1: canvas_undo_connect(x, a->data, UNDO_FREE); break; //connect
case 2: canvas_undo_disconnect(x, a->data, UNDO_FREE); break; //disconnect
case 3: canvas_undo_cut(x, a->data, UNDO_FREE); break; //cut
case 4: canvas_undo_move(x, a->data, UNDO_FREE); break; //move
case 5: canvas_undo_paste(x, a->data, UNDO_FREE); break; //paste
case 9: canvas_undo_create(x, a->data, UNDO_FREE); break; //create
......@@ -143,11 +144,11 @@ void canvas_undo_purge_abstraction_actions(t_canvas *x)
void canvas_undo_free(t_canvas *x)
{
fprintf(stderr,"canvas_undo_free");
//fprintf(stderr,"canvas_undo_free");
if (x->u_queue) {
t_undo_action *a;
for(a = x->u_queue; a; a = a->next) {
fprintf(stderr,".");
//fprintf(stderr,".");
switch(a->type)
{
case 1: canvas_undo_connect(x, a->data, UNDO_FREE); break; //connect
......@@ -162,6 +163,6 @@ void canvas_undo_free(t_canvas *x)
freebytes(a, sizeof(*a));
}
}
fprintf(stderr,"done!\n");
//fprintf(stderr,"done!\n");
}
......@@ -26,16 +26,18 @@ by an undo) all undo actions (except for its deletion in the parent window shoul
be purged since abstraction's state will now default to its original (saved) state.
Types of undo data:
0 - init data (start of the queue)
1 - connect
2 - disconnect
3 - cut, clear & typing into objects
4 - motion, inclding "tidy up" and stretching
5 - paste & duplicate
6 - apply
7 - arrange (to front/back)
8 - canvas apply
9 - create
0 - init data (start of the queue)
1 - connect
2 - disconnect
3 - cut, clear & typing into objects
4 - motion, inclding "tidy up" and stretching
5 - paste & duplicate
6 - apply
7 - arrange (to front/back)
8 - canvas apply
9 - create
10 - recreate
11 - rename (TODO)
*/
struct _undo_action
......@@ -74,6 +76,11 @@ EXTERN void *canvas_undo_set_disconnect(t_canvas *x,
int index1, int outno, int index2, int inno);
EXTERN void canvas_undo_disconnect(t_canvas *x, void *z, int action);
/* --------- 3. cut -------------- */
EXTERN void *canvas_undo_set_cut(t_canvas *x, int mode);
EXTERN void canvas_undo_cut(t_canvas *x, void *z, int action);
/* --------- 4. move ------------- */
EXTERN void *canvas_undo_set_move(t_canvas *x, int selected);
......@@ -92,7 +99,7 @@ EXTERN void *canvas_undo_set_create(t_canvas *x);
/* --------- 10. recreate -------- */
EXTERN void canvas_undo_recreate(t_canvas *x, void *z, int action);
EXTERN void *canvas_undo_set_recreate(t_canvas *x);
EXTERN void *canvas_undo_set_recreate(t_canvas *x, t_gobj *y);
/* ------------------------------- */
......
......@@ -801,9 +801,9 @@ if {$pd_nt == 2} {
}
set pd_opendir $untitled_directory