Menu.c

/*------------------------------------------------------------------------------
*
*  Apple Developer Technical Support
*
*  Menu handling routines
*
*  Program:    AEObject-Edition Sample
*  File:       Menu.c -    C Source
*
*  by:         C.K. Haun <TR>
*
*  Copyright © 1990-1992 Apple Computer, Inc.
*  All rights reserved.
*
*------------------------------------------------------------------------------
* This file handles menu stuff, swapping checkmarks, handling simple dialog 
* boxes, and the like.  If it happens because of a menu selection, it comes through
* here.
*----------------------------------------------------------------------------*/
 
#define __SAMPMENU__
 
#pragma segment Menu
 
#include "Sampdefines.h"
short pItemChecked;
 
static void SampleHelpDialog(void);
static void DoAbout(void);
CursHandle pCursHand = nil;
 
 
#pragma segment Menu
/* DoSelected is called from the main event loop in response to a 
*   MenuSelect or MenuKey action.  Some events are handled here,
*   some just set options.
*/
 
/* the long passed is the result from MenuSelect or MenuKey */
/* this passes back a Boolean, which I don't use right now. */
Boolean DoSelected(long val)
{
    short loval, hival;
    Boolean temp = false;
    Str63 menuText;
    windowCHandle tempWC;
    short tempActionOut;
    loval = LoWord(val);
    hival = HiWord(val);
    if(FrontWindow())tempWC = (windowCHandle)GetWRefCon(FrontWindow());    
    switch (hival) {                                        /* switch off the menu number selected */
        case kGetDataSubmenu:
            SendGetData(loval);
            break;
        case kSetDataSubmenu:
            SendSetData(loval);
        break;
        case kAppleMenu:                                    /* Apple menu */
            if (loval != kAboutItem) {                               /* if this was not About, it's a DA */
                DoDaCall(gAppleMenuHandle, loval);
            } else {
                DoAbout();                                  /* do about box */
            }
            break;
        case kFileMenu:                                     /* File menu */
            switch (loval) {
                WindowPtr tempW;
                AliasHandle tempAlias;                      /* for SaveAs */
                windowCHandle tempName;
                case kNewItem:
                    if (!(tempW = AddNewWindow(true)))      /* Call AddNewWindow.  If it fails, tell */
                    {
                        ModalFilterUPP upp = NewModalFilterProc(standardAlertFilter);
                        Alert(kNoMoreWindows, upp);         /* user why */
                        DisposeRoutineDescriptor(upp);
                   }
                    else
                        ChangePlane(tempW);
                    break;
                case kOpenItem:
                    OpenFile(nil);                          /* open a file, nil says that I am not passing a */
                    /* FileSpec, promt the user for a name */
                    break;
                case kCloseItem:                            /* call the close procedure for this window */
                    (ProcPtr)((*tempWC)->closeMe)(FrontWindow());
                    break;
                case kSaveItem:                             /* call the save procedure for this window */
                    HLock((Handle)(windowCHandle)((WindowPeek)FrontWindow())->refCon);
                    (ProcPtr)((*tempWC)->saveMe)(tempWC, FrontWindow());
                    HUnlock((Handle)(windowCHandle)((WindowPeek)FrontWindow())->refCon);
                    break;
                case kSaveAsItem:                           /* save under a different name */
                    HLock((Handle)tempWC);
                    tempName = (windowCHandle)GetWRefCon(FrontWindow());
                    /* save off the old alias in case the person cancels */
                    tempAlias = (*tempName)->fileAliasHandle;
                    /* get an empty handle and store it in the alias place, this tells the Save */
                    /* function that this file has not yet been saved, so put up a SF box */
                    (*tempName)->fileAliasHandle = (AliasHandle)NewHandle(0);
                    (ProcPtr)((*tempWC)->saveMe)(tempWC, FrontWindow());
                    /* see if they really saved (by checking the size of the alias) and if they have */
                    /* get rid of the alias you saved */
                    if (GetHandleSize((Handle)(*tempName)->fileAliasHandle) == nil) {
                        DisposeHandle((Handle)(*tempName)->fileAliasHandle);
                        (*tempName)->fileAliasHandle = tempAlias;
                    } else {
                        DisposeHandle((Handle)tempAlias);
                    }
                    HUnlock((Handle)tempWC);
                    break;
                    
                case kPrintItem:
                    PrintIt(FrontWindow(), true);
                    break;
                case kPreferences:
                    DoPreferences();
                    break;
                case kQuitItem:
                    PrepQuit();                             /* Call PrepQuit, which sets our quit flag, so we */
                    /* quit the next time through the event loop. The */
                    /* AEQuit handler also calls this routine */
                    break;
            }
            break;
        case kEditMenu:
            /* edit menu junk */
            switch (loval) {
                case kUndoItem:
                    UndoLast();                             /* Undoes the last action in the frontmost window */
                    break;
                    /* all the C/C/P stuff acts _first_ on any active TextEdit records. */
                    /* if there aren't any, then it goes to other stuff */
                case kCutItem:
                    if (!CutText()){
                        if((*tempWC)->hasSelection){
                        CutGraphic(tempWC);
                        } else {
                        CutSubscription();}}
                    break;
                case kCopyItem:
                    if (!CopyText()){
                        if((*tempWC)->hasSelection){
                        CopyGraphic(tempWC);
                        } else {
                        CopySubscription();}}
                    break;
                case kPasteItem:
                    /* pasting text has precidence over subscriptions.  Just because I felt like it */
                    /* vary to suit the needs of your users and application */
                    if (!PasteText())
                        PasteSubscription();
                    break;
                case kClearItem:
                    /* Clear item acts as 'cancel' for the selected section */
                    if (!ClearText()){
                        if((*tempWC)->hasSelection){
                        ClearGraphic(tempWC);
                        } else {
                        DeleteSubscriber();}}
                    break;
                case kPublishItem:
                    /* see if there is any text */
                    if (HasTESelection((windowCHandle)GetWRefCon(FrontWindow())))
                        CreatePublisher(kGenericTEXTWord, false, nil);
                    else
                        CreatePublisher(kGenericPICTWord, false, nil);        /* in Publish.c */
                    break;
                case kSubscribeItem:
                    DoSubscribe();                          /* in Subscribe.c */
                    break;
                case kSoptionsItem:
                    DoOptions(gShowingSecHandle);           /* in Subscribe.c.  Same */
                    /* function is called for a publish or subscribe section */
                    break;
                case kBorders:
                    if (gShowingAll) {
                        gShowingAll = false;
                        GetIndString(menuText, kGeneralStrings, kShowBString);
                        
                        SetMenuItemText(gEditMenuHandle, kBorders, menuText);
                        
                        /* and get rid of any currently shown borders, even the */
                        /* last clicked in one */
                        DeBorderSelection();
                        KillTextBorders();
                    } else {
                        gShowingAll = true;
                        GetIndString(menuText, kGeneralStrings, kHideBString);                        
                        SetMenuItemText(gEditMenuHandle, kBorders, menuText);
                        ShowAllTextBorders();
                    }
                    /* make sure they get redrawn */
                    InvalRect(&(FrontWindow()->portRect));                    
                    break;
                case kClapNum:
                    if (((WindowPeek)FindClipWindow())->visible) {
                        CloseClip(FindClipWindow());
                    } else {
                        ShowWindow(FindClipWindow());
                        AddToWindowMenu(FindClipWindow(), nil);
                        ChangePlane(FindClipWindow());
                        GetIndString(menuText, kGeneralStrings, kHideClipString);                        
                        SetMenuItemText(gEditMenuHandle, kClapNum, menuText);
                        
                    }
                    break;
                    
            }                                               /* edit menu switch */
            break;
        case kToolsMenu:
            switch (loval) {
                /* Clean this up, this is silly, I say, this is silly son..... */
                case kLineItem:
                    tempActionOut = kDrawLine;
                    break;
                case kRectItem:
                    tempActionOut = kDrawRect;
                    break;
                case kOvalItem:
                    tempActionOut = kDrawOval;
                    break;
                case kTextBoxItem:
                    tempActionOut = kTextBox;
                    break;
                case kSelectItem:
                    tempActionOut = kSelectStuff;
                    break;
                    
            }
            /* these set the current action for the front window, set the */
            /* cursor for the selected tool, and check the correct menu item */
            KillSelection((windowCHandle)GetWRefCon(FrontWindow()));
            SetCurAction(tempActionOut);
            SetMyCursor(loval);
            SwitchChecks(loval);
            break;
        case kAEMenu:
            switch (loval) {
                case kInteractionItem:
                    SetInteractionLevels();
                    break;
                case kAddressItem:
                    SetTargetAddress();
                    break;
                case kReplyItem:
                    SetReplyMode();
                    break;
                case kShowAEWind:
                    ToggleAEWindow();
                    break;
                    /* set the characteristics that will make up the object specifier */
                    /* for the window to be acted upon.  Jeez, pendantic enough, or what? */
                    
                case kWindowObjChar:
                case kTextObjectChar:
                case kShapeObjectChar:
                    DoObjectDefinition((loval - kWindowObjChar) + kSetWindowObject);
                    break;
                case kSendGetDataAE:
                    /* has sub-menu, should never be returned */
                    break;
                    
                case kSendSetDataAE:
                    /* has sub-menu, should never be returned */
                    break;
                default:
                    
                    break;
            }
            break;
        case kEditionMenu:
        DoEditionAdditional(loval);
        break;
        case kWindowMenu:
            WindowToFront(loval,nil);
            break;
        case kColorMenu:
 
        CheckItem(gColorMenuHandle, gCurrentColor,false);
        CheckItem(gColorMenuHandle, loval,true);
        if(loval == kCustomColorItem){Point where = {-1,-1};
        Str255 thewords;
        RGBColor newColor;
        GetIndString(thewords,kGeneralStrings,kCPick);
        if(GetColor(where,thewords,&gColorArray[gCurrentColor],&newColor))gColorArray[kCustomColorItem] = newColor;
        }
        gCurrentColor = loval;
                
        
        break;
        case kHMHelpMenuID:
            /* I only care about this one item.  If anything else is returned here, I don't know what */
            /* it is, so I leave it alone.  Remember, the Help Manager chapter syas that */
            /* Apple reserves the right to add and change things in the Help menu */
            if (loval == gHelpItem)
                SampleHelpDialog();
            break;
            
    }
    HiliteMenu(0);
    return(temp);   /* I have never actually use this return value in 6 years, but I might some day.  */
    /* I always put it in because it _could_ be real handy */
}
 
/* end DoSelected */
 
/* DoDaCall opens the requested DA.  It's here as a seperate routine if you'd */
/* like to perform some action or just know when a DA is opened in your */
/* layer.  Can be handy to track memory problems when a DA is opened */
/* with an Option-open */
void DoDaCall(MenuHandle themenu, long theit)
{
    long qq;
    char DAname[255];
    GetMenuItemText(themenu, theit, &DAname);
    qq = OpenDeskAcc(DAname);
}
 
/* end DoDaCall */
 
/* PrepQuit sets the stop flag.  Called from the menu or from the */
/* quit AppleEvent handler.  It also calls the close function on all open windows, and */
/* cancels the quit if the user stops things */
/* Also unregisters the ClipBoard section, if one exists */
OSErr PrepQuit(void)
{
    WindowPtr tempFront = (WindowPtr)LMGetWindowList();
    windowCHandle tempWCH;
    gStop = true;
    while (tempFront) {
        WindowPtr tempHolder;
        tempHolder = (WindowPtr)((WindowPeek)tempFront)->nextWindow;
        tempWCH = (windowCHandle)GetWRefCon(tempFront);
        (ProcPtr)((*tempWCH)->closeMe)(tempFront);          /* call this closing routine */
        tempFront = tempHolder;                             /* yeah, yeah , a little duplication.  */
        if (gStop == false)
            break;                                          /* if this is false, they hit cancel in the close routine */
    }
    if (gStop) {
        extern short gClipHasContents;
        extern SectionHandle gClipSection;
        /* clear the clipboard */
        /* if it has a section, we have to tell the Edition Manager we're done with it */
        if (gClipHasContents == kClipHasSub) {
            UnRegisterSection(gClipSection);
            DisposeHandle((Handle)(*gClipSection)->alias);
            DisposeHandle((Handle)gClipSection);
            gClipSection = nil;
            gClipHasContents = kClipEmpty;
        }
        return(noErr);                                      /* quit will happen */
    } else {
        return(userCanceledErr);
    }                                                       /* user stopped the termination */
}
 
/* end PrepQuit */
 
/* SetUndo sets the text of the Undo item based on the last action in */
/* the current window, if fromRecord is true, else use*/
/* undoNow */
void SetUndo(short undoNow, Boolean fromRecord)
{Str255 undoString;
    windowCHandle temp;
    if (FrontWindow() == nil) {
        GetIndString(undoString, kUndoStringsRes, 1);
        SetMenuItemText(gEditMenuHandle, kUndoItem, &undoString);
        DisableItem(gEditMenuHandle, kUndoItem);
    } else {
        temp = (windowCHandle)GetWRefCon(FrontWindow());
        if (fromRecord)
            undoNow = (*temp)->undoAction;
        else
            (*temp)->undoAction = undoNow;
        GetIndString(undoString, kUndoStringsRes, undoNow + 1);
        SetMenuItemText(gEditMenuHandle, kUndoItem, &undoString);
        if (undoNow)
            EnableItem(gEditMenuHandle, kUndoItem);
        else
            DisableItem(gEditMenuHandle, kUndoItem);
    }
}
 
/* end SetUndo */
 
/* SetMyCursor sets the cursor to the correct shape for the */
/* tool in use */
void SetMyCursor(short myCurs)
{
    if (pCursHand != nil) {
        ReleaseResource((Handle)pCursHand);
        pCursHand = nil;
    }
    if (myCurs == 0) {
        InitCursor();
    } else {
        switch (myCurs) {
            case kLineItem:
                pCursHand = GetCursor(crossCursor); /* in the system file */
                break;
            case kRectItem:
            case kTextBox:
            case kOvalItem:
                pCursHand = (CursHandle)GetResource('CURS', 126 + myCurs);
                break;
            case kSelectItem:
                pCursHand = (CursHandle)GetResource('CURS', 131);
                break;
        }
        SetCursor(*pCursHand);
    }
}
 
/* end SetMyCursor */
 
/* SwitchChecks sets the checking of the tool menu items  */
void SwitchChecks(short itemNow)
{
    Boolean how;
    if (pItemChecked == itemNow) {                          /* is this item currently checked?  If so */
        how = false;                                        /* uncheck it and set action to nil */
        SetCurAction(kNoAction);
        InitCursor();
        pItemChecked = 0;
    } else {
        CheckItem(gToolMenuHandle, pItemChecked, false);
        pItemChecked = itemNow;
        how = true;
    }
    CheckItem(gToolMenuHandle, itemNow, how);
}
 
/* end SwitchChecks */
 
/* SetCurAction sets the action value in the window record */
void SetCurAction(short actionIn)
{
    if (FrontWindow() != nil) {
        windowCHandle shortname = (windowCHandle)GetWRefCon(FrontWindow());
        HLock((Handle)shortname);
        (*shortname)->currentAction = actionIn;
        HUnlock((Handle)shortname);
    }
}
 
/* end SetCurAction */
 
void SetWMenus(Boolean how)
{
    short qq;
    if (how) {
        EnableItem(gFileMenuHandle, kCloseItem);
        EnableItem(gFileMenuHandle, kPrintItem);
        EnableItem(gFileMenuHandle, kSaveItem);
        EnableItem(gFileMenuHandle, kSaveAsItem);
        EnableItem(gEditMenuHandle, kSubscribeItem);
        EnableItem(gToolMenuHandle, 0);
        for (qq = 1; qq < 5; qq++) {
            EnableItem(gToolMenuHandle, qq);
        }
    } else {
        DisableItem(gFileMenuHandle, kCloseItem);
        DisableItem(gFileMenuHandle, kPrintItem);
        DisableItem(gFileMenuHandle, kSaveItem);
        DisableItem(gFileMenuHandle, kSaveAsItem);
        DisableItem(gEditMenuHandle, kSubscribeItem);
        DisableItem(gToolMenuHandle, 0);                    /* kill this whole thing */
    }
    DrawMenuBar();
}
 
/* end SetWMenus */
 
/* AdjustMenus is called right before MenuSelect or MenuKey to set the state of */
/* the menu items for the frontmost window.  */
void AdjustMenus(windowCHandle tempCH,WindowPtr currentWindow)
{
    Str63 menuText;
    register qq;
    Str63 item, name;
    short count;
    short wKind;
    /* Do we currently */
    /* have an area selected? */
    if(currentWindow)
        wKind = ((WindowPeek)currentWindow)->windowKind;
    if (tempCH && ((*tempCH)->hasSelection || HasTESelection(tempCH)))            /* Yes, enable the Publish item */
        EnableItem(gEditMenuHandle, kPublishItem);
    else                                                    /* No, dim the publish item */
        DisableItem(gEditMenuHandle, kPublishItem);
    
    /* Next, are we showing a border around a subscriber or */
    /* publisher? If so, then we allow the user to bring up */
    /* the Options dialog */
    if (gShowPub || gShowSub) {
        EnableItem(gEditMenuHandle, kSoptionsItem);
        EnableItem(gEditionMenuHandle,kGetSecInfo);
    } else {
        DisableItem(gEditMenuHandle, kSoptionsItem);
        DisableItem(gEditionMenuHandle,kGetSecInfo);
    }
       /* is there a document or AEStatus window in front? */
if (currentWindow != nil && (wKind == kDocumentWindow || wKind == kAEStatusWindow)) {
        EnableItem(gFileMenuHandle, kSaveItem);
        /* this following little if is based on a pickiness I have personally */
        /* If the window has not yet been saved, include an ellipsis in the 'SaveÉ' */
        /* item, since the standard file box will be coming up. */
        /* if it has been saved, then no dots, just 'Save' */
        /* since there won't be a dialog */
        if (GetHandleSize((Handle)(*tempCH)->fileAliasHandle) == nil) {
            GetIndString(menuText, kGeneralStrings, kSaveDotsString);
            SetMenuItemText(gFileMenuHandle, kSaveItem, menuText);
        } else {
            GetIndString(menuText, kGeneralStrings, kSaveNDotsString);
            SetMenuItemText(gFileMenuHandle, kSaveItem, menuText);
        }
        } else {
          DisableItem(gFileMenuHandle, kSaveItem);
        }       
    if (currentWindow != nil && wKind == kDocumentWindow ) {   /* is there a document window in front? */
            /* I'm only allowing a text box if there are no other objects. */
       if ((*tempCH)->boxHandle != nil || (*tempCH)->numShapes)
            DisableItem(gToolMenuHandle, kTextBoxItem);
        else
            EnableItem(gToolMenuHandle, kTextBoxItem);
        
    } else {
      
        /* make sure the undo and show borders items are right */
        SetUndo(nil, nil);
        GetIndString(menuText, kGeneralStrings, kShowBString);
        SetMenuItemText(gEditMenuHandle, kBorders, menuText);
        DisableItem(gEditMenuHandle, kBorders);
    }
    /* if there is a subscriber, or a subscription on the clipboard, or a TEselection enable the edit commands */
    if (tempCH && ((*tempCH)->hasSelection || gShowSub || HasTESelection(tempCH))) {
        EnableItem(gEditMenuHandle, kCutItem);
        EnableItem(gEditMenuHandle, kCopyItem);
        EnableItem(gEditMenuHandle, kClearItem);
    } else {
        DisableItem(gEditMenuHandle, kCutItem);
        DisableItem(gEditMenuHandle, kCopyItem);
        DisableItem(gEditMenuHandle, kClearItem);
    }
/* uuuh, sorry, this 'if' got a little out of hand */
if ((tempCH != nil) && (gClipHasContents == kClipHasSub || (gClipHasContents == kClipHasText && (*tempCH)->boxHandle != nil)) &&  wKind == kDocumentWindow) {
        EnableItem(gEditMenuHandle, kPasteItem);
    } else {
        DisableItem(gEditMenuHandle, kPasteItem);
    }
    if (currentWindow) {
        EnableItem(gFileMenuHandle, kCloseItem);
    } else {
        DisableItem(gFileMenuHandle, kCloseItem);
    }
    /* check frontmost window in the window menu */
    if (currentWindow) {
        count = CountMItems(gWindowMenuHandle);
        GetWTitle(currentWindow, name);
        for (qq = 1; qq < count + 1; qq++)
            CheckItem(gWindowMenuHandle, qq, false);
        for (qq = 1; qq < count + 1; qq++) {
            GetMenuItemText(gWindowMenuHandle, qq, &item);
            if (EqualString(item, name, false, false)) {
                CheckItem(gWindowMenuHandle, qq, true);
            }
        }
    } 
}
 
/* Just an example, since I had to have something to do when you select */
/* my Help item */
void SampleHelpDialog(void)
{
    DialogPtr tdial = GetNewDialog(kSampHelp, nil, (WindowPtr)-1);
    short itemhit = 0;
    ModalFilterUPP upp = NewModalFilterProc(standardDialogFilter);
 
    SetDialogDefaultItem(tdial, ok);
    while (itemhit != 1) {
        ModalDialog(upp, &itemhit);
    }
    DisposeRoutineDescriptor(upp);
    DisposeDialog(tdial);
}
 
/* The about box.   */
void DoAbout(void)
{
    DialogPtr tdial = GetNewDialog(kAboutBox, nil, (WindowPtr)-1);
    short hitItem = 0;
    short tempItem;
    Handle tempHandle;
    Rect tempRect;
    ModalFilterUPP upp = NewModalFilterProc(aboutFilter);
 
    GetDialogItem(tdial, kBorderArea, &tempItem, &tempHandle, &tempRect);
    SetDialogItem(tdial, kBorderArea, tempItem, (Handle)BorderDefault, &tempRect);
    GetDialogItem(tdial, kArrowArea, &tempItem, &tempHandle, &tempRect);
    SetDialogItem(tdial, kArrowArea, tempItem, (Handle)ArrowArea, &tempRect);
    ShowWindow(tdial);
    while (hitItem != ok) {
        ModalDialog(upp, &hitItem);
    }
    DisposeRoutineDescriptor(upp);
    DisposeDialog(tdial);
}
 
/* this filter does the icon animation */
pascal Boolean aboutFilter(DialogPtr theDialog, EventRecord *theEvent, short *itemHit)
{
    Boolean returnVal = false;
    static short pOffset = 1;
    static Boolean pMovingRight = true;
    
    static long count;
    long tilticks;
    Handle topIcon, bottomIcon;
    short tempItem;
    Handle tempHandle;
    Rect tempRect;
    Rect idleRect, iconRect;
    WindowPtr tempPort;
#define kReturnKey 0xd
#define kEnterKey 3
    GetPort(&tempPort);
    SetPort(theDialog);
    if ((theEvent->what == keyDown) || (theEvent->what == autoKey)) {
        switch (theEvent->message & charCodeMask) {
            case kReturnKey:
            case kEnterKey:                                 /* enter key */
                /* This filters for Return or Enter as item 1, and Esc as item 2 */
                    *itemHit = 1;                           /* change whatever the current item is to the OK item */
                /* now we need to invert the button */
                GetDialogItem(theDialog, ok, &tempItem, &tempHandle, &tempRect);
                HiliteControl(SnatchHandle(theDialog, ok), inButton);
                Delay(8, &tilticks);                        /* wait about 8 ticks so they can see it */
                HiliteControl(SnatchHandle(theDialog, ok), false);
                returnVal = true;
                break;
            default:
                break;
        }
    } else {
        /* Do fancy animation.  Hey, this sample is big, took a while to write, I should have */
        /* a fancy about box.  Anyway, it only took 1/2 hour (I used DialogBits.c) */
        GetDialogItem(theDialog, kArrowArea, &tempItem, &tempHandle, &tempRect);
        idleRect.top = tempRect.top;
        idleRect.bottom = idleRect.top + 32;
        idleRect.left = ((((tempRect.right - tempRect.left) / 2))+tempRect.left)-16;
        idleRect.right = idleRect.left + 32;
        iconRect = idleRect;
        if (pMovingRight) {
            /* going <- -> */
            topIcon = GetIcon(129);
            bottomIcon = GetIcon(130);
        } else {
            topIcon = GetIcon(130);
            bottomIcon = GetIcon(129);
            
        }
        OffsetRect(&iconRect, 1 * pOffset, 0);
        PlotIcon(&iconRect, topIcon);
        ReleaseResource(topIcon);
        iconRect = idleRect;
        OffsetRect(&iconRect, -1 * pOffset, 0);
        iconRect.bottom = tempRect.bottom;
        iconRect.top = iconRect.bottom - 32;
        PlotIcon(&iconRect, bottomIcon);
        ReleaseResource(bottomIcon);
        pMovingRight ? pOffset++ : pOffset--;
        if (pMovingRight) {
            if (iconRect.left <= tempRect.left)
                pMovingRight = false;
        } else {
            if (iconRect.right >= tempRect.right)
                pMovingRight = true;
        }
    }
    SetPort(tempPort);
    return(returnVal);
}
 
/* borders the default button.  Not needed with the new Dialog Manager calls, see Tech Note #304 */
pascal void BorderDefault(WindowPtr dwind, short dinum)
{
#pragma unused (dinum)
    short itemtype;
    Handle itemhandle;
    Rect borderRect;
    GetDialogItem(dwind, ok, &itemtype, &itemhandle, &borderRect);
    /* ok is defined as 1 in the interfaces.  If you'd like another item outlined, */
    /* change this number, of course. */
    InsetRect(&borderRect, -4, -4);
    PenSize(3, 3);
    FrameRoundRect(&borderRect, 16, 16);
    PenSize(1, 1);
}
 
/* user item for the area the arrows traverse.  doesn't do much */
pascal void ArrowArea(WindowPtr dwind, short dinum)
{
#pragma unused (dinum)
    short itemtype;
    Handle itemhandle;
    Rect borderRect;
    GetDialogItem(dwind, dinum, &itemtype, &itemhandle, &borderRect);
    EraseRect(&borderRect);
}
 
/* Our preferences dialog box */
pascal void FrameBox(WindowPtr rDial, short dinum);
void DoPreferences(void)
{
    DialogPtr tdial = CommonDStart(kPreferencesBox, nil, nil);
    short kindI;
    Handle HandL;
    Rect itemRect;
    short hitItem = 0;
    
    ShowWindow(tdial);
    /* Set the controls to the previously stored preferences */
    SetControlValue(SnatchHandle(tdial, kBringAEForwardCheck), gPreferences.bringAEUp);
    SetControlValue(SnatchHandle(tdial, kVerboseCheck), gPreferences.verboseAE);
    SetControlValue(SnatchHandle(tdial, kSaveWindCheck), gPreferences.saveWindDef);
    SetControlValue(SnatchHandle(tdial, kSaveTextCheck), gPreferences.saveTextDef);
    SetControlValue(SnatchHandle(tdial, kSaveShapeCheck), gPreferences.saveShapeDef);
    SetControlValue(SnatchHandle(tdial, kSaveInteractCheck), gPreferences.saveInteract);
    SetControlValue(SnatchHandle(tdial, kSaveTargetCheck), gPreferences.saveTarget);
    SetControlValue(SnatchHandle(tdial, kSaveReplyCheck), gPreferences.saveReply);
 
    GetDialogItem(tdial, kFBox1, &kindI, &HandL, &itemRect);
    SetDialogItem(tdial, kFBox1, userItem, (Handle)FrameBox, &itemRect);
    GetDialogItem(tdial, kFBox2, &kindI, &HandL, &itemRect);
    SetDialogItem(tdial, kFBox2, userItem, (Handle)FrameBox, &itemRect);
    GetDialogItem(tdial, kFBox3, &kindI, &HandL, &itemRect);
    SetDialogItem(tdial, kFBox3, userItem, (Handle)FrameBox, &itemRect);
 
    /* run the dialog */
    while (hitItem != ok && hitItem != cancel) {
        ModalFilterUPP upp = NewModalFilterProc(standardAlertFilter);
        ModalDialog(upp, &hitItem);
        DisposeRoutineDescriptor(upp);
        switch (hitItem) {
            case 9:
                {
                ModalFilterUPP upp = NewModalFilterProc(standardAlertFilter);
                Alert(350, upp);
                DisposeRoutineDescriptor(upp);
                }
                break;
            case kBringAEForwardCheck:
            case kVerboseCheck:
            case kSaveWindCheck:
            case kSaveTextCheck:
            case kSaveShapeCheck:
            case kSaveInteractCheck:
            case kSaveTargetCheck:
            case kSaveReplyCheck:
            /* if they hit a checkbox, just toggle state */
                SetControlValue(SnatchHandle(tdial, hitItem), (GetControlValue(SnatchHandle(tdial, hitItem)) ? 0 : 1));
                break;
            default:
                break;
        }
    }
 
    if (hitItem == ok) {
        /* generate our new preferences */
        gPreferences.bringAEUp = GetControlValue(SnatchHandle(tdial, kBringAEForwardCheck));
        gPreferences.verboseAE = GetControlValue(SnatchHandle(tdial, kVerboseCheck));
        gPreferences.saveWindDef = GetControlValue(SnatchHandle(tdial, kSaveWindCheck));
        gPreferences.saveTextDef = GetControlValue(SnatchHandle(tdial, kSaveTextCheck));
        gPreferences.saveShapeDef = GetControlValue(SnatchHandle(tdial, kSaveShapeCheck));
        gPreferences.saveInteract = GetControlValue(SnatchHandle(tdial, kSaveInteractCheck));
        gPreferences.saveTarget = GetControlValue(SnatchHandle(tdial, kSaveTargetCheck));
        gPreferences.saveReply = GetControlValue(SnatchHandle(tdial, kSaveReplyCheck));     
        gPreferences.prefsChanged = true;
    }
    DisposeDialog(tdial);
}
 
 
/* Draws a greay outline and some text around related items in a DialogBox */
pascal void FrameBox(WindowPtr rDial, short dinum)
{
    Str63 wordsAre;
    
    Rect framer;
    Rect tempR;
    short itemIs;
    short widthY;
    Point thePen;
    Point start, end;
    Handle yeah;
    GetIndString(&wordsAre, 129, dinum - 12);
    GetDialogItem(rDial, dinum, &itemIs, &yeah, &framer);
    widthY = StringWidth(&wordsAre);
    
    /* do the sides first */
    /* left */
    start.h = framer.left;
    start.v = framer.top;
    end.h = framer.left;
    end.v = framer.bottom;
    MoveTo(start.h, start.v);
    LineTo(end.h, end.v);
    MakeRect(&start, &end, &tempR);
    PenPat(&qd.gray);
    PenMode(notPatBic);
    PaintRect(&tempR);
    PenMode(srcCopy);
    PenPat(&qd.black);
    /* bottom */
    start.h = framer.left;
    start.v = framer.bottom;
    end.h = framer.right;
    end.v = framer.bottom;
    MoveTo(start.h, start.v);
    LineTo(end.h, end.v);
    MakeRect(&start, &end, &tempR);
    PenPat(&qd.gray);
    PenMode(notPatBic);
    PaintRect(&tempR);
    PenMode(srcCopy);
    PenPat(&qd.black);
    /* right */
    start.h = framer.right;
    start.v = framer.bottom;
    end.h = framer.right;
    end.v = framer.top;
    MoveTo(start.h, start.v);
    LineTo(end.h, end.v);
    start.h -= 3;
    MakeRect(&start, &end, &tempR);
    PenPat(&qd.gray);
    PenMode(notPatBic);
    PaintRect(&tempR);
    PenMode(srcCopy);
    PenPat(&qd.black);
    
    /* top line to start of text */
    start.h = framer.left;
    start.v = framer.top;
    end.h = start.h + 10;
    end.v = framer.top;
    MoveTo(start.h, start.v);
    LineTo(end.h, end.v);
    start.h -= 3;
    MakeRect(&start, &end, &tempR);
    PenPat(&qd.gray);
    PenMode(notPatBic);
    PaintRect(&tempR);
    PenMode(srcCopy);
    PenPat(&qd.black);
    MoveTo(end.h+3, end.v + 4);
    DrawString(&wordsAre);
    GetPen(&thePen);
    /* end of text to corner */
    start.h = thePen.h+4;
    start.v = thePen.v - 4;
    end.h = framer.right;
    end.v = thePen.v - 4;
    MoveTo(start.h, start.v);
    LineTo(end.h, end.v);
    start.h -= 3;
    MakeRect(&start, &end, &tempR);
    PenPat(&qd.gray);
    PenMode(notPatBic);
    PaintRect(&tempR);
    PenMode(srcCopy);
    PenPat(&qd.black);
    
    
}
 
 
 
 
 
 
 
 
 
/* This handles the EM Stuff menu */
void DoEditionAdditional(short which)
{
EditionInfoRecord tempRecord;
Str63 orgDate;
Str63 modDate;
Str15 typeCreator;
   switch (which) {
        case kExpandedItem:
            gExpanded = gExpanded ? false : true;
            CheckItem(gEditionMenuHandle, kExpandedItem, gExpanded);
            
            break;
        case kGetSecInfo:
            {
            ModalFilterUPP upp = NewModalFilterProc(standardAlertFilter);
            GetEditionInfo(gShowingSecHandle, &tempRecord);
            IUDateString(tempRecord.crDate, longDate, orgDate);
            IUDateString(tempRecord.mdDate, longDate, modDate);
            typeCreator[0]=9;
            BlockMove((Ptr)&tempRecord.fdCreator, (Ptr)&typeCreator[1], 4);
            typeCreator[5] = '/';
            BlockMove((Ptr)&tempRecord.fdType, (Ptr)&typeCreator[6], 4);
            ParamText(orgDate, modDate, typeCreator,tempRecord.container.theFile.name);
            Alert(kEdInfo, upp);
            DisposeRoutineDescriptor(upp);
            }
            break;
      }
 
}
 
 
 
#undef __SAMPMENU__