CustomPutAppend.c

/*
    File:       CustomPutAppend.c
 
    Contains:   This demonstrates a CustomPutDialog with an Append button that
                does not ask the user if he/she wants to replace the existing file.
                the sample code in InsideMac:Files, and the Human Interface Guidelines              It also has Baloon Help strings for the Append button
 
    Written by: David Hayward   
 
    Copyright:  Copyright © 1993-1999 by Apple Computer, Inc., All Rights Reserved.
 
                You may incorporate this Apple sample source code into your program(s) without
                restriction. This Apple sample source code has been provided "AS IS" and the
                responsibility for its operation is yours. You are not permitted to redistribute
                this Apple sample source code as "Apple sample source code" after having made
                changes. If you're going to re-distribute the source, we require that you make
                it clear in the source that the code was descended from Apple sample source
                code, but that you've made changes.
 
    Change History (most recent first):
                7/1/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                5/12/95                     updated project for Metrowerks
                2/3/93                      first draft
                
 
*/
 
 
#include <QuickDraw.h>
#include <Memory.h>
#include <Fonts.h>
#include <StandardFile.h>
#include <Files.h>
#include <Dialogs.h>
#include <TextUtils.h>
 
#include "InitMac.h"
 
 
/**\
|**| ==============================================================================
|**| DEFINES
|**| ==============================================================================
\**/
#define ReplyDialogID           128
#define ReplyDialogQuitItem     1
#define ReplyDialogAgainItem    2
 
#define CustomPutAppendDialogID 129
#define sfItemAppendButton      13
 
 
/**\
|**| ==============================================================================
|**| FUNCTION PROTOTYPES
|**| ==============================================================================
\**/
short           MyAlert     ( StandardFileReply *reply ) ;
pascal short    MyDlgHook   ( short item, DialogPtr theDialog, void *myDataPtr ) ;
 
                            
/**\
|**| ==============================================================================
|**| FUNCTIONS
|**| ==============================================================================
\**/
 
/*------------------------------------------------------------------------------*\
    MyDlgHook()
 *------------------------------------------------------------------------------*
        the dialog hook procedure responsible for activating and  
        dimming the Append control and supressing the "Replace Existing?" 
        dialog if the Append button is hit
\*------------------------------------------------------------------------------*/
pascal short MyDlgHook ( short item, DialogPtr theDialog, void *myDataPtr )
{
    static short        lastItem = 0;           /* remember lastItem so that we dont update    */
                                                /*  Append button on consecutive NullEvents    */
    static short        which;                  /* remember if Save or Append was hit so we    */
                                                /*  can dismiss the "Replace" dialog if needed */
    short               returnItem = item;      /* default returnItem is item */
    long                refCon;
    short               iType;
    Handle              iHandle;
    Rect                iRect;
    FInfo               fndrInfo;
    OSErr               err;
    StandardFileReply   *sfr;
 
    refCon = GetWRefCon((WindowPtr)theDialog);  /* get the refCon of the current dialog */
 
    if (refCon == sfReplaceDialogRefCon)            /* if its the "Replace Existing?" dialog */
        if (item == sfHookFirstCall)                /* and the dialog is just about to appear */
            if (which == sfItemAppendButton)        /* and user last hit the append button */
                returnItem = 1;                     /* then hit the Replace button automatically */
 
    if (refCon == sfMainDialogRefCon)               /* if its the "Save AsÉ" dialog */
    {
 
        sfr = (StandardFileReply*)myDataPtr;        /* coerce myDataPtr to StandardFileReply */
            
        /* update Append button state... */
        if ( (item == sfHookFirstCall) ||           /* if the dialog is just about to appear */
             ( (item == sfHookNullEvent) &&         /* or if we just got a NullEvent */
               (lastItem != sfHookNullEvent)))
        {
            GetDialogItem(theDialog,                        /* get the handle for the Append button */
                     sfItemAppendButton,
                     &iType, &iHandle, &iRect);
            
            /* GetFInfo with the current filespec to see it it exists */
            err = FSpGetFInfo(&(sfr->sfFile), &fndrInfo);
            
            if ((err)   ||                          /* if file doesn't exist or */
                (fndrInfo.fdType != 'TEXT'))        /* isn't 'TEXT', then dim Append */
                HiliteControl((ControlHandle)iHandle, 255);
            else                                    /* otherwise, activate Append Button */
                HiliteControl((ControlHandle)iHandle, 0);
        }
 
 
        if (item==sfItemOpenButton)                 /* if user hit Save button */
            which = sfItemOpenButton;               /* then remember this is what was hit */
 
        if (item==sfItemAppendButton)               /* if user hit Append button */
        {
            which = sfItemAppendButton;             /* then remember this is what was hit */
            sfr->sfReplacing |= 2;                  /* set 2nd bit so we we know it was append */
            returnItem = sfItemOpenButton;          /* but perform a Save instead */
        }
    }
    
    lastItem = item;                                /* save lastItem */
    return returnItem;
}
 
 
/*------------------------------------------------------------------------------*\
    MyAlert()
 *------------------------------------------------------------------------------*
        output vital stats of the StandardFileReply to an Alert box
\*------------------------------------------------------------------------------*/
short MyAlert ( StandardFileReply *reply )
{
    Str255  goodStr, replStr;
 
    NumToString( (long)reply->sfGood, goodStr); 
    NumToString( (long)reply->sfReplacing, replStr); 
    ParamText(goodStr, replStr, reply->sfFile.name, nil);
    return NoteAlert( ReplyDialogID, nil );
}
 
 
/*------------------------------------------------------------------------------*\
    main()
 *------------------------------------------------------------------------------*
        initialize mamagers and the keep doing 
        CustomPutFile until the user has had enough
\*------------------------------------------------------------------------------*/
void main ( void )
{
    StandardFileReply   reply;
    Point               where = {-1,-1};            /* center dialog on main screen */
    
    InitToolBox(1) ;
    
    do
    {
        CustomPutFile(  "\pSave file as:",          /* the prompt string */
                        "\pUntitled",               /* the default filename */
                        &reply,                     /* the StandardFileReply structure */
                        CustomPutAppendDialogID,    /* the dialog's ID */
                        where,                      /* position of dialog on screen */
                        NewDlgHookYDProc(MyDlgHook),    /* the Dialog Hook procedure */
                        nil,                        /* no modal dialog filterProc */
                        nil,                        /* no activeListPtr */
                        nil,                        /* no activateProc */
                        &reply                      /* yourDataPtr: pass reply in so that */
                      );                            /* MyDlgHook() can access current FSSpec */
    }                                                           
    while (MyAlert(&reply)==ReplyDialogAgainItem);  /* repeat until user has had enough */
}