📄 undo.c
字号:
/*
* CreateUndoStack - Creates a new undo stack (when a new image is opened
* or begun.
*/
void CreateUndoStack( img_node *node )
{
an_undo_stack *new_stack;
an_undo_stack *next_stack;
an_undo_stack *prev_stack;
img_node *nexticon;
int icon_count;
int i;
new_stack = MemAlloc( sizeof(an_undo_stack) );
new_stack->hwnd = node->hwnd;
new_stack->opcount = 0;
new_stack->redocount = 0;
new_stack->current_icon = 0;
new_stack->top_undo = NULL;
new_stack->bottom_undo = NULL;
new_stack->top_redo = NULL;
new_stack->modified = FALSE;
new_stack->nexticon = NULL;
new_stack->next = NULL;
new_stack->previous = NULL;
if (node->issaved) {
new_stack->original_xor = DuplicateBitmap(node->hxorbitmap);
new_stack->original_and = DuplicateBitmap(node->handbitmap);
} else {
new_stack->original_xor = NULL;
new_stack->original_and = NULL;
}
setBaseImage( node, new_stack );
icon_count = node->num_of_images;
nexticon = node->nexticon;
prev_stack = new_stack;
for (i = 1; i < icon_count; ++i) {
if (!nexticon) {
break;
}
next_stack = MemAlloc( sizeof(an_undo_stack) );
memcpy( next_stack, prev_stack, sizeof(an_undo_stack) );
/*
* If node->issaved is true then this was an opened image and we store
* the original bitmaps. Otherwise, the 'Restore' option is grayed.
*/
if (nexticon->issaved) {
next_stack->original_xor = DuplicateBitmap(nexticon->hxorbitmap);
next_stack->original_and = DuplicateBitmap(nexticon->handbitmap);
} else {
next_stack->original_xor = NULL;
next_stack->original_and = NULL;
}
setBaseImage( nexticon, next_stack );
nexticon = nexticon->nexticon;
prev_stack->nexticon = next_stack;
prev_stack = next_stack;
}
if (lastStack == NULL) {
new_stack->next = NULL;
new_stack->previous = NULL;
firstStack = new_stack;
lastStack = new_stack;
} else {
new_stack->next = NULL;
new_stack->previous = lastStack;
lastStack->next = new_stack;
lastStack = new_stack;
}
} /* CreateUndoStack */
/*
* DeleteUndoStack - We delete an undo stack when we close an image.
*/
void DeleteUndoStack( HWND hwnd )
{
an_undo_stack *stack;
an_undo_stack *previous_stack;
an_undo_stack *next_stack;
an_undo_stack *nexticon_stack;
HCURSOR prevcursor;
int i;
int max_ops;
int percent_complete;
stack = getTopStack( hwnd );
if (!stack) return;
prevcursor = _wpi_setcursor( _wpi_getsyscursor(IDC_WAIT) );
previous_stack = stack->previous;
next_stack = stack->next;
while(stack) {
deleteRedoStack( stack );
max_ops = stack->opcount;
i = 0;
while (stack->top_undo) {
moveFromTop( stack, FALSE );
--(stack->opcount);
percent_complete = (i * 100) / max_ops;
IEPrintAmtText( WIE_CLOSINGIMAGEPERCENT, percent_complete );
++i;
}
_wpi_deletebitmap( stack->firstxor );
_wpi_deletebitmap( stack->firstand );
if (stack->original_xor) {
_wpi_deletebitmap( stack->original_xor );
_wpi_deletebitmap( stack->original_and );
}
nexticon_stack = stack->nexticon;
MemFree( stack );
stack = nexticon_stack;
}
if (previous_stack) {
previous_stack->next = next_stack;
} else {
firstStack = next_stack;
}
if (next_stack) {
next_stack->previous = previous_stack;
} else {
lastStack = previous_stack;
}
_wpi_setcursor( prevcursor );
} /* DeleteUndoStack */
/*
* RedoOp - Undoes an operation.
*/
void RedoOp( void )
{
img_node *node;
an_undo_stack *stack;
node = GetCurrentNode();
if (!node) return;
stack = getStack( node->hwnd );
if (!stack) return;
if (!(stack->top_redo)) {
PrintHintTextByID( WIE_REDOSTACKEMPTY, NULL );
stack->redocount = 0;
return;
}
copyBitmaps( node, stack->top_redo->xorbitmap, stack->top_redo->andbitmap );
moveToUndo( stack );
++(stack->opcount);
--(stack->redocount);
IEPrintAmtText( WIE_REDOITEMSLEFT, stack->redocount );
InvalidateRect( node->viewhwnd, NULL, TRUE );
BlowupImage(node->hwnd, NULL);
if ((stack->original_xor) && (node->issaved)) {
SetIsSaved( node->hwnd, FALSE );
}
} /* RedoOp */
/*
* ResetUndoStack - resets the undo stack when the image size is changed
*/
void ResetUndoStack( img_node *node )
{
an_undo_stack *stack;
stack = getStack( node->hwnd );
deleteRedoStack( stack );
while (stack->top_undo) {
moveFromTop( stack, FALSE );
--(stack->opcount);
}
_wpi_deletebitmap( stack->firstxor );
_wpi_deletebitmap( stack->firstand );
stack->firstxor = DuplicateBitmap(node->hxorbitmap);
stack->firstand = DuplicateBitmap(node->handbitmap);
} /* ResetUndoStack */
/*
* RestoreImage - restores current image (sets to how it was when it was
* opened). Not a valid operation for a new bitmap.
*/
void RestoreImage( void )
{
img_node *node;
an_undo_stack *stack;
node = GetCurrentNode();
if (!node) return;
stack = getStack( node->hwnd );
if (!stack) return;
if (!(stack->original_xor)) {
return;
}
copyBitmaps( node, stack->original_xor, stack->original_and );
PrintHintTextByID( WIE_IMAGERESTORED, NULL );
InvalidateRect( node->viewhwnd, NULL, TRUE );
BlowupImage(node->hwnd, NULL);
RecordImage( node->hwnd );
if ( (node->imgtype == BITMAP_IMG) || (node->imgtype == CURSOR_IMG) ) {
SetIsSaved( node->hwnd, TRUE );
} else {
checkIfSaved( node );
}
} /* RestoreImage */
/*
* AllowRestoreOption - If a file is originally new, then the user saves the
* file, we now allow the user to select the restore
* option if they want.
*/
void AllowRestoreOption( img_node *node )
{
an_undo_stack *stack;
if (!node) return;
stack = getStack( node->hwnd );
if (!stack) return;
if (stack->original_xor) {
_wpi_deletebitmap( stack->original_xor );
_wpi_deletebitmap( stack->original_and );
}
stack->original_xor = DuplicateBitmap( node->hxorbitmap );
stack->original_and = DuplicateBitmap( node->handbitmap );
} /* AllowRestoreOption */
/*
* SelIconUndoStack - selecting a new icon means we must change the undo
* stack. We do this by just setting the current_icon
* field to the given index.
*/
void SelIconUndoStack( HWND hwnd, short index )
{
an_undo_stack *stack;
stack = getTopStack( hwnd );
while ( stack ) {
stack->current_icon = index;
stack = stack->nexticon;
}
} /* SelIconUndoStack */
/*
* AddIconUndoStack - When we add an icon to the current icon image, we also
* have to add an undo stack for that icon. Sets the
* is saved flag to false.
*/
void AddIconUndoStack( img_node *node )
{
an_undo_stack *stack;
an_undo_stack *new_stack;
stack = getTopStack( node->hwnd );
if (!stack) return;
while (stack->nexticon) {
stack = stack->nexticon;
}
new_stack = MemAlloc( sizeof(an_undo_stack) );
new_stack->hwnd = node->hwnd;
new_stack->opcount = 0;
new_stack->redocount = 0;
/*
* I don't change the current icon because select icon is called right
* after this so that will set the new current_icon value.
*/
new_stack->current_icon = 0;
new_stack->top_undo = NULL;
new_stack->bottom_undo = NULL;
new_stack->top_redo = NULL;
new_stack->modified = FALSE;
new_stack->nexticon = NULL;
new_stack->original_xor = NULL;
new_stack->original_and = NULL;
setBaseImage( node, new_stack );
stack->nexticon = new_stack;
/*
* we use the modified field to indicate when the image has FOR SURE
* been modified. Once this is set, the issaved flag cannot be set to
* true. (as in the case when an icon is deleted from the current image)
*/
SetIsSaved( node->hwnd, FALSE );
stack = getTopStack(node->hwnd);
while(stack) {
stack->modified = TRUE;
stack = stack->nexticon;
}
} /* AddIconUndoStack */
/*
* DelIconUndoStack - deletes the undo stack associated with icon image being
* deleted.
*/
void DelIconUndoStack( img_node *node, int index )
{
an_undo_stack *stack;
an_undo_stack *prev_icon;
an_undo_stack *next_icon;
an_undo_stack *prev_stack;
an_undo_stack *next_stack;
int i;
stack = getTopStack( node->hwnd );
if (!stack) return;
prev_stack = stack->previous;
next_stack = stack->next;
prev_icon = NULL;
next_icon = stack->nexticon;
for (i=0; i < index; ++i) {
if (!stack) {
break;
}
prev_icon = stack;
stack = stack->nexticon;
next_icon = stack->nexticon;
}
if (!prev_icon) {
if (prev_stack) {
prev_stack->next = next_icon;
}
if (next_icon) {
next_icon->next = next_stack;
next_icon->previous = prev_stack;
}
} else {
prev_icon->nexticon = next_icon;
}
stack->nexticon = NULL;
stack->previous = NULL;
stack->next = NULL;
deleteRedoStack( stack );
while (stack->top_undo) {
moveFromTop( stack, FALSE );
--(stack->opcount);
}
_wpi_deletebitmap( stack->firstxor );
_wpi_deletebitmap( stack->firstand );
if (stack->original_xor) {
_wpi_deletebitmap( stack->original_xor );
_wpi_deletebitmap( stack->original_and );
}
MemFree( stack );
/*
* we use the modified field to indicate when the image has FOR SURE
* been modified. Once this is set, the issaved flag cannot be set to
* true. (as in the case when an icon is deleted from the current image)
*/
SetIsSaved( node->hwnd, FALSE );
stack = getTopStack(node->hwnd);
while(stack) {
stack->modified = TRUE;
stack = stack->nexticon;
}
} /* DelIconUndoStack */
/*
* RelieveUndos - this routine is called when the main window (ie client
* window) gets the wm_compacting message, indicating that
* memory is getting low. We remove elements from the largest
* undo stack. It's also called when the record image
* routine realizes that memory is getting low.
*/
BOOL RelieveUndos( void )
{
an_undo_stack *stack;
an_undo_stack *iconstack;
an_undo_stack *delstack;
int max_ops = 0;
HCURSOR prevcursor;
int i;
PrintHintTextByID( WIE_DISCARDINGUNDOS, NULL );
prevcursor = _wpi_setcursor( _wpi_getsyscursor(IDC_WAIT) );
stack = firstStack;
while( stack ) {
iconstack = stack;
while (iconstack) {
if (iconstack->opcount > max_ops) {
max_ops = iconstack->opcount;
delstack = iconstack;
}
iconstack = iconstack->nexticon;
}
stack = stack->next;
}
if (max_ops == 0) {
PrintHintTextByID( WIE_NOUNDOSRECORDED, NULL );
_wpi_setcursor( prevcursor );
return( FALSE );
}
if (max_ops > 5) {
for (i=0; i < 5; ++i) {
deleteFromBottom( delstack );
--(delstack->opcount);
}
} else {
deleteFromBottom( delstack );
--(delstack->opcount);
}
_wpi_setcursor( prevcursor );
return( TRUE );
} /* RelieveUndos */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -