3 * sushivision copyright (C) 2006-2007 Monty <monty@xiph.org>
5 * sushivision is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * sushivision is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with sushivision; see the file COPYING. If not, write to the
17 * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
30 int _sv_undo_suspended
=0;
31 sv_undo_t
**_sv_undo_stack
=NULL
;
33 /* encapsulates some amount of common undo/redo infrastructure */
35 static void update_all_menus(){
38 for(i
=0;i
<_sv_panels
;i
++)
40 _sv_panel_update_menus(_sv_panel_list
[i
]);
44 void _sv_undo_suspend(){
48 void _sv_undo_resume(){
50 if(_sv_undo_suspended
<0){
51 fprintf(stderr
,"Internal error: undo suspend refcount count < 0\n");
60 _sv_undo_stack
= calloc(2,sizeof(*_sv_undo_stack
));
62 if(_sv_undo_stack
[_sv_undo_level
]){
64 while(_sv_undo_stack
[i
]){
65 u
= _sv_undo_stack
[i
];
67 if(u
->dim_vals
[0]) free(u
->dim_vals
[0]);
68 if(u
->dim_vals
[1]) free(u
->dim_vals
[1]);
69 if(u
->dim_vals
[2]) free(u
->dim_vals
[2]);
72 for(j
=0;j
<_sv_panels
;j
++){
73 _sv_panel_undo_t
*pu
= u
->panels
+j
;
74 if(pu
->mappings
) free(pu
->mappings
);
75 if(pu
->scale_vals
[0]) free(pu
->scale_vals
[0]);
76 if(pu
->scale_vals
[1]) free(pu
->scale_vals
[1]);
77 if(pu
->scale_vals
[2]) free(pu
->scale_vals
[2]);
81 free(_sv_undo_stack
[i
]);
82 _sv_undo_stack
[i
]= NULL
;
88 u
= _sv_undo_stack
[_sv_undo_level
] = calloc(1,sizeof(*u
));
89 u
->panels
= calloc(_sv_panels
,sizeof(*u
->panels
));
90 u
->dim_vals
[0] = calloc(_sv_dimensions
,sizeof(**u
->dim_vals
));
91 u
->dim_vals
[1] = calloc(_sv_dimensions
,sizeof(**u
->dim_vals
));
92 u
->dim_vals
[2] = calloc(_sv_dimensions
,sizeof(**u
->dim_vals
));
99 // log into a fresh entry; pop this level and all above it
101 u
= _sv_undo_stack
[_sv_undo_level
];
104 for(i
=0;i
<_sv_dimensions
;i
++){
105 sv_dim_t
*d
= _sv_dimension_list
[i
];
107 u
->dim_vals
[0][i
] = d
->bracket
[0];
108 u
->dim_vals
[1][i
] = d
->val
;
109 u
->dim_vals
[2][i
] = d
->bracket
[1];
113 // pass off panel population to panels
114 for(j
=0;j
<_sv_panels
;j
++)
115 if(_sv_panel_list
[j
])
116 _sv_panel_undo_log(_sv_panel_list
[j
], u
->panels
+j
);
119 void _sv_undo_restore(){
121 _sv_undo_t
*u
= _sv_undo_stack
[_sv_undo_level
];
124 // need to happen first as setting dims can have side effect (like activating crosshairs)
125 for(i
=0;i
<_sv_dimensions
;i
++){
126 sv_dim_t
*d
= _sv_dimension_list
[i
];
128 _sv_dim_set_thumb(d
, 0, u
->dim_vals
[0][i
]);
129 _sv_dim_set_thumb(d
, 1, u
->dim_vals
[1][i
]);
130 _sv_dim_set_thumb(d
, 2, u
->dim_vals
[2][i
]);
135 for(i
=0;i
<_sv_panels
;i
++){
136 sv_panel_t
*p
= _sv_panel_list
[i
];
138 _sv_panel_undo_restore(_sv_panel_list
[i
],u
->panels
+i
);
143 void _sv_undo_push(){
144 if(_sv_undo_suspended
)return;
150 realloc(_sv_undo_stack
,
151 (_sv_undo_level
+3)*sizeof(*_sv_undo_stack
));
153 _sv_undo_stack
[_sv_undo_level
]=NULL
;
154 _sv_undo_stack
[_sv_undo_level
+1]=NULL
;
159 if(!_sv_undo_stack
)return;
160 if(!_sv_undo_stack
[_sv_undo_level
])return;
161 if(!_sv_undo_stack
[_sv_undo_level
+1])return;
170 void _sv_undo_down(){
171 if(!_sv_undo_stack
)return;
172 if(!_sv_undo_level
)return;
174 if(!_sv_undo_stack
[_sv_undo_level
+1])
185 // load piggybacks off the undo infrastructure