Sources/MSAERevert.c

// MSAERevert.c
//
// Original version by Jon Lansdell and Nigel Humphreys.
// 4.0 and 3.1 updates by Greg Sutton.
// ©Apple Computer Inc 1996, all rights reserved.
 
#include "MSAERevert.h"
 
#include "MSWindow.h"       // for DPtrFromWindowPtr()
#include "MSFile.h"
 
#include "MSAEUtils.h"
#include "MSAETextUtils.h"
#include "MSAccessors.h"
#include "MSAEDelete.h"
#include "MSAEWindowUtils.h"
 
#pragma segment File
 
 
// -----------------------------------------------------------------------
//  Name:       DoRevert
//  Purpose:    Handles the Revert AppleEvent.
// -----------------------------------------------------------------------
 
pascal OSErr DoRevert(const AppleEvent  *theAppleEvent,
                            AppleEvent  *reply,
                            long        handlerRefCon)
{ 
#ifdef __MWERKS__
    #pragma unused (reply, handlerRefCon)
#endif
 
    AEDesc          directObj = {typeNull, NULL};
    WindowToken     aWindowToken;
    OSErr           err;
    
        // pick up the direct object
    err = AEGetParamDesc(theAppleEvent,  keyDirectObject, typeWildCard, &directObj);
    
    err = GotRequiredParams(theAppleEvent);
    if (noErr != err) goto done;
    
    if (typeNull != directObj.descriptorType)
        err = RevertDesc(&directObj);
    else if ( GetNthDocument( 1 ) )             // If no direct object given, default
    {                                           // to the front document.
        aWindowToken.tokenWindow = GetNthDocument( 1 );
        err = RevertDocumentToken( &aWindowToken );
    }
    else
        err = errAENoSuchObject;
        
done:
    (void)AEDisposeDesc(&directObj);
        
    return(err);
} // DoRevertWindow
 
 
OSErr    RevertDocumentToken(WindowToken* theToken)
{
    DPtr            docPtr;
    TextToken       aTextToken;
    OSErr           err;
    
    docPtr = DPtrFromWindowPtr(theToken->tokenWindow);
    
    if (! docPtr)
        return errAEWrongDataType;
 
                        // Get a token for all the text in the window
    err = TextTokenFromDocumentToken(theToken, &aTextToken);
    if (noErr != err) goto done;
                        // Delete all the text
    err = DeleteTextToken(&aTextToken);
    if (noErr != err) goto done;
 
    if (docPtr->everSaved) 
    {
        err = GetFileContents(docPtr->theFSSpec, docPtr);
        if (noErr != err) goto done;
 
        ResizeWindow(docPtr);
        docPtr->dirty = false;
    }
 
    DoUpdate(docPtr->theWindow);
 
done:
    return(err);
}
 
 
OSErr   RevertDocumentDesc(AEDesc* windowDesc)
{
    WindowToken     aWindowToken;
    Size            actualSize;
    OSErr           err;
 
    if (typeMyDocument != windowDesc->descriptorType)
        return(errAETypeError);
        
    GetRawDataFromDescriptor(windowDesc, (Ptr)&aWindowToken, sizeof(aWindowToken), &actualSize);
 
    err = RevertDocumentToken(&aWindowToken);
    
    return(err);
}
 
 
OSErr   RevertDesc(AEDesc* aDesc)
{
    AEDesc      revertDesc = { typeNull, NULL },
                windowDesc = { typeNull, NULL },
                itemDesc = { typeNull, NULL };
    long        itemCount,
                index;
    DescType    theAEKeyword;
    OSErr       err;
    
    if ( typeObjectSpecifier == aDesc->descriptorType )
        err = AEResolve( aDesc, kAEIDoMinimum, &revertDesc );
    else if ( typeNull != aDesc->descriptorType )
        err = AEDuplicateDesc( aDesc, &revertDesc );
        
    if ( noErr != err ) goto done;
    
    switch ( revertDesc.descriptorType )
    {
        case typeAEList:
            err = AECountItems( &revertDesc, &itemCount );
            if ( noErr != err ) goto done;
            
            for ( index = 1; index <= itemCount; index++ )  // Do front back order
            {
                err = AEGetNthDesc( &revertDesc, index, typeWildCard,
                                                &theAEKeyword, &itemDesc );
                if ( noErr != err ) goto done;
                
                err = RevertDesc( &itemDesc );  // Call recursively
                if (noErr != err) goto done;
 
                (void)AEDisposeDesc( &itemDesc );
            }
            break;
            
        default:
            err = AECoerceDesc( &revertDesc, typeMyDocument, &windowDesc );
            if ( noErr != err ) goto done;
            err = RevertDocumentDesc( &windowDesc );
    }
    
done:
    (void)AEDisposeDesc( &revertDesc );
    (void)AEDisposeDesc( &windowDesc );
    (void)AEDisposeDesc( &itemDesc );
    
    return err;
}