⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 undo.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:

/*
 * 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 + -