Source/MyPDEF_4_HandlingDialogs.c

/*
** Copyright 1991-1996 Apple Computer. All rights reserved.
**
**  You may incorporate this sample code into your applications without
**  restriction, though the sample code has been provided "AS IS" and the
**  responsibility for its operation is 100% yours.  However, what you are
**  not permitted to do is to redistribute the source as "DSC Sample 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 Code, but that you've made changes.
*/
 
#include <QuickDraw.h>
#include <Dialogs.h>
#include <Printing.h>
#include <Resources.h>
#include <Errors.h>
#include <Memory.h>
#include <TextUtils.h>
#include <OSUtils.h>
 
#include "DriverTypes.h"
 
pascal void HandleStyleItems(TPPrDlg theDlg, short ItemHit);
pascal void HandleJobItems(TPPrDlg theDlg, short ItemHit);
pascal void FilePrintDefault(THPrint hPrint);
pascal Boolean FilePrStlDialog(THPrint hPrint);
pascal Boolean FilePrJobDialog(THPrint hPrint);
pascal TPPrDlg FilePrStlInit(THPrint hPrint);
pascal TPPrDlg FilePrJobInit(THPrint hPrint);
pascal Boolean FilePrDlgMain(THPrint hPrint, PDlgInitProcPtr initFunc);
pascal Boolean FilePrValidate(THPrint hPrint);
pascal void FilePrJobMerge(THPrint hPrintSrc, THPrint hPrintDst);
 
#if defined(__MWERKS__)
asm void __Startup__ (void);
asm void __Startup__ (void)
{
    JMP FilePrintDefault
    JMP FilePrStlDialog
    JMP FilePrJobDialog
    JMP FilePrStlInit
    JMP FilePrJobInit
    JMP FilePrDlgMain
    JMP FilePrValidate
    JMP FilePrJobMerge
}
#endif
 
void SetDialogControlValue(DialogPtr theDialog, short theItem, short theValue)
{
    short theType;
    Handle theHandle;
    Rect theRect;
 
    GetDialogItem(theDialog, theItem, &theType, &theHandle, &theRect);
    if (!theHandle) return;
    SetCtlValue((ControlHandle)theHandle, theValue);
}
 
short GetDialogControlValue(DialogPtr theDialog, short theItem)
{
    short theType;
    Handle theHandle;
    Rect theRect;
 
    GetDialogItem(theDialog, theItem, &theType, &theHandle, &theRect);
    if (!theHandle) return -1;
    return GetCtlValue((ControlHandle)theHandle);
}
 
void SetDialogItemString(DialogPtr theDialog, short theItem, StringPtr theString)
{
    short theType;
    Handle theHandle;
    Rect theRect;
 
    GetDialogItem(theDialog, theItem, &theType, &theHandle, &theRect);
    if (!theHandle) return;
    SetIText(theHandle, theString);
}
 
void GetDialogItemString(DialogPtr theDialog, short theItem, StringPtr theString)
{
    short theType;
    Handle theHandle;
    Rect theRect;
 
    GetDialogItem(theDialog, theItem, &theType, &theHandle, &theRect);
    if (!theHandle) return;
    GetIText(theHandle, theString);
}
 
void SetDialogItemNumber(DialogPtr theDialog, short theItem, long theValue)
{
    short theType;
    Handle theHandle;
    Rect theRect;
    Str255 theStr;
 
    GetDialogItem(theDialog, theItem, &theType, &theHandle, &theRect);
    if (!theHandle) return;
    NumToString(theValue, theStr);
    SetIText(theHandle, theStr);
}
 
long GetDialogItemNumber(DialogPtr theDialog, short theItem)
{
    Str255 theStr;
    long theValue;
 
    GetDialogItemString(theDialog, theItem, theStr);
    StringToNum(theStr, &theValue);
    return theValue;
}
 
Rect GetDialogItemRect(DialogPtr theDialog, short theItem)
{
    short theType;
    Handle theHandle;
    Rect theRect;
 
    GetDialogItem(theDialog, theItem, &theType, &theHandle, &theRect);
    return theRect;
}
 
void SelectDialogItemString(DialogPtr theDialog, short theItem)
{
    SelIText(theDialog, theItem, startSelectAll, endSelectAll);
}
 
void InvertDialogItem(DialogPtr theDialog, short theItem)
{
    Rect    theRect;
 
    theRect = GetDialogItemRect(theDialog, theItem);
    InvertRect(&theRect);
}
 
void DialogPosition(DialogPtr theDialog)
{
#pragma unused(theDialog)
    /* this is a no-op here, since we're specifying the swell
    ** system 7 dialog positioning in the DLOG resources. If
    ** you want to support System 6, or have a position other
    ** than "Alert position, main screen", you'll need to flesh
    ** out this function.
    */
}
 
Handle ReallyGetResource(ResType theType, short resID)
{
    Handle  theRes = GetResource(theType,resID);
    if(!theRes) return 0;
    LoadResource(theRes);
    return theRes;
}
 
void FrameDialogItem(DialogPtr theDialog, short theItem)
{
    GrafPtr oldPort;
    Rect    itsBox = GetDialogItemRect((DialogPtr)theDialog, theItem);
 
    GetPort(&oldPort);
    SetPort((GrafPtr)theDialog);
    PenSize(3, 3);
    InsetRect(&itsBox, -4, -4);
    {
        short   radius = (itsBox.top - itsBox.bottom) / 2;
        if (radius < 16) radius = 16;
        FrameRoundRect(&itsBox, radius, radius);
    }
    SetPort(oldPort);
}
 
pascal void FilePrintDefault(THPrint hPrint)
{
    // the default in is the resource PREC 0, and we also initialize some important fields 
    THPrint theDefault;
 
    theDefault = (THPrint)ReallyGetResource('PREC', 0);
    if (theDefault == NULL) {
        setPrintErr(resNotFound);
        return;
    }
    **hPrint = **theDefault;
 
    if (StripAddress((Ptr)*hPrint) != StripAddress((Ptr)*theDefault)) 
        ReleaseResource((Handle)theDefault);
}
 
pascal Boolean FilterNumPrStlAndJob(DialogPtr theDialog, EventRecord *theEvent, short *ItemHit)
{
#pragma unused(theDialog)
    if ((theEvent->what == keyDown) || (theEvent->what == autoKey)) {
        char    theChar;
        theChar = theEvent->message & charCodeMask;
        if ((theChar == enterKey) || (theChar == returnKey)) {
            *ItemHit = printOkButton;
            return true;
        } else if ((theChar!=backspaceKey)&&(theChar!=tabKey)&&(!isdigit(theChar))) {
            SysBeep(1);
            *ItemHit = printInvalidItem;
            return true;
        }
    }
    return false;
}
 
void StlHideCustomSizeItems(DialogPtr theDialog)
{
    short item;
 
    if (!theDialog) return;
 
    for(item = stlHorizTitleID; item <= stlPixelsButtonID; item++) 
        HideDItem(theDialog, item);
}
 
void StlShowCustomSizeItems(DialogPtr theDialog)
{
    short item;
    
    if (!theDialog) return;
 
    for (item = stlHorizTitleID; item <= stlPixelsButtonID; item++) 
        ShowDItem(theDialog, item);
}
 
pascal Boolean FilePrValidate(THPrint hPrint)
{
    // if the signature mySignature is present in the hPrint, then I
    // consider that the values are ok else we just load anew the
    // resource PREC 0
    // this would be a bit more robust in a real driver
 
    THPrint theDefault;
    Boolean changedIt = false;
 
    theDefault = (THPrint)ReallyGetResource('PREC', 0);
    if (theDefault == NULL) {
        DebugStr("\pCouldn't find the PREC 0 resource. That doesn't seem good.");
        setPrintErr(resNotFound);
        return false;
    }
    
    if ((**hPrint).printX[7] != mySignature) {
        **hPrint = **theDefault;
        changedIt = true;
    }
 
    ReleaseResource((Handle)theDefault);
    
    (**hPrint).prJob.iCopies = 1;
    (**hPrint).prJob.pIdleProc = NULL;
    (**hPrint).prJob.pFileName = NULL;
    (**hPrint).prJob.iFileVol = 0;
    (**hPrint).prJob.bFileVers = 0;
    
    return changedIt;
}
 
pascal TPPrDlg FilePrStlInit(THPrint hPrint)
{
    // we initialize the dialog items with the right settings coming from hPrint 
    TPPrDlg theDlg;
    DialogPtr aDlg;
    THPrint theDefault;
 
    theDefault = (THPrint)ReallyGetResource('PREC', 1);
    if (theDefault != NULL) 
        **hPrint = **theDefault;
 
    theDlg = (TPPrDlg)NewPtr(sizeof(TPrDlg));
    if (theDlg == NULL) {
        setPrintErr(iMemFullErr);
        return 0;
    }
    
    theDlg->pFltrProc = NewModalFilterProc(FilterNumPrStlAndJob);
    theDlg->pItemProc = NewPItemProc(HandleStyleItems);
    theDlg->fDoIt = false;
    theDlg->fDone = false;
    theDlg->hPrintUsr = hPrint;
 
    aDlg = GetNewDialog(printDialogID, theDlg, (WindowPtr)-1L);
    if (aDlg == NULL) {
        setPrintErr(resNotFound);
        DisposePtr((Ptr)theDlg);
        return 0;
    }
    DialogPosition(aDlg);
 
    switch((**hPrint).printX[0]) {
        default:
            DebugStr("\pBad value for paper size");
            (**hPrint).printX[0] = printOnA4;
            // fall through
        case printOnA4:
            SetDialogControlValue(aDlg, stlPaperA4SizeButtonID, 1);
            SetDialogControlValue(aDlg, stlPaperLetterSizeButtonID, 0);
            SetDialogControlValue(aDlg, stlPaperCustomSizeButtonID, 0);
            StlHideCustomSizeItems(aDlg);
            break;
        case printOnLetter:
            SetDialogControlValue(aDlg, stlPaperA4SizeButtonID, 0);
            SetDialogControlValue(aDlg, stlPaperLetterSizeButtonID, 1);
            SetDialogControlValue(aDlg, stlPaperCustomSizeButtonID, 0);
            StlHideCustomSizeItems(aDlg);
            break;
        case printOnCustom:
            SetDialogControlValue(aDlg, stlPaperA4SizeButtonID, 0);
            SetDialogControlValue(aDlg, stlPaperLetterSizeButtonID, 0);
            SetDialogControlValue(aDlg, stlPaperCustomSizeButtonID, 1);
            StlShowCustomSizeItems(aDlg);
            break;
    }
 
    SetDialogItemNumber(aDlg, stlHorizTextID, (**hPrint).printX[2]);
    SetDialogItemNumber(aDlg, stlVertTextID, (**hPrint).printX[3]);
    switch((**hPrint).printX[4]) {
        default:
            DebugStr("\pBad value for units...repairing...");
            (**hPrint).printX[4] = unitsMilliInch;
            // fall through
        case unitsMilliInch:
            SetDialogControlValue(aDlg, stlMilliInchButtonID, 1);
            SetDialogControlValue(aDlg, stlMilliMeterButtonID, 0);
            SetDialogControlValue(aDlg, stlPixelsButtonID, 0);
            break;
        case unitsMilliMeter:
            SetDialogControlValue(aDlg, stlMilliInchButtonID, 0);
            SetDialogControlValue(aDlg, stlMilliMeterButtonID, 1);
            SetDialogControlValue(aDlg, stlPixelsButtonID, 0);
            break;
        case unitsPixels:
            SetDialogControlValue(aDlg, stlMilliInchButtonID, 0);
            SetDialogControlValue(aDlg, stlMilliMeterButtonID, 0);
            SetDialogControlValue(aDlg, stlPixelsButtonID, 1);
            break;
    }
    ShowWindow(aDlg);
    DrawDialog(aDlg);
    SetPort(aDlg);
    theDlg->lUser1 = (**hPrint).printX[5];
    if ((**hPrint).printX[5])
        InvertDialogItem(aDlg,stlLandscapeIconID);
    else
        InvertDialogItem(aDlg,stlPortraitIconID);
    ValidRect(&(aDlg->portRect));
    return theDlg;
}
 
// redraw the frame around the ok button, and pay attention to the orientation icons 
void RefreshDialog(TPPrDlg thePrDlg)
{
 
    DrawDialog((DialogPtr)thePrDlg);
    FrameDialogItem((DialogPtr)thePrDlg,printOkButton);
 
    if (thePrDlg->lUser1)
        InvertDialogItem((DialogPtr)thePrDlg,stlLandscapeIconID);
    else
        InvertDialogItem((DialogPtr)thePrDlg,stlPortraitIconID);
    ValidRect(&(((GrafPtr)thePrDlg)->portRect));
}
 
void HandleStlHelp(void) {
    short       item;
    DialogPtr   helpDlg = GetNewDialog(helpDialogID, NULL, (WindowPtr)-1);
 
    if (!helpDlg) {
        SysBeep(1);
        return;
    }
 
    for(item = 6; item <= 11; item++) 
        HideDItem(helpDlg, item);
 
    ShowWindow(helpDlg);
    DrawDialog(helpDlg);
    SetPort((GrafPtr)helpDlg);
    ValidRect(&(helpDlg->portRect));
 
    TextFont(1);
    TextSize(9);
 
    for(item = 6; item <= 11; item++) 
        ShowDItem(helpDlg, item);
 
    FrameDialogItem(helpDlg,1);
    
    while(item!=printOkButton)
        ModalDialog(NULL, &item);
 
    DisposeDialog(helpDlg);
}
 
// the paper sizes in the following routines come from the LaserWriter ppd
// I've used the full-paper size as the size for the PICT. You'll probably
// want to use something like the imageable area, but by making them this
// size, it'll get you to look here to fix up the sizes. All the sizes
// could be stored in resources (use the 'pgsz' maybe) as well, but this is
// a simple sample.
static void SetPaperA4(long *height, long *width, Boolean isLandscape)
{
    const short a4PaperWidth = 595;
    const short a4PaperHeight = 842;
 
    if (!isLandscape) {
        *width = a4PaperWidth;
        *height = a4PaperHeight;
    } else {
        *width = a4PaperHeight;
        *height = a4PaperWidth;
    }
}
 
static void SetPaperLetter(long *height, long *width, Boolean isLandscape)
{
    const short letterPaperWidth = 612;
    const short letterPaperHeight = 792;
 
    if (!isLandscape) {
        *width = letterPaperWidth;
        *height = letterPaperHeight;
    } else {
        *width = letterPaperHeight;
        *height = letterPaperWidth;
    }
}
 
static void SetPaperLegal(long *height, long *width, Boolean isLandscape)
{
    const short legalPaperWidth = 612;
    const short legalPaperHeight = 1008;
 
    if (!isLandscape) {
        *width = legalPaperWidth;
        *height = legalPaperHeight;
    } else {
        *width = legalPaperHeight;
        *height = legalPaperWidth;
    }
}
 
static void SetPaperCustom(long *height, long *width, Boolean isLandscape,
    short units, long rawHeight, long rawWidth)
{
    float   scaleFactor;
    long    scaleWidth,scaleHeight;
 
    switch (units) {
        case unitsMilliInch:    scaleFactor = 0.072;        break;
        case unitsMilliMeter:   scaleFactor = 720.0/254;    break;
        case unitsPixels:       scaleFactor = 1.0;          break;
        default:                scaleFactor = 1.0;          break;  // have to set it to SOMETHING
    }
    
    scaleWidth = rawWidth * scaleFactor;
    scaleHeight = rawHeight * scaleFactor;
 
    if (!isLandscape) {
        *width = rawWidth;
        *height = rawHeight;
    } else {
        *width = rawHeight;
        *height = rawWidth;
    }
}
 
static Boolean SetPaperSize(THPrint hPrintUsr)
{
    long    height=0,width=0;
 
    switch((**hPrintUsr).printX[0]) {
        case printOnA4:
            SetPaperA4(&height,&width,(**hPrintUsr).printX[5]);
            break;
        case printOnLetter:
            SetPaperLetter(&height,&width,(**hPrintUsr).printX[5]);
            break;
        case printOnCustom:
            SetPaperCustom(&height,&width,(**hPrintUsr).printX[5],
                (**hPrintUsr).printX[4],(**hPrintUsr).printX[3],(**hPrintUsr).printX[2]);
            break;
        case printOnLegal:
            SetPaperLegal(&height,&width,(**hPrintUsr).printX[5]);
            break;
        default:
            return false;
            break;
    }
    
    SetRect(&((**hPrintUsr).rPaper), 0, 0, width, height);
    (**hPrintUsr).prInfo.rPage = (**hPrintUsr).rPaper;
    (**hPrintUsr).prInfoPT.rPage = (**hPrintUsr).rPaper;
    (**hPrintUsr).prStl.iPageV = (height * iPrPgFract) / 72;
    (**hPrintUsr).prStl.iPageH = (width * iPrPgFract) / 72;
    return true;
}
 
pascal void HandleStyleItems(TPPrDlg thePrDlg, short ItemHit)
{
    THPrint hPrintUsr = thePrDlg->hPrintUsr;
    DialogPtr   theDialog = (DialogPtr)(thePrDlg);
 
    switch (ItemHit) { 
        case printOkButton:
            if (GetDialogControlValue(theDialog, stlPaperA4SizeButtonID) == 1) {
                (**hPrintUsr).printX[0] = printOnA4;
                (**hPrintUsr).printX[2] = 0;
                (**hPrintUsr).printX[3] = 0;
                (**hPrintUsr).printX[4] = unitsUndefined;
            } else if (GetDialogControlValue(theDialog, stlPaperLetterSizeButtonID) == 1) {
                (**hPrintUsr).printX[0] = printOnLetter;
                (**hPrintUsr).printX[2] = 0;
                (**hPrintUsr).printX[3] = 0;
                (**hPrintUsr).printX[4] = unitsUndefined;
            } else if (GetDialogControlValue(theDialog, stlPaperCustomSizeButtonID) == 1) {
                (**hPrintUsr).printX[0] = printOnCustom;
                if (GetDialogControlValue(theDialog, stlMilliInchButtonID) == 1)
                    (**hPrintUsr).printX[4] = unitsMilliInch;
                if (GetDialogControlValue(theDialog, stlMilliMeterButtonID) == 1)
                    (**hPrintUsr).printX[4] = unitsMilliMeter;
                if (GetDialogControlValue(theDialog, stlPixelsButtonID) == 1)
                    (**hPrintUsr).printX[4] = unitsPixels;
    
                (**hPrintUsr).printX[2] = GetDialogItemNumber(theDialog, stlHorizTextID);
                (**hPrintUsr).printX[3] = GetDialogItemNumber(theDialog, stlVertTextID);
            } else {
                (**hPrintUsr).printX[0] = printOnUndefined;
                (**hPrintUsr).printX[2] = 0;
                (**hPrintUsr).printX[3] = 0;
                (**hPrintUsr).printX[4] = unitsUndefined;
            }
 
            (**hPrintUsr).printX[5] = (thePrDlg->lUser1 != 0);
 
            if (SetPaperSize(hPrintUsr)) {
                thePrDlg->fDone = true;
                thePrDlg->fDoIt = true;
            } else {
                NoteAlert(badValueAlertID,nil);
            }
            break;
        case printCancelButton:
            thePrDlg->fDone = true;
            thePrDlg->fDoIt = false;
            break;
        case stlPaperA4SizeButtonID:
            if (GetDialogControlValue(theDialog, ItemHit) == 0) {
                if (GetDialogControlValue(theDialog, stlPaperCustomSizeButtonID)) 
                    StlHideCustomSizeItems(theDialog);
                SetDialogControlValue(theDialog, stlPaperCustomSizeButtonID, 0);
                SetDialogControlValue(theDialog, stlPaperLetterSizeButtonID, 0);
                SetDialogControlValue(theDialog, stlPaperA4SizeButtonID, 1);
            }
            break;
        case stlPaperLetterSizeButtonID:
            if (GetDialogControlValue(theDialog, ItemHit) == 0) {
                if (GetDialogControlValue(theDialog, stlPaperCustomSizeButtonID)) 
                    StlHideCustomSizeItems(theDialog);
                SetDialogControlValue(theDialog, stlPaperCustomSizeButtonID, 0);
                SetDialogControlValue(theDialog, stlPaperLetterSizeButtonID, 1);
                SetDialogControlValue(theDialog, stlPaperA4SizeButtonID, 0);
            }
            break;
        case stlPaperCustomSizeButtonID:
            if (GetDialogControlValue(theDialog, ItemHit) == 0) {
                StlShowCustomSizeItems(theDialog);
                SetDialogControlValue(theDialog, stlPaperCustomSizeButtonID, 1);
                SetDialogControlValue(theDialog, stlPaperLetterSizeButtonID, 0);
                SetDialogControlValue(theDialog, stlPaperA4SizeButtonID, 0);
            }
            break;
        case stlPortraitIconID:
            if (thePrDlg->lUser1) {
                InvertDialogItem(theDialog, stlPortraitIconID);
                InvertDialogItem(theDialog, stlLandscapeIconID);
                thePrDlg->lUser1 = false;
            }
            break;
        case stlLandscapeIconID:
            if (!thePrDlg->lUser1) {
                InvertDialogItem(theDialog, stlPortraitIconID);
                InvertDialogItem(theDialog, stlLandscapeIconID);
                thePrDlg->lUser1 = true;
            }
        case stlMilliInchButtonID:
        case stlMilliMeterButtonID: 
        case stlPixelsButtonID: 
            if (GetDialogControlValue(theDialog, ItemHit) == 0) {
                SetDialogControlValue(theDialog, stlMilliInchButtonID, 0);
                SetDialogControlValue(theDialog, stlMilliMeterButtonID, 0);
                SetDialogControlValue(theDialog, stlPixelsButtonID, 0);
                SetDialogControlValue(theDialog, ItemHit, 1);
            }
            break;
        case stlHelpButtonID:
            HandleStlHelp();
            SetPort((GrafPtr)thePrDlg);
            RefreshDialog(thePrDlg);
            break;
    }
}
 
Boolean FilePrDlgStl(THPrint hPrint)
{
    TPPrDlg thePrDlg;
    GrafPtr SavePort;
    short itemHit;
    THPrint theDefault;
    Boolean doit = false;
 
    thePrDlg = FilePrStlInit(hPrint);
    if (!thePrDlg) {
        SysBeep(1);
        return(false);
    }
 
    GetPort(&SavePort);
    FrameDialogItem((DialogPtr)thePrDlg, 1);
    while (!(thePrDlg->fDone)) {
        ModalDialog(thePrDlg->pFltrProc, &itemHit);
        CallPItemProc(thePrDlg->pItemProc,(DialogPtr)thePrDlg, itemHit);
    }
 
    SetPort(SavePort);
    if (thePrDlg->fDoIt) {              // save in PREC 1 
        theDefault = (THPrint)ReallyGetResource('PREC', 1);
        if (theDefault != NULL) {
            **theDefault = **hPrint;
            ChangedResource((Handle)theDefault);
            WriteResource((Handle)theDefault);
        }
        doit = true;
    }
 
    DisposeRoutineDescriptor(thePrDlg->pFltrProc);
    DisposeRoutineDescriptor(thePrDlg->pItemProc);
    CloseDialog((DialogPtr)thePrDlg);
    DisposePtr((Ptr)thePrDlg);
 
    return doit;
}
 
pascal TPPrDlg FilePrJobInit(THPrint hPrint)
{
    // we initialize the dialog items with the right settings coming from hPrint 
    DialogPtr aDlg;
    TPPrDlg theDlg;
    SysEnvRec theWorld;
 
    theDlg = (TPPrDlg) NewPtr(sizeof(TPrDlg));
    if (theDlg == NULL) {
        DebugStr("\pCouldn't allocate enough memory for a TPPrDlg. Ummerbay.");
        setPrintErr(iMemFullErr);
        return 0;
    }
 
    theDlg->pFltrProc = NewModalFilterProc(FilterNumPrStlAndJob);
    theDlg->pItemProc = NewPItemProc(HandleJobItems);
    theDlg->fDoIt = false;
    theDlg->fDone = false;
    theDlg->hPrintUsr = hPrint;
 
    aDlg = GetNewDialog(pageSetupDialogID, theDlg, (WindowPtr)-1);
    if (aDlg == NULL) {
        DebugStr("\pCouldn't load the Page Setup dialog. Ummerbay.");
        setPrintErr(resNotFound);
        DisposePtr((Ptr)theDlg);
        return 0;
    }
    DialogPosition(aDlg);
 
    SysEnvirons(1, &theWorld);
 
    if (!theWorld.hasColorQD) {
        HideDItem(aDlg, jobColorButtonID);
        HideDItem(aDlg, jobBlackWhiteButtonID);
        (**hPrint).printX[8] = 1;
    }
 
    if ((**hPrint).printX[6]) {
        SetDialogItemNumber(aDlg, jobFromTextID, (**hPrint).prJob.iFstPage);
        SetDialogItemNumber(aDlg, jobToTextID, (**hPrint).prJob.iLstPage);
        SetDialogControlValue(aDlg, jobAllButtonID, 0);
        SetDialogControlValue(aDlg, jobFromButtonID, 1);
    } else {
        SetDialogControlValue(aDlg, jobAllButtonID, 1);
        SetDialogControlValue(aDlg, jobFromButtonID, 0);
    }
 
    SetDialogControlValue(aDlg, jobColorButtonID, (**hPrint).printX[8] == 0);
    SetDialogControlValue(aDlg, jobBlackWhiteButtonID, (**hPrint).printX[8] == 1);
 
    ShowWindow(aDlg);
    SetPort(aDlg);
    return theDlg;
}
 
pascal void HandleJobItems(TPPrDlg thePrDlg, short ItemHit)
{
    THPrint hPrint = thePrDlg->hPrintUsr;
    DialogPtr theDialog = (DialogPtr)(thePrDlg);
    switch (ItemHit) { 
        case printOkButton:
            if (GetDialogControlValue(theDialog, jobAllButtonID) == 0) {
                (**hPrint).prJob.iFstPage = GetDialogItemNumber(theDialog, jobFromTextID);
                (**hPrint).prJob.iLstPage = GetDialogItemNumber(theDialog, jobToTextID);
                (**hPrint).printX[6] = 1;
            } else {
                (**hPrint).prJob.iFstPage = iPrPgFst;
                (**hPrint).prJob.iLstPage = iPrPgMax;
                (**hPrint).printX[6] = 0;
            }
 
            // We don't handle copies at the moment, but if we did,
            // and we were going to be the one to do multiple copies
            // instead of letting the application do it, this'd be
            // the place where we'd want to stuff the number of copies
            // into a private structure, and put 1 in for the app.
            // If we want the app to handle it, we should fill in the
            // iCopies field of the job record here.
 
            if (GetDialogControlValue(theDialog, jobColorButtonID) == 0) 
                (**hPrint).printX[8] = 1;
            else 
                (**hPrint).printX[8] = 0;
 
            thePrDlg->fDone = true;
            thePrDlg->fDoIt = true;
            break;
 
        case printCancelButton:
            thePrDlg->fDone = true;
            thePrDlg->fDoIt = false;
            break;
 
        case jobFromButtonID:
                SetDialogItemNumber(theDialog, jobFromTextID, (**hPrint).prJob.iFstPage);
                SetDialogItemNumber(theDialog, jobToTextID, (**hPrint).prJob.iLstPage);
        case jobAllButtonID:
            if (GetDialogControlValue(theDialog, ItemHit) == 0) {
                SetDialogControlValue(theDialog, ItemHit, 1);
                SetDialogControlValue(theDialog,
                    (jobAllButtonID+jobFromButtonID) - ItemHit, 0); // change the other one
            }
            break;
 
        case jobFromTextID:
        case jobToTextID:
            if (GetDialogControlValue(theDialog, jobFromButtonID) == 0) {
                SetDialogItemNumber(theDialog, jobFromTextID, (**hPrint).prJob.iFstPage);
                SetDialogItemNumber(theDialog, jobToTextID, (**hPrint).prJob.iLstPage);
                SetDialogControlValue(theDialog, jobFromButtonID, 1);
                SetDialogControlValue(theDialog, jobAllButtonID, 0);
            }
            break;
 
        case jobColorButtonID:
        case jobBlackWhiteButtonID:
            if (GetDialogControlValue(theDialog, ItemHit) == 0) {
                SetDialogControlValue(theDialog, ItemHit, 1);
                SetDialogControlValue(theDialog,
                    (jobColorButtonID + jobBlackWhiteButtonID) - ItemHit, 0);
            }
            break;
    }
}
 
Boolean FilePrDlgJob(THPrint hPrint)
{
    TPPrDlg thePrDlg;
    GrafPtr SavePort;
    short itemHit;
    Boolean doit = false;
 
    thePrDlg = FilePrJobInit(hPrint);
    if (!thePrDlg) {
        SysBeep(1);
        return(false);
    }
 
    GetPort(&SavePort);
    FrameDialogItem((DialogPtr)thePrDlg,1);
    while (!(thePrDlg->fDone)) {
        ModalDialog(thePrDlg->pFltrProc, &itemHit);
        CallPItemProc(thePrDlg->pItemProc,(DialogPtr)thePrDlg, itemHit);
    }
 
    SetPort(SavePort);
    if (thePrDlg->fDoIt) {
        THPrint theDefault;
 
        theDefault = (THPrint)ReallyGetResource('PREC', 1);
        if (theDefault != NULL) {
            **theDefault = **hPrint;
            ChangedResource((Handle)theDefault);
            WriteResource((Handle)theDefault);
        }
        doit = true;
    }
    DisposeRoutineDescriptor(thePrDlg->pFltrProc);
    DisposeRoutineDescriptor(thePrDlg->pItemProc);
    CloseDialog((DialogPtr)thePrDlg);
    DisposePtr((Ptr)thePrDlg);
 
    return doit;
}
 
// the main 4 entry points follow
pascal Boolean FilePrStlDialog(THPrint hPrint)
{
    return FilePrDlgStl(hPrint);
}
 
pascal Boolean FilePrJobDialog(THPrint hPrint)
{
    return FilePrDlgJob(hPrint);
}
 
pascal void FilePrJobMerge(THPrint hPrintSrc, THPrint hPrintDst)
{
    FilePrValidate(hPrintSrc);
    if (FilePrValidate(hPrintDst)) {    // something changed => it wasn't kosher
        **hPrintDst = **hPrintSrc;      // so just slam in the "good" stuff
    } else {
        (**hPrintDst).prJob = (**hPrintSrc).prJob;  // this is all job specific
        // printX[6] is flag saying whether we're doing a range or all pages
        (**hPrintDst).printX[6] = (**hPrintSrc).printX[6];
    }
    FilePrValidate(hPrintDst);
}
 
pascal Boolean FilePrDlgMain(THPrint hPrint, PDlgInitProcPtr initFunc)
{
    TPPrDlg thePrDlg;
    GrafPtr SavePort;
    short itemHit;
    Boolean doit = false;
 
    thePrDlg = CallPDlgInitProc(initFunc,hPrint);
    if (!thePrDlg) {
        SysBeep(1);
        return(false);
    }
 
    GetPort(&SavePort);
    FrameDialogItem((DialogPtr)thePrDlg,1);
    while (!(thePrDlg->fDone)) {
        ModalDialog(thePrDlg->pFltrProc, &itemHit);
        CallPItemProc(thePrDlg->pItemProc,(DialogPtr)thePrDlg, itemHit);
    }
 
    SetPort(SavePort);
    if (thePrDlg->fDoIt) {
        THPrint theDefault;
 
        theDefault = (THPrint)ReallyGetResource('PREC', 1);
        if (theDefault != NULL) {
            **theDefault = **hPrint;
            ChangedResource((Handle)theDefault);
            WriteResource((Handle)theDefault);
        }
        doit = true;
    }
    DisposeRoutineDescriptor(thePrDlg->pFltrProc);
    DisposeRoutineDescriptor(thePrDlg->pItemProc);
    CloseDialog((DialogPtr)thePrDlg);
    DisposePtr((Ptr)thePrDlg);
 
    return doit;
}