Sources/MSAESave.c

// MSAESave.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 "MSAESave.h"
 
#include "MSAEUtils.h"
#include "MSWindow.h"       // for DPtrFromWindowPtr()
#include "MSFile.h"         // for DoSave() etcÉ
#include "MSAEWindowUtils.h"
 
 
// -----------------------------------------------------------------------
//  Name:           DoSaveWindow
//  Purpose:        Handles the Save AppleEvent.
// -----------------------------------------------------------------------
 
#pragma segment File
 
pascal OSErr DoSaveWindow(const AppleEvent  *theAppleEvent,
                                AppleEvent  *reply,
                                long        handlerRefCon)
{ 
#ifdef __MWERKS__
    #pragma unused (reply, handlerRefCon)
#endif
 
    AEDesc          directObj = {typeNull, NULL};
    Size            actualSize;
    DescType        returnedType;
    FSSpec          destFSSpec;
    
    WindowToken     aWindowToken;
    OSErr           err;
    
        // pick up the direct object
    err = AEGetParamDesc( theAppleEvent, keyDirectObject, typeWildCard, &directObj );
                                                 
        // pick up optional destination param, if any
    if ( noErr != AEGetParamPtr( theAppleEvent, keyAEFile, typeFSS, &returnedType,
                                        (Ptr)&destFSSpec, sizeof( destFSSpec ), &actualSize ) )
    {
        destFSSpec.vRefNum = 0;
        destFSSpec.parID = 0;
    }
 
    err = GotRequiredParams( theAppleEvent );
    if (noErr != err) goto done;
    
    if ( typeNull != directObj.descriptorType )
        err = SaveDesc( &directObj, &destFSSpec );
    else if ( GetNthDocument( 1 ) )
    {
        aWindowToken.tokenWindow = GetNthDocument( 1 );
    
        err = SaveDocumentToken( &aWindowToken, &destFSSpec );
    }
    else
        err = errAENoSuchObject;
  
done:
    (void)AEDisposeDesc( &directObj );
            
    return err;
}   // DoSaveWindow
 
 
OSErr   SaveDocumentToken(WindowToken* theToken, FSSpec* destFSSpec)
{
    DPtr            docPtr;
    OSErr           err;
    
    docPtr = DPtrFromWindowPtr(theToken->tokenWindow);
    
    if (! docPtr)
        return errAEWrongDataType;
 
    if (docPtr->everSaved == false && ! destFSSpec->vRefNum && ! destFSSpec->parID) 
        return(kAEGenericErr);      // Never been saved and no destination to save
    
    if (destFSSpec->vRefNum || destFSSpec->parID)   // We were given a destination
        err = DoSave(docPtr, *destFSSpec);
    else
        err = SaveUsingTemp(docPtr);
 
    return(err);
}
 
 
OSErr   SaveDocumentDesc(AEDesc* windowDesc, FSSpec* destFSSpec)
{
    WindowToken     aWindowToken;
    Size            actualSize;
    OSErr           err;
 
    if (typeMyDocument != windowDesc->descriptorType)
        return(errAETypeError);
        
    GetRawDataFromDescriptor(windowDesc, (Ptr)&aWindowToken, sizeof(aWindowToken), &actualSize);
 
    err = SaveDocumentToken(&aWindowToken, destFSSpec);
    
    return(err);
}
 
 
OSErr   SaveDesc(AEDesc* aDesc, FSSpec* destFSSpec)
{
    AEDesc      saveDesc = {typeNull, NULL},
                windowDesc = {typeNull, NULL},
                itemDesc = {typeNull, NULL};
    long        itemCount,
                index;
    DescType    theAEKeyword;
    OSErr       err;
    
    if (typeObjectSpecifier == aDesc->descriptorType)
        err = AEResolve(aDesc, kAEIDoMinimum, &saveDesc);
    else if (typeNull != aDesc->descriptorType)
        err = AEDuplicateDesc(aDesc, &saveDesc);
        
    if (noErr != err) goto done;
    
    switch (saveDesc.descriptorType)
    {
        case typeAEList:
            err = AECountItems(&saveDesc, &itemCount);
            if (noErr != err) goto done;
            
            for (index = 1; index <= itemCount; index++)    // Do front back order
            {
                err = AEGetNthDesc(&saveDesc, index, typeWildCard, &theAEKeyword, &itemDesc);
                if (noErr != err) goto done;
                
                err = SaveDesc(&itemDesc, destFSSpec);      // Call recursively
                if (noErr != err) goto done;
 
                if (itemDesc.dataHandle)
                    AEDisposeDesc(&itemDesc);
            }
            break;
            
        default:
            err = AECoerceDesc(&saveDesc, typeMyDocument, &windowDesc);
            if (noErr != err) goto done;
            err = SaveDocumentDesc(&windowDesc, destFSSpec);
    }
    
done:
    (void)AEDisposeDesc(&saveDesc);
    (void)AEDisposeDesc(&windowDesc);
    (void)AEDisposeDesc(&itemDesc);
    
    return(err);
}